-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
add zip file support #1985
add zip file support #1985
Conversation
I don't know if you'd find that too specific to be in the core, but Yarn also makes a little change on the filesystem paths: if you have a path like
We do this because, to allow that a single package is instantiated multiple times (required when a package has peer dependencies that are provided by multiple different ancestors), they must have different paths on the disk (otherwise Node will cache them). Symlinks don't work, because Node runs realpath on them, hence those virtual paths, where in practice we replace |
Thanks for the extra context. I don't fully understand what you're saying because I don't know enough about how Yarn works. But I'm guessing you're saying this:
My idea was for esbuild to fully replace If Yarn did this And if Yarn did this
When does this form without |
Another idea: Once esbuild understands paths inside So specifically an import path of Not sure if this is a good idea or not because of the performance impact, but I'm putting it out there anyway. Actually I could potentially add an API to say "call resolve on the return value for me" for |
Yep, exactly! We do this work in the
In practice probably never, but we have a
I agree it'd be really nice! The PnP API even has a function ( Note however that some context has to be preserved for the resolution to work, in particular for the |
Any progress on this? |
This is sort of blocked waiting on Yarn to expose the necessary data, which from what I understand is blocked on releasing another major version of Yarn. See yarnpkg/berry#3591 specifically:
|
@evanw I've started writing a formal spec at yarnpkg/berry#4671 - do you mind reviewing it whenever you have some time? |
Thanks for putting that together! Took a look. Some thoughts (keep in mind while reading that I don't use Yarn myself):
I also tried implementing this specification on a branch here if it's interesting to you: https://github.com/evanw/esbuild/commits/yarn-pnp. |
That's some great feedback @evanw, could you make it in yarnpkg/berry#4671 instead/as well so readers of that PR can see it? |
My intent of posting a comment here was to provide one-off feedback instead of being drawn into the spec development process. You are welcome to do what you like with my feedback. |
Ah, that's totally fine, feel free to hide these three comments to not distract from the discussion 👍 |
Thanks for the review! I've updated the document and corrected a few other places. A couple of important mistakes I fixed:
Regarding your detailed feedbacks:
I've added a section about this.
I think so, although we perhaps should add markers around the data string, to make sure it doesn't change? 🤔
As a workaround we have some types here
I don't think so - we shouldn't have duplicate keys in those data, so order shouldn't matter. The only place where order matters is inside
Starts with
Clarified that the function cannot fail, because all packages referenced in the manifest are guaranteed to have a matching entry inside the
Clarified that it returns
I've started writing tests here. I wrote them in JSON so it's easier for you to integrate into your own test runner; in our case, the code that runs this JSON is here: pnpStandardRunner.test.ts. ¹ This behaviour was how the fallback worked, before |
* Writes a PnP spec * Formalizes the algorithms * Updates the PnP header * Addresses feedbacks from evanw/esbuild#1985 * Starts writing reusable tests * More tests, clarifications on FIND_PNP_MANIFEST * Updates style for code segments * Adds tests for aliases * Fixes inadvertent default setting change * Fixes tests * Versions
* Writes a PnP spec * Formalizes the algorithms * Updates the PnP header * Addresses feedbacks from evanw/esbuild#1985 * Starts writing reusable tests * More tests, clarifications on FIND_PNP_MANIFEST * Updates style for code segments * Adds tests for aliases * Fixes inadvertent default setting change * Fixes tests * Versions
I just deployed the documentation to the website: https://yarnpkg.com/advanced/pnp-spec/ |
Thank you for publishing the specification and the tests. I have updated my branch here, including incorporating the tests: https://github.com/evanw/esbuild/tree/yarn-pnp. Unfortunately many of the tests fail with the algorithm in the specification. I was able to get all tests to pass by deviating from the specification and following Yarn's implementation instead. I have the following additional feedback regarding the specification (sorry for another long post):
|
I've opened yarnpkg/berry#4724 to address the problems you pointed. A few notes:
I tried it and it worked out of the box with
I think it has something to do with the zip filesystem - running I have also tried to run the build on the Yarn repo, but it failed to resolve the workspaces. If you want to try it:
That's a bug in the test; the
Correct - it's only useful at runtime for the PnP API consumers.
Indeed - I originally fixed that in the |
This comment was marked as outdated.
This comment was marked as outdated.
Scratch my previous post - the reason is just that we changed the hook format in yarnpkg/berry#4320; before: #!/usr/bin/env node
/* eslint-disable */
try {
Object.freeze({}).detectStrictMode = true;
} catch (error) {
throw new Error(`The whole PnP file got strict-mode-ified, which is known to break (Emscripten libraries aren't strict mode). This usually happens when the file goes through Babel.`);
}
function $$SETUP_STATE(hydrateRuntimeState, basePath) {
return hydrateRuntimeState(JSON.parse('{\
"__info": [\
"This file is automatically generated. Do not touch it, or risk",\
"your modifications being lost. We also recommend you not to read",\
"it either without using the @yarnpkg/pnp package, as the data layout",\
"is entirely unspecified and WILL change from a version to another."\
],\
"dependencyTreeRoots": [\
{\ After: #!/usr/bin/env node
/* eslint-disable */
try {
Object.freeze({}).detectStrictMode = true;
} catch (error) {
throw new Error(`The whole PnP file got strict-mode-ified, which is known to break (Emscripten libraries aren't strict mode). This usually happens when the file goes through Babel.`);
}
const RAW_RUNTIME_STATE =
'{\
"__info": [\
"This file is automatically generated. Do not touch it, or risk",\
"your modifications being lost."\
],\
"dependencyTreeRoots": [\
{\ |
Thanks! I updated my branch, which now appears to be working correctly in all of these cases. So it seems like it's ready for people to try out. I'm planning to move forward here by landing this zip PR, then landing my branch, then releasing these changes as a new minor release. |
* Writes a PnP spec * Formalizes the algorithms * Updates the PnP header * Addresses feedbacks from evanw/esbuild#1985 * Starts writing reusable tests * More tests, clarifications on FIND_PNP_MANIFEST * Updates style for code segments * Adds tests for aliases * Fixes inadvertent default setting change * Fixes tests * Versions
* Writes a PnP spec * Formalizes the algorithms * Updates the PnP header * Addresses feedbacks from evanw/esbuild#1985 * Starts writing reusable tests * More tests, clarifications on FIND_PNP_MANIFEST * Updates style for code segments * Adds tests for aliases * Fixes inadvertent default setting change * Fixes tests * Versions
* Writes a PnP spec * Formalizes the algorithms * Updates the PnP header * Addresses feedbacks from evanw/esbuild#1985 * Starts writing reusable tests * More tests, clarifications on FIND_PNP_MANIFEST * Updates style for code segments * Adds tests for aliases * Fixes inadvertent default setting change * Fixes tests * Versions
* Writes a PnP spec * Formalizes the algorithms * Updates the PnP header * Addresses feedbacks from evanw/esbuild#1985 * Starts writing reusable tests * More tests, clarifications on FIND_PNP_MANIFEST * Updates style for code segments * Adds tests for aliases * Fixes inadvertent default setting change * Fixes tests * Versions
* Writes a PnP spec * Formalizes the algorithms * Updates the PnP header * Addresses feedbacks from evanw/esbuild#1985 * Starts writing reusable tests * More tests, clarifications on FIND_PNP_MANIFEST * Updates style for code segments * Adds tests for aliases * Fixes inadvertent default setting change * Fixes tests * Versions
* Writes a PnP spec * Formalizes the algorithms * Updates the PnP header * Addresses feedbacks from evanw/esbuild#1985 * Starts writing reusable tests * More tests, clarifications on FIND_PNP_MANIFEST * Updates style for code segments * Adds tests for aliases * Fixes inadvertent default setting change * Fixes tests * Versions
* Writes a PnP spec * Formalizes the algorithms * Updates the PnP header * Addresses feedbacks from evanw/esbuild#1985 * Starts writing reusable tests * More tests, clarifications on FIND_PNP_MANIFEST * Updates style for code segments * Adds tests for aliases * Fixes inadvertent default setting change * Fixes tests * Versions
* Writes a PnP spec * Formalizes the algorithms * Updates the PnP header * Addresses feedbacks from evanw/esbuild#1985 * Starts writing reusable tests * More tests, clarifications on FIND_PNP_MANIFEST * Updates style for code segments * Adds tests for aliases * Fixes inadvertent default setting change * Fixes tests * Versions
* Writes a PnP spec * Formalizes the algorithms * Updates the PnP header * Addresses feedbacks from evanw/esbuild#1985 * Starts writing reusable tests * More tests, clarifications on FIND_PNP_MANIFEST * Updates style for code segments * Adds tests for aliases * Fixes inadvertent default setting change * Fixes tests * Versions
* Writes a PnP spec * Formalizes the algorithms * Updates the PnP header * Addresses feedbacks from evanw/esbuild#1985 * Starts writing reusable tests * More tests, clarifications on FIND_PNP_MANIFEST * Updates style for code segments * Adds tests for aliases * Fixes inadvertent default setting change * Fixes tests * Versions
This PR enables esbuild to transparently traverse into
.zip
files as if they were directories. This is relevant to Yarn which stores packages in.zip
files and then monkey-patches the JavaScript file system API so other JS code doesn't need to know about it. That doesn't work for esbuild because it's written in Go, so Yarn needs an esbuild plugin to do this which is single-threaded and also doesn't handle all of the cases esbuild handles. This change to add.zip
file support to esbuild seems to work fine, and it's not a lot of code to maintain.I do still need to figure out what the lifecycle of the zip file reader is though. Right now they aren't closed. I also need to check that this works on Windows, which is always needs special-casing when it comes to path separators. And ideally this would have some test coverage.