Skip to content

打包 CJS

¥Bundling CJS

Rolldown 为 CommonJS 模块提供一流的支持。本文档解释了 Rolldown 如何处理 CJS 模块及其与 ES 模块的互操作性。

¥Rolldown provides first-class support for CommonJS modules. This document explains how Rolldown handles CJS modules and their interoperability with ES modules.

主要功能

¥Key Features

原生 CJS 支持

¥Native CJS Support

Rolldown 无需任何额外的插件或软件包即可自动识别和处理 CommonJS 模块。此原生支持意味着:

¥Rolldown automatically recognizes and processes CommonJS modules without requiring any additional plugins or packages. This native support means:

  • 无需安装额外的依赖

    ¥No need to install extra dependencies

  • 比基于插件的解决方案性能更佳

    ¥Better performance compared to plugin-based solutions

按需执行

¥On-demand Execution

Rolldown 保留了 CommonJS 模块的按需执行语义,这是 CommonJS 模块系统的关键特性。这意味着模块仅在实际需要时才执行。

¥Rolldown preserves the on-demand execution semantics of CommonJS modules, which is a key feature of the CommonJS module system. This means modules are only executed when they are actually required.

示例:

¥Here's an example:

js
// index.js
import { value } from './foo.js';

const getFooExports = () => require('./foo.js');

// foo.js
module.exports = { value: 'foo' };

打包后,生成:

¥When bundled, it produces:

js
// #region rolldown:runtime
// ...runtime code
// #endregion

// #region foo.js
var require_foo = __commonJS({
  'foo.js'(exports, module) {
    module.exports = { value: 'foo' };
  },
});

// #endregion
// #region index.js
const getFooExports = () => require_foo();
// #endregion

在此示例中,foo.js 模块直到调用 getFooExports() 才会执行,从而保持了 CommonJS 的延迟加载行为。

¥In this example, the foo.js module won't be executed until getFooExports() is called, maintaining the lazy-loading behavior of CommonJS.

ESM/CJS 互操作性

¥ESM/CJS Interoperability

Rolldown 提供了 ES 模块和 CommonJS 模块之间的无缝互操作性。

¥Rolldown provides seamless interoperability between ES modules and CommonJS modules.

从 CJS 导入 ESM 的示例:

¥Example of ESM importing from CJS:

js
// index.js
import { value } from './foo.js';

console.log(value);

// foo.js
module.exports = { value: 'foo' };

打包输出:

¥Bundled output:

js
// #region rolldown:runtime
// ...runtime code
// #endregion

// #region foo.js
var require_foo = __commonJS({
  'foo.js'(exports, module) {
    module.exports = { value: 'foo' };
  },
});

// #endregion
// #region index.js
var import_foo = __toESM(require_foo());
console.log(import_foo.value);

// #endregion

__toESM 助手确保 CommonJS 导出正确转换为 ES 模块格式,从而允许无缝访问导出的值。

¥The __toESM helper ensures that CommonJS exports are properly converted to ES module format, allowing seamless access to the exported values.

require 个外部模块

¥require external modules

设置 platform: 'node' 后,Rolldown 将从 module.createRequire 生成一个 require 函数。

¥When platform: 'node' is set, Rolldown will generate a require function from module.createRequire.

对于其他平台,Rolldown 将保持原样,因此请确保运行环境提供 require 函数或手动注入一个。

¥For other platforms, Rolldown will leave it as it is, so ensure that the running environment provides a require function or inject one manually.

例如,你可以使用 inject 功能 注入返回 import 所获值的 require 函数。

¥For example, you can inject the require function that returns the value obtained by import by using inject feature.

js
import path from 'node:path';
export default {
  inject: {
    require: path.resolve('./require.js'),
  },
};
js
import fs from 'node:fs';

export default (id) => {
  if (id === 'node:fs') {
    return fs;
  }
  throw new Error(`Requiring ${JSON.stringify(id)} is not allowed.`);
};

你还可以使用 内置 esmExternalRequirePluginrequire() 调用转换为 import 语句。

¥You can also use the built-in esmExternalRequirePlugin to convert require() calls to import statements.

未来计划

¥Future Plans

Rolldown 对 CommonJS 模块的顶层支持实现了多项潜在的优化:

¥Rolldown's first-class support for CommonJS modules enables several potential optimizations:

  • CommonJS 模块的高级摇树功能。

    ¥Advanced tree-shaking capabilities for CommonJS modules

  • 更好地消除死代码

    ¥Better dead code elimination