配置 Rollup 以将文件扩展名添加到 import/require 语句中
Configure Rollup to add file extensions into import/require statements
我有一个用 Typescript 编写的混合 cjs/esm 节点包。
比方说,它包含两个文件 - core.ts
和 extra.ts
,我想将它们分开。 extra.ts
导入 core.ts
(字面意思是 import { ... } from './core';
),它们是包的单独入口点。客户端仅导入 core.ts
或两者都导入。
Rollup 使构建多个入口点、多种输出格式的步骤变得容易,而且一切看起来都很好。
但是现在我运行遇到了一个问题:
假设我有 example.mjs
或 example.cjs
导入或需要 my-package
和 my-package/extra
入口点。
那是行不通的。错误消息略有不同,但含义相同 - ./core
读取 extra.mjs/cjs
时找不到模块。
extra.cjs
由 Rollup 构建包含行 var core = require('./core');
extra.mjs
由 Rollup 构建包含行 import { ... } from './core';
默认情况下,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 只会将它们捆绑到一个文件中,这也不是我需要的。
所以问题:
是否有插件或配置选项使 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.ts
和 extra.ts
导入的另一个 ts 文件的另一个输出文件。我想我可以接受。
理想的解决方案需要在我的初始配置中构建后使用类似 sed 的工具对输出文件进行猴子修补。
我有一个用 Typescript 编写的混合 cjs/esm 节点包。
比方说,它包含两个文件 - core.ts
和 extra.ts
,我想将它们分开。 extra.ts
导入 core.ts
(字面意思是 import { ... } from './core';
),它们是包的单独入口点。客户端仅导入 core.ts
或两者都导入。
Rollup 使构建多个入口点、多种输出格式的步骤变得容易,而且一切看起来都很好。
但是现在我运行遇到了一个问题:
假设我有 example.mjs
或 example.cjs
导入或需要 my-package
和 my-package/extra
入口点。
那是行不通的。错误消息略有不同,但含义相同 - ./core
读取 extra.mjs/cjs
时找不到模块。
extra.cjs
由 Rollup 构建包含行var core = require('./core');
extra.mjs
由 Rollup 构建包含行import { ... } from './core';
默认情况下,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 只会将它们捆绑到一个文件中,这也不是我需要的。
所以问题:
是否有插件或配置选项使 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.ts
和 extra.ts
导入的另一个 ts 文件的另一个输出文件。我想我可以接受。
理想的解决方案需要在我的初始配置中构建后使用类似 sed 的工具对输出文件进行猴子修补。