Node: ES Modules does not work with namespaced library

Created on 25 Apr 2019  ·  20Comments  ·  Source: nodejs/node

  • Version: 12.0.0
  • Platform: Windows 10

I'm using experimental-modules since v8. I tried to use "type": "module" in v12 and it's fine except for namespaced library (uuid, lodash, ...)

This kind of imports:

import uuid from 'uuid/v4'
import countBy from 'lodash/countBy'

Causes this error:

internal/modules/esm/default_resolve.js:69
  let url = moduleWrapResolve(specifier, parentURL);
            ^
Error: Cannot find module 'd:\[...]\node_modules\uuid\v4' imported from d:\[...]\[...].mjs
    at Loader.resolve [as _resolve] (internal/modules/esm/default_resolve.js:69:13)
    at Loader.resolve (internal/modules/esm/loader.js:70:33)
    at Loader.getModuleJob (internal/modules/esm/loader.js:143:40)
    at ModuleWrap.<anonymous> (internal/modules/esm/module_job.js:43:40)
    at link (internal/modules/esm/module_job.js:42:36)
ES Modules experimental

Most helpful comment

the modules implementation currently disables extension resolution. you'll need to use --es-module-specifier-resolution=node to get the good behaviour or go into the lodash and uuid folders and check what the extensions of those files are and add that to the import.

All 20 comments

the modules implementation currently disables extension resolution. you'll need to use --es-module-specifier-resolution=node to get the good behaviour or go into the lodash and uuid folders and check what the extensions of those files are and add that to the import.

Closing as answered.

Had this same issue, @devsnek solution worked, thanks!

this is sort of an ongoing feedback thing for modules team so i'm gonna re-open it

cc @bnoordhuis

@aadamsx how are you using lodash-es + experimental-modules flag on node?

This node --experimental-modules --experimental-json-modules --es-module-specifier-resolution=node index.js does not work for me with the following code:

//index.js
import func from './func.js';
console.log(func(1, 1.2));
// func.js
import { round } from 'lodash-es';
console.log(round);
export default (a, b) => round(a + b);

Error =>

file:///Users/damiano/Desktop/node-jest/func.js:1
import { round } from 'lodash-es';
         ^^^^^
SyntaxError: The requested module 'lodash-es' does not provide an export named 'round'
    at ModuleJob._instantiate (internal/modules/esm/module_job.js:93:21)
    at async ModuleJob.run (internal/modules/esm/module_job.js:108:20)
    at async Loader.import (internal/modules/esm/loader.js:128:24)
error Command failed with exit code 1.

Regarding

Currently only the “default export” is supported for CommonJS files or packages

Is node or the modules loader able to see that the file is exported via module.exports? If so, would it not be possible to export the hole object as default and every object entry as named export?
eg.

commonjs.js

  module.exports = {
    a: 1,
    b: 2,
    c: 3,
  }

node12.js:

  import abc, { a as foobar } from './commonjs.js'
  abc.a === 1 && foobar === 1 && console.log('Yippi')

no, we have to declare the export names before evaluation, so we don't know what module.exports looks like.

Have the same issue. And then when I use --es-module-specifier-resolution=node it breaks CommonJS modules in the namespaced library project SyntaxError: The requested module 'date-fns' does not provide an export named 'format'

Have the same issue. And then when I use --es-module-specifier-resolution=node it breaks CommonJS modules in the namespaced library project SyntaxError: The requested module 'date-fns' does not provide an export named 'format'

Have same issue with date-fns. Try using this syntax, works for me:
import format from 'date-fns/format'

@ench0 @TrevTheDev be careful: import format from 'date-fns/format' works only because the format.js file is not importing other files, otherwise death ☠️.

Try to import a lodash-es/whatever, or also a date-fns/whatever which imports other modules in the same library.

@ench0 @TrevTheDev be careful: import format from 'date-fns/format' works only because the format.js file is not importing other files, otherwise death ☠️.

