In modern JavaScript, there are two types of modules: ES6 module and CommonJS module used by NodeJS. These two types of module are not compatible. Many people would wonder how to load ES6 modules in their NodeJS project. This post will show how this can be done.
Difference
The syntax of the module being loaded is different. CommonJS modules are loaded with require()
and exported with module.exports
. ES6 modules are loaded and exported using import
and export
respectively.
Merchanismwise require()
is doing sequential loading, other statements must wait for this statement to complete before executing. However, import
is asynchronous, to be precise it has a static code analysis and dependency resolution phase which indicates internally it would not be sequential.
To be loaded in NodeJS, ES6 module files should have file extension .mjs
, i.e, if the file uses import
or export
inside, it should have .mjs
file extension. When NodeJS encounters .mjs
file, it will load it as ES6 modules and will enable strict mode by default.
If don't want to change the file extension to .mjs
, package.json
file needs to be updated to set type
to module
. Once this is done, all files under this folder will be loaded as ES6 modules.
{
"type": "module"
}
For CommonJS modules, the file extension is .cjs
. If there is no type setting or the type is set to commonjs
in package.json, the .js
file would be treated as CommonJS module as well.
In summary, .mjs
file will always be loaded as ES6 modules, .cjs
will always be loaded as CommonJS modules, .js
file will be loaded based on the type setting in package.json
.
Be careful when loading these different types of module. require()
cannot load .mjs
file and also import
cannot load .cjs
file.
Loading
ES6 modules cannot be loaded with require() which would throw error. They can be loaded with import only.
(async () => {
await import('./my-app.mjs');
})();
Above code can be ran in CommonJS modules.
As explained earlier, require() loads the modules sequentially, but ES6 modules support await
which would cause the module not be able to be loaded sequentially.
import can load CommonJS modules but the module should be loaded altogether, cannot just load one specific exported object.
// ok
import packageMain from 'commonjs-package';
// not ok
import { method } from 'commonjs-package';
This is because ES6 modules need to do static code analysis while CommonJS doesn't support this.
If want to load a specific exported object, can do below.
import packageMain from 'commonjs-package';
const { method } = packageMain;
Reference: http://www.ruanyifeng.com/blog/2020/08/how-nodejs-use-es6-module.html