After that, the Technical Steering Committee of Node.js formed a team responsible for the Modules Team to help design the missing parts for the upcoming (non experimental) release. This team consists of people from various branches of web development (frontend, backend, JS engines, etc.).
Phase 1: to create a "minimal" core - the basic set of rules and possibilities, minimal and indisputable, as far as possible.
Phase 2 and Beyond: Creating more complex functionality based on the kernel.
The minimum core will be the basis for future work. The new design will also replace the current experimental implementation as soon as it acquires similar capabilities.
Phase 1: Minimum ESM Support Core in Node.js
Simplify Module Ids
One of the goals of the Modules Team is to achieve "browser equivalence" : Node.js should be as close to the browser behavior as possible. The kernel achieves this by simplifying the parsing of module identifiers (URLs pointing to modules):
Each module identifier must end with a file name with extension. I.e
Extensions are not added automatically.
Directory importing is not supported (either via redirection to dir/index.mjs , or reading the main field in package.json ).
ES modules can import embedded Node.js modules ( path and the like). They are the only exception to the previous rule.
By default, only files with the .mjs extension are .mjs (see Phase 2 if you are interested in the status of other extensions). Thus, other types of modules cannot be imported via import : CommonJS modules, JSON files, native modules.
Bringing important CommonJS features to ES modules
URL of the current module (similar to __filename from CommonJS): import.meta.url
Dynamic import of ES modules (available through require() in CommonJS): import()
Compatibility
ES modules will be able to import CommonJS modules through createRequireFromPath() . This will work as follows (there are plans to make an abbreviated method, for example, the function createRequireFromUrl() ):
import {createRequireFromPath as createRequire} from 'module'; import {fileURLToPath as fromPath} from 'url'; const require = createRequire(fromPath(import.meta.url)); const cjsModule = require('./cjs-module.js');
CommonJS modules will be able to load ES modules via import() .
Phase 2 and Future Plans
In the second phase we are waiting for:
Support for bare identifiers such as 'lodash' . Most likely, this will include some way of mapping these identifiers into real paths.
Support for file extensions other than .mjs . This includes including support for ES modules in .js files.
Phase 3 is likely to focus on module loaders with extension points where users can connect their logic.
Warning: the behavior is not as described above in phase 1 (as of Node.js 11.5.0)
Without a flag and in accordance with phase 1: Modules The team tries to make this possible as soon as possible. We hope that the modules will be released from under the flag in Node.js 14 (April 2020) and will be ported to previous versions, if possible.
Frequently asked Questions
Why do you need a new .mjs file .mjs ?
Each solution for distinguishing between ESM and CommonJS formats has its advantages and disadvantages. Using a separate resolution seems like a good option ( more info ).
Why should the behavior of Node.js look like a browser?
Because it makes it possible to reuse the code. For example, to create libraries that work simultaneously in browsers and in Node.js
It should also facilitate switching between the backend and the frontend during coding.
Why all these limitations for compatibility?
Between ES and CommonJS-modules there are quite strong differences in the structure (static versus dynamic) and the method of loading (asynchronous versus synchronous). Restrictions help to keep things simple - given that in the long run, the overwhelming majority will be ES modules.
Why is it all lasting so long?
There are many stakeholders involved and many different platforms involved (Node.js, npm, browsers, JS engines, TypeScript, TC39, and others). If we really get ES-modules that can work everywhere, it's probably worth the wait, IMHO.
Thanks
Thanks to Miles Borins for his feedback on this post.