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