如何在运行时在 Node.js 应用程序中导入 ESM 模块而不使用 'type':'module' 或 .mjs 扩展名?

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

我需要开发一个nodejs应用程序,其中应该可以在运行时动态导入commonJS模块中的ESM模块。

  1. 无需在 package.json 文件中指定
    "type":"module"
    / 使用 .mjs 扩展名。
  2. 还支持导入ESM模块文件,进而导入一些纯ESM模块(例如:node-fetch@3) 或者 “esm”npm 包中是否有一些选项也支持导入 ESM 模块,进而导入纯 ESM 模块(示例:node-fetch@3

这是我迄今为止尝试过的:-

  1. 使用动态导入 这种方法可以按预期在运行时动态导入 commonjs 模块。但是,为了导入 ESM 模块,需要在 package.json 中提及“type”:“module”/使用“.mjs”扩展名命名文件。

  2. 使用 esm npm 包。 这是我发现的一个旧的 npm 包,它能够动态导入 commonJS 模块中的 ESM 模块,而不需要在

    package.json
    文件中指定 "type":"module"。但是,尝试导入导入纯 ESM 模块的 ESM 模块(例如:node-fetch@3)会失败。

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

关于 esm 库有一个开放的 问题 (#904)

错误 [ERR_INVALID_PROTOCOL]:协议“节点:”不支持。预期的“文件:”

如果我们查看 Node-fetch 版本 3 中的 index.js 的源代码, 你可以看到有一些进口,比如

import http from 'node:http'; import https from 'node:https';
与 esm 库不兼容。

我相信你也意识到了这一点,默认的

require

 也不适用于 Node-fetch,如 CommonJS [文档] 中所述:(
https://github.com/node-fetch/节点获取/blob/8b3320d2a7c07bce4afc6b2bf6c3bbddda85b01f/README.md#commonjs)

v3 中的node-fetch 是仅限 ESM 的模块 - 您无法使用 require() 导入它。

如果您无法切换到 ESM,请使用与 CommonJS 保持兼容的 v2。 v2 的关键错误修复将继续发布。


我有类似的需求,所以我写了

import-sync

    npm:
  • https://www.npmjs.com/package/import-sync
  • github:
  • https://github.com/nktnet1/import-sync
该库围绕

esm 进行封装,使您能够在运行时动态导入 commonJS 模块(甚至 ESM 模块)中的 ESM 模块,包括利用纯 esm 库(例如 node-fetch)的子模块。

您可以使用以下方式安装库:

npm install import-sync
然后按如下方式使用:

// import importSync from 'import-sync'; // for ESM const importSync = require('import-sync'); if (someCondition) { const someEs6Module = importSync('../../someEs6Module'); console.log(someEs6Module); }
具体到node-fetch,这里有一个例子:

package.json


{ "dependencies": { "import-sync": "^2.0.1", "node-fetch": "^3.3.2" } }

index.js


const importSync = require('import-sync'); const nodeFetch = importSync('node-fetch'); console.log(nodeFetch); const myModule = importSync('./myModule'); console.log(myModule);

myModule.js


import nodeFetch from 'node-fetch'; export const randomVariable = 'helloworld';
跑步

node index.js
将给出预期的结果:

希望这有帮助:)。

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