diff --git a/packages/core/package.json b/packages/core/package.json index 7a1c034f79..847d9d95b8 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -64,8 +64,8 @@ "@types/webpack-bundle-analyzer": "4.7.0", "@types/ws": "^8.5.13", "browserslist-load-config": "1.0.0", + "cac": "^6.7.14", "chokidar": "^4.0.3", - "commander": "^12.1.0", "connect": "3.7.0", "connect-history-api-fallback": "^2.0.0", "cors": "^2.8.5", diff --git a/packages/core/src/cli/commands.ts b/packages/core/src/cli/commands.ts index 49811e6475..7496353ef1 100644 --- a/packages/core/src/cli/commands.ts +++ b/packages/core/src/cli/commands.ts @@ -1,4 +1,4 @@ -import { type Command, program } from 'commander'; +import cac, { type CAC, type Command } from 'cac'; import { logger } from '../logger'; import { onBeforeRestartServer } from '../server/restart'; import type { RsbuildMode } from '../types'; @@ -30,69 +30,78 @@ export type DevOptions = CommonOptions; export type PreviewOptions = CommonOptions; -const applyCommonOptions = (command: Command) => { - command +const applyCommonOptions = (cli: CAC) => { + cli .option( - '-c --config ', + '-c, --config ', 'specify the configuration file, can be a relative or absolute path', ) .option( - '-r --root ', + '-r, --root ', 'specify the project root directory, can be an absolute path or a path relative to cwd', ) .option( - '-m --mode ', + '-m, --mode ', 'specify the build mode, can be `development`, `production` or `none`', ) .option( '--env-mode ', 'specify the env mode to load the `.env.[mode]` file', ) - .option( + .option( '--environment ', 'specify the name of environment to build', - (str, prev) => (prev ? prev.concat(str.split(',')) : str.split(',')), + { + type: [String], + default: [], + }, ) .option('--env-dir ', 'specify the directory to load `.env` files'); }; const applyServerOptions = (command: Command) => { command - .option('-o --open [url]', 'open the page in browser on startup') + .option('-o, --open [url]', 'open the page in browser on startup') .option('--port ', 'specify a port number for server to listen') .option('--host ', 'specify the host that the server listens to'); }; export function setupCommands(): void { - program.name('rsbuild').usage(' [options]').version(RSBUILD_VERSION); + const cli = cac('rsbuild'); + + cli.help(); + cli.version(RSBUILD_VERSION); - const devCommand = program.command('dev'); - const buildCommand = program.command('build'); - const previewCommand = program.command('preview'); - const inspectCommand = program.command('inspect'); + // Apply common options to all commands + applyCommonOptions(cli); - [devCommand, buildCommand, previewCommand, inspectCommand].forEach( - applyCommonOptions, + const devCommand = cli.command('dev', 'starting the dev server'); + const buildCommand = cli.command('build', 'build the app for production'); + const previewCommand = cli.command( + 'preview', + 'preview the production build locally', + ); + const inspectCommand = cli.command( + 'inspect', + 'inspect the Rspack and Rsbuild configs', ); - [devCommand, previewCommand].forEach(applyServerOptions); + applyServerOptions(devCommand); + applyServerOptions(previewCommand); - devCommand - .description('starting the dev server') - .action(async (options: DevOptions) => { - try { - const rsbuild = await init({ cliOptions: options }); - await rsbuild?.startDevServer(); - } catch (err) { - logger.error('Failed to start dev server.'); - logger.error(err); - process.exit(1); - } - }); + devCommand.action(async (options: DevOptions) => { + try { + const rsbuild = await init({ cliOptions: options }); + await rsbuild?.startDevServer(); + } catch (err) { + logger.error('Failed to start dev server.'); + logger.error(err); + process.exit(1); + } + }); buildCommand - .option('-w --watch', 'turn on watch mode, watch for changes and rebuild') - .description('build the app for production') + .option('-w, --watch', 'turn on watch mode, watch for changes and rebuild') .action(async (options: BuildOptions) => { try { const rsbuild = await init({ @@ -117,21 +126,18 @@ export function setupCommands(): void { } }); - previewCommand - .description('preview the production build locally') - .action(async (options: PreviewOptions) => { - try { - const rsbuild = await init({ cliOptions: options }); - await rsbuild?.preview(); - } catch (err) { - logger.error('Failed to start preview server.'); - logger.error(err); - process.exit(1); - } - }); + previewCommand.action(async (options: PreviewOptions) => { + try { + const rsbuild = await init({ cliOptions: options }); + await rsbuild?.preview(); + } catch (err) { + logger.error('Failed to start preview server.'); + logger.error(err); + process.exit(1); + } + }); inspectCommand - .description('inspect the Rspack and Rsbuild configs') .option('--output ', 'specify inspect content output path') .option('--verbose', 'show full function definitions in output') .action(async (options: InspectOptions) => { @@ -149,5 +155,5 @@ export function setupCommands(): void { } }); - program.parse(); + cli.parse(); } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e3b47f7df3..de04c7690c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -616,12 +616,12 @@ importers: browserslist-load-config: specifier: 1.0.0 version: 1.0.0 + cac: + specifier: ^6.7.14 + version: 6.7.14 chokidar: specifier: ^4.0.3 version: 4.0.3 - commander: - specifier: ^12.1.0 - version: 12.1.0 connect: specifier: 3.7.0 version: 3.7.0 @@ -3502,10 +3502,6 @@ packages: resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==} engines: {node: '>=14'} - commander@12.1.0: - resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==} - engines: {node: '>=18'} - commander@2.20.3: resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} @@ -9303,8 +9299,6 @@ snapshots: commander@10.0.1: {} - commander@12.1.0: {} - commander@2.20.3: {} commander@4.1.1: {}