我尝试在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