I'm trying to write a JavaScript package using ES modules (i.e. import/export syntax). Specifically the JavaScript is transpiled from TypeScript, using the settings suggested in What TypeScript configuration produces output closest to Node.js 14 capabilities?
This works fine in the latest version of Node 14 but fails in the base-14 executor in Cypress's CircleCI orb, which I think is using Node 14.7.0. The error is a little cryptic:
internal/process/esm_loader.js:74
internalBinding('errors').triggerUncaughtException(
^
Error [ERR_UNSUPPORTED_ESM_URL_SCHEME]: Only file and data URLs are supported by the default ESM loader
at Loader.defaultResolve [as _resolve] (internal/modules/esm/resolve.js:781:11)
at Loader.resolve (internal/modules/esm/loader.js:85:40)
at Loader.getModuleJob (internal/modules/esm/loader.js:229:28)
at ModuleWrap.<anonymous> (internal/modules/esm/module_job.js:51:40)
at link (internal/modules/esm/module_job.js:50:36) {
code: 'ERR_UNSUPPORTED_ESM_URL_SCHEME'
}
This doesn't say what the default ESM loader was actually trying to load. A minimal example would be importing one of Node's built-in modules like fs, which definitely exists:
package.json
{
"name": "demo",
"version": "0.1.0",
"type": "module",
"scripts": {
"start": "node index.js"
}
}
index.js:
import fs from "node:fs";
I've confirmed that this works in 14.20 but fails in 14.7, even though ES modules are supposed to be supported from 14.0.
By Node 14.13.0, the error message has become a lot clearer:
Error [ERR_UNSUPPORTED_ESM_URL_SCHEME]: Only file and data URLs are supported by the default ESM loader. Received protocol 'node:'
The node:-prefixed "namespace" imports are, per the docs, only supported from Node 12.20.0 and 14.13.1. If you're writing a library to support Node 14.0.0 and up, you have to e.g. import fs from "fs";.