【问题标题】:When can a CommonJS named export be imported by an ES module?ES 模块何时可以导入名为 export 的 CommonJS?
【发布时间】:2021-04-07 04:52:36
【问题描述】:

我有一个 ES 模块,它使用我创作的 CommonJS 模块的命名导出。

es.mjs

import { MyNamedExport } from './commonjs.cjs';

console.log(MyNamedExport);

commonjs.cjs(好一个)

exports.MyNamedExport = 'OK';

当我像这样在 Node.js 中运行 ES 模块时,一切都很好。

> node ./es.mjs
OK

无论如何,如果 CommonJS 模块中的导出部分以某种看似无关的方式进行了更改,即通过添加一对括号,命名的导出将停止工作。

commonjs.cjs(不好的)

(exports).MyNamedExport = 'OK';
> node ./es.mjs
file:///path/to/current/folder/es.mjs:1
import { MyNamedExport } from './commonjs.cjs';
         ^^^^^^^^^^^^^
SyntaxError: Named export 'MyNamedExport' not found. The requested module './commonjs.cjs' is a CommonJS module, which may not support all module.exports as named exports.
CommonJS modules can always be imported via the default export, for example using:

import pkg from './commonjs.cjs';
const { MyNamedExport } = pkg;

    at ModuleJob._instantiate (node:internal/modules/esm/module_job:104:21)
    at async ModuleJob.run (node:internal/modules/esm/module_job:149:5)
    at async Loader.import (node:internal/modules/esm/loader:166:24)
    at async Object.loadESM (node:internal/process/esm_loader:68:5)

当然,当我的 CommonJS 命名的 export 被另一个 CommonJS 模块导入时,括号没有任何区别。

为什么会这样?

写CommonJS模块时应该怎么做才能保证ES模块可以导入命名导出?

【问题讨论】:

  • 如果您查看nodejs module documentation 中对“静态分析”的两个引用,这似乎是您观察的来源。当您将括号放在那里时,静态分析会失败,因为它会看到一个可能的表达式,而不是直接分配给 module.exports
  • 请记住,ESM 模块中的导出无法计算,它们必须静态声明,以便 CommonJS 模块兼容,似乎必须通过代码的静态分析找到导出。看似经过计算的导出不会通过此测试。而且,在它周围加上括号使它成为一个显然会使静态分析失败的表达式。

标签: javascript node.js es6-modules commonjs module-export


【解决方案1】:

来自the docs

为了更好地兼容 JS 生态系统中的现有用法, Node.js 另外[到默认导入] 尝试确定 CommonJS 命名的导出 每个导入的 CommonJS 模块,以将它们作为单独的 ES 提供 使用静态分析过程导出模块。

[…]

命名导出的检测基于常见的语法模式,但 并不总是正确检测命名导出。在这些情况下,使用 上述默认导入表单可能是更好的选择。

命名导出检测涵盖了许多常见的导出模式,重新导出 模式和构建工具和转译器输出。见cjs-module-lexer 对于实现的确切语义。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-11-20
    • 2016-07-30
    • 1970-01-01
    • 2021-08-24
    • 2021-12-02
    • 2019-09-24
    • 2020-10-06
    • 1970-01-01
    相关资源
    最近更新 更多