-
-
Notifications
You must be signed in to change notification settings - Fork 34.2k
module: disable exports encapsulation for CJS #31718
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
Conversation
|
@developit Can we get a quick check on this: My understanding is that Preact wasn't really interested in encapsulation. Would this PR (encapsulation would've only affected modules) prevented you from adding My first reaction: I'm a bit concerned that this creates confusing situations. Code that uses Faux Modules via babel on the server would "work" but it would then fail to bundle because webpack implemented P.S.: That missing API could be an npm package, doesn't need to be in node core. |
|
I thought part of the design of I’m also not clear on why this change is needed. The package author doesn’t get encapsulation unless they use |
|
Very much so - the primary motivation, I thought, was the encapsulation. If a package needs to opt out of that for compat, so be it, but that does in no way mean encapsulation should be tossed out, IMO. |
|
In case there is any doubt, encapsulation for The concern is more that if packages upgrading to exports might want to opt out of encapsulation to provide backwards compatibility (just like how Node.js is locked to continue exporting internal private APIs), that this might provide a better middle ground to ensure encapsulation can continue to work for package authors today. |
If we only consider node then that's true. But once webpack & friends add support for exports, this becomes a lot less clear. Because they would use the import-variant exports and then there's suddenly a breaking change for existing consumers anyhow. So realistically a package that adopts |
In other words, you want to provide a way for package authors to encapsulate their package for My concern is that this seems to disable encapsulation for CommonJS; there’s no way to opt in. I think if I had to choose between no encapsulation in CommonJS, versus not being able to opt out of it in one environment separate from the other, I would choose the latter. I guess ideally you wouldn’t have to choose; is there some way to map |
Haven't tested but I would expect the following to work: {
"exports": {
".": "./main.cjs",
"./": { "require": "./" }
}
} |
|
I think not encapsulating both esm and cjs at the same time exacerbates the issue of a package really being two packages (an esm and a cjs one) jammed into the same namespace, since it causes them to present drastically different "public" APIs. IMO, if you need "backcompat" like this, but still want esm encapsulation, you should probably consider doing a major version bump for esm and cjs encapsulation and breaking your cjs consumers, or shipping a separate package with just encapsulated esm. |
|
I am strongly opposed to this change; the ENTIRE POINT of URL imports aren't a thing in node, and filesystem things are a "void your warranty" thing, so this is a strong encapsulation feature to me. I brought up package.json before; if Preact wants to allow that, they can explicitly add a If this encapsulation is removed, then I think we need to restore the entire ESM flag, and forget about backporting ESM into LTS - it's that important. |
|
Separately, adding "exports" is intended to be a breaking change in all but the most niche of edge cases, so if Preact did that in "not a major version" then any breakage caused is on them. |
Recently, Preact upgraded to using
"exports"and hit some compatibility issues with user code likerequire('preact/package.json'). As a result Preact now has"exports": { "./": "./" }in its package.json, effectively opting out of exports encapsulation entirely to ensure compatibility.This PR proposes a suggested way to avoid this issue by disabling "exports" encapsulation entirely for CJS require usage.
It's worth noting encapsulation is not a strong encapsulation (URL imports allow getting around it), so that there is no strictness loss here.
I think this approach would be a good compromise to allow adoption without breaking changes in forcing encapsulation for CJS.
//cc @nodejs/modules-active-members
Checklist
make -j4 test(UNIX), orvcbuild test(Windows) passes