Skip to content

Commit

Permalink
Merge branch 'trunk-rs:main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
mnemotic authored Aug 27, 2024
2 parents fd21baa + 5008569 commit 4763d66
Show file tree
Hide file tree
Showing 3 changed files with 159 additions and 45 deletions.
4 changes: 4 additions & 0 deletions examples/wasm_threads/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,7 @@ console_error_panic_hook = "0.1.7"
console_log = { version = "1.0.0", features = ["color"] }
log = "0.4.22"
wasm_thread = "0.3.0"

# Optimize all dependencies even in debug builds:
[profile.dev.package."*"]
opt-level = 2
50 changes: 33 additions & 17 deletions examples/wasm_threads/README.md
Original file line number Diff line number Diff line change
@@ -1,47 +1,63 @@
# Support workers with shared memory and one wasm binary
# Web Workers with shared memory, using only a single WASM binary

This is a port of [wasm_threads `simple.rs` example](https://github.com/chemicstry/wasm_thread/tree/main?tab=readme-ov-file#simple).
This is a port of the [wasm_threads `simple.rs` example](https://github.com/chemicstry/wasm_thread/tree/main?tab=readme-ov-file#simple).

It should also work similarly with `wasm-bindgen-rayon` and other packages that use SharedArrayBuffer.

An explanation of that approach is described [here](https://rustwasm.github.io/wasm-bindgen/examples/raytrace.html)
An explanation of this approach is described [here](https://rustwasm.github.io/wasm-bindgen/examples/raytrace.html).

## Limitations

It has a few considerable advantages over the `webworker*` examples, but also considerable disadvantages.
It has some significant advantages over the `webworker*' examples, but also some significant disadvantages.

For starters, this needs Cross Site Isolation (setting 2 headers), which is [required for this approach to workers](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer#security_requirements).
We've added them in the trunk config.
For starters, it requires cross-site isolation (setting 2 headers), which is [required for this approach to workers](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer#security_requirements).
We've added it to the trunk config.

These same headers are also required during deployment. Github pages does not allow setting headers, and alternatives such as using `<meta>` did not work in my testing, so these sites can't be deployed like that. Cloudflare Pages is a free alternative that allows setting headers that worked for me.
These same headers are also required for deployment. Github Pages does not allow setting headers, and alternatives such as using `<meta>` did not work in my tests, so these sites can't be deployed that way. Cloudflare Pages is a free alternative that does allow headers, and it worked for me.

Then it also requires nightly Rust, because [the standard library needs to be rebuild](https://github.com/RReverser/wasm-bindgen-rayon?tab=readme-ov-file#building-rust-code).
It also requires nightly Rust, because [the standard library needs to be rebuilt](https://github.com/RReverser/wasm-bindgen-rayon?tab=readme-ov-file#building-rust-code).

Some libraries might not work correctly like that, since they are written under the assumption of the historially single threaded wasm32 runtimes. `wgpu` has the `fragile-send-sync-non-atomic-wasm` flag, which if set will not work with this. Eg. `egui` sets this flag currently, though it can be removed with a manual, not well tested [patch](https://github.com/9SMTM6/egui/commit/11b00084e34c8b0ff40bac82274291dff64c26db).
Some libraries may not work correctly in this way, as they were written assuming the historical single-threaded wasm32 runtimes. wgpu` has the `fragile-send-sync-non-atomic-wasm` flag which, if set, will not work with this. For example, `egui` currently sets this flag, although it can be removed with a manual, not well tested [patch](https://github.com/9SMTM6/egui/commit/11b00084e34c8b0ff40bac82274291dff64c26db).

Additional limitations are listed [here](https://rustwasm.github.io/wasm-bindgen/examples/raytrace.html#caveats) (some of them might be solved or worked around in libraries). Specifically for `wasm_thread` limitations are explained in the comments in the source code.
Additional restrictions are listed [here](https://rustwasm.github.io/wasm-bindgen/examples/raytrace.html#caveats) (some of which may be solved or worked around in libraries). Limitations specific to `wasm_thread' are explained in the source code comments.

## Advantages

* code sharing
* improves dev experience
* also means that the WASM binary will be shared, which can in the extreme case half the size of the website.
* shared memory between threads
* can be a huge performance win
* Code sharing
* Improves developer experience
* Also means that the WASM binary is shared, which in extreme cases can be half the size of the deployed application.
* Avoids the [web-worker cache-invalidation issue](https://github.com/trunk-rs/trunk/issues/405)
* Memory sharing between threads
* can be a huge performance gain


## Notes on applying this

Note that this requires the [toolchain file](./rust-toolchain.toml) and the [cargo config](.cargo/config.toml).

The `_headers` file and its copy in `index.html` is simply an example of how to set the headers using Cloudflare Pages.

If you get errors such as
If you receive errors such as

> [Firefox] The WebAssembly.Memory object cannot be serialized. The Cross-Origin-Opener-Policy and Cross-Origin-Embedder-Policy HTTP headers can be used to enable this.
> [Chrome] SharedArrayBuffer transfer requires self.crossOriginIsolated.
Then the headers did not set correctly. You can check the response headers on the `/` file in the network tab of the browser developer tools.
Then the headers are not set correctly. You can check the response headers on the `/` file in the Network tab of the browser developer tools.

Errors such as
> InternalError: too much recursion
Were solved in the example by enabling optimizations. It was sufficient to do this on dependencies only, with

```
# in Cargo.toml
# Optimize all dependencies even in debug builds:
[profile.dev.package."*"]
opt-level = 2
```

This will slow down clean rebuilds, but should not affect rebuild speed during normal development.

## Using rust-analyzer

Expand Down
150 changes: 122 additions & 28 deletions site/content/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,128 @@ Trunk supports an optional `Trunk.toml` config file. An example config file is i

Note that any relative paths declared in a `Trunk.toml` file will be treated as being relative to the `Trunk.toml` file itself.

## Trunk Version

Starting with `0.19.0-alpha.2`, it is possible to enforce having a certain
version of trunk building the project.

As new features get added to trunk, this might be helpful to ensure that the
version of trunk building the current is actually capable of doing so. This can
be done using the `trunk-version` (or using the alias `trunk_version`) on the
**root** level of the `Trunk.toml` file.

The version format is a "version requirement", the same format you might know
from Cargo's version field on dependencies as a [Semantic Versioning
constraint](https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#version-requirement-syntax).

This also supports pre-release requirements, which allows to adopt upcoming
features early.

**NOTE:** Versions prior do `0.19.0-alpha.2` currently do not support this
check, and so they will silently ignore such an error for now.


```toml
trunk-version = "^0.20.1"
```

## Build section

The build section has configuration settings for the build process. These
control the arguments passed to Cargo when building the application, and the
generation of the assets.

```toml
[build]
target = "index.html" # The index HTML file to drive the bundling process.
release = false # Build in release mode.
dist = "dist" # The output dir for all final assets.
public_url = "/" # The public URL from which assets are to be served.
filehash = true # Whether to include hash values in the output file names.
inject_scripts = true # Whether to inject scripts (and module preloads) into the finalized output.
offline = false # Run without network access
frozen = false # Require Cargo.lock and cache are up to date
locked = false # Require Cargo.lock is up to date
minify = "never" # Control minification: can be one of: never, on_release, always
no_sri = false # Allow disabling sub-resource integrity (SRI)
```

## Watch section

Trunk has built-in support for watching for source file changes, which triggers
a rebuild and a refresh in the browser. In this section, you can override what
paths to watch and set files to be ignored.

```toml
[watch]
watch = [] # Paths to watch. The `build.target`'s parent folder is watched by default.
ignore = [] # Paths to ignore.
```

## Server section

Trunk has a built-in server for serving the application when running `trunk serve`.
This section lets you override how this works.

```toml
[serve]
addresses = ["127.0.0.1"] # The address to serve on.
port = 8080 # The port to serve on.
open = false # Open a browser tab once the initial build is complete.
no_spa = false # Whether to disable fallback to index.html for missing files.
no_autoreload = false # Disable auto-reload of the web app.
no_error_reporting = false # Disable error reporting
ws_protocol = "ws" # Protocol used for autoreload WebSockets connection.
# Additional headers set for responses.
headers = { "test-header" = "header value", "test-header2" = "header value 2" }
# The certificate/private key pair to use for TLS, which is enabled if both are set.
tls_key_path = "self_signed_certs/key.pem"
tls_cert_path = "self_signed_certs/cert.pem"
```

## Clean section

The clean section controls the behaviour when running `trunk clean`, which will
remove build artifacts.

```toml
[clean]
dist = "dist" # The output dir for all final assets.
cargo = false # Optionally perform a cargo clean.
```

## Proxy section

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` and `ws` fields, both
corresponding to the `--proxy-*` CLI flags discussed below.

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.

```toml
[[proxy]]
backend = "https://localhost:9000/api/v1" # Address to proxy requests to
ws = false # Use WebSocket for this proxy
insecure = false # Disable certificate validation
no_system_proxy = false # Disable system proxy
rewrite = "" # Strip the given prefix off paths
```

## Hooks section

Hooks are tasks that are run before, during or after the build. You can run
arbitrary commands here, and you can specify multiple hooks to run.

```toml
[[hooks]]
stage = "post_build" # When to run hook, must be one of "pre_build", "build", "post_build"
command = "ls" # Command to run
command_arguments = [] # Arguments to pass to command
```

# Environment Variables
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 invocation would be `trunk serve --port=80`.

Expand All @@ -36,31 +158,3 @@ The `trunk serve` command accepts two proxy related flags.

`--proxy-ws` specifies that the proxy is for a WebSocket endpoint.

## Config File
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` and `ws` fields, 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 the Trunk repo:

```toml
[[proxy]]
rewrite = "/api/v1/"
backend = "http://localhost:9000/"
```

### Required version

Starting with `0.19.0-alpha.2`, it is possible to enforce having a certain version of trunk building the project.

As new features get added to trunk, this might be helpful to ensure that the version of trunk building the current
is actually capable of doing so. This can be done using the `trunk-version` (or using the alias `trunk_version`) on
the **root** level of the `Trunk.toml` file.

The version format is a "version requirement", the same format you might know from Cargo's version field on
dependencies.

This also supports pre-release requirements, which allows to adopt upcoming features early.

**NOTE:** Versions prior do `0.19.0-alpha.2` currently do not support this check, and so they will silently ignore
such an error for now.

0 comments on commit 4763d66

Please sign in to comment.