Translated from:
Using ES modules natively in Node.js, the original author is
Dr. Axel Rauschmayer, the circle called “German Ruan Yifeng”.
Node.js has supported ES modules natively since 8.5.0, but still requires command line arguments. This is thanks to Bradley Farias’ contribution to this new feature.
This article describes this feature in detail.
Take a chestnut
File structure:
esm-demo/
lib.mjs
main.mjs
Copy the code
Lib. MJS:
exportfunctionadd(x, y) {
return x + y;
}
Copy the code
The main MJS:
import {add} from'./lib.mjs';
console.log('Result: '+add(2, 3));
Copy the code
Run example:
$ node --experimental-modules main.mjs
Result: 5
Copy the code
Pay attention!
Module name of ES:
- All module names are urls – this introduces something new to Node.js;
- Files: It is best to use opposite bands
.mjs
Suffix path to reference ES module, which ensures browser compatibility. If no suffix is included, the module search is the same as CJS. If we find both.mjs
和.js
File, then use.mjs
File;- Such as:
../util/tools.mjs
- Such as:
- Library modules: Use the module name directly, omitting the extension is best. This is best compatible with the way library modules are distributed at this stage;
- Such as:
lodash
- Such as:
- How to make
node_modules
There is still work to be done to see how the bundler module works in the browser (without bundler). One alternative is to introduce a requireJs-class configuration that converts the bare path to the real path. Currently, bare-path modules are not available in browsers;
Features of ES module:
- Unable to dynamically import modules; But the dynamic operator import() will soon be introduced;
- like
__dirname
和__filename
And such meta-variables will no longer be provided, there is a new proposal introduced that will give ES modules a similar approach – Domenic Denicola proposedimport.meta
。
console.log(import.meta.url);
Copy the code
Interoperability with CJS modules
-
The ES module can import CJS modules, but the imported module contains only a default export — that is, module.exports value. Plans have been made to have the CJS module print named export (by adding a compile instruction at the beginning of the file), but this may take some time to implement. If you want to help, look here.
import fs1 from'fs'; console.log(Object.keys(fs1).length); // 86 import * as fs2 from'fs'; console.log(Object.keys(fs2)); // ['default'] Copy the code
-
Require () cannot be called in an ES module, mainly because:
- Path resolution is quite different in the two specifications: ESM does not support it
NODE_PATH
和require.extensions
; Its module identifier is always a URL, which makes a small difference; - For maximum compatibility with browsers, ES modules are always loaded asynchronously. This asynchronous loading approach works with CJS
require()
Synchronous loading doesn’t work well together; - The synchronization module is also disabled to use top-level in ES modules
await
Closed the door (a feature currently under consideration);
- Path resolution is quite different in the two specifications: ESM does not support it
-
CJS cannot require() ES modules. The reason is similar to that mentioned in the previous article, synchronous loading of asynchronous modules various problems ah. However, it might be possible to load the ES module with import().
Use the ES module on older versions of Node.js
Well, if you want to use ES modules on older Node.js, check out John-David Dalton’s @STD/ESM.
Tip: As long as you don’t use the Unlockables feature, you can guarantee full compatibility with native ES Modules.
FAQ
When is it possible to use ES modules without command configuration?
The current plan is to support ES modules directly in the Node.js 10 LTS version;
.mjs
Does it work in a browser?
Yes, just provide the correct Media Type (text/javascript or Application /javascript). The standardization of MJS and the upgrade of peripheral tools are in progress.
File extension.mjs
Is it required for the ES module?
Yes, that’s true for Node.js. Browsers don’t care about file extensions, just Media types.
Why is Node.js needed.mjs
?
Node.js could have checked whether a file was a CJS module or an ES module. Several other options were discussed before choosing the option of adding extensions. You can read another post on this blog. Each scheme has its advantages and disadvantages. In my opinion,.mjs is the right choice.