rustwasm / wasm-pack

📦✨ your favorite rust -> wasm workflow tool!
https://rustwasm.github.io/wasm-pack/
Apache License 2.0
6.33k stars 411 forks source link

yew framework: I think i want to run `wasm-pack` from `build.rs` #916

Open Tanja-4732 opened 4 years ago

Tanja-4732 commented 4 years ago

I think i want to run web-pack from build.rs. I have a workspace of multiple crates. The WebAssembly generating crate is just one of them. I'd like to have one command to build everything, ideally cargo build.

Any advice on how to call wasm-pack build --target web in the one crate from the workspace's cargo build?

Originally posted by @kud1ing in https://github.com/rustwasm/wasm-pack/issues/251#issuecomment-520207166

Using Yew

I'm using the yew framework, and I'm working inside of a Rust workspace. Since the backend/ folder contains a bin crate for the backend server, and the frontend/ folder contains a yew project (which needs wasm-pack build --target web --out-name wasm --out-dir ../target/static or something like that to be run to compile to webassembly), I'd like to be able to do so in an automated fashion (ideally using cargo build in the root of the repo).

How should this be achieved?
If possible, integration with VS Code tasks is also desired.

Thanks for reading :hugs:

TheNeikos commented 4 years ago

Heya! So I was thinking about this issue and got it working with this simple setup:

use std::env;
use std::path::Path;
use std::process::Command;

fn main() {
    println!("cargo:rerun-if-changed=client/");
    let out_dir = env::var_os("OUT_DIR").unwrap();
    let dest_path = Path::new(&out_dir).join("web-client");
    let output = Command::new("wasm-pack")
        .args(&[
            "build",
            "--target",
            "web",
            "--out-name",
            "client",
            "--out-dir",
        ])
        .arg(&dest_path)
        .arg("./client/")
        .output()
        .expect("To build wasm files successfully");

    if !output.status.success() {
        panic!(
            "Error while compiling:\n{}",
            String::from_utf8_lossy(&output.stdout)
        );
    }

    let js_file = dest_path.join("client.js");
    let wasm_file = dest_path.join("client_bg.wasm");

    for file in &[&js_file, &wasm_file] {
        let file = std::fs::metadata(file).expect("file to exist");
        assert!(file.is_file());
    }

    println!("cargo:rustc-env=PROJECT_NAME_JS={}", js_file.display());
    println!(
        "cargo:rustc-env=PROJECT_NAME_WASM={}",
        wasm_file.display()
    );
}

This puts the filepaths into those env variables, which can then be used in an include! or whatever you wish to do with them.

I do think this is just a temporary and somewhat hacky way to do it

cecton commented 3 years ago

Hey o/ I just found this issue and I might have a good news for you.

I'm building a tooling library that is more or less like wasm-pack but more customizable and instead of being an external binary it replaces cargo run (cargo build cannot be tweaked). More details on this tweet.

I'm not entirely sure but I think it would be useful for you. Let me know if you have any suggestion/question.

cecton commented 3 years ago

Finally released something! \o/ Give it a look and let me know if it covers/help your use case :) Otherwise I would be interested to know more to see if I can help. Check the "backend-and-frontend" example.

https://github.com/IMI-eRnD-Be/wasm-run

(More detail when I announced it here)

vogtb commented 3 years ago

Heya! So I was thinking about this issue and got it working with this simple setup: ... I do think this is just a temporary and somewhat hacky way to do it

@TheNeikos, I'm not sure that works. I gave it a try today, and found that it hangs. Since wasm-pack runs through cargo it needs to acquire the cargo lock, but since you ran cargo in the first place, you've already got the lock. Maybe there's something I'm missing though?

cecton commented 3 years ago

No I think that's correct. The devs of https://github.com/panoptix-za/web-bundler/issues/6#issuecomment-788290576 found the same issue and circumvent it with a second target directory. This is something I want to address in wasmbl (a merge of wasm-run and web-bundler)

vogtb commented 3 years ago

Hmmm, so if I did something like this in build.rs

fn main() {
    Command::new("wasm-pack")
            .arg("build")
            .arg("--target=web")
            .arg("--out-dir=dist")
}

and ran it with cargo build -p myproject --target-dir=whatever it would work? Interesting. I'll give it a shot.

ajeetdsouza commented 2 years ago

I just tried changing the target-dir and out-dir, but the build still deadlocks. Here's my build.rs file:

fn main() {
    let build_opts = wasm_pack::command::build::BuildOptions {
        disable_dts: true,
        target: wasm_pack::command::build::Target::Web,
        release: true,
        extra_options: vec![
            "--target-dir".to_string(),
            "target-wasm".to_string(),
            "--out-dir".to_string(),
            "target-wasm".to_string(),
            "-Z".to_string(),
            "unstable-options".to_string(),
        ],
        ..Default::default()
    };
    wasm_pack::command::build::Build::try_from_opts(build_opts).unwrap().run().unwrap();
}
max-sixty commented 1 year ago

Edit: See response at https://github.com/rustwasm/wasm-bindgen/discussions/3494#discussioncomment-6245992

Original comment:


Over at https://github.com/PRQL/prql/pull/2881 we're hoping to use a build.rs file to build our wasm binaries, mostly to take advantage of cargo's caching — wasm-pack seems to require a significant rebuild even if no files have changed.

We're planning to use https://crates.io/crates/substrate-wasm-builder. That seems to allow building from build.rs. It's less focused on JS projects though, so probably need additional CLI calls into wasm-bindgen.

I just found https://github.com/rustminded/xtask-wasm/blob/main/src/dist.rs by following some links from here, which also looks interesting, but doesn't seem to support building from build.rs.

I'm right at the beginning of looking at this — any thoughts or feedback welcome...