packages/cli: lazy-load commands to speed up cli boot time
This commit is contained in:
@@ -12,25 +12,33 @@ if (!isLocal) {
|
||||
// This is a solution for getting src-relative imports to work with typescript/node in
|
||||
// the published package. We're using `module: "amd"` to ship the entire cli implementation
|
||||
// in one file, and it also happens to generate correct module definition and import statements.
|
||||
|
||||
// Minimal AMD implementation
|
||||
const moduleFactories = {};
|
||||
const moduleCache = {};
|
||||
global.define = (name, deps, moduleFunc) => {
|
||||
moduleFactories[name] = () => {
|
||||
const exportsObj = {};
|
||||
const impls = deps.slice(2).map(dep => {
|
||||
const factory = moduleFactories[dep];
|
||||
if (!factory) {
|
||||
return require(dep);
|
||||
}
|
||||
if (!moduleCache[dep]) {
|
||||
moduleCache[dep] = factory();
|
||||
}
|
||||
return moduleCache[dep];
|
||||
});
|
||||
|
||||
moduleFunc(require, exportsObj, ...impls);
|
||||
// require() that first searches for locally defined amd modules
|
||||
const requireFunc = name => {
|
||||
let factory = moduleFactories[name];
|
||||
if (!factory) {
|
||||
// Check /index as well, to mirror nodejs resolution
|
||||
const index = `${name}/index`;
|
||||
if (!moduleFactories[index]) {
|
||||
return require(name);
|
||||
}
|
||||
name = index;
|
||||
factory = moduleFactories[name];
|
||||
}
|
||||
if (!moduleCache[name]) {
|
||||
moduleCache[name] = factory();
|
||||
}
|
||||
return moduleCache[name];
|
||||
};
|
||||
const impls = deps.slice(2).map(requireFunc);
|
||||
|
||||
moduleFunc(requireFunc, exportsObj, ...impls);
|
||||
|
||||
return exportsObj;
|
||||
};
|
||||
|
||||
+14
-21
@@ -16,16 +16,6 @@
|
||||
|
||||
import program from 'commander';
|
||||
import chalk from 'chalk';
|
||||
import createAppCommand from './commands/create-app/createApp';
|
||||
import createPluginCommand from './commands/create-plugin/createPlugin';
|
||||
import watch from './commands/watch-deps';
|
||||
import buildCache from './commands/build-cache';
|
||||
import lintCommand from './commands/lint';
|
||||
import testCommand from './commands/testCommand';
|
||||
import appBuild from './commands/app/build';
|
||||
import appServe from './commands/app/serve';
|
||||
import pluginBuild from './commands/plugin/build';
|
||||
import pluginServe from './commands/plugin/serve';
|
||||
import { exitWithError } from './helpers/errors';
|
||||
import { paths } from './helpers/paths';
|
||||
|
||||
@@ -37,51 +27,53 @@ const main = (argv: string[]) => {
|
||||
program
|
||||
.command('create-app')
|
||||
.description('Creates a new app in a new directory')
|
||||
.action(actionHandler(createAppCommand));
|
||||
.action(actionHandler(() => require('commands/create-app/createApp')));
|
||||
|
||||
program
|
||||
.command('app:build')
|
||||
.description('Build an app for a production release')
|
||||
.action(actionHandler(appBuild));
|
||||
.action(actionHandler(() => require('commands/app/build')));
|
||||
|
||||
program
|
||||
.command('app:serve')
|
||||
.description('Serve an app for local development')
|
||||
.action(actionHandler(appServe));
|
||||
.action(actionHandler(() => require('commands/app/serve')));
|
||||
|
||||
program
|
||||
.command('create-plugin')
|
||||
.description('Creates a new plugin in the current repository')
|
||||
.action(actionHandler(createPluginCommand));
|
||||
.action(
|
||||
actionHandler(() => require('commands/create-plugin/createPlugin')),
|
||||
);
|
||||
|
||||
program
|
||||
.command('plugin:build')
|
||||
.option('--watch', 'Enable watch mode')
|
||||
.description('Build a plugin')
|
||||
.action(actionHandler(pluginBuild));
|
||||
.action(actionHandler(() => require('commands/plugin/build')));
|
||||
|
||||
program
|
||||
.command('plugin:serve')
|
||||
.description('Serves the dev/ folder of a plugin')
|
||||
.action(actionHandler(pluginServe));
|
||||
.action(actionHandler(() => require('commands/plugin/serve')));
|
||||
|
||||
program
|
||||
.command('lint')
|
||||
.option('--fix', 'Attempt to automatically fix violations')
|
||||
.description('Lint a package')
|
||||
.action(actionHandler(lintCommand));
|
||||
.action(actionHandler(() => require('commands/lint')));
|
||||
|
||||
program
|
||||
.command('test')
|
||||
.option('--watch', 'Enable watch mode')
|
||||
.option('--coverage', 'Report test coverage')
|
||||
.description('Run all tests for package')
|
||||
.action(actionHandler(testCommand));
|
||||
.action(actionHandler(() => require('commands/testCommand')));
|
||||
|
||||
program
|
||||
.command('watch-deps')
|
||||
.description('Watch all dependencies while running another command')
|
||||
.action(actionHandler(watch));
|
||||
.action(actionHandler(() => require('commands/watch-deps')));
|
||||
|
||||
program
|
||||
.command('build-cache')
|
||||
@@ -98,7 +90,7 @@ const main = (argv: string[]) => {
|
||||
'Cache dir',
|
||||
'<repoRoot>/node_modules/.cache/backstage-builds',
|
||||
)
|
||||
.action(actionHandler(buildCache));
|
||||
.action(actionHandler(() => require('commands/build-cache')));
|
||||
|
||||
program.on('command:*', () => {
|
||||
console.log();
|
||||
@@ -119,10 +111,11 @@ const main = (argv: string[]) => {
|
||||
|
||||
// Wraps an action function so that it always exits and handles errors
|
||||
function actionHandler<T extends readonly any[]>(
|
||||
actionFunc: (...args: T) => Promise<any>,
|
||||
actionRequireFunc: () => { default(...args: T): Promise<any> },
|
||||
): (...args: T) => Promise<never> {
|
||||
return async (...args: T) => {
|
||||
try {
|
||||
const actionFunc = actionRequireFunc().default;
|
||||
await actionFunc(...args);
|
||||
process.exit(0);
|
||||
} catch (error) {
|
||||
|
||||
Reference in New Issue
Block a user