节点中的 Grunt 和 ES6 模块 - 不使用 .mjs 不兼容?

Grunt and ES6 modules in node - incompatible without the use of .mjs?

所以,我现在正在尝试使用 Typescript 和 Grunt,看看它对我来说是否值得。问题是:Typescript 不会编译为 *.mjs 文件,而只会编译为常规 *.js 文件。 Node 确实支持 ES6 模块,但前提是您将它​​们标记为“*.jsm”文件或通过设置 "type": "module"。但是,在 package.json 中设置此顶级字段对同一目录中的任何 *.js 文件和任何后续文件具有全局范围。

这会破坏 Gruntfile.js 文件,因为它使用 CommonJS 模块,请参阅我的非常基本的 Gruntfile 作为示例:

module.exports = function (grunt) {
   grunt.initConfig({
      ts: {
         default: {tsconfig: "./tsconfig.json"}
      }
   })
   grunt.loadNpmTasks("grunt-ts");
   grunt.registerTask("default", ["ts"]);
}

没想到会成功,我天真地将导出语法从 module.exports = 更改为 export default,这预计不会起作用,因为它没有多大意义。

问题

  1. 是否有任何选项可以在节点中启用 ES6 模块的情况下使用 Grunt?
  2. 是否有正确的方法告诉 TypeScript 编译成 *.mjs 个文件?

可以先使用babel-node编译。这将解决 ES6 导出和导入问题。

npm install --save-dev @babel/core @babel/node
npx babel-node server.js

在 G运行t 之前使用 Babel 运行ning 的建议方法使 G运行t 有点多余。由于 TypeScript 尚不支持将 ES6 模块导出到 *.mjs 文件(当节点仍应为 运行 CommonJS 系统时,您必须在导入中使用 *.mjs 后缀)并且可能永远不会完全(参见 Design Meeting Notes 11/22/2019)我必须得出结论,ES6 模块仍然具有严重的影响和问题。更改文件扩展名不够,因为无扩展名的导入因节点而失败。您需要遍历每个已编译的文件并更改导入以专门加载 *.mjs 个文件。

但是,TypeScript 编译器 可以 以它确实理解 ES6 模块语法并编译为 CommonJS 的方式设置(参见 TS handbook)。

{
  "compilerOptions": {
    "module": "CommonJS",
    // [...]
  },
}

这样 TypeScript 代码就可以用 ES6 模块语法编写,并且输出可以与 CommonJS 兼容,而不会破坏其他代码。作为奖励,您可以跳过 Babel 方法,g运行t 可以 运行 TS 编译器。

如果您在 package.json 中设置了 "type": "module",您需要将 Gruntfile.js 重命名为 Gruntfile.cjs,并 运行 将其重命名为 grunt --gruntfile Gruntfile.cjs .