Node: ESM modules failed to load

Created on 9 Dec 2019  路  6Comments  路  Source: nodejs/node

  • v13.3.0:
  • OSX:
  • 10.13.6:

I have a package.json which amounts to what is the following.

{
"name": "dyo",
"type": "module",
"main": "dist/dyo.umd.js",
"exports": "index.js",
}

Where index.js is the esm entry point. When trying to test this with for example node ./ within the package it always defaults back to loading from the "main" field instead of the entry specified by "exports".

ES Modules question

Most helpful comment

Thanks for trying out ES modules, really appreciate the report!

in addition, I think exports is only used for key/value pairs of package exports. I might be wrong on that, but the docs don't mention single-value-only usage.

The single-value-only usage is valid. It's a short-hand for setting the . field in the exports object.

What you're running into is that exports only applies to actual imports of the package using the package's name, not when importing files using relative paths. We're working on a feature that allows trying it out from inside of the package directory (called "resolve self", available as --experimental-resolve-self). Until then, making the exports work requires making importing by name work, e.g. by creating a symlink from some node_modules directory.

All 6 comments

hey @thysultan

es6 modules are available unflagged since node.js v11.2.0. you might still be able to use es6 modules in your version of node with the experimental-modules flag applied, although it's use is only recommended for testing.

I was on version 13.3.0 when this happened.

ah, I see. sorry, the above 10.13.6 threw me off.

re-reading https://medium.com/@nodejs/announcing-core-node-js-support-for-ecmascript-modules-c5d6dc29b663 and the docs, the way I understand it is that _currently_ the type defines what the main field references. so node . would still only look into the main field, ignoring exports.

in addition, I think exports is only used for key/value pairs of package exports. I might be wrong on that, but the docs don't mention single-value-only usage.

also, I think dual package support is still being worked on, although I think you can already publish your package with es6 and cjs, but _currently_ the module itself is either es6 or cjs, not both. if a module is of type module, one could reference the module with bare specifiers (e.g. import foo from 'my-module') and would need to reference the cjs files with relative or absolute paths, or with package-exports.

@nodejs/modules-active-members PTAL

Thanks for trying out ES modules, really appreciate the report!

in addition, I think exports is only used for key/value pairs of package exports. I might be wrong on that, but the docs don't mention single-value-only usage.

The single-value-only usage is valid. It's a short-hand for setting the . field in the exports object.

What you're running into is that exports only applies to actual imports of the package using the package's name, not when importing files using relative paths. We're working on a feature that allows trying it out from inside of the package directory (called "resolve self", available as --experimental-resolve-self). Until then, making the exports work requires making importing by name work, e.g. by creating a symlink from some node_modules directory.

Self resolve has landed now and can be used to test exports internally.

The main Node.js entry point node ... will resolve using legacy resolution rules because to change that would be a difficult breaking change.

It would be nice to do, but there are no plans for a deprecation path currently - it is certainly something that can be discussed if people are interested though.

Was this page helpful?
0 / 5 - 0 ratings