imi-ernd-be/wasm-run

Build tool that replaces cargo run to build WASM projects

Just like webpack, wasm-run

wasm-run

Synopsis

Build tool that replaces cargo run to build WASM projects. Just like webpack, wasm-run offers a great deal of customization.

To build your WASM project you normally need an external tool like wasm-bindgen, wasm-pack or cargo-wasm. wasm-run takes a different approach: it's a library that you install as a dependency to a binary of your project. Because of that you don't need any external tool, the tooling is built as part of your dependences.

To build your project for production you can use the command cargo run -- build and to run a development server that reloads automatically when the sources change you can use cargo run -- serve.

Please note that there is a space between -- and build and between -- and serve!

One of the main advantage of this library is that it provides greater customization: you can set a few hooks during the build process in order to customize the build directory or use a template to generate your index.html, download some CSS, ... you name it. I personally use it to reduce the amount of files by bundling the CSS and the JS into the index.html so I had only two files (index.html, app_bg.wasm).

Examples

There are two basic examples to help you get started quickly:

  • a "basic" example for a frontend only app that rebuilds the app when a file change is detected;
  • a "backend-and-frontend" example using the web framework Rocket (backend) which uses Rocket itself to serve the file during the development (any file change is also detected and it rebuilds and restart automatically).

Usage

All the details about the hooks can be find on the macro [main].

Additional Information

  • You can use this library to build examples in the examples/ directory of your project. cargo run --example your_example -- serve. But you will need to specify the name of the WASM crate in your project and it must be present in the workspace. Please check the "example" example.
  • If you want to use your own backend you will need to disable the serve feature by disabling the default features. You can use the full-restart feature to force the backend to also be recompiled when a file changes (otherwise only the frontend is re-compiled). You will also need to specify run_server to the macro arguments to run your backend.
  • You can add commands to the CLI by adding variants in the enum.
  • You can add parameters to the Build and Serve commands by overriding them. Please check the documentation on the macro main.
  • If you run cargo run -- serve --profiling, the WASM will be optimized.

Features

  • prebuilt-wasm-opt: if you disable the default features and enable this feature, a binary of wasm-opt will be downloaded from GitHub and used to optimize the WASM. By default, wasm-opt is compiled among the dependencies (binaryen). This is useful if you run into troubles for building binaryen-sys. (binaryen cannot be built on Netlify at the moment.)
  • sass: support for SASS and SCSS. All SASS and SCSS files found in the directories styles/, assets/, sass/ and css/ will be automatically transpiled to CSS and placed in the build directory. This can be configured by overriding: [BuildArgs::build_sass_from_dir], [BuildArgs::sass_lookup_directories], [BuildArgs::sass_options] or completely overriden in the [Hooks::post_build] hook. sass-rs is re-exported in the prelude of wasm-run for this purpose.
  • full-restart: when this feature is active, the command is entirely restarted when changes are detected when serving files for development (cargo run -- serve). This is useful with custom serve command that uses a custom backend and if you need to detect changes in the backend code itself.

License: MIT OR Apache-2.0

Issues

Collection of the latest Issues

szagi3891

szagi3891

Comment Icon3

I wanted to use this wasm_bindgen functionality for importing a js file https://github.com/rustwasm/wasm-bindgen/tree/master/examples/import_js

This is the file structure that wasm-run generated:

The problem can be observed on this branch:

An attempt to run the application ends with a 404 error on the resource: /snippets/vertigo-browserdriver-cf73457c3ed6503a/jsdriver/out/jsdriver.js

In a project where I used wasm-pack directly, I get this structure:

it looks like wasm-run omits the generated "snippets" directory. Could you please help me with this problem?

cecton

cecton

Comment Icon0

When I see how fast is the WASM compiled I wonder if we could not bypass the wasm-bindgen build entirely.

The current process to build is as follow:

  1. run pre-build
  2. run cargo build --target wasm...
  3. run wasm-bindgen to generate the JS and stuff that wraps the wasm
  4. run post-build

I believe the really slow stuff is actually in the point 3 with wasm-bindgen. Maybe it is possible to run it once and then re-use the existing JS code and stuff.

This is an idea and it should be explored. It doesn't mean it is true or can be done.

YohDeadfall

YohDeadfall

Comment Icon0

Issue #34 added basic logging, so the user can see what's going on. The next step is to improve it by grouping messages by steps or by using a different color for actions (see how cargo build shows progress). Time spent on each action would be helpful too.

cecton

cecton

Comment Icon0

Using the single crate mechanism is not easy to setup because:

  • of the specific targets dependencies
  • it doesn't work very well with cargo. Sometimes cargo build the lib.rs even if it is not asked for it
  • It's also annoying for autocompletion and cargo check command as they don't work because of the limitation of the target on lib.rs.

For all those reason it is best to actually force the user to separate the run crate from the app crate. Making the first argument of the proc macro required is also a good thing because it's easy to forget that it exists (it's the name of the frontend crate in the workspace).

cecton

cecton

