Move yarn new templates from @backstage/cli to @backstage/cli-module-new

The built-in templates used by `yarn new` are moved from `packages/cli/templates/`
to `packages/cli-module-new/templates/`, colocating them with the code that
consumes them.

A backwards compatibility rewrite in the template resolution ensures that
existing `@backstage/cli/templates/*` references in root `package.json`
configurations continue to work by transparently resolving them to
`@backstage/cli-module-new/templates/*`.

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
This commit is contained in:
Patrik Oldsberg
2026-03-17 12:39:05 +01:00
parent e9eb585978
commit ea90ab0590
129 changed files with 146 additions and 49 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/cli': patch
---
The built-in `yarn new` templates have been moved to `@backstage/cli-module-new`. Existing references to `@backstage/cli/templates/*` in your root `package.json` will continue to work through a backwards compatibility rewrite in the `new` command.
@@ -0,0 +1,5 @@
---
'@backstage/create-app': patch
---
Updated the `next-app` template to reference `@backstage/cli-module-new/templates/*` instead of `@backstage/cli/templates/*` for the built-in `yarn new` templates.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/cli-module-new': patch
---
The built-in `yarn new` templates have been moved to this package from `@backstage/cli`. The default template references have been updated from `@backstage/cli/templates/*` to `@backstage/cli-module-new/templates/*`. Existing references to `@backstage/cli/templates/*` in your root `package.json` will continue to work through a backwards compatibility rewrite.
@@ -915,17 +915,17 @@ When creating a new Backstage app with `create-app` and using the `--next` flag
"license": "UNLICENSED"
},
"templates": [
"@backstage/cli/templates/new-frontend-plugin",
"@backstage/cli/templates/new-frontend-plugin-module",
"@backstage/cli/templates/backend-plugin",
"@backstage/cli/templates/backend-plugin-module",
"@backstage/cli/templates/plugin-web-library",
"@backstage/cli/templates/plugin-node-library",
"@backstage/cli/templates/plugin-common-library",
"@backstage/cli/templates/web-library",
"@backstage/cli/templates/node-library",
"@backstage/cli/templates/catalog-provider-module",
"@backstage/cli/templates/scaffolder-backend-module"
"@backstage/cli-module-new/templates/new-frontend-plugin",
"@backstage/cli-module-new/templates/new-frontend-plugin-module",
"@backstage/cli-module-new/templates/backend-plugin",
"@backstage/cli-module-new/templates/backend-plugin-module",
"@backstage/cli-module-new/templates/plugin-web-library",
"@backstage/cli-module-new/templates/plugin-node-library",
"@backstage/cli-module-new/templates/plugin-common-library",
"@backstage/cli-module-new/templates/web-library",
"@backstage/cli-module-new/templates/node-library",
"@backstage/cli-module-new/templates/catalog-provider-module",
"@backstage/cli-module-new/templates/scaffolder-backend-module"
]
}
}
+16 -12
View File
@@ -73,7 +73,7 @@ Custom templates can be installed from local directories. To install a template
Each entry in the `templates` array should be a relative path that points to a directory containing a `portable-template.yaml` file. If the path starts with `./` it will be used as is, otherwise it will be resolved as a module within `node_modules`.
When defining the `templates` array it will override the default set of templates. If you want to keep using one of the build-in templates in the Backstage CLI you can reference them directly within the CLI package. This following is the full list of built-in templates:
When defining the `templates` array it will override the default set of templates. If you want to keep using one of the build-in templates in the Backstage CLI you can reference them directly within the `@backstage/cli-module-new` package. This following is the full list of built-in templates:
```json
{
@@ -82,16 +82,16 @@ When defining the `templates` array it will override the default set of template
"cli": {
"new": {
"templates": [
"@backstage/cli/templates/frontend-plugin",
"@backstage/cli/templates/backend-plugin",
"@backstage/cli/templates/backend-plugin-module",
"@backstage/cli/templates/plugin-web-library",
"@backstage/cli/templates/plugin-node-library",
"@backstage/cli/templates/plugin-common-library",
"@backstage/cli/templates/web-library",
"@backstage/cli/templates/node-library",
"@backstage/cli/templates/catalog-provider-module",
"@backstage/cli/templates/scaffolder-backend-module"
"@backstage/cli-module-new/templates/frontend-plugin",
"@backstage/cli-module-new/templates/backend-plugin",
"@backstage/cli-module-new/templates/backend-plugin-module",
"@backstage/cli-module-new/templates/plugin-web-library",
"@backstage/cli-module-new/templates/plugin-node-library",
"@backstage/cli-module-new/templates/plugin-common-library",
"@backstage/cli-module-new/templates/web-library",
"@backstage/cli-module-new/templates/node-library",
"@backstage/cli-module-new/templates/catalog-provider-module",
"@backstage/cli-module-new/templates/scaffolder-backend-module"
]
}
}
@@ -99,6 +99,10 @@ When defining the `templates` array it will override the default set of template
}
```
:::note
The old `@backstage/cli/templates/*` paths are still supported for backwards compatibility and will be automatically rewritten to `@backstage/cli-module-new/templates/*`.
:::
## Creating your own CLI templates
Each template lives in its own directory and must have a `portable-template.yaml` file that describes the template. The template directory can also contain any files that should be templated or copied to the generated package.
@@ -128,7 +132,7 @@ export function getPluginId() {
}
```
If you'd like to see more examples, you can find all the default templates and their yaml files [here](https://github.com/backstage/backstage/tree/master/packages/cli/templates).
If you'd like to see more examples, you can find all the default templates and their yaml files [here](https://github.com/backstage/backstage/tree/master/packages/cli-module-new/templates).
Once your template is ready, [add it to your config](#installing-custom-templates), and you should now be able to select it when running `yarn new`.
+4 -3
View File
@@ -19,9 +19,11 @@
"license": "Apache-2.0",
"main": "src/index.ts",
"types": "src/index.ts",
"bin": "bin/backstage-cli-module-new",
"files": [
"dist",
"bin"
"bin",
"templates"
],
"scripts": {
"build": "backstage-cli package build",
@@ -57,6 +59,5 @@
"@types/inquirer": "^8.1.3",
"@types/lodash": "^4.14.151",
"@types/recursive-readdir": "^2.2.0"
},
"bin": "bin/backstage-cli-module-new"
}
}
@@ -15,15 +15,15 @@
*/
export const defaultTemplates = [
'@backstage/cli/templates/frontend-plugin',
'@backstage/cli/templates/backend-plugin',
'@backstage/cli/templates/backend-plugin-module',
'@backstage/cli/templates/plugin-web-library',
'@backstage/cli/templates/plugin-node-library',
'@backstage/cli/templates/plugin-common-library',
'@backstage/cli/templates/web-library',
'@backstage/cli/templates/node-library',
'@backstage/cli/templates/cli-module',
'@backstage/cli/templates/catalog-provider-module',
'@backstage/cli/templates/scaffolder-backend-module',
'@backstage/cli-module-new/templates/frontend-plugin',
'@backstage/cli-module-new/templates/backend-plugin',
'@backstage/cli-module-new/templates/backend-plugin-module',
'@backstage/cli-module-new/templates/plugin-web-library',
'@backstage/cli-module-new/templates/plugin-node-library',
'@backstage/cli-module-new/templates/plugin-common-library',
'@backstage/cli-module-new/templates/web-library',
'@backstage/cli-module-new/templates/node-library',
'@backstage/cli-module-new/templates/cli-module',
'@backstage/cli-module-new/templates/catalog-provider-module',
'@backstage/cli-module-new/templates/scaffolder-backend-module',
];
@@ -200,6 +200,72 @@ describe('loadPortableTemplateConfig', () => {
});
});
it('should rewrite legacy @backstage/cli/templates paths', async () => {
mockDir.setContent({
'package.json': JSON.stringify({
backstage: {
cli: {
new: {
templates: [
'@backstage/cli/templates/backend-plugin',
'@backstage/cli/templates/frontend-plugin',
],
},
},
},
}),
node_modules: {
'@backstage': {
'cli-module-new': {
templates: {
'backend-plugin': {
[TEMPLATE_FILE_NAME]:
'name: backend-plugin\nrole: backend-plugin\n',
},
'frontend-plugin': {
[TEMPLATE_FILE_NAME]:
'name: frontend-plugin\nrole: frontend-plugin\n',
},
},
},
},
},
});
await expect(
loadPortableTemplateConfig({
packagePath: mockDir.resolve('package.json'),
}),
).resolves.toEqual({
isUsingDefaultTemplates: false,
templatePointers: [
{
name: 'backend-plugin',
target: realpathSync(
mockDir.resolve(
'node_modules/@backstage/cli-module-new/templates/backend-plugin',
TEMPLATE_FILE_NAME,
),
),
},
{
name: 'frontend-plugin',
target: realpathSync(
mockDir.resolve(
'node_modules/@backstage/cli-module-new/templates/frontend-plugin',
TEMPLATE_FILE_NAME,
),
),
},
],
license: 'Apache-2.0',
private: true,
version: '0.1.0',
packageNamePrefix: '@internal/',
packageNamePluginInfix: 'backstage-plugin-',
});
});
it('should reject templates with conflicting names', async () => {
mockDir.setContent({
'package.json': JSON.stringify({
@@ -157,6 +157,9 @@ export async function loadPortableTemplateConfig(
};
}
const CLI_TEMPLATE_PREFIX = '@backstage/cli/templates/';
const CLI_MODULE_NEW_TEMPLATE_PREFIX = '@backstage/cli-module-new/templates/';
function resolveLocalTemplatePath(pointer: string, basePath: string): string {
if (isAbsolute(pointer)) {
throw new Error(`Template target may not be an absolute path`);
@@ -166,7 +169,14 @@ function resolveLocalTemplatePath(pointer: string, basePath: string): string {
return resolvePath(basePath, pointer, TEMPLATE_FILE_NAME);
}
return require.resolve(`${pointer}/${TEMPLATE_FILE_NAME}`, {
// Rewrite legacy @backstage/cli/templates/* paths to @backstage/cli-module-new/templates/*
const resolvedPointer = pointer.startsWith(CLI_TEMPLATE_PREFIX)
? `${CLI_MODULE_NEW_TEMPLATE_PREFIX}${pointer.slice(
CLI_TEMPLATE_PREFIX.length,
)}`
: pointer;
return require.resolve(`${resolvedPointer}/${TEMPLATE_FILE_NAME}`, {
paths: [basePath],
});
}

Some files were not shown because too many files have changed in this diff Show More