Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 34.5k
esm: Implement package.json "esm": true flag for ES modules in ".js" files#18156
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
Uh oh!
There was an error while loading. Please reload this page.
Conversation
guybedford commented Jan 15, 2018 • edited
Loading Uh oh!
There was an error while loading. Please reload this page.
edited
Uh oh!
There was an error while loading. Please reload this page.
targos commented Jan 15, 2018
How would you recommend to write a hybrid package with this approach? |
guybedford commented Jan 15, 2018
@targos a package.json file can be created in the dist subfolder to override a subfolder to be interpreted as either CommonJS or es modules. |
targos commented Jan 15, 2018
@guybedford Yes, but how would you redirect to the right subfolder? There is only one possible "main" entry. |
guybedford commented Jan 15, 2018
@targos ah I see what you mean. Hybrid packages effectively rely on conditional mapping applying on only in the ES module case. There are various package.json metadata approaches that could work for this, and I think are a somewhat orthogonal consideration to this technique. That said, they would build on this same principle of using package.json meta for all module loads, so this would lay the same groundwork. |
dnalborczyk commented Jan 15, 2018 • edited
Loading Uh oh!
There was an error while loading. Please reload this page.
edited
Uh oh!
There was an error while loading. Please reload this page.
@targos you could also tell the user to require said module explicitly from e.g. /dist-cjs, if cjs module is being preferred, or if esm is not an option. |
devsnek commented Jan 15, 2018
wouldn't this just end up making modules published that a lot of people can't use? IMO setting main to a file without an extension is still a better solution. an fs stat isn't really that evil. |
14e1fa6 to a1e8886Comparebmeck commented Jan 15, 2018
Now that our loaders have had some time to brew and be tested against situations. I'm partial to adding a way to set the format of URLs. This per package isolation seems good to me, though I would prefer a tweak on implementation. I think with several other modes being talked about:
And some often overlooked:
We can move to a MIME based approach. In addition this would prevent the Loader APIs from going out of sync with other APIs that might make sense to come to Node like |
a1e8886 to 8b0ff27CompareThis allows ".js" files to be loaded as es modules whenever the parent package.json file contains "esm": true. Original proposal and discussion at nodejs/node-eps/pull/60
bmeck commented Jan 18, 2018
bmeck commented Jan 18, 2018
I have a counter proposal to use MIMEs to achieve this in https://gist.github.com/bmeck/7ee7eb2147e2dafe3167c856d9b4151a ; I think having an alias like |
jasnell commented Jan 18, 2018
No specific thoughts on this just yet. Need to work through the cases a bit more. The specific thing I'm struggling with is what the value should be on here. Btw, the reason @bmeck mentions |
arackaf commented Jan 20, 2018
@bmeck - does your MIME solution do any better with respect to hybrid packages, or would either have to revert to either .mjs or @std/esm? |
bmeck commented Jan 20, 2018 • edited
Loading Uh oh!
There was an error while loading. Please reload this page.
edited
Uh oh!
There was an error while loading. Please reload this page.
@arackaf it has no difference than |
arackaf commented Jan 20, 2018
As I expected, thank you @bmeck. So it sounds like your MIME proposal would be as transparent and automatic for end users, but would allow for greater extensibility in userland? Is that right? If so, what sort of use cases would be possible? Something like compiling typescript files when loaded, on startup? |
bmeck commented Jan 20, 2018 via email
I wouldn't recommend doing that on every startup, but yes it could be used for that. On Jan 20, 2018 11:27 AM, "Adam Rackis" <notifications@github.com> wrote: As I expected, thank you @bmeck <https://github.com/bmeck>. So it sounds like your MIME proposal would be as transparent and automatic for end users, but would allow for greater extensibility in userland? Is that right? If so, what sort of use cases would be possible? Something like compiling typescript files when loaded, on startup? — You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub <#18156 (comment)>, or mute the thread <https://github.com/notifications/unsubscribe-auth/AAOUo5oUeQGJLVBwo-ZY311JWT3AxQFTks5tMiHmgaJpZM4ReYiR> . |
guybedford commented Jan 26, 2018 • edited
Loading Uh oh!
There was an error while loading. Please reload this page.
edited
Uh oh!
There was an error while loading. Please reload this page.
This approach has been superseded by #18392. |
guybedford commented Jan 26, 2018
Correction: #18392 |
As previous proposed and discussed at nodejs/node-eps#60, this implements a package.json lookup process for the module format so that adding
"esm": trueto the package.json enables ".js" files as ES modules.There has been some discussion as well here as to whether this property should be a string to allow for extensibility in future, which is also still ongoing.
The ideal workflow imagined would be one where the package manager init process itself adds this into the package.json so that it becomes an invisible part of the authoring process, not completely dissimilar to the
<!doctype>in html.The cost of this approach is loading the base-level package.json for all module loads (instead of just for mains). The argument here is that there is already a lot of statting in the module lookup process, and since this shares the package.json cache with the mains, it adds around one extra stat on average for subfolder package lookups per package loaded. (Compare to adding ".mjs", which has added an extra stat per lookup path checked, an order of magnitude more in cost here).
The benefit of this approach is end-users never need to worry about the authoring format of a package they are importing, build tools and bundlers won't need to adapt to a separate linking mechanism for CommonJS, and that NodeJS ES modules wouldn't need to themselves be built for the browser.
The test cases here cover nesting, invalid values and subpaths. A package.json without an "esm": true property, or an invalid "esm" property is treated as if it contained "esm": false (ie ".js" files as CommonJS modules).
Checklist
make -j4 test(UNIX), orvcbuild test(Windows) passesAffected core subsystem(s)
esmodules