-
Notifications
You must be signed in to change notification settings - Fork 177
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
Parcel Integration #93
Comments
Yes, closer integration with JavaScript bundlers is something I plan to actively pursue Very Soon™. For the last two weeks I've been refactoring and rewriting a lot of |
You can see the code they use to load rust code here, it's quite straightforward: https://github.com/parcel-bundler/parcel/blob/master/src/assets/RustAsset.js It should be pretty easy to extend that to support I'd be happy to make that PR, but if changes to |
Yeah, that certainly looks pretty straightforward. Hm... yep, there are a few ways you could detect that a crate needs
On a side note, something would probably have to be done with parcel-bundler/parcel#647 as we'll need to pass a bunch of imports into the WASM module for anything to work. (Unless we'd use a |
Looking through their generated code, it seems to build a graph of modules that use simple Mulling this over, it's probably best to generate both a js file and a wasm file, where the js file is responsible for loading the wasm file, and then recursively run the js file through their preprocessor. That way you'll be able to have something like:
module.exports = {
moo: function() { console.log('moo!'); }
}
#[no_mangle]
pub fn do_thing() {
js! {
var moo = require("../cow.js").moo;
moo();
}
} For this code, we can spit out a small file that looks like: function initialize(instance) {
var __imports = {
__thing_needed_by_rust_runtime: function(x,y) { /* ... */ }
__moo_js_code: function() {
var moo = require("../cow.js").moo;
moo();
}
};
instance.instantiate(__imports);
instance.do_initialization_things();
}
var instance = require('src/lib.rs-wasm-artifact.wasm')
initialize(instance);
module.exports = instance; and then jury-rig Parcel to recursively run its JS processing on this file, which will be what you get when you This would need parcel-bundler/parcel#647 to be implemented so that we would have access to the instantiate method of the WebAssembly module. We'd also need cargo-web to generate the |
I took a closer look at this, and it seems that right now it would only be possible to generate a module with We can easily work around Parcel's lack of support for specifying WASM imports by simply instantiating the WASM module ourselves (we can rename the However, it looks like Parcel supports plugins which, from what I can tell, should allow us to get around the problem. I'll try to whip up an experimental plugin and see how it goes. |
I've just added a I've also started an experimental Parcel plugin which, while still missing some essential features, seems to work. I'll probably push it tomorrow once I'll get it a little more fleshed out. |
I'm happy to announce that I've made an experimental Parcel plugin which, surprisingly, seems to work! (Or at least I hope so...) You can find it here: https://github.com/koute/parcel-plugin-cargo-web To use it you should just have to run Unfortunately I had to resort to a quite... creative hack to make it work. (You can look at the sources if you're interested; the plugin itself is very small.) So please treat it as something experimental for now. Hopefully Parcel with support this kind of a thing natively in the future. |
@koute, there actually is a way to make that work! See https://github.com/parcel-bundler/parcel/blob/master/src/Bundler.js#L38-L46, you can add a "bundle loader" that preloads certain kinds of modules. I'm working on a PR against the main parcel repository now, and using that. The problem I'm running up against is that dynamically changing the output type of my module is causing Parcel some confusion (you've sidestepped this problem by having the user import |
Yes, I know. Unfortunately these are precisely the problem. The point is that (as far as I know) those bundle loaders must be preregistered (so you can't really add new ones dynamically), they have to be static (you register one bundle loader per artifact type and you can't change it), and they only have the access to I've worked around this issue by replacing |
Is there any existing parcel issue for addressing the rust specific concerns that we're hacking around? If not, I can try to get this on their radar and potentially implement a proper fix. |
@bgourlie AFAIK the issue isn't really Rust specific, and Emscripten folks have (AFAIK) exactly the same issues as we do. The whole issue boils down to the fact that Parcel expects the WASM bundle loader (or any other one for that matter) to be static, but we can't use a static one since we need to supply our own imports for the WASM module instantiation and we need to do stuff like manually calling If you'd like to take a stab at fixing this properly you might want to ask @kazimuth how far he managed to get and perhaps talk with the Parcel folks how they would like it to be fixed. |
The Parcel project recently released Rust support; it's now extremely easy to bundle rust into a production application. See the announcement of the release.
They have a good story for the calling-into-rust end:
add.rs:
index.js:
However, they don't have a good story for calling-out-of-rust the way stdweb does. Currently, when you use the
js!
macro,TypeError: second argument must be an object
is logged to the console, and nothing happens - I suspect because of missing glue code.Parcel seems to be using
wasm32-unknown-unknown
- the generated loading code doesn't do anything emscripten-y. I don't know what magiccargo-web
does, but it's currently missing from parcel. If it could be integrated, that would be amazing.The text was updated successfully, but these errors were encountered: