Closed bitdom8 closed 2 years ago
Yes. It is indented. 4.0 removed CommonJS support (require()
).
You can move your app to ESM a use import
instead of require
.
Or you can stack with 3.x branch. We will support 3.x for a year.
Thanks you sir @ai
@ai please consider using only CHANGELOG.md or Releases. Makes it super confusing to know where to go for info when both exist. There's also the matter of the CHANGELOG.md have far less information than what is provided in Releases for the 3.0 release.
Please also consider publishing 3.x versions under the latest-3
dist-tag.
The decision to go ESM only is really unfortunate and sad. Hobbyists and open source (e.g. package) developers will probably absorb this change without much issue. But the business world will not, and ending support for the package in CommonJS (just as Sindre and countless others have done) will ultimately hurt the ecosystem's biggest users; businesses. Hell, it took AWS a full year and a month to release Node v16 support. I'm sure I won't change your mind, but I've personally always admired you and your work, and I'm really disappointed in your decision.
@shellscape businesses (even if they do not pay we still try to support them) will not have difference.
They still have CJS version of Nano ID 3. This version still have a good support. I am still using Nano ID 3 in PostCSS.
About what problem do you taking exactly?
Yes, we'll continue to use the 3.x version branch as long as we're able to. And still grateful for that.
Or you can stack with 3.x branch. We will support 3.x for a year.
After a year, 3.x will no longer have support, and that's sad. Businesses will not be updated to ESM-only dependencies and codebases in that time.
My best-guess estimate, based on watching the ecosystem and commercial adoption since v0.10, is that it will take the ecosystem at least 5 more years to get there. I'm not suggesting you support 3.x for 5 years, only providing my take on adoption of ESM-only.
We will support 3.x for a year.
It is not an exactly a year, but a year minimum.
Anyway I need Nano ID 3 in PostCSS.
@ai can you elaborate on why this decision was made?
It's worth noting that every single module that's gone ESM-only has gotten virtually no adoption for those versions; you can check on their npm package page under the "versions" tab. nano, so far, has only 1.57% after 5 months; there are packages that have been made this change for almost 2 years with similarly low uptake.
nano, so far, has only 1.57% after 5 months;
It doesn’t look a problem for me. For this small utility projects, not everyone should be on the latest 4.x branch. 3.x is still supported.
I am using 4.x in my ESM-only projects (like @logux/core
) and happy with smaller node_modules
footprint.
@ai sure, that's fine. I'd still love to understand why you made this change.
Sure, my personal reasons:
postcss
) and pure ESM (like most of nano*
projects). Before 4.x I have 3 types and must to always remember using special tools for dual ESM/CJS packages.That all makes sense - but what’s the value of “pure esm” given that esm can import CJS?
@ljharb originally we added ESM to use package from ESM-compatible CDNs and have destructor in import API import { customAlphabet } from 'nanoid'
.
I am not sure that migration to CJS will keep project compatible with all edge cases. But maybe I am wrong.
ESM can named-import from CJS if the CJS is babel-transpiled.
npm packages simply aren't (in any consistent sense) usable from a CDN without a build process; any such build process can easily handle CJS modules just as well as ESM modules. I agree that you can't get a no-build-process native ESM setup working with a CJS module, but since many, many 9's of npm packages are in CJS, that's not really a viable option anyways.
ESM can named-import from CJS if the CJS is babel-transpiled.
npm packages simply aren't (in any consistent sense) usable from a CDN without a build process
Nano ID not only can but even specially created to be served from the simplest CDN:
// Not sure that it works because of GitHub content-type
import { nanoid } from 'https://raw.githubusercontent.com/ai/nanoid/main/nanoid.js'
any such build process can easily handle CJS modules just as well as ESM modules
Are we 100% sure with it, and about what CDNs are we sure?
A lot of people were forced me to release CJS/ESM version (2.x→3.x) because they told that their ESM CDN supports only ESM packages.
What does it mean?
node's ESM implementation uses https://npmjs.com/cjs-module-lexer to try to infer named imports from CJS files. It works especially well for transpiler output.
Where exactly it will work with 100% guarantee?
By definition, "what node does" is the correct thing, so if any of those bundlers don't support this, then they're broken :-) That said, I'm pretty sure all of these support this, or they wouldn't be able to support the majority of the ecosystem's existing practices.
Are we 100% sure with it, and about what CDNs are we sure?
I'm 100% sure it could be done. I certainly haven't audited existing CDNs to figure out what capabilities they have (mostly because using CDNs isn't a best practice anymore - it's best to control the serving of your own assets).
There are only a very, very small number of authors that have chosen to publish ESM-only packages. If ESM CDNs want to gain adoption, they have no choice but to support CJS eventually anyways - why make life harder for your existing consumers in the meantime by switching to ESM-only? "ESM CDN" is a much less important use case than "every existing node user who uses your package", I'd expect.
For what it's worth, here's everything Sindre has compiled on his move to ESM for all of his stuff: https://github.com/sindresorhus/meta/discussions/15. @wooorm as done the same for rehype/remark/unified and supporting packages as well. I don't like it and don't agree with their reasoning, but it's more than a handful of packages affected.
@shellscape indeed, but it's still only a handful of authors
By definition, "what node does" is the correct thing, so if any of those bundlers don't support this, then they're broken :-)
@ljharb :D. On one hand I have “3.x ESM+CJS & 4.x ESM” solution which works perfectly and has a single problem of not be so beautiful for CJS cases.
On another hand, I have months of my life spending fixing many edge cases (which we already fixed for 3.x) for rare bundlers and ESM CDNs.
I think you see the reason of why I prefer to keep it. Update to 4.x if you want to use latest versions. CJS is outdated too.
CJS isn’t outdated; it’s a first-class module system for node, and will be supported for the foreseeable future - ESM will one day reach feature parity with CJS, although it’s not there yet.
I’m sorry you had to spend so much time on v4; i maintain hundreds of packages that are just CJS and haven’t had to spend any time on supporting ESM for them ¯\_(ツ)_/¯
Fun! Another thread! 😅
It's worth noting that every single module that's gone ESM-only has gotten virtually no adoption for those versions; you can check on their npm package page under the "versions" tab. nano, so far, has only 1.57% after 5 months; there are packages that have been made this change for almost 2 years with similarly low uptake. — @ljharb
This is semver and the npm ecosystem working as designed. There is no reason why people must update in droves to a new major version in 5 months. Slower update cycles are fine. And download counts are terrible!
That’s like saying: hey, I made this new package, I just released it on npm last week, why doesn’t it have millions of downloads yet?!
what’s the value of “pure esm” given that esm can import CJS? — @ljharb
That is true in Node.js but not in other places.
it's still only a handful of authors — @ljharb
It’s… like… all the still active maintainers of lots of popular packages in the JavaScript world that don’t only care about Node.js.
CJS isn’t outdated — @ljharb
I’d argue it very much is. At least for folks that like JavaScript and not necessarily one particular runtime. And if not: it should be!
I’m sorry you had to spend so much time on v4; i maintain hundreds of packages that are just CJS and haven’t had to spend any time on supporting ESM for them ¯_(ツ)_/¯
This just isn't constructive and unfortunately on-brand. Just zero need for that.
I don't agree with the decision to move to ESM-only, but I respect @ai and the decision he's made, especially so given the immense value he's contributed to the Node over the years. I credit him for maintaining the CJS branch in the meantime. I understand the arguments from him, Sindre and others, but I don't have to agree with them. They've all explained themselves thoroughly so we can gain perspective on their positions. At this point, that should be enough.
@ai thanks for your explanation. I suspect you'll find that maintaining v3 and v4 is harder than shipping a dual package, and not maintaining v3 will mean folks have to find another solution but that'll be yours to discover :-)
here's how i fixed v4 with require. be careful not to call the method too soon because the import is asynchronous.
id.js
let id = null;
(async () => {
const nanoid = await import("nanoid");
const CustomAlphabet = nanoid.customAlphabet;
const alphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
id = CustomAlphabet(alphabet, 12);
})();
module.exports = () => id();
const nanoid = require("./id.js");
//nanoid(); // crash, async import takes a few ms
setTimeout(() => console.log(nanoid()), 100); // working
openbase.com now displays the ES Module support level (e.g. type of exports) on all of their package pages. If you're continually caught off guard by installing a dependency only to find out it's ESM-only, check the package out there first.
@shellscape since CJS also works in ESM, the only way something should show "CJS" is if it has a .node
module.
lol no need to block me just for disagreeing with you ¯\_(ツ)_/¯
thats worked for me:
npm uninstall nanoid
npm install nanoid@3.3.4
@ai has been developing this project for a long time. If you want to assist in shipping a 4x branch that supports CJS, then perhaps you can step forward to help code it. Thank you for your work on this project, @ai.
@ai doesn't need someone running to his defense. and we don't need another useless notification (I realize the irony in saying that whilst writing this comment which will generate a useless notification). Please virtue signal elsewhere.
Thank you for your work on this project, @ai.
yup. but next time, take it to twitter https://twitter.com/sitnikcode or sponsor him instead of leaving a comment on a closed issue.
— sorry useless reply — read and/or copy-paste my monkey patch above or use something else.
const { customAlphabet } = require('nanoid') ^
Error [ERR_REQUIRE_ESM]: require() of ES Module C:\Users\Administrator\Documents\serverws\node_modules.pnpm\nanoid@4.0.0\node_modules\nanoid\index.js from C:\Users\Administrator\Documents\serverws\routes.js not supported.