Environment
-
OS: macOS (darwin)
-
Node.js version: v23.9.0 (also tested with v20.11.1)
-
JupyterLab branch: main (latest)
Problem Description
I’m unable to run Jest tests locally on macOS. Tests that pass in CI fail locally with ESM module resolution errors. I’ve tested with both Node 23 (latest) and Node 20, and both fail (with different errors).
Node Version Compatibility Issues
| Node Version | Error |
|---|---|
| v23.9.0 (latest) | Must use import to load ES Module: …/nanoid/index.browser.js |
| v20.11.1 | Same ESM errors after various fixes |
| v18.x | ReferenceError: File is not defined (jest-env.ts uses File global only available in Node 20+) |
The CI uses Ubuntu with Node 20, but the tests don’t work locally on macOS with any Node version.
Steps to Reproduce
cd packages/rendermime
jlpm test
Error Message
FAIL test/factories.spec.ts
● Test suite failed to run
Must use import to load ES Module: /path/to/node_modules/@jupyter/web-components/dist/esm/index.js
2 | // Distributed under the terms of the Modified BSD License.
3 |
> 4 | import { Button } from '@jupyter/react-components';
| ^
at Runtime.requireModule (../../node_modules/jest-runtime/build/index.js:841:21)
at Object.require (../../node_modules/@jupyter/react-components/lib/Accordion.js:1:1)
Investigation Findings
1. Root Cause Chain
-
jest-environment-jsdom adds “browser” to export conditions: [“require”, “default”, “browser”]
-
This causes nanoid to resolve to index.browser.js (ESM) instead of index.cjs (CommonJS)
-
After fixing nanoid, the issue shifts to @jupyter/web-components which is ESM-only
2. The @jupyter/web-components Problem
This package is ESM-only with no CommonJS fallback:
{
"type": "module",
"main": "dist/esm/index.js"
}
3. The @jupyter/react-components Problem
Uses ESM syntax in lib/ without declaring "type": "module":
// node_modules/@jupyter/react-components/lib/Accordion.js
import { jpAccordion } from '@jupyter/web-components'; // ESM syntax!