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

ES6 import support? #245

Closed
Samstiles opened this issue Dec 21, 2017 · 45 comments · Fixed by #423
Closed

ES6 import support? #245

Samstiles opened this issue Dec 21, 2017 · 45 comments · Fixed by #423
Milestone

Comments

@Samstiles
Copy link

Samstiles commented Dec 21, 2017

Hey y'all,

Thanks for your work on this lib. Any plans for ES6 import support in the near future? If it's something actively being worked on I'm gonna wait, otherwise I may look into possibly PRing?

EG

import { uuidv1 } from 'node-uuid'

@ZachMayer35
Copy link

ZachMayer35 commented Jan 2, 2018

not quite what your example asks for, but you can already do this:

import {v1 as uuidv1} from 'uuid';

or just

import {v1} from 'uuid';

if you're not picky about the accessor.

@broofa
Copy link
Member

broofa commented Jan 4, 2018

As noted in the README, importing uuid is deprecated. Instead, import uuid/<version>. E.g. to import the v1 generator using ES6 notation:

import uuidv1 from 'uuid/v1';

Edit: Recommended incantation is now:

import {v1 as uuidv1} from 'uuid';

@broofa broofa closed this as completed Jan 4, 2018
@Oliboy50
Copy link

Oliboy50 commented Aug 27, 2018

@broofa import uuid from 'uuid/v4'; syntax does not work, at least in a Typescript v3 project running on Node v10.9.0 (without webpack nor babel, only ts-node to compile/run Typescript)

I get the following error: TypeError: v4_1.uuid is not a function

on the other hand, import {v4 as uuid} from 'uuid'; works as expected

(tested on uuid v3.3.2)

@broofa
Copy link
Member

broofa commented Nov 3, 2018

Apologies for the late response on this. I [still] consider this issue closed, but in light of the "reactions" the above comment has garnered, let me state my position on this...

at least in a Typescript v3 project

... which makes this a Typescript (or TS configuration) issue. This module conforms with the requirements for CommonJS module systems. ES6 syntax should work with packagers that know how to transpile CommonJS modules to ES6.

@Oliboy50
Copy link

Oliboy50 commented Nov 3, 2018

@broofa actually you're right, in my case this was only due to how Typescript is handling CommonJS/ES6 imports

so, just like many other JS libs like this one, it works this way using TS:

import * as uuid from 'uuid/v4';

console.log(uuid());

here is a codesandbox to play with: https://codesandbox.io/s/5372omm68n

@Sampath-Lokuge
Copy link

This too works

import uuid from 'uuid/v4';
const id = uuid();

@jonathanstiansen
Copy link

@Sampath-Lokuge that doesn't work in Typescript.

@Sampath-Lokuge
Copy link

@jonathanstiansen What was the error? I have used above on Ionic / Typescript app and no issues.

@MartinX3
Copy link

MartinX3 commented Mar 2, 2019

Typescript 3.2.4 in angular 7.2.7

Creating an object from this class

import { UUID } from 'uuid/v4';

export class entity {
  id: string;
  name: string;

  constructor() {
    this.id = UUID();
    this.name = '';
  }
}

results in

ERROR TypeError: "Object(...) is not a function"

But switching to
import UUID from 'uuid/v4';
fixed it.

@vladshcherbin
Copy link

Should be reopened and fixed.

Rollup is also giving error, with import uuidv4 from 'uuid/v4'. Plugins need to be used to fix it there and this's a single package I met which requires actions from developer to make imports work.

Current index.js with exports is a mess and should be changed to a correct one so we don't need to import from separate files. Package.json file also doesn't reflect needed files.

Es modules support would be also great since it's actually quite easy to add and maintain using modern tools.

@broofa if you are okay with this, PR's can be made to reflect this changes as this package clearly needs some fresh updates to it 😉

@broofa
Copy link
Member

broofa commented Apr 26, 2019

Current index.js with exports is a mess

Agreed. Hence the deprecation warning about it going away.

