-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
feat(pnp): experimental esm support #2161
Conversation
b043a03
to
cf42a1d
Compare
cf42a1d
to
aa834f8
Compare
aa834f8
to
7bc1960
Compare
1b86f68
to
3201a51
Compare
Added the config |
I'm not sure exactly why (I'm trying to read Node.js' internals to understand it), but this breaks Node.js' support for named imports from CommonJS modules. import { rollup } from "rollup";
EDIT: I am debugging the resolution process, and it seems like that for CJS modules (specifically, I'm debugging EDIT2: This was anticipated by @arcanis more than one year ago 😬 nodejs/modules#351 (comment) I think |
Yeah, sadly node doesn't let me pass on the entrypoint to a package and have it resolve the rest using exports :( |
Almost got it to work with |
@nicolo-ribaudo Added exports support, fixed module type detection, and file reading so should be good to go now. Thanks to @sokra for fixing the bug in |
Thanks! I got
|
It should be able to detect the correct type either way 🤨 |
The problem is that Node.js reads the file source to analyze the exports (here), and it doesn't work with PnP. In Node.js this works: // file.js
exports.foo = 2; // main.mjs
import { foo } from "./foo.js" but not when |
That's because they destructure |
Got commonjs to work on babel/babel#12296 so |
054f61b
to
d523789
Compare
a7110bc
to
ce798fb
Compare
This works great for me. Thanks! |
What kind of feature parity are we looking to achieve with node's builtin ESM resolution?
IMO it's dangerous to deviate from node's standard in these cases. That would quickly lead to "it works in PnP but not via node-modules/npm/pnpm or vice versa" kinds of problems. |
I'd like to have it at a level where what works without PnP works with it, nothing more
What a twist, PnP was more forgiving for once 😄, fixed.
Fixed |
@@ -391,5 +394,19 @@ export function applyPatch(pnpapi: PnpApi, opts: ApplyPatchOptions) { | |||
return false; | |||
}; | |||
|
|||
// Specifying the `--experimental-loader` flag makes Node enter ESM mode so we change it to not do that |
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.
Can you add inside the comment a reference to the test that would break if this part of the code was removed?
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.
Sure, added the upstream issue as well.
nodejs/node#33226
I've added integration tests that cover the same things
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.
Looks good; I'm a little worried about the auto-detect, but it's not clear whether it'll cause issues in practice.
pnpEnableExperimentalEsm: true, | ||
}, | ||
async ({path, run, source}) => { | ||
await xfs.writeFilePromise(ppath.join(path, `index` as Filename), `console.log(typeof require === 'undefined')`); |
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.
Shouldn't it be index.js
(with the extension?)
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.
No, it's testing nodejs/node#33226 where Node incorrectly loads a commonjs file without an extension as an ESM file.
Added a link to the issue, same as #2161 (comment)
test( | ||
`it should be able to import a dependency`, | ||
makeTemporaryEnv( | ||
{ | ||
type: `module`, | ||
dependencies: { | ||
"no-deps": `1.0.0`, | ||
}, | ||
}, | ||
async ({path, run, source}) => { | ||
await expect(run(`install`)).resolves.toMatchObject({code: 0}); | ||
|
||
await xfs.writeFilePromise( | ||
ppath.join(path, `index.js` as Filename), | ||
`import noDeps from 'no-deps/index.js';\nconsole.log(noDeps)`, | ||
); | ||
|
||
await expect(run(`node`, `./index.js`)).resolves.toMatchObject({ | ||
code: 0, | ||
stdout: `{ name: 'no-deps', version: '1.0.0' }\n`, | ||
}); | ||
}, | ||
), | ||
); |
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.
Would be worth adding a test to make sure that ESM packages can import other ESM packages
niiiiiiiiiiiiice. congrats @merceyz and team 🥳! your effort is much appreciated. |
Awesome! 🎉 |
What's the problem this PR addresses?
PnP doesn't work with ESM
Closes #638
How did you fix it?
Implemented an experimental ESM loader
Checklist