-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
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
Adds support for Rust/wasm assets via wasm-pack #4970
base: v2
Are you sure you want to change the base?
Conversation
… them from transform, now just gotta wire it all together
…and update the glue to use url path
…re like integration tests just for comparison
…tween input and output file systems
…o use more modern sintax, fix a relative path issue
…ith a generated wasm entry
|
This looks great! Thanks for working on it. Will look more in depth soon. 😄 |
Which of the problems that you ran into and mentioned in the various other issues are still relevant?
You mean according to parcel/packages/runtimes/js/src/JSRuntime.js Line 292 in 82747eb
|
The issues described here: #3365 (comment) (apart from item 1) are largely unaddressed because I find myself agreeing with @qwerty2501's conclusion here: #3365 (comment) (mainly that, as an MVP it should be a thin wrapper around "vanilla" wasm-pack behavior). @Pauan's comments here: #3365 (comment) are mostly addressed with the exceptions of the first and last items there. In the case of the first, I think I prefer to use wasm-pack's verbose output in Parcel's In the case of the last, I think unless we can target ES Modules we need to do some work on wasm-pack's output to fetch and instantiate the wasm module, and to create the imports object … indeed removing this boilerplate appears to be one of the key motivations behind the WebAssembly/ESM integration spec, but I'm pretty sure it's not yet widely supported.
According to the integration test … I do like this: await assertBundles(b, [
{
assets: [
'browser-loader.js',
'bundle-manifest.js',
'bundle-url.js',
'Cargo.toml',
'index.js',
'JSRuntime.js', // <-- one JSRuntime
'JSRuntime.js', // <-- two JSRuntimes
'relative-path.js',
'single_bg.js',
],
},
{
assets: ['single_bg.wasm'],
},
]); As far as what's left goes, I think just getting that integration test a little more robust? Possibly adding a NodeJS-targeted integration test and a multi-crate integration test? Any feedback on the changes to Also, it looks to me like the test failures are coming from unrelated tests … obv. should figure out what's going on there. |
@mysterycommand It is not necessary to have ESM integration, instead you can use If you use |
@Pauan super interesting, thanks! You're reminding me of a couple of things that may or may not be issues for using If we could split it up this way we wouldn't need the loaders (you're right … in fact, even in the case of the Rollup plugin I think using However, I think there's a couple things I'm not so jazzed about with this approach:
Super open to feedback on all of this … my use case/desired usage might not be in exactly in line with Parcel's? I'm really not sure what other users/authors might want or expect either. |
That's enabled by default since Babel 7.10. Though we probably need to handle it in Parcel itself: #3269 |
@mysterycommand I personally would not recommend using init(promisify(readFile)(wasmPath)) This works because the This allows you to load the
That's unavoidable, since the imports object, JS heap, and linear memory must be different for each crate. So the only things which could be deduplicated are a handful of small utility functions like Any sort of deduplication would have to be done in wasm-bindgen, I don't think this plugin is the right place to do it.
I don't know how Parcel works internally, and I don't know what Parcel plugins are capable of doing, so I don't know if that's possible without ESM integration or top-level await. Rollup does not work with top-level await (it simply relies on the browser's implementation of top-level await), so that's why the Rust Rollup plugin needed to use a less convenient API. Whereas Webpack does transform top-level await, so it has great support for |
[profile.release] | ||
# Tell `rustc` to optimize for small code size. | ||
# @see: https://doc.rust-lang.org/cargo/reference/manifest.html#the-profile-sections | ||
opt-level = "s" |
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.
It would be good to add more describes and lto example.
[profile.release] | |
# Tell `rustc` to optimize for small code size. | |
# @see: https://doc.rust-lang.org/cargo/reference/manifest.html#the-profile-sections | |
opt-level = "s" | |
# Customizing compiler settings when release build. | |
# @see: https://doc.rust-lang.org/cargo/reference/manifest.html#the-profile-sections | |
[profile.release] | |
# Tell `rustc` to optimize for small code size. | |
# @see: https://rustwasm.github.io/docs/book/reference/code-size.html#tell-llvm-to-optimize-for-size-instead-of-speed | |
opt-level = "s" | |
# Compiling with `link time optimizations`. It is more optimize and small code size. But compile time to be longer. | |
# @see: https://rustwasm.github.io/docs/book/reference/code-size.html#compiling-with-link-time-optimizations-lto | |
lto = true |
Does this PR add anything reusable for #5598? |
↪️ Pull Request
This PR is a first implementation of support for Rust/wasm assets via wasm-pack in Parcel 2. It's based on
parcel-plugin-wasm-pack
for Parcel 1 (which I also wrote). It has been discussed in #4422 (comment) and in #3365.💻 Examples
There are examples in
packages/examples/wasm-single-crate
andpackages/examples/wasm-multiple-crates
. They both use anindex.html
as the entry forparcel build/serve
. The html adds ajs
script file which does something likeimport {run} from '../Cargo.toml';
.I updated
packages/configs/default/index.json
so that imports ofCargo.toml
flow through a newWasmPackTransformer
which runswasm-pack
and generates a loader and some glue code to wire the wasm module and it's imports object together.Probably the most "controversial" part of this PR are some changes to
JSPackager
that are based on the original plugin implementation'sWasmPackPackager
which registered itself to handle JS files in the plugin implementation. I wasn't sure if (now that I'm contributing to core) there was a better way/place to make these changes, but this seems to work at least … as a starting point.🚨 Test instructions
I am very open to ways of making the integration test better/more meaningful … it's really just a scaffold right now that asserts the names of the generated bundle's assets. Weirdly, it appears that one of the bundles includes the
JSRuntime
asset twice … is that normal/expected? Seems weird to me.That said, both the examples mentioned above work, and navigating into one of those folders and running
yarn build
oryarn start
will generate a valid bundle that logs something to the console from the wasm module.✔️ PR Todo