配置 Rollup 以将文件扩展名添加到 import/require 语句中

Configure Rollup to add file extensions into import/require statements

我有一个用 Typescript 编写的混合 cjs/esm 节点包。

比方说,它包含两个文件 - core.tsextra.ts,我想将它们分开。 extra.ts 导入 core.ts(字面意思是 import { ... } from './core';),它们是包的单独入口点。客户端仅导入 core.ts 或两者都导入。

Rollup 使构建多个入口点、多种输出格式的步骤变得容易,而且一切看起来都很好。

但是现在我运行遇到了一个问题:

假设我有 example.mjsexample.cjs 导入或需要 my-packagemy-package/extra 入口点。

那是行不通的。错误消息略有不同,但含义相同 - ./core 读取 extra.mjs/cjs 时找不到模块。

默认情况下,Node 12 不会猜测文件扩展名(我不是在质疑这一点)。

我必须将其命名为 node --experimental-modules --es-module-specifier-resolution=node ./example.mjs 才能使其正常工作。这是不令人满意的解决方案。我需要 example.mjs 可以在没有附加标志的情况下运行。

在我看来,文件扩展名可以而且应该添加到已编译的 cjs/mjs 文件中的 import/require 语句中,以使其根据规范工作。

尽管如此,由于我在 Rollup 配置中对两个文件和 external: ['./core']extra.ts 的选项中有不同的构建步骤,对于 Rollup 它们完全不相关。否则 Rollup 只会将它们捆绑到一个文件中,这也不是我需要的。

所以问题:

得到满意的解决方案

output.preserveModules 选项在一次性构建文件时将所有文件分开(尽管在某些方面可能会受到限制)。

output.entryFileNames 选项允许指定文件扩展名。 (它不适用于被认为是外部的模块,没有 preserveModules 就不能使用它。)

我只能构建 extra.ts,因为它会导入所有其他文件。但是我在像这样构建时必须注意摇树 - 需要保留 core.ts.

的所有导出
export default [
  {
    external: [],
    input: 'src/extra.ts',
    treeshake: false,
    plugins: [
      typescript(),
      cleanup({ extensions: ['ts'] })
    ],
    output: [
      {
        dir: 'lib',
        format: 'es',
        preserveModules: true,
        entryFileNames: '[name].mjs',
      },
      {
        dir: 'lib',
        format: 'cjs',
        preserveModules: true,
        entryFileNames: '[name].cjs',
      },
    ],
  },
];

退一步说,我得到了 core.tsextra.ts 导入的另一个 ts 文件的另一个输出文件。我想我可以接受。

理想的解决方案需要在我的初始配置中构建后使用类似 sed 的工具对输出文件进行猴子修补。