-
Notifications
You must be signed in to change notification settings - Fork 145
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
Create doc on how to support ESM and CommonJS when publishing modules #542
Comments
Given that by far the easiest way is “only publish CJS”, and if you want named exports, “publish CJS transpiled from ESM” - what more would go in this document? |
This comment was marked as outdated.
This comment was marked as outdated.
@lemanschik i strongly disagree with that; a default export is what a module is; named exports are what module has, and most modules should be something. That’s a stylistic choice and not something node should be weighing in on. I, and the Airbnb style guide ftr, say that you should almost always do module.exports = function. |
This comment was marked as off-topic.
This comment was marked as off-topic.
I have a number of projects that work perfectly compatibly with a build process, so I’m not sure about those reports. |
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
What is the benefit of doing all this when “just CJS” works everywhere? |
@ljharb i am happy that you ask for example it makes total new forms of builds more enjoyable and compose able at present we have overall good results with opening component based ipc specifiers inside chromium and v8 it self. this leads to stuff like running the monaco editor as chrome extension directly then using workspaces and overrides and then directly use unmodified directly loaded modules out of the npm ecosystem in a way that i can patch and replace them or use single functions of them to compose something total diffrent It is simply expressiv when i can write const reused = import('anything').then(any=> Object.assign(any, { addOrpatch })) and get all original source references without parsing generating and all that of tons of import maps in facts i am also working mean while on building the whole chromium platform in a browser in a virtual x86 vm running on wasm and other stuff also directly exposing remote filesystems for distributed builds via webrtc and such stuff it helps a lot if we do not need to add incremental build steps and can directly cache distributed incremental build results note also collabing on MESON Build system written in ECMAScript that opens up building NodeJS inside the browser distributed. we talk about projects with a lot of dynamic references and far more then some million well documented symbols. |
@lemanschik @frank-dspeed i'm not sure that answers the question. CJS is equally composable; enjoyable is subjective. I agree that a build process remains required, but I haven't seen an advisable "no build process" setup anywhere yet, so i'm not sure why that's important. |
@ljharb you will see it in action at present we use that all over simply via userland loaders but we would benefit when npm users would create packages in a way that we do not need to handle nodejs logic so we can depend on a nodejs indidpendent logic for the resolve. that allows us to do content based hashing and cascasing builds so we can hot replace modules in large builds see it as fast distributed hot module reload helper in general we at present worked a lot on tooling to create indipendent specifier resolvers all over the ecosystem. When NodeJS and the NPM System would agree on such thing we simply can save a lot of build time energie and frustrations for millions of developers. For example if some one patches a single module in a stack of millions where some do depend of it that helps a lot. and i mean with module real modules not this npm modules that contain 22 mb of redundant objects renamed. refatored |
maybe the best description what all that does solve is it reduces the need to implement own resolver implementations inside every package manager and stuff like typescript and vscode electron can share the resolve logic cross context. and also our chromium ipc can share the resolve logic via remote pipe stdio imagin tesing your builds directly in the browser no need for input output directly fix bugs and hit run again in the same view. |
Hot reloading all modules generically isn't a thing that's possible without engine cooperation, due to the nature of JavaScript itself, and node would require support from v8 to do it. Either way, this issue's document should be written to fit actual reality, not aspirational reality. |
@ljharb ok then your correct lets start with a doc that points out your observations always bundle to CJS and in some months we will revisit that so no one gets hurt by writing that up for no need. |
This comment was marked as resolved.
This comment was marked as resolved.
That would be a harmful recommendation, because then you'd be exporting a Promise for a Module object. ESM wrappers don't add value. |
hmm ok i guess as you sayed transpil everything there will be no edgecase where something needs to stay esm? like scripts that use the import.meta.url on dynamic load and parse url parms to return a conditional module? |
Correct, that's my understanding. The only thing is top-level await, and i've seen no reasonable use cases for that besides an application entrypoint. |
This comment was marked as off-topic.
This comment was marked as off-topic.
Found this on the node.js docs: https://nodejs.org/api/packages.html#dual-commonjses-module-packages Does this cover what we wanted? |
@lholmquist it was not what we search for but it is today maybe the thing we search for let me explain: Out of Historical Reason there where 1x Export per Package JSON then later with es2015 the package json got the import / export field which can store multiple exports. This exports have also support for nested conditional exports thats the part that your posting. So the Field is only supported by current tooling every tooling today supports them as far as i know. If not support can be added in less then a day. the --condition flag lets you choose one set of imports/exports. Also i can announce the landing of require esm inside NodeJS 22+ require('es-module.js') works under a flag if the ESM does not contain top level await at last. |
I would propose the following path forward now:
Special edge case electron and other runtimes consuming npmThere are cases where .cjs is needed they will simple need to create a cjs entrypoint inside that single application where they use the modules they should not publish that application but if they wish to publish it then they simple publish it with a post install transpil to cjs hook or again use the -r esm flag ESM -r esm as migration path is green for
|
From discussion at the last collaborator summit.
This would help as the suggestion was that there were some easy ways to do this.
The text was updated successfully, but these errors were encountered: