如何让CJS包动态需要ES模块?

问题描述 投票:0回答:1

我正在使用一个 loader 包,我向其中传递了 loadee 模块的名称,它就是

require()

loader使用CJS的

require()
来动态请求loadee,但loadee是一个ES模块。因此 Node.js 会抛出错误。

Error [ERR_REQUIRE_ESM]: require() of ES Module LOADEE from LOADER not supported.
Instead change the require of LOADEE in LOADER to a dynamic import() which is available in all CommonJS modules.

loaderloadee都不是我管理的,所以我无法修改它们。我也无法避免使用它们。

我当然可以编写一个用 CJS 编写的中介 loadee(以便 loader 可以加载它),然后加载真正的 loadee 并将其传递回 loader。但我不知道该怎么做,因为动态

import()
是异步的(返回承诺),但 loader
require()
是同步的,并期望立即加载模块。

我还能做些什么来让这件事发挥作用吗?

展示正在发生的事情的示例

如果我给出的描述不够清楚,我尝试发布一些最小的代码片段来显示发生的情况:

LOADER(CJS;不是我写的)
module.exports = function(pkg) {
  const x = require(pkg)
  console.log(x)
}
LOADEE(ES模块;不是我写的)
default export const x = 1
./index.js(这个是我的:我可以选择 CJS 或 ES 模块或其他任何东西)
import load from 'LOADER'
load('LOADEE')

当我运行

node ./index.js
时,这就是我得到的:

Error [ERR_REQUIRE_ESM]: require() of ES Module LOADEE from LOADER not supported.
Instead change the require of LOADEE in LOADER to a dynamic import() which is available in all CommonJS modules.

类似问题

我已经在堆栈溢出上发现了类似的问题。例如:

他们解释了如何使用

import()
动态导入模块。但这对我没有帮助,因为我无法更改
loader
中的 require() 调用,并且不知道如何用异步动态
import()
来包装它。

我能做些什么来让这件事发挥作用吗?

javascript node.js node-modules commonjs
1个回答
0
投票

我为此目的编写了import-sync

该库是 esm 的包装器,支持从 ES6 和基于 CJS 的 NodeJS 项目导入 ESM。


假设你有一个 ES6 模块:

/*
 * es6ModuleExample.js/es6ModuleExample.mjs
 */
export const myEs6SumExport = (a, b) => a + b;

对于基于 CJS 的 NodeJS 项目:

/*
 * index.js/index.cjs
 */
const importSync = require('import-sync');
const { myEs6SumExport } = importSync('./es6ModuleExample');
console.log(myEs6SumExport(2,3)); // prints 5

对于基于 ESM 的 NodeJS 项目:

/*
 * index.mjs/index.js with "type": "module" in package.json
 */
import importSync from 'import-sync';
const { myEs6SumExport } = importSync('./es6ModuleExample');
console.log(myEs6SumExport(2,3)); // prints 5

希望这有帮助:)。

© www.soinside.com 2019 - 2024. All rights reserved.