简体   繁体   English

ES 模块何时可以导入名为 export 的 CommonJS?

[英]When can a CommonJS named export be imported by an ES module?

I have an ES module that uses a named export from a CommonJS module that I authored.我有一个 ES 模块,它使用我创作的 CommonJS 模块的命名导出。

es.mjs es.mjs

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

console.log(MyNamedExport);

commonjs.cjs (good one) commonjs.cjs (好一个)

exports.MyNamedExport = 'OK';

When I run the ES module in Node.js like this everything is fine.当我像这样在 Node.js 中运行 ES 模块时,一切都很好。

> node ./es.mjs
OK

Anyway, if the export part in the CommonJS module is changed in some seemingly irrelevant way, ie by adding a pair of parentheses, the named export stops working.无论如何,如果 CommonJS 模块中的导出部分以某种看似无关的方式进行了更改,即通过添加一对括号,命名导出将停止工作。

commonjs.cjs (bad one) 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)

Of course, when my CommonJS named export is imported by another CommonJS module, the parentheses make no difference.当然,当我的 CommonJS 命名导出被另一个 CommonJS 模块导入时,括号没有任何区别。

Why is this happening?为什么会这样?

What should I do when I write a CommonJS module to make sure that named exports can be imported by ES modules?当我写一个 CommonJS 模块来确保命名的导出可以被 ES 模块导入时,我应该怎么做?

From the docs :文档

For better compatibility with existing usage in the JS ecosystem, Node.js in addition [to the default import] attempts to determine the CommonJS named exports of every imported CommonJS module to provide them as separate ES module exports using a static analysis process.为了更好地兼容 JS 生态系统中的现有用法,Node.js 除了[默认导入]尝试确定每个导入的 CommonJS 模块的 CommonJS 命名导出,以使用 static 分析过程将它们作为单独的 ES 模块导出提供。

[…] […]

The detection of named exports is based on common syntax patterns but does not always correctly detect named exports.命名导出的检测基于常见的语法模式,但并不总是正确检测命名导出。 In these cases, using the default import form described above can be a better option.在这些情况下,使用上述默认导入表单可能是更好的选择。

Named exports detection covers many common export patterns, reexport patterns and build tool and transpiler outputs.命名导出检测涵盖了许多常见的导出模式、重新导出模式以及构建工具和转译器输出。 Seecjs-module-lexer for the exact semantics implemented.有关实现的确切语义,请参见cjs-module-lexer

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 防止导入ES模块的CommonJS模块执行代码 - Prevent CommonJS module imported into ES module from executing code 将commonjs模块与ES6模块混合以导出两个功能 - mixing commonjs module with ES6 module to export two functions 将 CommonJS 默认导出导入为命名导出/无法加载 ES 模块 - Import CommonJS default exports as named exports / Cannot load ES module 将 CommonJS (CJS) 导入 ES Module (MJS) 导致“TypeError: module is not a function”错误 - Imported CommonJS (CJS) into ES Module (MJS) leads to "TypeError: module is not a function" error 将angular模块导出为commonjs模块 - Export an angular module as a commonjs module ES 模块脚本的 CommonJS 包装器 - CommonJS wrapper for ES module scripts 无法从默认导出模块导入命名导出“XXX”(导入为“XXX”)(仅默认导出可用) - Can't import the named export 'XXX' (imported as 'XXX') from default-exporting module (only default export is available) CommonJS 到 ES6 的迁移导出。 出口 - CommonJS to ES6 migration exports. to export 如何判断一个特定模块是 CommonJS 模块还是 ES6 模块? - How can I tell if a particular module is a CommonJS module or an ES6 module? 我该如何解决 --> File 是一个 CommonJS 模块; 它可以转换为 ES6 模块 - how can i fix --> File is a CommonJS module; it may be converted to an ES6 module
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM