NodeJS ES6模块和“默认”导出/导入

9

我尝试在NodeJS v13.13中使用ES6风格的模块,但是遇到了冲突的行为。

最初我的项目是通过node-babel进行转译的,但后来我通过将 "type": "module" 添加到我的package.json文件中启用了内置的ES6模块支持。

在这一点上,像 import * as esprima from 'esprima'; 这样的导入语句停止正常工作。经过检查,导入语句并没有创建函数 esprima.parse,而是创建了一个函数esprima.default.parse

当然,可以通过使用类似以下的内容进行修复:

import * as esprimaLoad from 'esprima';
const esprima = esprimaLoad.default;

然而,根据规范,什么行为是正确的?Babel 删除 / 折叠默认对象是正确的吗?当前 node.js 行为是否存在 bug 仍被标记为实验性质?所有这些 ES 模块与 CommonJS 模块之间的区别让我头疼。

更新:

我仍未找到问题的根本原因,但涉及更多内容。其中出现这个问题的库之一 esprima.js 似乎是使用 webpack 创建的 UMD(通用模块定义)格式。它以以下方式开始:

(function webpackUniversalModuleDefinition(root, factory) {
/* istanbul ignore next */
    if(typeof exports === 'object' && typeof module === 'object')
        module.exports = factory();
    else if(typeof define === 'function' && define.amd)
        define([], factory);
/* istanbul ignore next */
    else if(typeof exports === 'object')
        exports["esprima"] = factory();
    else
        root["esprima"] = factory();
})(this, function() { ...

我认为webpack的UMD格式早已可以在浏览器内使用“import”语句和在node.js内使用“require”语句。但是,当在node.js中使用实验模块/babel时,似乎以下内容根本不起作用:
“import esprima from 'esprima'”
以下与babel一起使用,但与实验模块不兼容:
“import * as esprima from 'esprima'”
以下与babel和实验模块都兼容:
import * as esprimaLoad from 'esprima'
const esprima = esprimaLoad.default?esprimaLoad.default:esprimaLoad;

对于不使用Webpack UMD技巧的模块,Babel和实验性模块似乎都能正常工作。


我认为你的意思是 import esprima from 'esprima'; - Bergi
目前还没有关于 CommonJS 与 ES6 模块之间互操作性的规范。 - Bergi
1个回答

1
如果您正在导出default,那么您就不需要以那种迂回的方式进行导入。

The simplest version directly imports the default:

import myDefault from '/modules/my-module.js';

It is also possible to use the default syntax with the ones seen above (namespace imports or named imports). In such cases, the default import will have to be declared first. For instance:

import myDefault, * as myModule from '/modules/my-module.js';
// myModule used as a namespace

您可以查看MDN获取更多信息。

所以在您的情况下

import esprima from 'esprima';

这应该是最简单的导入语句。

3
这通常是正确的,但事实证明esprima实际上是一个webpack UMD风格的模块,无法正确导入。请参见我的更新。 - bruceceng

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接