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

bru*_*eng 7 javascript node.js webpack babeljs es6-modules

我正在尝试在 NodeJS v13.13 中使用 ES6 样式模块,但我遇到了冲突行为。

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

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

当然,这一切都可以通过使用以下内容来解决:

import * as esprimaLoad from 'esprima';
const esprima = esprimaLoad.default;
Run Code Online (Sandbox Code Playgroud)

但是,根据规范,哪些行为是正确的?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() { ...
Run Code Online (Sandbox Code Playgroud)

我认为 webpack UMD 格式已经意味着可以处理import浏览器中的require语句和 node.js 中的语句。但是,在 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;
Run Code Online (Sandbox Code Playgroud)

对于不使用这种 webpack UMD 技巧的模块,babel 和实验模块似乎都可以正常工作。

Ari*_*rty 1

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

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

import myDefault from '/modules/my-module.js';
Run Code Online (Sandbox Code Playgroud)

也可以使用上面看到的默认语法(命名空间导入或命名导入)。在这种情况下,必须首先声明默认导入。例如:

import myDefault, * as myModule from '/modules/my-module.js';
// myModule used as a namespace
Run Code Online (Sandbox Code Playgroud)

您可以从MDN查看更多内容

所以在你的情况下

import esprima from 'esprima';
Run Code Online (Sandbox Code Playgroud)

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

  • 这通常是正确的,但事实证明 esprima 实际上是一个 webpack UMD 样式模块,无法正确导入。查看我的更新。 (3认同)