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
improve our CJS scanner #2859
improve our CJS scanner #2859
Conversation
This pull request is being automatically deployed with Vercel (learn more). 🔍 Inspect: https://vercel.com/pikapkg/snowpack/CkQP7YzDYJv36HBxsypCtffigvpz |
/cc @BPScott this was the feature I'd mentioned on Friday. CJS support should get a lot more reliable with this PR. |
6c1561a
to
55daea7
Compare
snowpack/src/sources/local.ts
Outdated
]; | ||
|
||
function isPackageEsm(packageManifest: any): boolean { | ||
return !!(packageManifest.module || packageManifest.exports || packageManifest.type === 'module'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Edge case: Looking at node docs I don't think just the existence of an exports field is enough to prove that the package should be treated as esm.
It is supported in Node.js 12+ as an alternative to the "main" that can support defining subpath exports and conditional exports while encapsulating internal unexported modules.
I think the following should be treated as exposing commonjs:
{"exports": "./main.js"} //omiting type defaults to type being commonjs
{"exports": "./main.js", "type": "commonjs"}
{"exports": "./main.cjs", "type": "module"}
I think a comprehensive check for this needs to take into account the type field and the extension used in the exports field.
I think this gets further complicated as "is this ESM" is something that needs to happen on a single entrypoint level rather than across a whole package. But a larger refactor for this can totally be punted. E.g. I could create exports where one entrypoint is exposed as esm, and another entrypoint is cjs only:
"exports": {
".": "./main.cjs", // cjs only
"./subpath": "./secondary.mjs", // mjs only
"./another-subpath": "./secondary.js", // To know if this is esm/cjs, check the type field
}
I could probably take this to pathological obnoxiousness by then introducing conditional exports, but I'm already falling too far down the rabbit hole for this PR :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good call, even if unlikely you're right that it's not impossible. Luckily I think that we can remove this entirely now with the better CJS handling in place.
Lovely stuff! Commented on what I think might be an incorrect assumption inline. I mentioned this on Friday, and I'm sure you've wrote it down somewhere already but mentioning here for posterity: I think it'd be neat if logging the package info included if the package was CJS. When integrating snowpack into an existing application I think it'd be useful to be able to see at a glance which packages are CJS and thus may result in FUN when importing them. (And thus which packages you check for updates to see if newer versions ship esm) |
ec4d3d7
to
00ccca7
Compare
00ccca7
to
34379e4
Compare
34379e4
to
1d5bb99
Compare
1d5bb99
to
aff27b8
Compare
aff27b8
to
549a005
Compare
This didn't seem worth opening an issue: this PR introduces the |
Changes
namedExports
opt-in support fixing most issues in the scanner.namedExports
scanner on all CJS packages. Because they're CJS, they are expected to run in Node.js without error. But, on the off chance that runtime analysis fails, we will silently continue and you won't be any worse off then you were before.Testing
Docs