I just got this error when trying to import a module from Node:
» node --import=tsx foo.ts 1 ↵
/foo.ts:1
import { blah } from "thing/otherthing";
^
SyntaxError: The requested module 'thing/otherthing' does not provide an export named 'blah'
at ModuleJob._instantiate (node:internal/modules/esm/module_job:177:21)
at async ModuleJob.run (node:internal/modules/esm/module_job:260:5)
at async onImport.tracePromise.__proto__ (node:internal/modules/esm/loader:543:26)
at async asyncRunEntryPointWithESMLoader (node:internal/modules/run_main:116:5)
Node.js v23.0.0
But it did provide that export! thing was a package I made that had a mapping in its packages json.exports from “otherthing” to “otherthing.ts” and “otherthing.ts” for sure exported “blah”.
Notice that I’m using node --import=tsx, and not ts-node. I’m not sure whether that’s significant, but it’s worth noting.
Typescript didn’t have any errors, though. I could properly command-click on “blah” and navigate to its definition inside my editor.
There were two possible fixes for this scenario:
Fix for when the package can’t be changed
Turns out if I imported the whole module, and _then_ accessed the export, Node worked:
import * as stuff from "thing/otherthing"
const blah = stuff.blah
I don’t love this fix, since it’s not the typical way of doing an import, and it’d be easy to run into the issue again. But for someone who doesn’t have a way to modify the node_module, it works.
Fix for when the package can be changed
Turns out in the package.json inside of thing, I only had to set its “type” to “module:
{
"name": "blah",
...
"type": "module"
}
Then Node knew how to find my named exports.