FWIW, the problem with hanging all versions off the top-level module is that it it creates a dependency tree that causes packagers to pull in all 350-600 lines of code in this module, even in the very-common case where you only need the 30-50 lines required to implement v4.

Rollup is also giving error

What's the Rollup team have to say about this?

@vladshcherbin
Copy link

@broofa rollup team is pushing forward es modules, for a very long time. To get rid of such cjs errors, a plugin (rollup-plugin-commonjs) should be used there, but with top imports from index.js file it's not needed.

Top level exports from index.js file shouldn't be a problem because tree shaking is used to get only needed dependencies. Rollup and webpack both have it and should remove unused functions from bundle. So, if you only import v4 function, all other functions should be removed.

@broofa
Copy link
Member

broofa commented Apr 27, 2019

tree-shaking only works on ES6 modules (according to webpack).

@vladshcherbin
Copy link

@broofa yep, this is why I am proposing to add es modules to this package.

Bundlers (webpack, rollup) will use es modules and tree shake unused exports while cjs users will have a separate cjs version. This is how a lot of modern packages work nowadays :)

@arjunyel
Copy link

arjunyel commented May 8, 2019

I recommend using pika pack, it will generate Deno, browser, and Node compatible versions https://next.pikapkg.com/blog/introducing-pika-pack/

@cannjeff
Copy link

Any ETA on this?

@broofa
Copy link
Member

broofa commented May 14, 2019

@cannjeff: There's no ETA. If your packager doesn't support ES6-style import of CommonJS modules like this one, then you need to take that up with the packager project.

@arjunyel
Copy link

Would you accept a PR that created different distribution types?

@broofa
Copy link
Member

broofa commented May 14, 2019

@arjunyel: Short answer? No, not at this time.

Longer answer: I know this is causing people pain, and I genuinely feel bad about not being responsive to that. However, to the best of my knowledge this module complies with the CommonJS spec, which makes this an issue with how packagers support CommonJS -> ES6 transpiling. Adding extra complexity to this project to create packager-specific distributions (which are just going to get repackaged/transpiled a second time anyhow) is not something I'm interested in.

I'm open to continuing this conversation, but only to the extent you or others (or, ideally, the Rollup/Angular/Typescript teams) make a compelling argument for why this problem should be fixed here rather than in the packagers. To date, I haven't seen that effort being made.

@thepassle
Copy link

I feel like his may be relevant to the discussion here: https://jasonformat.com/enabling-modern-js-on-npm/ and will hopefully make you reconsider 😊

@quanganhtran
Copy link

I came to this issue after going from https://www.pika.dev/search?q=uuid

Package found! However, no "module" entrypoint was found in its package.json manifest. If possible, explore the site for a more web-friendly alternative.

I believe as patterns like this get adopted, ES module is going to be directly used in the browser instead of being repackaged or transpiled away.

@robrez
Copy link

robrez commented Jun 20, 2019

We've published a mirror of this repo which is bundled as ESM.

https://github.com/bundled-es-modules/uuid
https://www.npmjs.com/package/@bundled-es-modules/uuid

Cheers

@ctavan
Copy link
Member

ctavan commented Feb 17, 2020

Sorry for taking such a long time but we have finally released uuid@7.0.0-beta.0 which features native ESModules-Support for the browser:

npm install uuid@7.0.0-beta.0

The master branch README already reflects the API of v7.0.0.

It would be awesome to get feedback from you if this release works well for you.

@Oliboy50
Copy link

To try your different uuid releases using Typescript, you can use this sandbox if you want: https://codesandbox.io/s/gallant-voice-iwy7z

(I personnally didn't try to use uuid without TS, so I don't know how to make sure your ESModule configuration works using vanilla JS)

anyway, both versions (3.4.0 and 7.0.0-beta.0) seem to work fine with Typescript using this syntax:

import uuid from "uuid/v4"

as long as you:

  • add this dev dependency: "@types/uuid": "3.4.7"
  • make sure "esModuleInterop": true is set in your tsconfig file

