The ESM move #15
Replies: 26 comments 114 replies
This comment was marked as off-topic.
This comment was marked as off-topic.
-
If a module only exports JSON files, using Node APIs to reexport them opens a whole new can of worms which include the best way to import a json file worm and the browser support worm. We could try moving the JSON file to JavaScript but that might require us to add extra Typings to egg on the TypeScript compiler which can already understand static JSON files way easier. It might also make it more boilerplatey to create update scripts. I think we should wait for JSON imports to be usable without flags before making the move. |
Beta Was this translation helpful? Give feedback.
-
Do you plan to include CommonJS fallback files?
If I understand correctly(?) requiring ESM modules from CJS is a tricky topic, see:
In this case what happens to existing code bases, which migrate to nodejs 12 on May It is perfectly fine to only support ESM from a library maintenance overhead perspective. |
Beta Was this translation helpful? Give feedback.
-
I tried making one of my packages use Hope this is useful information. I didn't know that. |
Beta Was this translation helpful? Give feedback.
-
I thought TLA requires Node 14.3.0 or greater. Is it wise to suggest it when still targeting Node 12? |
Beta Was this translation helpful? Give feedback.
-
I think this is being purposefully blind to reality. Yes, Node.js 12 supports ESM natively. The key word is "supports." Node.js 12 does not deprecate CJS in favor of ESM, and to my knowledge no one has suggested that ever be the case. So you'll be breaking a lot of people who do not see any benefit in restructuring their whole code base to support a different syntax. I see this plan as creating more fragmentation than cohesion. |
Beta Was this translation helpful? Give feedback.
-
Why? IMO
My packages (~4.3m/wk installs) already support both CJS and native ESM, but on May 1, 2021 I plan to join you (and it looks like Babel too now) and publish them all as pure ESM. To avoid copping a lot of individual heat from CJS users that will no longer be able to Nothing, and I mean nothing has been a greater maintenance headache than trying to support dual ESM/CJS exports whilst avoiding the dual package hazard through all the iterations of Node.js I can't wait to get this revolution started. One other suggestion for the "What to do" list; now is a good opportunity for each package to:
|
Beta Was this translation helpful? Give feedback.
-
Automatic migration from Commonjs to ESMputout code transformer can be used for automatic migration to It converts {
"rules": {
"convert-commonjs-to-esm": "on"
}
} Using import as requireWhen things can't be solved with automatic migration, simport can help, solving a couple edge cases. One of them is Also you can use plain old import {createSimport, createCommons} from 'simport';
const simport = createSimport(import.meta.url);
const {
__filename,
__dirname,
require
} = createCommons(import.meta.url);
// now you can use require, __filename and __dirname in ESM
await simport('./package');
// will read `package.json
await simport('c:\\some-js-file');
// will also works Mocking of modules for testing purpose in ESMWith You can mock imports using mock-import. Which is based on Testing of ESM modulestape doesn't supports |
Beta Was this translation helpful? Give feedback.
-
Is it possible to make an ordered list of exactly what packages need to be done first? |
Beta Was this translation helpful? Give feedback.
-
Practically, this means, if anybody has TS packages, until microsoft/TypeScript#33079 is solved, we won't be able to update the consumed Sindre's packages. I tried this morning to wire the |
Beta Was this translation helpful? Give feedback.
-
Another roadblock here is extension-less executable files using a shebang like |
Beta Was this translation helpful? Give feedback.
-
The
|
Beta Was this translation helpful? Give feedback.
-
Native modulesNative modules cannot (yet?) be loaded using ref: https://nodejs.org/api/esm.html#esm_no_native_module_loading
@sindresorhus will you be using I'm personally leaning towards |
Beta Was this translation helpful? Give feedback.
-
Can someone explain this one to me like I'm 5?
I've read the Twitter thread and other related material but I'm still not grokking it. 🙁 Surely
Or am I still way off? |
Beta Was this translation helpful? Give feedback.
-
I just want to drop a tooling related ESM success story. Often tooling lags behind major tech transitions and Oclif was the main framework that kept me working with CJS. I'm aggressively moving to native ESM for all my current and future dev efforts on Node. I recently had the opportunity as an external developer to add comprehensive ESM support to Oclif v2 which is the next generation of the Salesforce / Heroku CLI framework launching later this summer. You can read more about the process and how things went down here: I'll make another post when all of my open source repos are converted to native ESM and available on Node as well. Let's go ESM! |
Beta Was this translation helpful? Give feedback.
-
I cannot tell you the hell I've gone through trying to support using the updated ESM only packages you've published. Every framework I use from TypeScript itself, to Jest, to Ts-node, to Yarn 2.0 all have issues with ESM support. Even NodeJS still considers parts of it experimental. jestjs/jest#9430 While I appreciate the reasoning behind why you're doing this, the cut over was done prematurely before the ecosystem was ready IMO. Without supporting both CJS and MJS while packages correct issues means I as a user of published packages have literally spent 100s of hours trying to make what you've done work to be constantly thwarted at every corner and had to swap back to your prior versions meaning if there is ever a vulnerability found in them, I won't be able to upgrade. The work arounds that you've stated simply don't work when the libraries we use all break.
"There's no point" is a pretty strong statement. There is a major point. Not breaking the entirety of the dependency ecosystem while your attempt to force a paradigm change. All of the above mentioned projects were already attempting ESM support before you strong armed your 1000+ libraries to only ESM but there are still serious problems across the entirety of the ecosystem. Trying to state that the only way the ecosystem will move to ESM is by package maintainers forcing people to use ESM is simply untrue. The whole reason the dual syntax support exists is so packages can support both while the ecosystem changes. As you update your packages one by one, my RenovateBot attempts to upgrade and breaks every time and I have to exclude that package from dependency upgrade management or I have to disable Renovate attempting to upgrade any major version of any package in my monorepo of more than 7000+ dependencies. Since you don't have a package prefix on all your packages (i.e. no @sindresorhus/...) there is no way for me to even exclude all of them from upgrades. If any libraries that I use that transitively depend on any of your packages happens to update to your new ESM only versions (even if that package supports both), my whole build now breaks because of the above Yarn 2.0 issue. There is no work around for this, I have to exclude that package as well. I'm stuck in a place where now I have the potential of a whole set of dependencies (everything you've changed and every library that transitively depends on your ESM packages) that I can no longer update and I have no work arounds until all those above libraries fix their issues. Very :-( 👎 |
Beta Was this translation helpful? Give feedback.
-
Just a tip, if you're using tsup and install ESM modules as dev deps they'll be rolled up into your final build. No extra step needed. |
Beta Was this translation helpful? Give feedback.
-
Very happy to see that other popular packages are also making the shift: node-fetch v3 is ESM only. |
Beta Was this translation helpful? Give feedback.
-
I'm more positive about the moving speed. Way more less than 14 years! 😃
JS community is such a uniq community, everyone seems kind of using AST tools somehow. 😂
I can't image a world without Internet! 😂
As I'm personally on
But, I guess
ESM-only decrease library maintainence. But moving too fast, I think might be roadblock to let people adapt it, compared to dual-module. Anyway, glad to see ESM movement! 😃 |
Beta Was this translation helpful? Give feedback.
-
Idea: Could we have dist-tags pointing to the last So we can do: |
Beta Was this translation helpful? Give feedback.
-
For all of those who are unable or unwilling to change their codebase to ESM, fix-esm makes it possible to load ESM modules from CJS ( (Disclosure: I'm the author of that module. Already mentioned it in some subthreads, but posting it top-level now for visibility.) |
Beta Was this translation helpful? Give feedback.
-
Hi, I want to tell a little story: A week ago, the move by node-fetch to ESM broke one of my projects. It actually broke in production because a part of our CI installed dependencies without a package.json to lock versions 😅. Upon understanding the cause of this breakage, I didn't go hunt for github issues where I could post "+1" and hope maintainers would revert the change and fix my problem for me. Instead, I just upgraded my project to ESM. It was quick and easy. It will never be an issue again 🚀 I just came here to express my huge respect for @sindresorhus, @Richienb, @jimmywarting, @LinusU and others to have the balls for this move. A clear break is 1000x better than decade-long legacy-supporting maintenance hell. This thread demonstrates that without breaks like these, a large part of the community would prefer to cling to CJS for years and years to come, which would imply most JS devs would still have to deal with it in one way or the other (please don't). @sindresorhus & co, you may be the people that save JS from a python2-level mess. I'm only a small fish in the package maintainer sea, but I want to say that I'm with you on this move and won't publish CJS to npm ever again. Thank you ❤️ |
Beta Was this translation helpful? Give feedback.
-
I made a list of ESLint rules that can help migrating projects from CommonJS to ESM: https://gist.github.com/Jaid/164668c0151ae09d2bc81be78a203dd5 |
Beta Was this translation helpful? Give feedback.
-
Good news for typescript beta, https://devblogs.microsoft.com/typescript/announcing-typescript-4-5-beta the ecosystems moves to ES-modules |
Beta Was this translation helpful? Give feedback.
-
AWS lambda now supports ESM: https://aws.amazon.com/de/blogs/compute/using-node-js-es-modules-and-top-level-await-in-aws-lambda/ |
Beta Was this translation helpful? Give feedback.
-
Here we are more than a year in the future and the primary issues (nodejs/node#35889 and nodejs/node#37648) that keep the most important JavaScript testing framework from converting to ESM (jestjs/jest#9430) are still not resolved. Even code coverage is not functioning when using ESM.
Too bad. Never happened. microsoft/TypeScript#46452 Even using a ESM module in TypeScript using NodeJS has STILL not removed the VM modules for ESM from experimental nodejs/modules#507. A full year yet the ecosystem is not any closer to resolving the major issues that prevent people from using ESM in server side NodeJS. Thanks for causing every one of us a combined total of 1000s of hours (perhaps even more) trying to work around your forcing ESM for every tiny package you maintain that are used across the entire JS ecosystem long before the ecosystem as a whole could support it. I'm going to put my money on this being one of the direct causes that forces people to move away from server-side JavaScript all together and is the eventually downfall of the entire community. Guess we'll see. |
Beta Was this translation helpful? Give feedback.
-
At the end of April, Node.js 10 goes out of LTS, which means I can target Node.js 12 in my packages. Node.js 12 has full ESM support!
Required reading: https://nodejs.org/api/esm.html
I plan to migrate most of my (1K+) packages to ESM within 2021.
At the start of April, I will begin with some less popular packages, just to test the waters.
I will use
"type": "module"
in package.json and not.mjs
.What to do:
"type": "module",
to package.json (below theauthor
field)"exports": "./index.js",
to package.json (below thetype
field)engines
field in package.json to Node.js 12.index.d.ts
to use ESM imports/exports.index.d.ts
to use ESM and also top-level await.'use strict';
.'.'
to'./index.js'
.node:
protocol for imports.Notes to self
index.d.ts
) to use ESM syntax instead of CommonJS.nyc
toc8
for packages with code coverage?exports
/imports
package.json fields: https://twitter.com/bradleymeck/status/1346466891070664704fs.promises.readFile
instead: https://twitter.com/MylesBorins/status/1346730287363985409Write a blog post encouraging other package maintainers to move their packages to ESM.(Done: https://blog.sindresorhus.com/get-ready-for-esm-aa53530b3f77)FAQ
Do you plan to include CommonJS fallback files?
No. Node.js 12 supports ESM natively. There's no point.
Can I help out?
Sure, but not yet. I need to figure out the best way to approach this first.
Beta Was this translation helpful? Give feedback.
All reactions