使用 Rollup 仅转换为 CommonJS,无需捆绑

Using Rollup to only convert to CommonJS, without bundling

解决下面列出的这个问题的最佳方法是什么?

...或者我应该使用 Rollup 以外的东西来完成这项任务?

...

假设我正在开发一个库 foo,它公开了两个 es6 模块 a.jsb.js(即允许 import a from foo/aimport b from foo/b

来源 es6 模块

// src/a.js
export default function a(x) { return x+'!' }

...

// src/b.js
import a from './a.js'
export default function b() { return a('Hi') }

然后我想将 a.js 和 b.js 都转换成 CommonJs 模块并将它们保存在项目的根文件夹中。所以实际上我希望行 import a from './a' 只变成 const a = require('./a') 并跳过任何捆绑。像这样:

期望的 CommonJS 输出

// a.js
module.exports = function a(x) { return x+'!' }

...

// b.js
const a = require('./a')
module.exports = function b() { return a('Hi') }

我的第一直觉是在 rollup.config.js 中使用 external: (id) => id!==currentFile 之类的东西将所有同级模块定义为外部模块。 几乎可以工作,但导致相对导入路径被重写为const a = require('./src/a')(从src文件夹导入a.js的es6版本)。

实际结果

// a.js
module.exports = function a(x) { return x+'!' }

...

// b.js
const a = require('./src/a')
module.exports = function b() { return a('Hi') }

你可以使用这个:

// rollup.config.js
export default {
    input: ['src/a.js', 'src/b.js'],
    output: {
        dir: '.',
        format: 'cjs'
    },
    experimentalCodeSplitting: true,
}

还值得一提的是 rollupresolveId 挂钩,因为它允许您更好地控制排除以及替换导入路径。来自 rollup doc:

resolveId

Type: (source: string, importer: string) => string | false | null | {id: string, external?: boolean, moduleSideEffects?: boolean | null} Kind: async, first

Defines a custom resolver. A resolver can be useful for e.g. locating third-party dependencies. Returning null defers to other resolveId functions and eventually the default resolution behavior; returning false signals that source should be treated as an external module and not included in the bundle. If this happens for a relative import, the id will be renormalized the same way as when the external option is used.

If you return an object, then it is possible to resolve an import to a different id while excluding it from the bundle at the same time. This allows you to replace dependencies with external dependencies without the need for the user to mark them as "external" manually via the external option:

resolveId(source) {
  if (source === 'my-dependency') {
    return {id: 'my-dependency-develop', external: true};
  }
  return null;
}

Relative ids, i.e. starting with ./ or ../, will not be renormalized when returning an object. If you want this behaviour, return an absolute file system location as id instead.

If false is returned for moduleSideEffects in the first hook that resolves a module id and no other module imports anything from this module, then this module will not be included without checking for actual side-effects inside the module. If true is returned, Rollup will use its default algorithm to include all statements in the module that have side-effects (such as modifying a global or exported variable). If null is returned or the flag is omitted, then moduleSideEffects will be determined by the treeshake.moduleSideEffects option or default to true. The load and transform hooks can override this.