@ctavan ctavan closed this as completed Feb 24, 2020
@ctavan ctavan mentioned this issue Feb 24, 2020
10 tasks
@dav1dddd
Copy link

I get a syntax error when importing uuid
SyntaxError: The requested module 'uuid' does not provide an export named 'v4'

@TrySound
Copy link
Member

@Dps910 Which version do you see in your node_modules?

@dav1dddd
Copy link

dav1dddd commented Mar 14, 2020

@Dps910 Which version do you see in your node_modules?

version 7.0.2
this is how I imported

import { v4 as uuidv4 } from "uuid";

also my nodejs version v13.11.0

@TrySound
Copy link
Member

Ah, it's node. Only bundlers esm is supported for now.
#402

Can you try this?
import uuid from 'uuid';
uuid.v4

@dav1dddd
Copy link

Ah, it's node. Only bundlers esm is supported for now.
#402

Can you try this?
import uuid from 'uuid';
uuid.v4

thanks, it works 😄

@FloodGames
Copy link

FloodGames commented Apr 27, 2020

Ah, it's node. Only bundlers esm is supported for now.
#402

Can you try this?
import uuid from 'uuid';
uuid.v4

WARNING in ./src/server/object.js 204:14-18
"export 'default' (imported as 'uuid') was not found in 'uuid'

Yes, it's the latest node trying to use 'import'

The alternative import v4 from "uuid"
v4() seems to run with warnings as well

@ctavan
Copy link
Member

ctavan commented Apr 27, 2020

@FloodGames I'm not sure what you are trying to say.

Per the docs the recommended way of using uuid as an ES Module is:

import { v4 as uuidv4 } from 'uuid';
uuidv4(); // ⇨ '9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d'

Does this not work for you?

@ctavan
Copy link
Member

ctavan commented Apr 27, 2020

Oh, I think I lost something in my previous answer. This does indeed currently not work in blank nodeNode.js.

Running Node.js 14.0.0 I can do the following:

import uuid from 'uuid';
console.log(uuid.v4()); // -> 'b80a7443-e722-4877-be96-4f608304ca81'

ctavan added a commit that referenced this issue Apr 29, 2020
BREAKING CHANGE: Native ES Modules is still an experimental API in
Node.js 14.0.0 and has so far not officially been supported by the
`uuid` module.

Since Node.js allows importing CommonJS modules it was possible to
import the `uuid` module like this:

```js
import uuid from 'uuid';
console.log(uuid.v4()); // -> 'cd6c3b08-0adc-4f4b-a6ef-36087a1c9869'
```

This will no longer work with proper ES Module exports in place. You
can now import the `uuid` library as described in the documentation:

```js
import { v4 as uuidv4 } from 'uuid';
uuidv4(); // ⇨ '9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d'
```

or

```js
import * as uuid from 'uuid';
console.log(uuid.v4()); // -> 'cd6c3b08-0adc-4f4b-a6ef-36087a1c9869'
```

Enabling native ES Modules for Node.js requires some special care for
the v1 algorithm which needs internal state. This makes this library
susceptible to the dual package hazard described in
https://nodejs.org/docs/latest-v14.x/api/esm.html#esm_dual_commonjs_es_module_packages

While the "isolated state" solution seems to make more sense it causes
trouble with rollup which supports CommonJS files only with an
additional plugin, see rollup/rollup#3514.

It is worth noting that webpack could deal with the "isolated state"
solution since webpack supports CommonJS sources out of the box without
further plugins and also doesn't get confused by `.cjs` file extensions
that would have to be used in the state isolation approach for
compatibility with Node.js.

The wrapper approach should however work fine. Here's what code will be
used in each case:

1. Node.js `require('uuid')`
  -> dist/index.js (CommonJS) -> dist/v1.js (CommonJS)
2. Node.js `import { v1 as uuidv1 } from 'uuid'`
  -> wrapper.mjs (ESM) -> dist/v1.js (CommonJS)
