Using ECMAScript module in NodeJs project
As Nodejs v16
becomes a long-term and stable version, ESM
has also become a standardized module system officially supported by NodeJs
, which allows us to pass ESM
to develop our NodeJs
project and import other ESM
packages in the project.
Create a project
Let’s take the example of creating a new NodeJs project, which has the following structure:
./my-esm-package
├── lib
│ ├── resolve.js
│ └── index.js
└── package.json
The function of this project is to export a resolve method, which is an encapsulated implementation of path.resolve
.
export * from './resolve.js'
import path from 'path'
export const resolve = (...arg) => path.resolve(...arg)
package.json
In package.json
we need to make the following statement:
- Declare the
type
field value ismodule
This field declares that your package will be loaded and parsed as an ECMAScript module by NodeJs
and allows files in the .mjs
format.
- Declare the
exports
field
This field describes how the project exports modules to other packages for use.
- Default export
{
"exports": "./lib/index.js"
}
That is, when using import { resolve } from 'my-esm-package'
, the default file introduced is lib/index.js
.
- Export multiple modules
{
"exports": {
".": "./lib/index.js",
"resolve": "./lib/resolve.js"
}
}
Two modules are declared to export: one is the default export, using "."
as the key; the other is the name export.
When using import { resolve } from 'my-esm-package'
, the default imported file is lib/index.js
.
When using import { resolve } from 'my-esm-package/resolve'
, the imported file is lib/resolve.js
.
exports
also supports other forms of values, which will not be described here.Declare the
engines
field
Since Nodejs
does not support esm
in the full version, it has been experimentally supported since v14.16.0
, and it was not officially supported until v16
. And the current v16
version is the current long-term and stable supported version. The NodeJs version of this project's running environment should be recommended to use v16
or above. That is, its value should be { "node": ">=16" }
At this point, the package.json file of this project contains the following content:
{
"name": "my-esm-package",
"description": "My first esm package.",
"type": "module",
"exports": {
".": "./lib/index.js",
"resolve": "./lib/resolve.js"
},
"engines": {
"node": ">=16"
}
}
Write project code
Since it is an
esm
project, it is natural that you cannot userequire()
/module.exports
in the project to import and export modules. Instead, all the import/
export` methods should be used to import and export modules.You do not need to use
use strict
in your project code.Since
ESM
project,NodeJs
no longer supports__dirname
/__filename
, when there are related scenarios that need to be used, you need to use other methods to implement the same function:
import { dirname, basename } from 'path'
import { fileURLToPath } from 'url'
const _dirname = typeof __dirname !== 'undefined' ? __dirname : dirname(fileURLToPath(import.meta.url))
const _filename = typeof __filename !== 'undefined' ? __filename : basename(fileURLToPath(import.meta.url))
TypeScript
If you use TypeScript
in your project, in addition to following the above content, you also need to add the following configuration in the tsconfig.json
configuration file:
{
"module": "node16",
"moduleResolution": "node16"
}
Moreover, the .ts
file should be compiled into a .js
file, and the exports
configured in package.json
is the compiled .js
file.
at last
When the above steps are completed, you can get a NodeJs ESM
project. It can also be used only in another project that supports esm
.