Skip to main content

ES module system

When to test

  • Your package runs in Node.js
  • Your package is expected to be imported/required by projects
  • Your package uses a conditional export for the ES module system
    • Via the exports key in the package.json file

What to test

Test that your package works in projects that use the ES module system (a.k.a., “ECMAScript modules”) and use ES6-style import/export syntax. This is especially important if your package is written and tested using the Common JS module system.

How to set up

Specify the module type in the package.json file:

test-projects/es-module-system/package.json
{
"type": "module",
"scripts": {
"test": "jest"
}
}

Common problems to watch for

External import syntax

Make sure that your package can be imported successfully and without using * as.

import yourPackage from 'your-package'; // Good
import * as yourPackage from 'your-package'; // Bad

Internal import syntax

This is especially important if you’re using a compiler/transpiler like TypeScript. Make sure that internal imports don’t throw ERR_MODULE_NOT_FOUND errors.

Consider the following two TypeScript files:

./bar.ts
export default function bar() {
return 'bar';
}
./foo.ts
import bar from './bar';
bar();

Consider also the following configuration directives:

tsconfig.json
{
"compilerOptions": {
"module": "ESNext",
"target": "ES2020"
}
}
package.json
{
"type": "module",
}

If you run tests directly against the TypeScript source files with a test runner like Jest, chances are your tests will pass. But, when you run the compiled version, you may encounter ERR_MODULE_NOT_FOUND errors stating that the ./bar file can't be found. To fix this (in this scenario), you must add .js to the end of every import path:

./foo.ts
import bar from './bar.js';
bar();

Use of require()

If your package attempts to require() a file from the project using your package, you may encounter a ERR_REQUIRE_ESM error. This is because you can’t use require() to load an ES module.

const someFile = require(path.join(process.cwd(), 'some-file.js')); // Probably won’t work