3. rollup/webpack (targeting Node.js environments)
  -> dist/esm-node/index.js (ESM) -> dist/esm-node/v1.js (ESM)
4. rollup/webpack (targeting Browser environments)
  -> dist/esm-browser/index.js (ESM) -> dist/esm-browser/v1.js (ESM)

Fixes #245
Fixes #419
Fixes #342
@ctavan
Copy link
Member

ctavan commented Apr 29, 2020

For everyone in this thread: we have just released uuid@8.0.0 which comes with native ESM support for Node.js! Let us know if that works for you. See CHANGELOG for more info.

@FloodGames @Dps910 this means that the way to go from now on is:

import { v4 as uuidv4 } from 'uuid';
uuidv4();

@dav1dddd
Copy link

For everyone in this thread: we have just released uuid@8.0.0 which comes with native ESM support for Node.js! Let us know if that works for you. See CHANGELOG for more info.

@FloodGames @Dps910 this means that the way to go from now on is:

import { v4 as uuidv4 } from 'uuid';
uuidv4();

Yes, it is working thank you :)

@Tzahile
Copy link

Tzahile commented May 14, 2020

Hi, I'm using jest to test my project.
Trying to test a file where I import uuid results with an error:

 ● Test suite failed to run

    SyntaxError: The requested module 'uuid' does not provide an export named 'v1'

          at async Promise.all (index 0)
      at jasmine2 (node_modules/jest-jasmine2/build/index.js:228:5)

I saw @Dps910 comment and I guess it's something similar.
I'm using UUID@8, node@14 and Jest@26 (and it's freshly-supported esm modules implementation).

Jest command:
node --experimental-vm-modules .\node_modules\jest\bin\jest.js
The file that I'm testing imports uuid like you suggested:

import { v1 as uuidv1 } from 'uuid';
uuidv1();

It fails only when I'm testing though.

@picozzimichele
Copy link

Had the same issue, this worked in fixing the import:

Import correct version (v1-4)

import {v4 as uuid} from "uuid"

use now the function

uuid()

@kryz81
Copy link

kryz81 commented Jun 6, 2020

This compiled to typescript doesn't work:

import { v4 } from 'uuid';
v4();

Error:
Error: Package exports for '........ /node_modules/uuid' do not define a valid '.' target

I had to downgrade to v7

@erinoggz
Copy link

const { v4: uuidv4 } = require( 'uuid' );
console.log ( uuidv4( ) )

@gizm0bill
Copy link

Angular compilation warning: application.service.ts depends on 'uuid'. CommonJS or AMD dependencies can cause optimization bailouts. For more info see: https://angular.io/guide/build#configuring-commonjs-dependencies

@crystalfp
Copy link

crystalfp commented Jan 19, 2022

Maybe this could be useful to someone.

In a Vue application (Vue 3 with typescript) I call uuid this way: import { v4 as uuid } from "uuid" and receive during build by npm run serve the following error:

./node_modules/uuid/index.js
Module build failed: Error: ENOENT: no such file or directory, open 'D:\AProject\node_modules\uuid\index.js'

To make it works I have to change the import to: import { v4 as uuid } from "uuid/dist/esm-browser"
Hope it helps
mario

@broofa
Copy link
Member

broofa commented Jan 19, 2022

Module build failed: Error: ENOENT: no such file or directory, open 'D:\AProject\node_modules\uuid\index.js'

@crystalfp: This package does not supply a top level index.js. If you look at our package.json, you'll see that the main and exports sections all point to files within the dist directory. You'll need to figure out why Vue (or tsc or whatever...) is thinks it's supposed to have one.

@broofa
Copy link
Member

broofa commented Jan 19, 2022

Locking this conversation. Anyone having issues with importing uuid should just file a new issue with detailed instructions for how to reproduce the problem.

@uuidjs uuidjs locked as off-topic and limited conversation to collaborators Jan 19, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.