Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ES Modules does not work with namespaced library #27408

Closed
madmoizo opened this issue Apr 25, 2019 · 20 comments
Closed

ES Modules does not work with namespaced library #27408

madmoizo opened this issue Apr 25, 2019 · 20 comments
Labels
esm Issues and PRs related to the ECMAScript Modules implementation. experimental Issues and PRs related to experimental features.

Comments

@madmoizo
Copy link

madmoizo commented Apr 25, 2019

  • 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)
@devsnek
Copy link
Member

devsnek commented Apr 25, 2019

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.

@devsnek devsnek added esm Issues and PRs related to the ECMAScript Modules implementation. experimental Issues and PRs related to experimental features. labels Apr 25, 2019
@bnoordhuis
Copy link
Member

Closing as answered.

@aadamsx
Copy link

aadamsx commented May 5, 2019

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

@devsnek
Copy link
Member

devsnek commented May 5, 2019

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

cc @bnoordhuis

@devsnek devsnek reopened this May 5, 2019
@damianobarbati
Copy link

@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.

@valoricDe
Copy link

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')

@devsnek
Copy link
Member

devsnek commented Sep 18, 2019

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

@TrevTheDev
Copy link

TrevTheDev commented Dec 14, 2019

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'

@ench0
Copy link

ench0 commented Mar 9, 2020

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'

@damianobarbati
Copy link

@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
Copy link

ench0 commented Mar 10, 2020

@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'

@damianobarbati
Copy link

damianobarbati commented Mar 12, 2020

@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'

@guybedford
Copy link
Contributor

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.

@pubmikeb
Copy link

@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?

@ljharb
Copy link
Member

ljharb commented Mar 28, 2020

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

@damianobarbati
Copy link

@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?

@guybedford
Copy link
Contributor

guybedford commented Apr 11, 2020 via email

@damianobarbati
Copy link

@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?

@ljharb
Copy link
Member

ljharb commented Apr 15, 2020

@damianobarbati in https://unpkg.com/browse/es-get-iterator@1.1.0/, 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)

@damianobarbati
Copy link

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

samccone added a commit to samccone/rxjs-1 that referenced this issue Mar 29, 2021
In order for module resolution to work with .mjs or package: module code
we need to utilize the conditional export feature of node.

> The current specifier resolution does not support all default behavior of the CommonJS loader. One of the behavior differences is automatic resolution of file extensions and the ability to import directories that have an index file.

https://nodejs.org/api/esm.html#esm_customizing_esm_specifier_resolution_algorithm
https://nodejs.org/api/packages.html#packages_conditional_exports

This directly enables rxjs to work with mjs code and commonjs code since
mjs does not support loading bare folder paths.

This is a fix to:
sveltejs/kit#612

and is directly related to the conversation in this issue within node
core nodejs/node#27408
samccone added a commit to samccone/rxjs-1 that referenced this issue Mar 29, 2021
In order for module resolution to work with .mjs or package: module code
we need to utilize the conditional export feature of node.

> The current specifier resolution does not support all default behavior of the CommonJS loader. One of the behavior differences is automatic resolution of file extensions and the ability to import directories that have an index file.

https://nodejs.org/api/esm.html#esm_customizing_esm_specifier_resolution_algorithm
https://nodejs.org/api/packages.html#packages_conditional_exports

This directly enables rxjs to work with mjs code and commonjs code since
mjs does not support loading bare folder paths.

This is a fix to:
sveltejs/kit#612

and is directly related to the conversation in this issue within node
core nodejs/node#27408
samccone added a commit to samccone/rxjs-1 that referenced this issue Mar 30, 2021
…oading.

In order for module resolution to work with .mjs or package: module code
we need to utilize the conditional export feature of node.

> The current specifier resolution does not support all default behavior of the CommonJS loader. One of the behavior differences is automatic resolution of file extensions and the ability to import directories that have an index file.

https://nodejs.org/api/esm.html#esm_customizing_esm_specifier_resolution_algorithm
https://nodejs.org/api/packages.html#packages_conditional_exports

This directly enables rxjs to work with mjs code and commonjs code since
mjs does not support loading bare folder paths.

This is a fix to:
sveltejs/kit#612

and is directly related to the conversation in this issue within node
core nodejs/node#27408
samccone added a commit to samccone/rxjs-1 that referenced this issue Mar 30, 2021
samccone added a commit to samccone/rxjs-1 that referenced this issue Mar 30, 2021
benlesh pushed a commit to ReactiveX/rxjs that referenced this issue Mar 30, 2021
…oading. (#6192)

* feat(esm): Add exports within package.json to enable scoped package loading.

In order for module resolution to work with .mjs or package: module code
we need to utilize the conditional export feature of node.

> The current specifier resolution does not support all default behavior of the CommonJS loader. One of the behavior differences is automatic resolution of file extensions and the ability to import directories that have an index file.

https://nodejs.org/api/esm.html#esm_customizing_esm_specifier_resolution_algorithm
https://nodejs.org/api/packages.html#packages_conditional_exports

This directly enables rxjs to work with mjs code and commonjs code since
mjs does not support loading bare folder paths.

This is a fix to:
sveltejs/kit#612

and is directly related to the conversation in this issue within node
core nodejs/node#27408

* feat(esm): Add test case for esm imports.

Context:
sveltejs/kit#612
nodejs/node#27408
joshuanianji added a commit to joshuanianji/nerd-bot that referenced this issue Mar 15, 2023
Maybe this will help my esm imports?

Notes:
- SO Discussion: https://stackoverflow.com/a/65588027
- GH Discussion: nodejs/node#27408 (comment)
joshuanianji added a commit to joshuanianji/nerd-bot that referenced this issue Mar 15, 2023
HOPEFULLY CI WORKS!!!!!

* Highlight features in README more

* Use `--es-module-specifier-resolution=node`

Maybe this will help my esm imports?

Notes:
- SO Discussion: https://stackoverflow.com/a/65588027
- GH Discussion: nodejs/node#27408 (comment)

* Delete unused imports

* use `npm run start` in dockerfile

* Delete `node-canvas` imports

those were only for arm, and i only installed them to test stuff on my own machine
ziedHamdi pushed a commit to ziedHamdi/user-credits that referenced this issue Oct 26, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
esm Issues and PRs related to the ECMAScript Modules implementation. experimental Issues and PRs related to experimental features.
Projects
None yet
Development

No branches or pull requests