-
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
[Feature] Support yarn berry/PnP #237
Comments
It looks like the second part is a duplicate of #154. See that issue for my thoughts. I plan to start experimenting with resolve plugins in esbuild soon FWIW. For the first part, it sounds like your saying if you install esbuild with yarn, you are unable to call the JavaScript API from a module loaded by PnP because Yarn breaks with all binary files. Is that right? Can you provide example code to reproduce the issue? |
Sorry for not searching through the closed issues. |
Just took a look. It looks like you want to use the I read through yarnpkg/berry#882 but I don't understand the cross-platform argument. The I can think of several workarounds for this bug:
|
One of berry's features is, that you commit the install to git. So you don't even run yarn install anymore after git clone. It runs out of the box. I guess binaries don't fit well in that model. |
Ah, I see. Well if you want a cross-platform esbuild package you should install esbuild-wasm instead. Normally I don’t encourage people to install it because it’s a lot slower but if you need to use a single package for all platforms then it’s pretty much your only option (I’m assuming you don’t want to simultaneously install all 8 esbuild native packages for all supported platforms). Luckily esbuild is more than 10x faster than other tools, so even though esbuild-wasm is 10x slower than native esbuild, I’m guessing it’s still faster than other tools. You might want to check the performance for your use case yourself though. Also keep in mind that checking in a huge binary into git and then repeatedly updating it over time might not be the best for git repo size depending on your use case. |
Using the wasm might be a good option in this case, agree. I know the yarn maintainers have been in contact with github about the possible implications that PnP will have when checking in the zip file of every dependency (and updating these on a regular basis). It seemed to be fine. In our case we see that the benefits of berry far outweigh the storage issue. But adding all 8 esbuild binaries does sound like a lot of unnecessary weight. |
FYI in case you aren't following along with #111: I'm currently working on the plugin system and keeping this use case in mind. This work is being done on the Here's a simple plugin using the work-in-progress API that appears to add support for Yarn's PnP API: let { PosixFS, ZipOpenFS } = require(`@yarnpkg/fslib`)
let libzip = require(`@yarnpkg/libzip`).getLibzipSync()
let zipOpenFs = new ZipOpenFS({ libzip })
let crossFs = new PosixFS(zipOpenFs)
let pnpapi = require('pnpapi')
// More info: https://classic.yarnpkg.com/en/docs/pnp/
let pnpYarnPlugin = plugin => {
plugin.setName('pnp')
plugin.addResolver({ filter: /.*/ }, args => {
return { path: pnpapi.resolveRequest(args.path, args.importDir + '/') }
})
plugin.addLoader({ filter: /.*/ }, args => {
return { contents: crossFs.readFileSync(args.path), loader: 'default' }
})
} I say "appears to" because I don't personally use Yarn so I'm not familiar with it. Everything seems to be working but there may be edge cases I'm not aware of. In any case I think it at least shows that the plugin system should be able to solve this, even if the final Yarn PnP API calls are a little different. |
Thanks @evanw for taking the time to test this with the plugin system! Will have a look at this soon. |
@evanw I finally got around to testing esbuild plugins api with PnP. It looks very promising! One issue I had to "work around" was how to handle |
@evanw Just a note on that plugin, it's missing the |
If anyone is interested in testing a plugin with pnp support: https://www.npmjs.com/package/esbuild-plugin-pnp |
You don't actually have to use the |
Closing this because it should now be possible to build this with the plugin API. As mentioned above, something like this may be sufficient: let yarnPnpPlugin = {
name: 'yarn-pnp',
setup(build) {
build.onResolve({ filter: /.*/ }, args => ({
path: require.resolve(args.path, {paths: [args.resolveDir]}),
}))
build.onLoad({ filter: /.*/ }, async (args) => ({
contents: await require('fs').promises.readFile(args.path),
loader: 'default',
}))
},
} |
@evanw I don't suppose you're willing to automatically register a plugin like that if you detect PnP? Totally understandable if you don't |
I'm not planning to do that. Yarn PnP is a very invasive change to node that changes a fundamental assumption about how it works, so I think it will at best only sort of work with esbuild. The Go world won't know about the monkey-patching Yarn PnP does, as well as binary plugins when they are supported in the future. So there will likely always be things about Yarn PnP that don't work with esbuild. I expect people to need to do custom tweaks to the path resolution logic to get it to work correctly in a real code base and I don't think it's appropriate for esbuild to try to handle this automatically. For example, the above plugin may need to also modify |
Just some resolution to this closed issue in case anyone else stops by, yarn now officially supports a esbuild plugin for pnp that they use internally to build yarn itself: https://github.com/yarnpkg/berry/tree/master/packages/esbuild-plugin-pnp |
FYI: Native support for PnP has been added to esbuild: https://github.com/evanw/esbuild/releases/tag/v0.15.0 (it became possible to implement this now that the PnP data format has been documented: https://yarnpkg.com/advanced/pnp-spec/). |
In our pursuit to speed up our development flow and CI/CD esbuild has been amazing. Another tool I've been testing a few times is yarn berry (yarn 2.0). As far as I have been able to figure out there are currently two issues with using esbuild with berry.
Any thoughts on making esbuild work natively with berry?
The text was updated successfully, but these errors were encountered: