-
-
Notifications
You must be signed in to change notification settings - Fork 795
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
v4 can't be imported in node #365
Comments
I'm also having this issue |
Me too. |
This is a feature, not a bug. See the changelog for details of the breaking change in version 4.0 (semantic versioning major increment): https://github.com/ai/nanoid/blob/main/CHANGELOG.md#40 |
Also see the author's feedback in this previously-closed issue: #364 (comment) |
Check your TS config. Seems like TS convert |
This doesn't help at all, we saw the comment in the commit on main page of code repo, as stated.
In this one the guy says he was using require, and is told to move to import. As stated, I (we ?) are already using import since long.
Thanks, I've tried changing module: "commonjs" to module: "esnext", but it made no difference. Could you share your whole tsconfig file ? Here's mine:
|
Maybe you should remove Here is one of my examples https://github.com/hplush/slowreader/blob/main/tsconfig.json |
Hello @g012 , Support for ESM depends heavily on tooling, for example you may have different tsconfig.json settings for your unit tests, your dev builds, and your production release ... depending on whether your codebase is managed with WebPack, Rollup, Vite, Jest, Vitest, etc. The author of NanoID said that he will kindly continue to offer off-the-shelf compatibility with CommonJS by maintaining v3 in parallel to ESM v4, but I am concerned that noise/signal ratio will increase in this issue tracker due to v4 support queries. As far as I can tell there are no problems with NanoID's published package.json export map etc. so I think it would make sense to continue such general ESM/CJS conversations in a GitHub discussion instead. :) |
I'm having the same issue in two flavors. first one was described above. second one is: Details:
/home/circleci/project/node_modules/nanoid/index.js:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,jest){import { randomFillSync } from 'crypto'
^^^^^^
SyntaxError: Cannot use import statement outside a module
> 1 | import { customAlphabet } from 'nanoid';
| ^
2 |
3 | const letters = customAlphabet('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', 1);
4 | const alphanumeric = customAlphabet('0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', 5);
in short, I need to turn on an experimental feature in node to enable ESModules import in Jest. this is my update PR: starwards/starwards#847 |
I think this decision was made far too early. ESM has just started to be supported by NodeJS. I'm not sure if I want to refactor my whole "production application" for ESM right now. I just wanted to point that out. |
"We will support 3.x branch with CommonJS for users who can’t migrate to ESM" https://github.com/ai/nanoid/blob/main/CHANGELOG.md#40 |
Hi Daniel, Yes I think you're right, the Keystone JS toolset converts typescript to CJS, and if I disable that, I get lint warnings for k6 core and some others, so I've decided to stick with branch 3 until everything migrates. Thanks for the help ! |
Really terrible decision. Was gonna use this in place of shortid because apparently this is more secure? But since I literally can't import the latest I'm just gonna keep using shortid. Good luck building a product that people can't use! |
"We will support 3.x branch with CommonJS for users who can’t migrate to ESM" https://github.com/ai/nanoid/blob/main/CHANGELOG.md#40 |
Are you planning any security updates for 3.x? Can you clarify what you mean with 'support 3.x branch'? |
Of course. All fixes will be backported. |
Use this version while the author fixes commonjs issue: npm i -S nanoid@^3.0.0 |
Whatever works for the maintainer. I am happy the person still maintains the CommonJS version for security updates :) |
Dual ESM/CJS packages is not a good thing. As a developer of dual-publish I can say it without a doubt.
Current state of ecosystem when we need to support both ESM and CJS is very hard for maintainers. Our community need to migrate to ESM-only future. It was already a few years since ESM announce. |
That is true, but esm only packages can be very hard for users ;) Im perfectly happy to keep using v3 until I can switch things to ESM (there is already a pretty long list of other dependencies that cant be updated), but that switch is currently impossible due to electron not supporting ESM in the backend at all, and jest needing nodejs to finish some features before they can have feature parity with CJS. |
Electron and Node.js will not be ready for years if there will not be push from the community. It is better to support ESM issues in Electron and Node.js.
You do not need to always use the latest version of the dependency. You need to use the latest supported version. Both branches 3.x and 4.x are supported. Don’t worry that you are on 3.x branch. |
I don't really mind maintainers of packages switching to ESM. It's their project. Only I wish they don't forget their old CommonJS packages when vulnerabilities in dependencies or similar occur. So I was glad to hear this is the case for this super useful package :) I really need to find out how I can get ESM modules working with Jest. Or is there a better alternative for Jest that has better ESM support? Anyone tried Vitest? Looks like its compatible with Jest's |
For simple Node.js libraries For React projects Vitest is the best option. |
Exactly. Im using 4.x in some projects and 3.x in others, depending on whether they are ESM or not. Hopefully 3.x will get updates for a few years, as I expect ESM wont be usable for everyone for at least a couple more years
I believe that Jest does mostly work, but they don't have feature parity with CJS. jestjs/jest#9430 |
Thank you, it's works for me |
Just stay on Nano ID 3 if you have CJS project. We will support Nano ID 3 for a few years. I delete a very hacky and dangerous advice of crazy wraps to load ESM to CJS. |
No, I'm going to use v4 using the 'hacky and dangerous' method because I don't want to worry about being stuck on an obsolete version which will not be supported soon. |
Nano ID 3 is not obsolete. It is a parallel version. We will support it for a few years. Just use Nano ID 3.x. There are no rational problems with this version. |
If a version of an open source node library has got an end of life announced for it, I consider it already on its way out. It's how I and many other devs out there work, and it's all about minimising technical debt. That will be the only dependency of over 50 in my package.json I have to worry about pinning, which I've managed to avert worrying about by doing this 'super dangerous hack' (which isn't really that dangerous at all, I have an integration test that covers usage of it and continuously audit my packages). The problem here isn't whether or not people should stay on v3 or not, it's about understanding the reality of many projects out there that do not have the resources or priorities around upgrading to ESM. ESM isn't a magical solution to dependency security, you can still do plenty of mischief whether your lib is used in CJS or ESM mode. |
@vdjurdjevic if you like to keep everything fresh, you have an another reason to move to ESM. ESM is the future of imports in JS. Keep your project fresh too. 😊 |
Trust me I tried :) But everything started to break, spent few hours trying to make it work and then decided to go back. It's medium size project, with 70 dependencies, it's not that easy to switch |
I admire the attempted prescience but please stop making these decisions for developers that take pride in their work. We will decide the future of our own stack whether it includes this dep or not. |
v3 is still supported |
see ai/nanoid#365 and Error: require() of ES Module /Users/rob/fastlane-web/node_modules/@tldraw/store/node_modules/nanoid/index.js from /Users/rob/fastlane-web/node_modules/@tldraw/store/dist-cjs/lib/RecordType.js not supported. Instead change the require of index.js in /Users/rob/fastlane-web/node_modules/@tldraw/store/dist-cjs/lib/RecordType.js to a dynamic import() which is available in all CommonJS modules.
You should be able to wrap this with a dynamic import: For example:
import type NanoidLib from 'nanoid';
let _lib: typeof NanoidLib;
/**
* Wrapper to import the ESM module into this project
*
*/
export async function nanoid(size?: number) {
// Load library
if (!_lib) {
_lib = await import('nanoid');
}
// Create ID
return _lib.nanoid(size);
}
import { nanoid } from 'lib/nanoid';
async function doingStuff() {
const id = nanoid();
} |
Some funny stats from npmjs: nanoid weekly downloads: 37 million. v4 and v5 combined combined weekly downloads (ESM): 1.9 million. "ESM is the future". Ok, but how many centuries into the future ? :) |
@pBread just move your project on ESM. You will have problems with CJS project not only because of Nano ID, but because of all Sandre's packages, etc. Even Vite deprecated CJS API. Open source is about community work, not about demanding something from people whom you are not paying. |
It is exactly what we did in 3.x. It has three problems:
|
lol, this thread keeps going. @ai I admire that you still have the strength to write everyone back 😅 |
@pBread are you forking nanoid? 3.3.7 was released not too long ago.. 3.x is still fine if you need CJS, and don't want to for whatever reason move to ESM. ..
I'm impressed as @jsardev is. So incredibly patient. |
For people coming here because of Jest specifically you can setup a mock for nanoid which worked to solve our issues:
and then call it in global setup:
|
Node.js 22 allowed to Just run your app with node --experimental-require-module app.js |
Is there no way to have a single source that exports ESM and commonjs? |
There are many ways, but none of them works in 100% cases of big user base of Nano ID. For instance, Jest replaces Node.js loader with own implementation which kills most of hacks. And all methods bloats The best way is to use latest Node.js where you can require ESM in CJS (they are going to remove that limit) or just migrate your app to ESM. |
maybe its worth creating a new library which is ESM only to avoid this breaking change breaking people's apps? FWIW I only use typescript now and getting ESM to work there seems extremely fragile. switching the compiler output then breaks other things. |
We removed CJS because we had many issues from Jest users because of dual CJS/ESM system. Just move your app to ESM. And easy and future proof. |
I have tried to migrate my application to ESM. After several days I gave up because there were so many hurdles for which I could not find a solution. From my point of view, ESM is stillborn and many other developers have probably had the same experience as me, otherwise your package in version 3 would not have so many daily downloads. |
@ai Hey, thank you for the efforts on this library but please consider the following:
I understand that the goal of P.S. I'm not against ESM, just unable to put it to good use till now |
@aggarwaldev thanks for get reasoning. My current 2 reasons to keep ESM-only:
Your arguments do not change my arguments, so I still not convinced (but I open for discussion). A few words about why your arguments did not convince me:
I do not believe in front-end community anymore. I am mostly creating tools for myself and my project in new fields. Front-end community doesn’t give enough back to maintainers (not only in terms of money), but demanding a lot.
Since: I prefer to works with “indie” ecosystem. For me, it is ESM-only. In my indie ecosystem everything works out-of-box and even better than with 3.x. Why I should care about main-stream community ecosystem if the community behind this ecosystem doesn’t care about my need?
Since I do not believe in main-stream community choices, I care about feedback from people important to me. It was too many mistakes in front-end stack to believe in every feedback.
There is no strict 3.0 end-of-time. Even if I do not believe in the main-stream community, I will support 3.x as much it is needed (for instance, until we will have stable
We do not plan any new features for 5.x or 6.x. Web Crypto API update is not a new feature. Nothing will be changed in public API by moving to Web Crypto API internally (correct me if I am missing something). |
The only thing that saves ESM is that NodeJS 22 and higher will finally allow mixing ESM and CJS modules. Otherwise we would keep seeing ESM packages downloaded 25 times less than CJS for years. As I have always said, allowing coexistence of CJS and ESM in software was the only way to save ESM. So basically after NodeJS 22 (and especially after that "experimental" flag will be default") this kind of thread will disappear. As for me, I find CommonJS to be powerful, flexible, with clear rules, basically meeting all my needs, I never felt the need for anything else, but I am also not opposed to it as long as it allows me to deliver software into real, money-making production (and not only to embrace a new technology just because it's new and shiny). |
You can try this package to support the latest version of nanoid and compile it into the format supported by cjs. https://github.com/Leizhenpeng/nanoid-cjs
|
New Node.js 20 supports This flag allow you to use Nano ID 5.x with CJS apps. |
Hello,
I'm not knowledgeable at all in all the module formats / import mess of javascript / node, but I'm using KeystoneJS and I import nanoid in it. Since version 4 (2 days ago), I have this error :
Error [ERR_REQUIRE_ESM]: require() of ES Module /node_modules/nanoid/async/index.js from schema.ts not supported. Instead change the require of index.js in schema.ts to a dynamic import() which is available in all CommonJS modules.
This is how I've always imported nanoid :
import { nanoid } from 'nanoid/async';
Reverting to 3.3.4 works.
I see in the commit comment that you removed CJS support, but as I understand, using this import statement, I'm using the new thingy module stuff, not CJS which uses require instead, and you have "type: module" in your package.json, so I really don't know what's wrong here.
Any idea what I'm doing wrong ? Thanks !
The text was updated successfully, but these errors were encountered: