diff --git a/packages/cli/.eslintrc.js b/packages/cli/.eslintrc.js index 4ae4e8d91b..69bec6cd2a 100644 --- a/packages/cli/.eslintrc.js +++ b/packages/cli/.eslintrc.js @@ -1,5 +1,5 @@ module.exports = { - extends: [require.resolve('@backstage/cli/config/eslint')], + extends: [require.resolve('@backstage/cli/config/eslint.backend')], ignorePatterns: ['templates/**'], rules: { 'no-console': 0, diff --git a/packages/cli/bin/backstage-cli b/packages/cli/bin/backstage-cli index 15b97d7063..2b445ca9af 100755 --- a/packages/cli/bin/backstage-cli +++ b/packages/cli/bin/backstage-cli @@ -21,11 +21,13 @@ const path = require('path'); const isLocal = require('fs').existsSync(path.resolve(__dirname, '../src')); if (!isLocal || process.env.BACKSTAGE_E2E_CLI_TEST) { - require('../dist'); + require('..'); } else { require('ts-node').register({ - project: path.resolve(__dirname, '../tsconfig.build.json'), transpileOnly: true, + compilerOptions: { + module: 'CommonJS', + }, }); require('../src'); diff --git a/packages/cli/config/eslint.js b/packages/cli/config/eslint.js index 922867ea5a..9c461a1b24 100644 --- a/packages/cli/config/eslint.js +++ b/packages/cli/config/eslint.js @@ -67,6 +67,7 @@ module.exports = { name: '@material-ui/icons', message: "Please import '@material-ui/icons/' instead.", }, + ...require('module').builtinModules, ], }, ], diff --git a/packages/cli/package.json b/packages/cli/package.json index 9cf60c0c4d..5a7aa1d8cf 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -16,9 +16,9 @@ "backstage" ], "license": "Apache-2.0", - "main": "dist/index.js", + "main": "dist/index.cjs.js", "scripts": { - "build": "backstage-cli build-cache -- tsc --project tsconfig.build.json", + "build": "backstage-cli build --outputs cjs", "lint": "backstage-cli lint", "test": "backstage-cli test", "test:e2e": "node e2e-test/cli-e2e-test.js", diff --git a/packages/cli/src/index.ts b/packages/cli/src/index.ts index 8288f776e1..a0302c4713 100644 --- a/packages/cli/src/index.ts +++ b/packages/cli/src/index.ts @@ -25,93 +25,101 @@ const main = (argv: string[]) => { program .command('create-app') .description('Creates a new app in a new directory') - .action(actionHandler(() => require('./commands/create-app/createApp'))); + .action( + lazyAction(() => import('./commands/create-app/createApp'), 'default'), + ); program .command('app:build') .description('Build an app for a production release') .option('--stats', 'Write bundle stats to output directory') - .action(actionHandler(() => require('./commands/app/build'))); + .action(lazyAction(() => import('./commands/app/build'), 'default')); program .command('app:serve') .description('Serve an app for local development') .option('--check', 'Enable type checking and linting') - .action(actionHandler(() => require('./commands/app/serve'))); + .action(lazyAction(() => import('./commands/app/serve'), 'default')); program .command('app:diff') .option('--check', 'Fail if changes are required') .option('--yes', 'Apply all changes') .description('Diff an existing app with the creation template') - .action(actionHandler(() => require('./commands/app/diff'))); + .action(lazyAction(() => import('./commands/app/diff'), 'default')); program .command('create-plugin') .description('Creates a new plugin in the current repository') .action( - actionHandler(() => require('./commands/create-plugin/createPlugin')), + lazyAction( + () => import('./commands/create-plugin/createPlugin'), + 'default', + ), ); program .command('remove-plugin') .description('Removes plugin in the current repository') .action( - actionHandler(() => require('./commands/remove-plugin/removePlugin')), + lazyAction( + () => import('./commands/remove-plugin/removePlugin'), + 'default', + ), ); program .command('plugin:build') .description('Build a plugin') - .action(actionHandler(() => require('./commands/plugin/build'))); + .action(lazyAction(() => import('./commands/plugin/build'), 'default')); program .command('plugin:serve') .description('Serves the dev/ folder of a plugin') .option('--check', 'Enable type checking and linting') - .action(actionHandler(() => require('./commands/plugin/serve'))); + .action(lazyAction(() => import('./commands/plugin/serve'), 'default')); program .command('plugin:diff') .option('--check', 'Fail if changes are required') .option('--yes', 'Apply all changes') .description('Diff an existing plugin with the creation template') - .action(actionHandler(() => require('./commands/plugin/diff'))); + .action(lazyAction(() => import('./commands/plugin/diff'), 'default')); program .command('build') .description('Build a package for publishing') .option('--outputs ', 'List of formats to output [types,cjs,esm]') - .action(actionHandler(() => require('./commands/build'))); + .action(lazyAction(() => import('./commands/build'), 'default')); program .command('lint') .option('--fix', 'Attempt to automatically fix violations') .description('Lint a package') - .action(actionHandler(() => require('./commands/lint'))); + .action(lazyAction(() => import('./commands/lint'), 'default')); program .command('test') .allowUnknownOption(true) // Allows the command to run, but we still need to parse raw args .helpOption(', --backstage-cli-help') // Let Jest handle help .description('Run tests, forwarding args to Jest, defaulting to watch mode') - .action(actionHandler(() => require('./commands/testCommand'))); + .action(lazyAction(() => import('./commands/testCommand'), 'default')); program .command('prepack') .description('Prepares a package for packaging before publishing') - .action(actionHandler(() => require('./commands/pack').pre)); + .action(lazyAction(() => import('./commands/pack'), 'pre')); program .command('postpack') .description('Restores the changes made by the prepack command') - .action(actionHandler(() => require('./commands/pack').post)); + .action(lazyAction(() => import('./commands/pack'), 'post')); program .command('watch-deps') .option('--build', 'Build all dependencies on startup') .description('Watch all dependencies while running another command') - .action(actionHandler(() => require('./commands/watch-deps'))); + .action(lazyAction(() => import('./commands/watch-deps'), 'default')); program .command('build-cache') @@ -128,12 +136,12 @@ const main = (argv: string[]) => { 'Cache dir', '/node_modules/.cache/backstage-builds', ) - .action(actionHandler(() => require('./commands/build-cache'))); + .action(lazyAction(() => import('./commands/build-cache'), 'default')); program .command('clean') .description('Delete cache directories') - .action(actionHandler(() => require('./commands/clean/clean'))); + .action(lazyAction(() => import('./commands/clean/clean'), 'default')); program.on('command:*', () => { console.log(); @@ -153,15 +161,16 @@ const main = (argv: string[]) => { }; // Wraps an action function so that it always exits and handles errors -function actionHandler( - actionRequireFunc: - | (() => { default(...args: T): Promise }) - | (() => (...args: T) => Promise), +function lazyAction( + actionRequireFunc: () => Promise< + { [name in Export]: (...args: T) => Promise } + >, + exportName: Export, ): (...args: T) => Promise { return async (...args: T) => { try { - const ret = actionRequireFunc(); - const actionFunc = typeof ret === 'function' ? ret : ret.default; + const module = await actionRequireFunc(); + const actionFunc = module[exportName]; await actionFunc(...args); process.exit(0); } catch (error) { diff --git a/packages/cli/src/lib/packager/config.ts b/packages/cli/src/lib/packager/config.ts index aaecd4a148..9d60fa09f4 100644 --- a/packages/cli/src/lib/packager/config.ts +++ b/packages/cli/src/lib/packager/config.ts @@ -53,13 +53,17 @@ export const makeConfigs = async ( if (options.outputs.has(Output.cjs)) { output.push({ - file: 'dist/index.cjs.js', + dir: 'dist', + entryFileNames: 'index.cjs.js', + chunkFileNames: 'cjs/[name]-[hash].js', format: 'commonjs', }); } if (options.outputs.has(Output.esm)) { output.push({ - file: 'dist/index.esm.js', + dir: 'dist', + entryFileNames: 'index.esm.js', + chunkFileNames: 'esm/[name]-[hash].js', format: 'module', }); } @@ -67,6 +71,8 @@ export const makeConfigs = async ( configs.push({ input: 'src/index.ts', output, + preserveEntrySignatures: 'strict', + external: require('module').builtinModules, plugins: [ peerDepsExternal({ includeDependencies: true, diff --git a/packages/cli/src/lib/packager/packager.ts b/packages/cli/src/lib/packager/packager.ts index 0c41d0f767..65e33bcb7a 100644 --- a/packages/cli/src/lib/packager/packager.ts +++ b/packages/cli/src/lib/packager/packager.ts @@ -14,6 +14,7 @@ * limitations under the License. */ +import fs from 'fs-extra'; import { rollup, RollupOptions } from 'rollup'; import chalk from 'chalk'; import { relative as relativePath } from 'path'; @@ -83,5 +84,6 @@ async function build(config: RollupOptions) { export const buildPackage = async (options: BuildOptions) => { const configs = await makeConfigs(options); + await fs.remove(paths.resolveTarget('dist')); await Promise.all(configs.map(build)); }; diff --git a/packages/cli/tsconfig.build.json b/packages/cli/tsconfig.build.json deleted file mode 100644 index ae42e652e6..0000000000 --- a/packages/cli/tsconfig.build.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "extends": "./config/tsconfig.json", - "include": ["src"], - "exclude": ["**/*.test.*"], - "compilerOptions": { - "outDir": "dist", - "emitDeclarationOnly": false, - "removeComments": true, - "module": "CommonJS" - } -} diff --git a/packages/config-loader/.eslintrc.js b/packages/config-loader/.eslintrc.js index 13573efa9c..16a033dbc6 100644 --- a/packages/config-loader/.eslintrc.js +++ b/packages/config-loader/.eslintrc.js @@ -1,3 +1,3 @@ module.exports = { - extends: [require.resolve('@backstage/cli/config/eslint')], + extends: [require.resolve('@backstage/cli/config/eslint.backend')], };