I've been looking all over the Internet without a clear answer for this.
Currently Node.js uses only CommonJS syntax to load modules, and if you really want to use the standard ECMAScript 2015 modules syntax, you either have to transpile it beforehand or use an external module loader at runtime.
Currently I'm not too positive to use either of those two methods, are the Node.js maintainers even planning to support ECMAScript 2015 modules or not? I haven't found an hint at all about this.
At the moment Node.js 6.x claims to support 96% of the ECMAScript 2015 features, but there isn't any reference to modules (Node.js ECMAScript 2015 support link).
Do you know if Node.js will support these modules out of the box, in the near future?
Node.js 13.2.0 & Above
Node.js 13.2.0 now supports ES Modules without a flag 🎉. However, the implementation is still marked as experimental so use in production with caution.
To enable ECMAScript module (ESM) support in 13.2.0, add the following to your package.json
:
{
"type": "module"
}
All .js
, .mjs
(or files without an extension) will be treated as ESM.
There are a number of different options other than entire package.json
opt-in, all of which are detailed in the documentation for 13.2.0.
Node.js 13.1.0 & Below
Those still using older versions of Node may want to try the [esm][3]
module loader, which is a production-ready implementation of the ES Modules Specificaiton for Node.js:
node -r esm main.js
Detailed Updates...
23 April 2019
A PR recently landed to change the way ECMAScript modules are detected: https://github.com/nodejs/node/pull/26745
It's still behind the --experimental-modules
flag, but there are major changes in the way modules can be loaded:
package.type
which can be either module
or commonjs
type: "commonjs"
:
.js
is parsed as CommonJStype: "module"
:
.js
is parsed as an ECMAScript module--type=[mode]
to let you set the type on entry point. Will override package.type
for entry point..cjs
.
module
mode.--es-module-specifier-resolution=[type]
explicit
(default) and node
--es-module-specifier-resolution=node
to enable the CommonJS specifier resolution algorithm--experimental-json-loader
"type": "module"
import 'thing.json'
will go through the experimental loader independent of modepackage.main
to set an entry point for a module
17 January 2019
Node.js 11.6.0 still lists ES Modules as experimental, behind a flag.
13 September 2017
Node.js 8.5.0 has been released with support for mjs files behind a flag:
node --experimental-modules index.mjs
The plan for this is to remove the flag for the v10.0 LTS release.
--Outdated Information. Kept here for historical purposes--
8 September 2017
The Node.js master branch has been updated with initial support for ESM modules: https://github.com/nodejs/node/commit/c8a389e19f172edbada83f59944cad7cc802d9d5
This should be available in the latest nightly (this can be installed via nvm to run alongside your existing install): https://nodejs.org/download/nightly/
And enabled behind the --experimental-modules
flag:
package.json
{
"name": "testing-mjs",
"version": "1.0.0",
"description": "",
"main": "index.mjs" <-- Set this to be an mjs file
}
Then run:
node --experimental-modules .
February 2017:
An Update on ES6 Modules in Node.js
The Node.js guys have decided that the least bad solution is to use the .mjs
file extension. The takeaway from this is:
In other words, given two files
foo.js
andbar.mjs
, usingimport * from 'foo'
will treatfoo.js
as CommonJS whileimport * from 'bar'
will treatbar.mjs
as an ES6 Module
And as for timelines...
At the current point in time, there are still a number of specification and implementation issues that need to happen on the ES6 and Virtual Machine side of things before Node.js can even begin working up a supportable implementation of ES6 modules. Work is in progress but it is going to take some time — We’re currently looking at around a year at least.
October 2016:
One of the developers on Node.js recently attended a TC-39 meeting and wrote up a superb article on the blockers to implementing for Node.js:
The basic take-away from that is:
*.mjs
seems the most likely solution, unless they can accurately detect an ECMAScript module without user-input-- Original Answer --
This has been a hot potato for quite some time. The bottom line is that yes, Node.js will eventually support the ES2015 syntax for importing/exporting modules - most likely when the specification for loading modules is finalized and agreed upon.
Here is a good overview of what's holding Node.js up. Essentially, they need to make sure that the new specification works for Node.js which is primarily conditional, synchronous loading and also HTML which is primarily asynchronous.
Nobody knows for sure right now, but I imagine Node.js will support import/export
for static loading, in addition to the new System.import
for dynamic loading - while still keeping require
for legacy code.
Here's a few proposals on how Node might achieve this: