Skip to content

Using ECMAScript module in NodeJs project

About 593 wordsAbout 2 min

node

2022-06-17

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.

lib/index.js
export * from './resolve.js'

package.json

In package.json we need to make the following statement:

  • Declare the type field value is module

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
package.json
{
  "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
package.json
{
  "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:

package.json
{
  "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

  1. Since it is an esm project, it is natural that you cannot use require()/module.exports in the project to import and export modules. Instead, all the import/export` methods should be used to import and export modules.

  2. You do not need to use use strict in your project code.

  3. 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.