Try to import a lodash-es/whatever, or also a date-fns/whatever which imports other modules in the same library.

Tried, this is my full list of imports, no issues at all:

// @ts-ignore
import toDate from 'date-fns/toDate'
import addDays from 'date-fns/addDays'
import addHours from 'date-fns/addHours'
import addMinutes from 'date-fns/addMinutes'
import getYear from 'date-fns/getYear'
import getMonth from 'date-fns/getMonth'
import getDate from 'date-fns/getDate'
import startOfDay from 'date-fns/startOfDay'
import endOfDay from 'date-fns/endOfDay'
import isBefore from 'date-fns/isBefore'
import isAfter from 'date-fns/isAfter'
import isWithinInterval from 'date-fns/isWithinInterval'
import differenceInSeconds from 'date-fns/differenceInSeconds'

@ench0 if you are using typescript (without explicitly configuring es6 modules transpiling) then your using commonjs aka require.

Test is easy as creating a folder with the following:

package.json:

{
  "type": "module",
  "dependencies": {
    "date-fns": "^2.10.0"
  }
}

test.js:

import addDays from 'date-fns/addDays.js'
// import { addDays } from 'date-fns';

And then:

yarn install 
node --experimental-modules test.js

First import dies with:

Error: Cannot find module /Users/damians/Desktop/esm-test/node_modules/date-fns/addDays.js imported from /Users/damians/Desktop/esm-test/test.js

Second import dies with:

SyntaxError: The requested module 'date-fns' does not provide an export named 'addDays'

The actual path is date-fns/addDays/index.js here.

These lookups are not enabled for ES modules.

Closing as this is by design.

Help ensuring this is better explained in the documentation would be very welcome as it is a very common issue.

@guybedford, I'm trying to convert my project from CommonJS (CJS) to ES Module (MJS), to do that I use:

import mysqlPromise from "mysql2/promise";

But then I get an error:

Error [ERR_MODULE_NOT_FOUND]: Cannot find module 'C:\Users\User\IdeaProjects\…\node_modules\mysql2\promise' imported from…

I checked this thread but although the issue is closed I can't find a solution proposal.
Is it currently possible to import namespaced libraries into ES module/MJS on Node.js 13.00 / 14.00?

@pubmikeb in ESM, you can't omit the extension for https://unpkg.com/browse/[email protected]/promise.js so you'd need from 'mysql2/promise.js'.

@guybedford I understand, but what is the intended path for all the ecosystem to move to ESM then?
Do you expect all package mantainers to add the exports field in the package.json?

As a package consumer, just including extensions for any resolution not
governed by main or exports. And this will ensure compatibility in other JS
environments too.

On Sat, Apr 11, 2020 at 00:23 Damiano notifications@github.com wrote:

@guybedford https://github.com/guybedford I understand, but what is the
intended path for all the ecosystem to move to ESM then?
Do you expect all package mantainers to add the exports field in the
package.json?


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/nodejs/node/issues/27408#issuecomment-612353904, or
unsubscribe
https://github.com/notifications/unsubscribe-auth/AAESFSX7V2VUDL65FJC5R3DRMALF5ANCNFSM4HILSXPQ
.

@guybedford I'm not sure I understood, my bad!
Do you know a library who is handling both esm and cjs correctly at the moment so I can get an idea on how to move?

@damianobarbati in https://unpkg.com/browse/[email protected]/, i'm using the exports field combined with main to load index.js as CJS and in browsers, node.js in CJS node, and node.mjs in ESM node. I'm also allowing ./package.json and ./package (which only works for require atm, but would work for import in the future if JSON ESM became a thing)

@ljharb thank you! I'll give it a try soon.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

willnwhite picture willnwhite  ·  3Comments

cong88 picture cong88  ·  3Comments

danielstaleiny picture danielstaleiny  ·  3Comments

sandeepks1 picture sandeepks1  ·  3Comments

loretoparisi picture loretoparisi  ·  3Comments