-
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
Support native system access from wasm #2968
base: main
Are you sure you want to change the base?
Conversation
This commit adds support for native system access for WASM. This is used through a new `wasmSystemAccess` option on the `esbuild.initialize` options bag. This options bag can contain either a specifier or namespace for a Node.js compatible `fs` and `process` module. During setup these are injected into `globalThis.fs` and `globalThis.process`, where Go's WASM runtime uses them to back the regular Go FS APIs. Finally, if this option is set, we set the `hasFS` option on `createChannel`, and everything just works :) Example for Deno: ```ts import * as esbuild from "./deno/wasm.js" await esbuild.initialize({ wasmSystemAccess: { fsSpecifier: "node:fs", processSpecifier: "node:process" } }) await esbuild.build({ format: "esm", entryPoints: ["./lib/deno/mod.ts"], target: "esnext", outfile: "./out.js" }) ```
The test failure on Windows is related to denoland/deno#18053. Shall I ignore Windows for now? |
This is a temporary fix for file loading on WASM. It will ultimately be fixed by evanw/esbuild#2968. This commit also improves the test suite to run all tests in both native and wasm versions of esbuild.
This is a temporary fix for file loading on WASM. It will ultimately be fixed by evanw/esbuild#2968. This commit also improves the test suite to run all tests in both native and wasm versions of esbuild.
This is a temporary fix for file loading on WASM. It will ultimately be fixed by evanw/esbuild#2968. This commit also improves the test suite to run all tests in both native and wasm versions of esbuild.
denoland/deno#18053 is fixed in Deno canary. However this still does not work on Windows, because Go assumes unix-style paths when running within WASM, which is incompatible with Windows backed fs syscalls. This is an upstream limitation in Go's WASM target. As such, I have disabled support on Windows for now and added a doc comment. @evanw this is now ready for review. |
Yes, this is unfortunate. I have filed an issue with Go about this and they have indicated that they do not plan on fixing this: golang/go#43768. However, I have tried to work around this by forking the Go standard library and making the Unix-vs-Windows behavior a dynamic run-time decision instead of a static compile-time decision: esbuild/internal/fs/fs_real.go Lines 67 to 73 in 3b38ce3
Specifically the So in theory esbuild should use Windows-style paths on Windows even with WASM and this should work. I wonder why this isn't working with your implementation. Ideally this would work on Windows too, as Windows is a platform that esbuild works hard to support natively. Do you know why esbuild's Windows-style path manipulation isn't happening in your case given that esbuild has built-in support for it? Is |
Regarding this PR: My first impression of this is that the Also I don't necessarily want to expose the ability to inject a custom file system like this. That's already an existing feature request (#690) and I'd like to expose that ability more uniformly to all API environments that esbuild supports instead of only to Deno + WASM. |
Took a couple weeks of trying all of the WASI shims + a fixed So, to answer my own question, yes, it's very possible! |
thanks @lucacasonato , any plan to have your PR merged or deliver forked wasm binaries for use (for example in Deno Fresh) ? |
This commit adds support for native system access for WASM. This is used
through a new
wasmSystemAccess
option on theesbuild.initialize
options bag. This options bag can contain either a specifier or
namespace for a Node.js compatible
fs
andprocess
module. Duringsetup these are injected into
globalThis.fs
andglobalThis.process
,where Go's WASM runtime uses them to back the regular Go FS APIs.
Finally, if this option is set, we set the
hasFS
option oncreateChannel
, and everything just works :)Example for Deno:
Closes #690