Jasmine 5 ESM config loading across Node.js 16 CI and Node 18+ local
0 reputation · 16 Nov 2024, 14:47 UTC
0 reputation · 16 Nov 2024, 14:47 UTC
Goal is to use Jasmine 5 native ES module support with package.json "type": "module" and a jasmine.json config file in both local development and CI pipelines.
Jasmine 5 loads the config via dynamic import(). Node.js 18.19+ stabilizes ESM without flags, while Node 16/17 require --experimental-vm-modules for ESM config loading. The Jasmine CLI does not auto-detect Node version or inject flags, and --experimental-vm-modules is deprecated in Node 18 and removed in Node 20.
With differing Node versions across environments, config loading behavior is not consistent and the handling of mixed-version environments is unresolved.
Should Jasmine emit a warning when config loading depends on experimental VM modules? Is there a documented compatibility boundary for jasmine.json loading across Node 16, 18 and 20? How should projects declare supported Node versions for Jasmine 5 ESM configs?
33275 reputation · 16 Nov 2024, 21:17 UTC
The short answer: there is no official Jasmine compatibility matrix for jasmine.json loading across Node 16, 18, and 20, and the Jasmine CLI will not warn you or inject flags. The practical fix for a mixed-version setup is to stop relying on the CLI to adapt and instead pin the Node floor in your project metadata and CI, treating Node 18.19+ (or 20 LTS) as the minimum for ESM config loading.
What is well-established:
import(), so config loading inherits whatever ESM support the running Node version provides.--experimental-vm-modules for parts of this path; Node 18.19+ runs ESM without flags; Node 20 removed the old experimental flag entirely.What is less certain: the exact failure mode you see depends on whether your jasmine.json is plain JSON or a JS module, and on how your CI image invokes Node. A silent "config not found" fallback versus a hard ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING-style error are both plausible; check your CI logs before assuming which one you have.
Arguably yes, but it does not today, and you should not design around a warning that may never ship. Because the failure surfaces inside Node's module loader rather than in Jasmine's own code, the CLI has limited context to produce a precise message. Treat this as your project's responsibility, not the framework's.
The cleanest resolution is to declare the boundary yourself:
package.json:"engines": { "node": ">=18.19" }node-version: '20' in GitHub Actions, or the equivalent image tag elsewhere) so local and CI cannot drift..nvmrc or .node-version file so local shells match CI automatically.NODE_OPTIONS=--experimental-vm-modules jasmine, and schedule its removal — Node 16 is past end of life and the flag is gone in Node 20.Confirm behavior rather than trusting assumptions:
node --version
npx jasmine --version
npx jasmine --config=spec/support/jasmine.jsonThen deliberately break the config (rename a spec dir) and run it on each Node version. If the error message or exit code differs between Node 16 CI and Node 18+ local, that confirms the flag-dependent path is your inconsistency source.
Is your jasmine.json a pure JSON file or a JS config module? If it is pure JSON, moving CI to Node 18.19+ should resolve everything with no flag juggling. If it is a JS module, the dynamic-import path is more sensitive and the engines floor becomes mandatory rather than advisory.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.