Trunk is a WASM web application bundler for Rust. Trunk uses a simple, zero-config pattern for building & bundling WASM, JS snippets & other assets (images, css, scss) via a source HTML file.
```bash
cargo install trunk
wget -qO trunk.zip ${LINKTORELEASE_BINARY} && \ unzip trunk.zip && \ chmod a+x trunk
cargo install wasm-bindgen-cli ``` Release binaries can be found on the Github releases page.
Get setup with your favorite wasm-bindgen
based framework. Yew & Seed are the most popular options today, but there are others. Trunk will work with any wasm-bindgen
based framework. The easiest way to ensure that your application launches properly is to setup your app as an executable with a standard main
function:
rust
fn main() {
// ... your app setup code here ...
}
Trunk uses a source HTML file to drive all asset building and bundling. Trunk also ships with a built-in sass/scss compiler, so let's get started with the following example. Copy this HTML to the root of your project's repo as index.html
:
html
<html>
<head>
<link rel="stylesheet" href="index.scss"/>
</head>
</html>
trunk build
will produce the following HTML at dist/index.html
, along with the compiled scss, WASM & the JS loader for the WASM:
html
<html>
<head>
<link rel="stylesheet" href="/index.700471f89cef12e4.css">
<script type="module">
import init from '/index-719b4e04e016028b.js';
init('/index-719b4e04e016028b_bg.wasm');
</script>
</head>
</html>
The contents of your dist
dir are now ready to be served on the web. But that's not all! Trunk has even more useful features. Continue reading to learn about other Trunk commands and supported asset types.
trunk build
runs a cargo build targeting the wasm32 instruction set, runs wasm-bindgen
on the built WASM, and spawns asset build pipelines for any assets defined in the target index.html
.
Trunk leverages Rust's powerful concurrency primitives for maximum build speeds & throughput.
trunk watch
does the same thing as trunk build
, but also watches the filesystem for changes, triggering new builds as changes are detected.
trunk serve
does the same thing as trunk watch
, but also spawns a web server.
trunk clean
cleans up any build artifacts generated from earlier builds.
trunk config show
prints out Trunk's current config, before factoring in CLI arguments. Nice for testing & debugging.
Trunk is still a young project, and new asset types will be added as we move forward. Keep an eye on trunk#3 for more information on planned asset types, implementation status, and please contribute to the discussion if you think something is missing.
Currently supported assets:
- ✅ sass
: Trunk ships with a built-in sass/scss compiler. Just link to your sass files from your source HTML, and Trunk will handle the rest. This content is hashed for cache control.
- ✅ css
: Trunk will copy linked css files found in the source HTML without content modification. This content is hashed for cache control.
- In the future, Trunk will resolve local @imports
, will handle minification (see trunk#7), and we may even look into a pattern where any CSS found in the source tree will be bundled, which would enable a nice zero-config "component styles" pattern. See trunk#3 for more details.
- ✅ icon
: Trunk will automatically copy referenced icons to the dist
dir. This content is hashed for cache control.
- ✅ js snippets
: wasm-bindgen JS snippets are automatically copied to the dist dir, hashed and ready to rock.
Images and other resource types can be copied into the dist
dir by adding a link like this to your source HTML: <link rel="trunk-dist" href="path/to/resource"/>
(note the rel="trunk-dist"
attribute). This will cause Trunk to find the target resource, and copy it to the dist
dir unmodified. No hashing will be applied. The link itself will be removed from the HTML.
This will allow your WASM application to reference images directly from the dist
dir, and Trunk will ensure that the images are available in the dist
dir to be served. You will need to be sure to use the correct public URL in your code, which can be configured via the --public-url
CLI flag to Trunk.
NOTE: as Trunk continues to mature, we will find better ways to include images and other resources. Hashing content for cache control is great, we just need to find a nice pattern to work with images referenced in Rust components. Please contribute to the discussion over in trunk#9! See you there.
Trunk supports a layered config system. At the base, a config file can encapsulate project specific defaults, paths, ports and other config. Environment variables can be used to overwrite config file values. Lastly, CLI arguments / options take final precedence.
Trunk supports an optional Trunk.toml
config file. An example config file is included in the Trunk repo, and shows all available config options along with their default values. By default, Trunk will look for a Trunk.toml
config file in the current working directory. Trunk supports the global --config
option to specify an alternative location for the file.
Trunk environment variables mirror the Trunk.toml
config schema. All Trunk environment variables have the following 3 part form TRUNK_<SECTION>_<ITEM>
, where TRUNK_
is the required prefix, <SECTION>
is one of the Trunk.toml
sections, and <ITEM>
is a specific configuration item from the corresponding section. E.G., TRUNK_SERVE_PORT=80
will cause trunk serve
to listen on port 80
. The equivalent CLI invokation would be trunk serve --port=80
.
The final configuration layer is the CLI itself. Any arguments / options provided on the CLI will take final precedence over any other config layer.
Trunk ships with a built-in proxy which can be enabled when running trunk serve
. There are two ways to configure the proxy, each discussed below. All Trunk proxies will transparently pass along the request body, headers, and query parameters to the proxy backend.
The trunk serve
command accepts two proxy related flags.
--proxy-backend
specifies the URL of the backend server to which requests should be proxied. The URI segment of the given URL will be used as the path on the Trunk server to handle proxy requests. E.G., trunk serve --proxy-backend=http://localhost:9000/api/
will proxy any requests received on the path /api/
to the server listening at http://localhost:9000/api/
. Further path segments or query parameters will be seamlessly passed along.
--proxy-rewrite
specifies an alternative URI on which the Trunk server is to listen for proxy requests. Any requests received on the given URI will be rewritten to match the URI of the proxy backend, effectively stripping the rewrite prefix. E.G., trunk serve --proxy-backend=http://localhost:9000/ --proxy-rewrite=/api/
will proxy any requests received on /api/
over to http://localhost:9000/
with the /api/
prefix stripped from the request, while everything following the /api/
prefix will be left unchanged.
The Trunk.toml
config file accepts multiple [[proxy]]
sections, which allows for multiple proxies to be configured. Each section requires at least the backend
field, and optionally accepts the rewrite
field, both corresponding to the --proxy-*
CLI flags discussed above.
As it is with other Trunk config, a proxy declared via CLI will take final precedence and will cause any config file proxies to be ignored, even if there are multiple proxies declared in the config file.
The following is a snippet from the Trunk.toml
file in this repo:
toml
[[proxy]]
rewrite = "/api/v1/"
backend = "http://localhost:9000/"
Anyone and everyone is welcome to contribute! Please review the CONTRIBUTING.md document for more details. The best way to get started is to find an open issue, and then start hacking on implementing it. Letting other folks know that you are working on it, and sharing progress is a great approach. Open pull requests early and often, and please use Github's draft pull request feature.
trunk is licensed under the terms of the MIT License or the Apache License 2.0, at your choosing.