7 ms·
If this feature ever becomes the default (ie not behind a flag) - how will the NPM ecosystem respond? Will contributors still bother to build CJS end EJS versio
by unilynx 2y ago
If this feature ever becomes the default (ie not behind a flag) - how will the NPM ecosystem respond? Will contributors still bother to build CJS end EJS versions when publishing a NPM module, or just slap an 'engine: nodejs >= 25' on the package.json and stop bothering with the build step before pushing to NPM ?
I personally would very much prefer if NPM modules that have their original code in TS and are currently transpiling would stop shipping dist/.cjs so I unambiguously know where to put my debugger/console.log statements. And it would probably be very tempting to NPM contributors to not have to bother with a build step anymore.
But won't this start a ripple effect through NPM where everyone will start to assume very quickly 'everyone accepts TS files' - it only takes one of your dependencies for this effect to ripple through? It seems to me that nodejs can't move this outside an opt-in-experimental-flag without the whole community implicitly expecting all consumers to accept TS files before you know it. And if they do, it will be just months before Firefox and Safari will be force to accept it too, so all JS compilers will have to discard TS type annotations
Which I would personally be happy with - we're building transcompiling steps into NPM modules that convert the ts code into js and d.ts just to support some hypothetical JS user even though we're using TS on the including side. But if node accepts .ts files we could just remove those transpiling steps without ever noticing it... so what's stopping NPM publishers from publishing js/d.ts files without noticing they broke anything?
- rnmkr 2y agoI would love to ship my source code (.ts) to npm. But Typescript team was very much against this, as there'll be tsconfig issues and other performance issues. But still fingers crossed.
- nfriedly 2y agoFor the old libraries I maintain that are typescript and transpiled into .cjs and .mjs for npm, I'll probably just start shipping all three versions. For a new thing I was writing from scratch, yeah, I might just ship typescript and not bother transpiling. [edit: Apparently not. TS is only for top-level things, not libraries in node_modules according to the sibling comment from satanacchio who I believe is the author of the PR that added TS support and a member of the Node.js Technical Steering Committee]
- WorldMaker 2y agoWhy are you still transpiling to .cjs in 2024? ESM is supported in every LTS version of Node now. We can kill CJS, we have the power.
- nfriedly 2y agoBecause I don't like breaking things unnecessarily. Some of my libraries are 10 years old and depended upon by similarly old projects that are not using ESM and probably never will. Besides, it's already going through one transpilation step to go from TS to ESM, so adding a second one for CJS really isn't that much hassle. I think if node.js had made require() work with ESM, I could probably drop CJS. But since that's probably never going to happen, I'm just going to continue shipping both versions for old projects and not worry about it.
- sureIy 2y ago> adding a second one for CJS Nobody is arguing for that. Once you ship ESM, you can continue shipping ESM. In Node 22 you can even require() ES modules (with an experimental flag, at the moment)
- nfriedly 2y ago> > adding a second one for CJS > Nobody is arguing for that. Once you ship ESM, you can continue shipping ESM. I'm not sure I follow you there. I did continue shipping ESM. > In Node 22 you can even require() ES modules (with an experimental flag, at the moment) Oh, I didn't know about that, cool! Once it becomes un-flagged I might consider dropping CJS.
- WorldMaker 2y ago> I think if node.js had made require() work with ESM, I could probably drop CJS Why is making downstream have to switch to `await import()` that big of a deal? You can use async/await in CJS just fine. Sure, sometimes you may need to resort to some ugly async IIFE wrappers because CJS doesn't support top-level await like ESM does, but is that really such a big deal? Sure, it's a breaking change, but that's what semver major bumps are for. I just think that if projects want to stay in CJS they should learn how to use async/await. I clearly don't understand why CJS libraries feel a need synchronous require() for everything. (Though to be fair, I've also never intentionally written anything directly in CJS. I learned enough in the AMD days to avoid CJS like a plague.)
- satanacchio 2y agoWe dont support running .ts files in node_modules, this is one of the main constraints to avoid breaking the ecosystem
- Omerd6 2y agoThe legendary Ryan dahl is actually working on solving the exact problem you described by creating a new package registry called JSR. Essentially what it does is allow you to upload your typescript code without a build step so when other devs install it they can see the source code of the module in it's original typescript instead of transpiled JavaScript.
- sam_perez 2y agoThat's really cool. One of the benefits of the JS ecosystem is the ability to step through code and crack open your dependencies. Not sure if this would directly make this possible when running your projects/tests, but it at least sounds like a step in that direction.
- meowtimemania 2y agoit must install compiled and uncompiled versions? Otherwise node (without the above flag) would throw errors when it encounters types in node_modules
- Omerd6 2y agoI just checked and you are correct, in node it only installs the compiled version. Apparently you can only view the uncompiled source code in deno since it natively supports typescript. My bad
- meowtimemania 2y agoNo worries! I was curious how it worked on node. Thanks!