test: test suite fails on Node 20+ (esm package incompatible with modern Node)
leva13007 opened ·
## Problem `esm@3.2.25` (last release: 2019) is no longer compatible with Node 20+. Running `npm test` fails immediately:
SyntaxError: Cannot use import statement outside a module
This means contributors on modern Node versions cannot run the test suite locally.
## Root cause
The test command uses `-r esm` which hooks into Node's CJS module loader to support ESM syntax in test files. This mechanism stopped working in Node 20+ due to changes in how Node handles module loading hooks.
## Reproduction
```bash node --version # v20.x or higher npm test # fails ```
What still works
The library itself (dist/clsx.js, dist/clsx.mjs) works fine for consumers on Node 20+. Only the test suite is affected.
The constraint
Since the package declares "engines": ">=6" and CI covers Node 8–18, a simple solution of removing -r esm is not straightforward — it works on Node 20+ but breaks on Node 8–18 (no native ESM for .js files without "type": "module").
Possible approaches
1. Rename test/*.js → test/*.mjs (explicit ESM marker) — worth investigating for old Node compat 2. Add "type": "module" to package.json + rename dist/clsx.js → .cjs + update exports — larger change, affects build output 3. Replace esm with a maintained modern alternative — adds a dev dependency 4. Two CI workflows (legacy Node 8–18 + modern Node 20+) — parallel coverage without dropping either
Question
What's the preferred direction? Happy to open a PR once the approach is clear.
- LU
Thanks, I'm aware but I'd rather keep the outdated tooling which proves far-reaching backwards compatibility than update it all at the expense of losing the current proof.
- LE
I totally agree with you. But in another way we can create two CI workflows (legacy Node 8–18 + modern Node 20+) — parallel coverage without dropping either And one more thing - in the package.json you set "engines": ">=6" but in reality it works only from >=8 If you don't mind I can help you with it)
- LU
It's easy, but not worth the effort. As you've pointed out, CI only covers 8+ despite the fact that clsx _does_ work in Node 6.x (and below, technically, but I restricted)