admin管理员组

文章数量:1424902

So, I'm dabbling a bit with Typescript and Grunt at the moment to see if it's worth it for me. The thing is: Typescript does not pile to *.mjs files but only regular *.js files. Node does support ES6 Modules but only if you either mark them as '*.jsm' files or by setting "type": "module". Setting this top-level field in package.json however has global scope for any *.js file in the same directory and any following ones.

This breaks the Gruntfile.js file as it seems since it uses CommonJS modules, see my very basic Gruntfile as example:

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

Without expecting much success I naively changed the export syntax from module.exports = to export default which expectedly did no work since it didn't make much sense.

Questions

  1. Is there any option to use Grunt with ES6 modules enabled in node?
  2. Is there a proper way to tell TypeScript to pile to *.mjs files?

So, I'm dabbling a bit with Typescript and Grunt at the moment to see if it's worth it for me. The thing is: Typescript does not pile to *.mjs files but only regular *.js files. Node does support ES6 Modules but only if you either mark them as '*.jsm' files or by setting "type": "module". Setting this top-level field in package.json however has global scope for any *.js file in the same directory and any following ones.

This breaks the Gruntfile.js file as it seems since it uses CommonJS modules, see my very basic Gruntfile as example:

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

Without expecting much success I naively changed the export syntax from module.exports = to export default which expectedly did no work since it didn't make much sense.

Questions

  1. Is there any option to use Grunt with ES6 modules enabled in node?
  2. Is there a proper way to tell TypeScript to pile to *.mjs files?
Share Improve this question edited Jun 20, 2020 at 9:12 CommunityBot 11 silver badge asked Jun 17, 2020 at 1:15 bowrillabowrilla 1941 silver badge7 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 5

If you set "type": "module" in your package.json, you need to rename Gruntfile.js to Gruntfile.cjs, and run it with grunt --gruntfile Gruntfile.cjs.

The suggested approach with Babel running before Grunt makes Grunt a bit redundant. Since TypeScript does not yet support exporting ES6 modules to *.mjs files (and you have to use the *.mjs suffix in your import when node should still be running with its CommonJS system) and will probably never fully (see Design Meeting Notes 11/22/2019) I have to conclude that ES6 modules still have serious implications and issues. Changing the file extension is not enough since the extension-less imports fail with node. You'd need to go through every piled file and change the import to specifically load *.mjs files.

However, the TypeScript Compiler can be set up in a way that it does understand ES6 module syntax and to pile to CommonJS (see TS handbook).

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

This way the TypeScript code be written with ES6 module syntax and the output can be CommonJS patible without braking other code. As a bonus you can skip the Babel approach and grunt can run TS piler.

You can using babel-node to pile first. Which will resolve ES6 export and import problem.

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

本文标签: javascriptGrunt and ES6 modules in nodeincompatible without the use of mjsStack Overflow