You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Rollup构建可执行CLI脚本的模块打包异常问题

Rollup构建库+CLI工具配置问题解决

问题场景

我正在开发一个同时包含库和小型CLI工具的包,CLI工具位于bin/cli.ts,代码如下:

import yargs from 'yargs';

import myPackage from '../dist/esm/index.js';

import { someCommand } from './someCommand';

yargs.<a bunch of stuff>;

期望构建后:yargs和myPackage保留为外部导入,someCommand被打包进CLI脚本。

当前使用的rollup.config.js配置:

import ts from 'rollup-plugin-ts';
import shebang from 'rollup-plugin-add-shebang';

export default [
  {
    input: 'src/index.ts',
    output: [
      {
        file: 'dist/esm/index.js',
        format: 'esm',
      },
      {
        file: 'dist/cjs/index.js',
        format: 'cjs',
      },
    ],
    plugins: [
      ts({}),
    ],
  },
  {
    input: 'bin/cli.ts',
    output: [
      {
        file: 'dist-bin/cli.js',
        format: 'esm',
      },
    ],
    plugins: [
      ts({}),
      shebang({
        shebang: '#!/usr/bin/env node',
      }),
    ],
  },
];

构建后生成的dist-bin/cli.js与dist/esm/index.js内容几乎一致,仅多了shebang,完全没有包含yargs或someCommand相关逻辑,显然配置有误,想确认Rollup是否适合该场景,尽量不想新增构建系统。

解决方案

Rollup完全适配这种同时构建库和CLI工具的场景,只需调整配置和代码即可解决问题:

1. 修正CLI的导入路径

不要导入构建后的库文件,改为直接导入源码(避免构建顺序问题,同时让Rollup正确识别依赖关系):

// bin/cli.ts
import yargs from 'yargs';
import myPackage from '../src/index.ts'; // 替换原导入路径
import { someCommand } from './someCommand';

// 确保yargs逻辑被执行,比如添加.argv触发解析
yargs
  .command(someCommand)
  .argv;

2. 配置Rollup的external选项

在CLI的构建配置中,通过external指定不需要打包的外部依赖,让Rollup保留这些模块的导入语句:

// rollup.config.js
import ts from 'rollup-plugin-ts';
import shebang from 'rollup-plugin-add-shebang';

export default [
  // 库的构建配置保持不变
  {
    input: 'src/index.ts',
    output: [
      { file: 'dist/esm/index.js', format: 'esm' },
      { file: 'dist/cjs/index.js', format: 'cjs' },
    ],
    plugins: [ts({})],
  },
  // 修改后的CLI构建配置
  {
    input: 'bin/cli.ts',
    output: [
      { file: 'dist-bin/cli.js', format: 'esm' },
    ],
    // 指定外部依赖,Rollup不会打包这些模块
    external: ['yargs', '../src/index.ts'],
    plugins: [
      ts({}),
      shebang({ shebang: '#!/usr/bin/env node' }),
    ],
  },
];

如果后续发布包时,CLI需要导入已发布的库(而非源码),可以将../src/index.ts替换为你的包名(比如external: ['yargs', 'your-package-name']),并确保package.json的main或exports配置正确。

3. 确保CLI代码不会被Tree-shaking移除

Rollup的Tree-shaking会移除未被使用的代码,所以必须确保yargs的逻辑被实际执行(比如调用.argv),否则相关代码会被误删。

4. 检查TypeScript配置

确保bin目录被包含在tsconfig.json的include范围内,让rollup-plugin-ts能正确编译CLI的TypeScript文件:

// tsconfig.json
{
  "include": ["src/**/*", "bin/**/*"],
  // 其他配置...
}

内容的提问来源于stack exchange,提问作者Thom Smith

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 07:47:17