Closed trusktr closed 4 years ago
@Haringat except that your package can't be used by the majority of the ecosystem. to me that's not "done" but certainly you're not alone in calling it thus.
@ljharb what do you mean? What's stopping you from createRequire
in and then exporting whatever you want from there?
@benjamingr That is the wrong direction. That is for consuming CJS files from ESM files. You were talking about exporting ESM to CJS.
@benjamingr i'm confused, createRequire
is used to make a require
function, which can't pull in ESM - afaik the only way to consume ESM in a CJS module is import()
, which is async.
CommonJS starts faster. ESM is meant to be used with browser, which means that it is async. Async does cost some microticks and overhead.
CommonJS starts faster.
Not always, but it can be the case (especially when everything is on the FS)
ESM is meant to be used with browser, which means that it is async.
It is async but not because it was meant to be a browser-technology, but because it was meant to work everywhere.
@xieyuheng Well it is not really about it being technically impossible to support both, but rather about it becoming annoying in the long run. For the moment the call is definitely to support both, simply because there are literally thousands of cjs packages out there.
I predict that in a few years there will be two kinds of packages: Those that use mjs and those that have not seen an update in years by then. And then the argument to keep supporting cjs only to not break some unmaintained packages will not be too strong.
No, it’s technically impossible - the way bun did it is to disable a language feature, top-level await, and likely to violate some of the timing guarantees in the spec (i haven’t investigated yet to be certain).
Why are we talking about what Bun is doing in a thread about what Node.js should or shouldn't do?
I totally agree - node has different constraints, and “but not-node does X” isn’t relevant to whether node can or should do X.
if there is not competition to nodejs, your prediction might be right.
but since there is competing server runtime supporting both.
people forced by nodejs to remove all commonjs code from their codebase maybe will simply choose the competing runtime.
if it is your team and your app, what you would do?
The fact that this thread is still open for comments is a testament to the overwhelming patience and tolerance of the steering committee and the Node core team.
@xieyuheng
millions not thousands.
Okay, more thousands than I thought 😉
if there is not competition to nodejs, your prediction might be right.
but since there is competing server runtime supporting both.
AFAIK there are two competing JavaScript runtimes: deno and bun.
Deno promotes ESM as it is typescript-first. Bun supports both as you mentioned.
I fail to see your point...
people forced by nodejs to remove all commonjs code from their codebase maybe will simply choose the competing runtime.
My guess would be that if node ever removed cjs (which they would only do after one hell of a deprecation period), people who would still depend on it would either move on to ESM or stay on a node version that supports cjs.
if it is your team and your app, what you would do?
See my prediction above.
Please take whatever this conversation is to another thread.
My 2c, today I wrote this file because CommonJS can still do things ESM cannot, and work in both cases (as that file does).
There was a lot of effort to make dual packaging reality, and for personal experience I can say it works fine with everything out there (bundlers, CJS only projects, ESM ony projects), plus cache invalidation/hot reloading is still extremely hard in ESM, so that choosing to ditch CJS when there are tools (ascjs/ucjs to name two) that makes dual packaging a no-brainer, beside the only constraint that is live bindings, sounds a bit "capricious" indeed.
My demo might be incorrect, but I feel like it may still be possible, doing so like this maybe?
If you instead compare module.exports =
to that of export * from
, rather than export default
, then yeah I think you're right, you can't have conditionally-imported named exports from another module.
/* c8 ignore start */
let canvas;
try {
canvas = await import('canvas');
} catch (fallback) {
canvas = await import('./canvas-shim.cjs');
}
export default canvas;
/* c8 ignore stop */
Come to think of it, I think this pattern may be similar as well.
/* c8 ignore start */
export default await import('canvas').catch(() => import('./canvas-shim.cjs'));
/* c8 ignore stop */
Just curious if this is planned to happen, or is it something no one is thinking about yet?