Comment Icon0
  • Make the module bundler private and re-export what is necessary in the root and/or prelude
  • web-bundler SASS support should be optional
  • Use a builder pattern to create the WebBundlerOpt because some fields in there are not important for the users (they shouldn't be required to be type explicitly)
cecton

cecton

Comment Icon6

cc @fstephany

Q: What are the available CLI commands by default? serve and build? The --help output is a bit sparsed.

The doc string for build and serve are duplicated and wrong. There is already a ticket for it: #39

Q: I can't find in the doc the order of execution for stuff. I see the doc for the main macro. Are the named arguments that I pass to the macro 'hooks'? What is the order of execution?

  • pre_build, post_build are pretty obvious on their own.
  • watch is to change the watching behavior, it's not linked to an order of execution. serve is to change the serving behavior, again it's not particularly linked to an order.
  • run_server is to change the behavior when the serve feature is disabled. The serve feature provide a small HTTP server to serve the files. Without it, you need to configure your own server.
  • default_build_path is to override the default build path, it's not related to an order of execution either.
  • other_cli_commands is to handle the other (not build or serve) cli commands, it's not related to an order of execution though I think it should be the very first thing executed

Q: I see that I can add new custom commands? How does that look like?

This is an example of custom command that builds a Docker image https://github.com/IMI-eRnD-Be/wasm-run/blob/main/examples/backend-and-frontend/frontend/src/main.rs#L11

Q: In the case of a pure WASM project, build and serve makes sense on their own. When there other components, like this example with a backend, SCSS and frontend, what do they mean? Is build for the three components? How should I express that I only want to rebuild the backend (e.g., if a file changes for example?).

wasm-run builds the frontend so it rebuilds only the frontend components by default.

You can use the full-restart feature to trigger a full rebuild (backend and anything else). It's done in the example: https://github.com/IMI-eRnD-Be/wasm-run/blob/main/examples/backend-and-frontend/frontend/Cargo.toml#L16

There is no way to rebuild only the backend as wasm-run is not intended to assist backend development but frontend development (or the interactions between the two as a whole).

Q: There's no mention in the README of the watcher. In the main macro documentation we see "a function that is called when the watcher is being initialized (allowing you to add extra things to watch for example)" How is this working? Does wasm-run always initialize a watcher? What does it watch?

Yes. Everything* is watched by default. wasm-run intend is to assist frontend development as a whole.

Q: How does sass/scss building works? It seems to be part of the post_build hook step. Will the sass/scss still be transpiled if I provide a post_build hook? Why isn't this addivitive?

Yes if you override post_build you need to setup your own sass/scss generation. It isn't additive because it's a one-size-fit-all by default hook configuration which you can entirely override if you wish.

We could provide a separate "css" hook. It's an idea.

Q: How do I prevent the generation of the index.html without overriding the post_build hook? I don't need it as HTML is generated by my backend server.

You can't prevent it without overriding the post_build hook. We could add a flag to customize that in particular... I think the problem we have here in general is that there are too many things in the post_build hook and it makes it cumbersome when you only want to override one small behavior.

Q: Oh! its the post_build step that writes the wasm+js to disk.

Yes, you can totally change that the way you want by overriding post_build. I personally do that to embed the JS in the index.html.

Q: Is the anyhow requirement appropriate? I guess we can afford it as the scope is quite reduced?

Anyhow is useful for binaries. It's an opinionated and pragmatic choice as you usually don't want to make error enums in script that just build the frontend.

Q: Oh ok, in the backend example in wasm-run, the binary (let's call it main) is dependent on the backend and runs it from there. This means

  1. the backend must be startable from outside its main (what about dotenv for example?)
  2. it can be started without using an external process. As it is the running process.
  1. You can load your configuration in an entrypoint function in the backend then just call it from main.rs. So the behavior will be shared for both.
  2. It can be started without using an external process indeed as it needs to go into production without wasm-run
cecton

cecton

Comment Icon0

Sass lookup directory should be overwritable? Right now sass_lookup_directories() only looks up in the 'frontend' directory.

This is probably an invalid issue because the sass directory can be changed by overriding the post_build hook.

Maybe it's not well suited? @fstephany let met know your opinion

cecton

cecton

Comment Icon0

Compile Sass files one by one? Cannot concatenate all of them into one css?

Sass files starting with _ do not produce a css file on their own. This is normal SASS but it might be good to remind it and point to the documentation.

yozhgoor

yozhgoor

Comment Icon6

Clippy tell me that i have an error with my pre_build function, an unnecessary wraps as the Result in the return type signature

My program compile, i just don't pass clippy checks

Information - Updated Apr 11, 2022

Stars: 33
Forks: 3
Issues: 26
Actix

2.1K

Curated examples using the Actix ecosystem

Zero2prod : Source code of zero to production series Triox : A free file hosting server that focuses on speed, reliability and security

Curated examples using the Actix ecosystem

Actix codebase containing real world examples (CRUD, auth, advanced patterns, etc) that adheres to the...

Learn by example when using actix and speed up development time

Actix codebase containing real world examples (CRUD, auth, advanced patterns, etc) that adheres to the...

Pure rust based webgl with examples

This project is under heavily development, all api are very unstable until version 1.0 GA release

Pure rust based webgl with examples

Crossterm Examples

The examples crate is deprecated and no longer maintained

Crossterm Examples

Rust-AV examples

A series of some multimedia examples

Rust-AV examples

SmartCore Examples

Examples of code using machine learning models from SmartCore's User guide and grouped into same categories as pages from the manual

SmartCore Examples

arkwork-rs library examples

Few basic examples showing how to use Christian Lundkvist's libsnark tutorial

arkwork-rs library examples

Rust WASM Web Worker Examples

This repository contains four different examples of using web workers in conjunction with WASM in

Rust WASM Web Worker Examples

wasmCloud Examples

Example actors, capability providers, and other demonstrations

wasmCloud Examples

blackhole is a server that responds to any request with http status code 200

For example, you can check what kind of request is notified by GitHub webhook from the access log

blackhole is a server that responds to any request with http status code 200

Rust Examples for the DERULER project

install GNU Arm Toolchain:

Rust Examples for the DERULER project

Examples for the Rust Meetup Linz talk

See the subfolders described below for the individual examples

Examples for the Rust Meetup Linz talk
Facebook Instagram Twitter GitHub Dribbble
Privacy