NodeJS ES6 模块和"default"导出/导入



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

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

此时,import * as esprima from 'esprima';等导入语句已停止正常工作。经过检查,它不是创建函数esprima.parse的导入,而是创建了函数esprima.default.parse

当然,这一切都可以通过使用类似的东西来解决:

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

但是,根据规范,什么行为是正确的?babel剥离/折叠默认对象是正确的吗?当前node.js行为中是否存在仍被标记为实验性的错误?所有这些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和实验模块似乎都工作得很好。

如果要导出default,则不需要以迂回方式导入它。

最简单的版本直接导入默认值:

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

也可以将默认语法与上面看到的语法一起使用(命名空间导入或命名导入(。在这种情况下,默认进口必须先申报。例如:

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

您可以从MDN 查看更多信息

所以在你的情况下

import esprima from 'esprima';

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

最新更新