简介
Trunk 是一个用于 Rust 的 WebAssembly (WASM) Web 应用程序打包器。Trunk 使用简单的可选配置模式,通过源 HTML 文件来构建和打包 WASM、JS 代码片段以及其他资源(图像、css、scss)。
或者用外行的话来说:锈迹斑斑的东西进去,网络化的东西出来。
开始入门
以下小节将解释安装和使用 trunk
所需的条件,以及如何开始一个基本项目。
先决条件
虽然 trunk
尝试在需要时自动获取工具(除非您使用 --offline
运行),但根据您的环境,可能需要一些先决条件。
锈
这可能是显而易见的,但 trunk
需要安装 Rust。不仅在从源代码安装 trunk
本身时需要,而且在将基于 Rust 的项目编译为 WebAssembly 时也需要。
Rust 的安装说明可能因您的操作系统而异,一个合理的默认方法来自 Rust 项目:https://rust-lang.net.cn/learn/get-started
安装完成后,您应该在命令行中使用以下工具
rustup
cargo
WebAssembly 目标
默认情况下,Rust 安装只会安装您当前机器的目标。但是,在本例中,我们想要交叉编译到 WebAssembly。因此,需要安装目标 wasm32-unknown-unknown
。假设您已使用标准流程安装了 Rust 并且可以使用 rustup
,则可以使用以下命令添加目标
rustup target add wasm32-unknown-unknown
安装
trunk
是一个标准的 Rust 命令行工具,可以使用标准的 Rust 工具(cargo
)、下载预编译的二进制文件或通过一些发行版包管理器进行安装。
从源代码安装
由于 trunk
使用标准的 Rust 构建和发布流程,因此您可以像“标准方式”一样安装 trunk
。以下部分将给出一些示例。
trunk
支持构建时功能,它们是
rustls
(默认)- 使用 rustls 作为客户端和服务器套接字
native-tls
- 启用系统原生 TLS 堆栈用于客户端套接字,并启用 `openssl` 用于服务器套接字
update_check
(默认)- 启动时启用更新检查
从 crates.io 安装发布版本
由于 trunk
在 crates.io 上发布,因此可以通过简单地执行以下命令来安装
cargo install --locked trunk
直接从 git 安装
使用 cargo
您也可以直接从 git 安装
cargo install --git https://github.com/trunk-rs/trunk trunk
这将构建并安装 main
分支的最新提交。您还可以选择特定的提交
cargo install --git https://github.com/trunk-rs/trunk trunk --rev <commit>
或特定的标签
cargo install --git https://github.com/trunk-rs/trunk trunk --tag <tag>
从本地目录安装
假设您已检出 trunk
存储库,即使有本地更改,您也可以使用以下命令安装本地构建
cargo install --path . trunk
从 trunk
安装预编译的二进制文件
预编译的发布版本启用了 default
功能。
从 GitHub releases 下载
trunk
在发布过程中发布了适用于各种平台的编译二进制文件。它们可以在 trunk
的 GitHub 发布区 中找到。只需像平常一样下载并解压二进制文件即可。
使用 cargo binstall
cargo-binstall
允许以更方便的方式安装预编译的二进制文件。给定某个模式,它可以从 crates.io 检测版本,然后从 GitHub 发布版本中获取匹配的二进制文件。trunk
支持此模式。因此,假设您已经安装了 cargo-binstall
,您可以简单地运行
cargo binstall trunk
发行版
Trunk 由不同的发行版发布。在大多数情况下,发行版将构建自己的二进制文件,并且可能不保留默认功能标志。也可能是最新版本的更新可能会因发行版的发布流程而延迟。
由于发行版将有自己的更新管理,因此 Trunk 的更新检查很可能被禁用。
Brew
trunk
可以使用 brew
,可以使用以下命令安装
brew install trunk
Fedora
从 Fedora 40 开始,可以通过执行以下命令安装 trunk
sudo dnf install trunk
Nix OS
使用 Nix,可以使用以下命令安装 trunk
nix-env -i trunk
更新检查
起始版本:0.19.0-alpha.2
。
Trunk 内置了更新检查。默认情况下,它将在 crates.io
上检查 trunk
crate 是否有较新(非预发布)版本。如果找到,信息将显示在命令行中。
可以通过禁用 cargo 功能 update_check
来完全禁用此检查。也可以在运行时使用环境变量 TRUNK_SKIP_VERSION_CHECK
或使用命令行开关 --skip-version-check
来禁用它。
与 crates.io
的实际检查仅每 24 小时执行一次。
一个基本项目
为了构建 Web 应用程序,trunk
运行工具的组合,主要是 cargo build
和 wasm-bindgen
。因此,拥有一个简单的 cargo
项目和一个 index.html
文件作为入口点就足以让您入门。
创建项目
首先创建一个新的 Rust 项目并切换到该文件夹
cargo new trunk-hello-world
cd trunk-hello-world
为 Web 添加一些依赖项
cargo add wasm-bindgen console_error_panic_hook
cargo add web_sys -F Window,Document,HtmlElement,Text
在新建的项目中,创建一个文件 src/main.rs
,内容如下
use web_sys::window; fn main() { console_error_panic_hook::set_once(); let document = window() .and_then(|win| win.document()) .expect("Could not access the document"); let body = document.body().expect("Could not access document.body"); let text_node = document.create_text_node("Hello, world from Vanilla Rust!"); body.append_child(text_node.as_ref()) .expect("Failed to append text"); }
在项目根目录中创建一个 index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<title>Hello World</title>
</head>
<body>
</body>
</html>
然后,在该项目内启动 trunk
以进行构建和服务
trunk serve --open
这应该编译项目,运行 wasm_bindgen
,并基于原始文件创建一个 index.html
,该文件加载并初始化应用程序。
应用程序本身非常基础,只是获取文档的正文并添加一个注释。
下一步
很可能,您不想手动更新应用程序的 DOM 树。您可能想要添加一些资源、调整构建过程、使用更多浏览器 API、执行一些 HTTP 请求、使用现有的 crate 用于 Web,甚至可能与 JavaScript 世界交互。但是,所有这些都是对我们刚刚创建的基本项目的扩展。
这里有一些提示
命令
Trunk 附带一组 CLI 命令,可帮助您进行开发工作流程。
build
trunk build
运行 cargo 构建,目标为 wasm32 指令集,在构建的 WASM 上运行 wasm-bindgen
,并为目标 index.html
中定义的任何资源生成资源构建管道。
Trunk 利用 Rust 强大的并发原语来实现最大的构建速度和吞吐量。
watch
trunk watch
执行与 trunk build
相同的操作,但也监视文件系统中的更改,并在检测到更改时触发新的构建。
serve
trunk serve
执行与 trunk watch
相同的操作,但也启动一个 Web 服务器。
clean
trunk clean
清理由早期构建生成的任何构建工件。
config show
trunk config show
打印出 Trunk 的当前配置,在考虑 CLI 参数之前。非常适合测试和调试。
tools show
trunk tools show
打印出有关 trunk 和项目所需工具的信息。它显示了预期哪些工具以及找到了哪些工具。
配置
Trunk 的配置在 0.21.0 版本中发生了巨大变化。目标不是破坏任何东西,但这可能还是发生了。分层系统现在的工作方式也略有不同。
也可能是文档仍然只提到 Trunk.toml
。如果是这种情况,那么现在这也包括所有其他配置文件变体。
Trunk 支持分层配置系统。基础来自一组合理的默认值,被配置文件覆盖,然后被命令行参数覆盖。
从技术上讲,有一个项目配置结构,它具有合理的默认值。Trunk 将尝试查找配置文件并将其加载到此结构中。然后,它将使用来自命令行解析器的设置(包括环境变量)覆盖此配置。
配置文件
Trunk 将尝试查找配置文件。可以在本地目录中,也可以使用全局参数 --config
,它可以接受文件或目录。如果参数是文件,则将直接使用此文件。否则,Trunk 将加载找到的第一个文件,搜索
Trunk.toml
.trunk.toml
Trunk.yaml
.trunk.yaml
Trunk.json
.trunk.json
如果找不到这些文件中的任何一个,Trunk 将使用来自 Cargo.toml
的元数据,默认情况下,该元数据是一个空集。
配置文件的目录将成为项目根目录,所有相对文件都将基于该项目根目录进行解析。
格式
Trunk 的配置仅限于 JSON 兼容模型。这意味着您可以轻松地在这些不同的格式之间进行转换。
例如,具有以下 Trunk.toml
配置
[build]
dist = "dist"
[serve]
port = 8080
在 YAML 中将是以下内容
build:
dist: "dist"
serve:
port: 8080
此外,Cargo.toml
也基于该模型。但是,它将数据向下移动到 package.metadata.trunk
部分。上面的示例将变为
[package.metadata.trunk.build]
dist = "dist"
[package.metadata.trunk.serve]
port = 8080
命令行参数(和环境变量)
命令行参数可以覆盖部分配置。并非所有配置方面都可以被命令行参数覆盖。命令行参数包括环境变量的使用。
Trunk 在所有级别的命令和子命令上都支持 --help
。这将向您显示可用选项,以及要使用的环境变量的名称。
所有相对路径都将根据项目根目录进行解析,项目根目录通过加载配置进行评估。
从 0.21.0 之前的版本迁移到向前发展的最佳方法
虽然目标是支持 Trunk.toml
、命令行参数以及环境变量中的所有字段,但这仍然是一个破坏 API 的版本。在某些情况下,它只是没有多大意义,因此这些字段被标记为“已弃用”。它们今天会触发警告,并可能在接下来的版本之一中删除。
理想情况下,您无需更改任何内容。在某些理想情况下,您甚至不需要任何配置。如果您需要配置,那么您现在有更多选择。您可以继续使用 TOML,您可以使用 .trunk.*
变体隐藏它。您可以使用 YAML 或 JSON 来利用生成的 JSON 模式。或者,如果您喜欢将所有内容都放在 Cargo.toml
中,那也可以。选择权在您手中。
但是,在使用旧版本的 Trunk 时,您需要注意。如果您将旧版本的 Trunk(0.21.0 之前)与使用较新配置文件的项目一起使用,则该版本将不考虑这些文件,并且可能由于缺少 Trunk.toml
文件而考虑默认设置。
所需版本
从 0.19.0-alpha.2
开始,可以强制要求使用特定版本的 trunk 构建项目。
随着新功能添加到 trunk 中,这可能有助于确保构建当前的 trunk 版本实际上能够做到这一点。这可以使用 Trunk.toml
文件的根级别的 trunk-version
(或使用别名 trunk_version
)来完成。
版本格式是“版本要求”,与您可能从 Cargo 的依赖项版本字段中了解到的格式相同。
这也支持预发布版本要求,这允许尽早采用即将推出的功能。
配置模式
Trunk 为配置模型提供了一个 JSON 模式。可以使用以下语法将其添加到例如 YAML 文件中
$schema: "./schema.json"
获取模式
您可以通过运行以下命令生成模式
trunk config generate-schema
或直接将其写入文件
trunk config generate-schema path/to/file
编辑器/IDE 支持
您的编辑器/IDE 需要支持此功能。Trunk 仅提供模式。以下部分提供有关如何使用它的一些信息。
IntelliJ(及同类产品)
基于 IntelliJ 的 IDE(包括 Rust Rover)确实支持 YAML 和 JSON 文件中的 JSON 模式。您只需要引用模式,例如
$schema: "./schema.json"
钩子
如果您发现您需要 Trunk 执行直接不支持的额外构建操作,那么可以使用 Trunk 灵活的钩子系统在管道的各个阶段启动外部进程。
构建步骤
这是 Trunk 构建过程的简要概述,目的是描述何时执行钩子。请注意,确切的顺序将来可能会更改以添加新功能。
- 步骤 1 — 读取和解析 HTML 文件。
- 步骤 2 — 生成要构建的所有资源的计划。
- 步骤 3 — 并行构建所有资源。
- 步骤 4 — 完成并将资源写入暂存目录。
- 步骤 5 — 将 HTML 写入暂存目录。
- 步骤 6 - 将
dist
目录内容替换为暂存目录内容。
钩子阶段与此对应如下
pre_build
:发生在步骤 1 之前。build
:与步骤 3 同时发生,与资源构建并行执行。post_build
:发生在步骤 5 之后和步骤 6 之前。
钩子执行
钩子可以专门在 Trunk.toml
中声明,并且由 stage
、command
和 command_arguments
组成
stage
:(必需)pre_build
、build
或post_build
之一。它指定在 Trunk 的构建管道中何时执行钩子。command
:(必需)所需可执行文件的名称或路径。command_arguments
:(可选,默认为无)要按给定顺序传递给可执行文件的任何参数。
在每个阶段的相关点,该阶段的所有钩子都会同时生成。在此之后,Trunk 会立即等待所有钩子退出后再继续,除了 build
阶段的情况,如下所述。
所有钩子都使用与 trunk 相同的 stdin
和 stdout
执行。可执行文件应返回错误代码 0
以指示成功。任何其他代码都将被视为错误并终止构建过程。此外,以下环境变量提供给进程
TRUNK_PROFILE
:正在使用的构建配置文件。当前为debug
或release
。TRUNK_HTML_FILE
:Trunk 使用的 HTML 文件的完整路径(通常是TRUNK_SOURCE_DIR
中的index.html
)。TRUNK_SOURCE_DIR
:Trunk 使用的源目录的完整路径。这始终是TRUNK_HTML_FILE
所在的目录。TRUNK_STAGING_DIR
:Trunk 暂存目录的完整路径。TRUNK_DIST_DIR
:Trunk dist 目录的完整路径。TRUNK_PUBLIC_URL
:Trunk 配置的公共 URL。
特定于操作系统的覆盖
通常,您希望在不同的操作系统上执行相同的构建步骤,这需要不同的命令。一个典型的例子是在 Linux 上使用 sh
命令,但在 Windows 上使用 cmd
。为了适应这一点,您可以选择为每个钩子创建特定于操作系统的覆盖。为此,请指定默认钩子,然后在正下方创建一个 [hooks.<os>]
条目,其中 <os>
可以是 windows
、macos
或 linux
之一。在此条目中,您必须仅指定 command
和 command_argumnets
键。您可以为每个钩子提供多个覆盖。即,一个用于 windows
,一个用于 macos
,一个用于 linux
。
资源
声明要由 Trunk 处理的资源既简单又可扩展。
链接资源类型
要由 Trunk 处理的所有链接资源必须遵循以下三个规则
- 必须声明为有效的 HTML
link
标签。 - 必须具有属性
data-trunk
。 - 必须具有属性
rel="{type}"
,其中{type}
是下面列出的资源类型之一。
这通常看起来像:<link data-trunk rel="{type}" href="{path}" ..其他选项在这里.. />
。下面描述的每种资源类型都指定了其资源类型的必需属性和可选属性。所有 <link data-trunk .../>
HTML 元素都将被关联管道的输出 HTML 替换。
rust
✅ rel="rust"
:Trunk 将编译指定的 Cargo 项目作为 WASM 并加载它。这是可选的。如果未指定,Trunk 将在源 HTML 文件的父目录中查找 Cargo.toml
。
href
:(可选)Rust 项目的Cargo.toml
的路径。如果指定了目录,则 Trunk 将在给定目录中查找Cargo.toml
。如果未指定值,则 Trunk 将在源 HTML 文件的父目录中查找Cargo.toml
。data-target-name
:(可选)要加载的目标工件的名称。如果 Cargo 项目有多个目标(二进制文件和库),则可以使用此值选择应由 trunk 使用的目标。data-bin
:(可选)要编译和加载的二进制文件的名称。如果 Cargo 项目有多个二进制文件,则可以使用此值指定应编译(使用--bin
)并由 trunk 使用的特定二进制文件。这隐式地包括data-target-name
。data-type
:(可选)指定应如何将二进制文件加载到项目中。可以设置为main
或worker
。main
是默认值。只能有一个main
链接。对于 worker,将创建一个 wasm-bindgen javascript 包装器和 wasm 文件(带有_bg.wasm
后缀),以二进制名称(如果提供)或项目名称命名。请参阅 Web Worker 示例,了解如何加载它们。data-cargo-features
:(可选)要激活的 cargo 功能的空格或逗号分隔列表。data-cargo-no-default-features
:(可选)禁用默认的 Cargo 功能。data-cargo-all-features
:(可选)启用所有 Cargo 功能。- 与
data-cargo-features
和data-cargo-no-default-features
都不兼容。
- 与
data-wasm-opt
:(可选)使用设置的优化级别运行 wasm-opt。可能的值为0
、1
、2
、3
、4
、s
、z
或 空值(表示 wasm-opt 的默认值)。将此选项设置为0
可显式禁用 wasm-opt。值1-4
是速度越来越快的优化级别。s
和z
(z 表示更多优化)优化二进制文件大小。仅在--release
模式下使用。data-wasm-opt-params
:(可选)使用其他参数运行 wasm-opt。仅在--release
模式下使用。data-keep-debug
:(可选)指示wasm-bindgen
在最终 WASM 输出中保留调试信息,即使在--release
模式下也是如此。这可能与 wasm-opt 的使用冲突,因此为了确保安全,建议在使用此选项时设置data-wasm-opt="0"
。data-no-demangle
:(可选)指示wasm-bindgen
不要解构 Rust 符号名称。data-reference-types
:(可选)指示wasm-bindgen
启用 引用类型。data-weak-refs
:(可选)指示wasm-bindgen
启用 弱引用。data-typescript
:(可选)指示wasm-bindgen
输出 Typescript 绑定。默认为 false。data-bindgen-target
:(可选)指定wasm-bindgen
标志--target
的值(有关可能的值,请参见链接)。默认为no-modules
。主要用例是切换到web
和data-type="worker"
,这降低了向后 兼容性,但具有一些 优势。data-loader-shim
:(可选)指示trunk
为 Web Worker 创建加载器 shim。默认为 false。data-cross-origin
:(可选)加载代码和脚本资源时的crossorigin
设置。默认为纯anonymous
。data-integrity
:(可选)代码和脚本资源的integrity
摘要类型。默认为纯sha384
。data-wasm-no-import
:(可选)默认情况下,Trunk 将生成从 Rust 导出的函数的导入。启用此标志将禁用此功能。默认为 false。data-wasm-import-name
:(可选)全局变量的名称,WASM 导入的函数将在其中可用(在window
对象下)。默认为wasmBindings
(这使它们可以通过window.wasmBindings.<functionName>
访问)。data-target-path
:(可选)输出放置在 dist 目录内的路径。如果不存在,则目录放置在 dist 根目录中。路径必须是相对路径,不带..
。data-initializer
:(可选)初始化器的(模块)JavaScript 文件的路径。data-cargo-profile
:(可选)要使用的 cargo 配置文件,而不是默认配置文件,用于发布或开发模式。data-cargo-profile-release
:(可选)要使用的 cargo 配置文件,而不是默认配置文件,用于发布模式。覆盖data-cargo-profile
设置。data-cargo-profile-dev
:(可选)要使用的 cargo 配置文件,而不是默认配置文件,用于开发模式。覆盖data-cargo-profile
设置。
sass/scss
✅ rel="sass"
或 rel="scss"
:Trunk 使用官方的 dart-sass 进行编译。只需从您的源 HTML 链接到您的 sass 文件,Trunk 将处理其余的事情。此内容已哈希处理以进行缓存控制。href
属性必须包含在指向要处理的 sass/scss 文件的链接中。
data-inline
:(可选)此属性将来自 SASS/SCSS 文件的已编译 CSS 内联到<style>
标签中,而不是使用<link rel="stylesheet">
标签。data-integrity
:(可选)代码和脚本资源的integrity
摘要类型。默认为纯sha384
。data-target-path
:(可选)输出放置在 dist 目录内的路径。如果不存在,则目录放置在 dist 根目录中。路径必须是相对路径,不带..
。
css
✅ rel="css"
:Trunk 将复制在源 HTML 中找到的链接 css 文件,而无需内容修改。此内容已哈希处理以进行缓存控制。href
属性必须包含在指向要处理的 css 文件的链接中。
- 将来,Trunk 将解析本地
@imports
,将处理缩小(请参阅 trunk#7),我们甚至可能会研究一种模式,其中源树中找到的任何 CSS 都将被捆绑,这将启用一个不错的零配置“组件样式”模式。有关更多详细信息,请参阅 trunk#3。 data-integrity
:(可选)代码和脚本资源的integrity
摘要类型。默认为纯sha384
。data-no-minify
:(可选)选择退出缩小。另请参阅:缩小。data-target-path
:(可选)输出放置在 dist 目录内的路径。如果不存在,则目录放置在 dist 根目录中。路径必须是相对路径,不带..
。
tailwind
✅ rel="tailwind-css"
:Trunk 使用官方的 tailwindcss cli 进行编译。只需从您的源 HTML 链接到您的 tailwind css 文件,Trunk 将处理其余的事情。此内容已哈希处理以进行缓存控制。href
属性必须包含在指向要处理的 sass/scss 文件的链接中。
data-inline
:(可选)此属性将来自 tailwind 编译的已编译 CSS 内联到<style>
标签中,而不是使用<link rel="stylesheet">
标签。data-integrity
:(可选)代码和脚本资源的integrity
摘要类型。默认为纯sha384
。data-no-minify
:(可选)选择退出缩小。另请参阅:缩小。data-target-path
:(可选)输出放置在 dist 目录内的路径。如果不存在,则目录放置在 dist 根目录中。路径必须是相对路径,不带..
。
icon
✅ rel="icon"
:Trunk 将在 href
属性中指定的图标图像复制到 dist
目录。此内容已哈希处理以进行缓存控制。
data-integrity
:(可选)代码和脚本资源的integrity
摘要类型。默认为纯sha384
。data-no-minify
:(可选)选择退出缩小。另请参阅:缩小。data-target-path
:(可选)输出放置在 dist 目录内的路径。如果不存在,则目录放置在 dist 根目录中。路径必须是相对路径,不带..
。
inline
✅ rel="inline"
:Trunk 将 href
属性中指定的文件内容内联到 index.html
中。此内容被完全复制,不执行哈希处理。
type
:(可选)– 如果不存在,则类型由文件扩展名推断。html
,svg
css
:包装在style
标签中的 CSSjs
:包装在script
标签中的 JavaScriptmjs
,module
:包装在带有type="module"
的script
标签中的 JavaScript
copy-file
✅ rel="copy-file"
:Trunk 将 href
属性中指定的文件复制到 dist
目录。此内容被完全复制,不执行哈希处理。
data-target-path
:(可选)输出放置在 dist 目录内的路径。如果不存在,则目录放置在 dist 根目录中。路径必须是相对路径,不带..
。
copy-dir
✅ rel="copy-dir"
:Trunk 将递归复制 href
属性中指定的目录到 dist
目录。此内容被完全复制,不执行哈希处理。
data-target-path
:(可选)输出放置在 dist 目录内的路径。如果不存在,则目录放置在 dist 根目录中。路径必须是相对路径,不带..
。
脚本资源类型
脚本资源更加多样化。
脚本资源
由 Trunk 处理的经典脚本资源必须遵循以下三个规则
- 必须声明为有效的 HTML
script
标签。 - 必须具有属性
data-trunk
。 - 必须具有属性
src
,指向脚本文件
一个有效的 HTML script
标签始终具有结束标签(如 <script></script>
)。一个自闭合的脚本标签(如 <script />
)是不是一个有效的 HTML 脚本标签,将触发警告,并可能创建一个无法正常工作的 HTML 文件。
这通常看起来像:<script data-trunk src="{path}" ..其他选项在这里..></script>
。所有 <script data-trunk ...></script>
HTML 元素都将被关联管道的输出 HTML 替换。
Trunk 将复制在源 HTML 中找到的脚本文件,而无需内容修改。此内容已哈希处理以进行缓存控制。src
属性必须包含在指向要处理的脚本文件的脚本中。
data-no-minify
:(可选)选择退出缩小。另请参阅:缩小。data-target-path
:(可选)输出放置在 dist 目录内的路径。如果不存在,则目录放置在 dist 根目录中。路径必须是相对路径,不带..
。
JS 代码片段
从 wasm-bindgen JS 代码片段功能 生成的 JS 代码片段会自动复制到 dist 目录,哈希处理并准备就绪。无需额外设置。只需在您的应用程序中使用该功能,Trunk 将负责其余的工作。
图像和其他资源
图像和其他资源类型可以通过将如下链接添加到您的源 HTML 中来复制到 dist
目录中:<link data-trunk rel="copy-file" href="path/to/image"/>
。支持任何普通文件类型。这将导致 Trunk 查找目标资源,并将其未修改地复制到 dist
目录。不会应用哈希处理。链接本身将从 HTML 中删除。要复制整个资源/图像目录,您可以使用以下 HTML:<link data-trunk rel="copy-dir" href="path/to/images-dir"/>
。
这将允许您的 WASM 应用程序直接从 dist
目录引用图像,并且 Trunk 将确保图像在 dist
目录中可用以供服务。
随着 Trunk 继续成熟,我们将找到更好的方法来包含图像和其他资源。对内容进行哈希处理以进行缓存控制很棒,我们只需要找到一种与 Rust 组件中引用的图像配合使用的好模式。请在 trunk#9 中参与讨论!在那里见。
指令
您可以指示 Trunk 将传递给 --public-url
的 URL 写入 HTML 输出,方法是将此添加到您的 <head>
中:<base data-trunk-public-url/>
。
Trunk 将元素的 href
属性设置为公共 URL。这更改了相对 URL 的行为,使其相对于公共 URL 而不是当前位置。
您还可以在运行时使用 document.baseURI
访问此值,这对于需要知道它们托管在哪个基本 URL 上的应用程序(例如,用于路由)非常有用。
缩小
Trunk 支持缩小资源。默认情况下禁用此功能,并且可以在不同级别进行控制。
在任何情况下,Trunk 本身都不执行缩小,而是将该过程委托给执行实际实现的依赖项。如果缩小破坏了某些东西,那么很可能是该依赖项的问题。
从 Trunk 0.20.0 开始,默认情况下禁用缩小。可以使用命令行中的 --minify
(或 -M
)开关将其打开。或者,可以使用 Trunk.toml
文件中的 build.minify
字段进行控制。此字段的值是一个枚举,具有以下可能的值:never
(默认,从不缩小)、on_release
(在使用 --release
运行 Trunk 时缩小)、always
(始终缩小)。
启用缩小后,所有 Trunk 已知的资源(这不包括 copy-dir
和 copy-file
对 Trunk 不透明的 blob)都将被缩小。可以使用 data-no-minify
属性在每个资源的基础上选择退出此过程(请参阅各个资源配置)。在这种情况下,资源永远不会被缩小。
子资源完整性
Trunk 可以自动生成文件的哈希值,并为 Web 应用程序获取的资源添加 integrity
属性。默认情况下启用此功能,但可以使用 data-integrity
属性覆盖。请参阅不同的资源类型。
以下值可用
none
sha256
sha384
(默认)sha512
高级
还有一些更高级的主题,将在以下小节中描述。
JavaScript 互操作性
Trunk 将创建必要的 JavaScript 代码来引导和运行基于 WebAssembly 的应用程序。它还将包括由 wasm-bindgen
生成的所有 JavaScript 代码片段,用于与 JavaScript 功能交互。
默认情况下,从 Rust 导出的函数(使用 wasm-bingen
)可以通过全局变量 window.wasmBindings
在 JavaScript 代码中访问。此行为可以禁用,并且可以自定义名称。有关更多信息,请参阅 rust
资源类型。
初始化顺序
绑定仅在应用程序初始化完成后才可用和工作。
如果您的 WebAssembly 应用程序将代码渲染到网页/DOM 树中,然后从 JavaScript 调用到 WebAssembly 应用程序,那么这将不是问题,因为应用程序已经初始化。
但是,如果您想从例如 index.html
文件本身调用 WebAssembly 应用程序,则必须延迟该调用,直到应用程序启动。
这可以通过使用 TrunkApplicationStartup
事件执行该代码来确保。另请参阅 启动事件。
启动事件
当 WebAssembly 应用程序已加载并启动时,Trunk 的初始化代码片段将发出一个事件。
定义
该事件称为 TrunkApplicationStarted
,并在 WebAssembly 加载和初始化后执行。
该事件将具有自定义详细信息
{
wasm // The web assembly instance
}
示例
以下代码片段可用于在 WebAssembly 应用程序初始化后运行代码
<script type="module">
addEventListener("TrunkApplicationStarted", (event) => {
console.log("application started - bindings:", window.wasmBindings, "WASM:", event.detail.wasm);
// wasm_ffi is a function exported from WASM to JavaScript
window.wasmBindings.wasm_ffi();
// You can also run this via the WASM instance in the details
// event.detail.wasm.wasm_ffi();
});
</script>
另请参阅 vanilla 示例:https://github.com/trunk-rs/trunk/tree/main/examples/vanilla。
初始化器
起始版本:0.19.0-alpha.1
。
Trunk 支持接入 WebAssembly 应用程序的初始化过程。默认情况下,这不处于活动状态,并且工作方式与以前的版本相同。
默认过程是 trunk 注入一个小的 JavaScript 代码片段,该代码片段导入由 wasm_bindgen
生成的 JavaScript 加载器并调用 init
方法。这将获取 WASM blob 并运行它。
这样做的缺点是,在此过程中,用户没有任何反馈。无论是在加载 WASM 文件需要更长时间时,还是在出现问题时。
现在可以通过将 data-initializer
设置为 JavaScript 模块文件来接入此过程。此模块文件需要(默认)导出一个函数,该函数返回“initializer”实例。这是一个例子
export default function myInitializer () {
return {
onStart: () => {
// called when the loading starts
},
onProgress: ({current, total}) => {
// the progress while loading, will be called periodically.
// "current" will contain the number of bytes of the WASM already loaded
// "total" will either contain the total number of bytes expected for the WASM, or if the server did not provide
// the content-length header it will contain 0.
},
onComplete: () => {
// called when the initialization is complete (successfully or failed)
},
onSuccess: (wasm) => {
// called when the initialization is completed successfully, receives the `wasm` instance
},
onFailure: (error) => {
// called when the initialization is completed with an error, receives the `error`
}
}
};
有关完整示例,请参阅:https://github.com/trunk-rs/trunk/tree/main/examples/initializer。
库 crate
除了具有 main
函数之外,还可以将您的项目作为 cdylib
项目启动。为此,请将以下内容添加到您的 Cargo.toml
中
[lib]
crate-type = ["cdylib", "rlib"]
接下来,像这样在你的 lib.rs
中定义入口点(不需要是 async
)
#![allow(unused)] fn main() { #[wasm_bindgen(start)] pub async fn run() {} }
基础 URL、公共 URL、路径 & 反向代理
始于:0.19.0-alpha.3
。
最初,trunk
只有一个 --public-url
,它允许设置托管应用程序的基础 URL。简单明了。它是所有生成 URL 的前缀,并作为 trunk serve
的基础。
不幸的是,生活并非如此简单,命名也很难。
现在 trunk
有三个路径
- “公共基础 URL”:充当所有生成 URL 的前缀
- “服务基础路径”:充当
trunk serve
服务的所有内容的范围/前缀 - “WebSocket 基础路径”:充当自动重载 WebSocket 的基础路径
所有三个都可以配置,但都有合理的默认设置。默认情况下,服务基础路径和 WebSocket 基础路径默认为公共基础路径的绝对路径。如果公共基础路径没有斜杠,则会附加一个斜杠。公共基础路径可以是以下之一
- 未设置/无/默认(意味着
/
) - 绝对 URL(例如
http://domain/path/app
) - 绝对路径(例如
/path/app
) - 相对路径(例如
foo
或./
)
如果公共基础路径是绝对 URL,则该 URL 的路径将用作服务基础路径和 WebSocket 基础路径。如果公共基础路径是相对路径,则它将被转换为绝对路径。根据您的环境,这两种方法都可能导致应用程序功能失常。控制台上将显示警告。但是,通过使用 serve-base 或 ws-base 提供显式值,可以解决此问题。
为什么这是必要的?它在什么时候有用?它主要是为了为那些没有考虑到的情况提供所有的旋钮/配置。public-url
的魔力对很多人都有效,但并非对所有人有效。为了支持这种情况,现在可以调整所有设置,但代价是增加了复杂性。对于简单的情况,合理的默认设置应该使其保持简单。
一个用例示例是在 trunk serve
前面的反向代理,它无法配置为在 trunk serve
期望的位置服务 trunk websocket。现在,可以使用 --public-url
在生成链接时选择基础路径,以便在通过代理服务时看起来是正确的。但也可以使用 --serve-base /
来保持从根目录提供资源。
后端代理
Trunk 自带一个内置代理,可以在运行 trunk serve
时启用。有两种配置代理的方法,每种方法将在下面讨论。所有 Trunk 代理都将透明地将请求体、标头和查询参数传递给代理后端。
代理 CLI 标志
trunk serve
命令接受两个与代理相关的标志。
--proxy-backend
指定后端服务器的 URL,请求应代理到该服务器。给定 URL 的 URI 段将用作 Trunk 服务器上处理代理请求的路径。例如,trunk serve --proxy-backend=https://#:9000/api/
会将路径 /api/
上接收到的任何请求代理到侦听 https://#:9000/api/
的服务器。进一步的路径段或查询参数将无缝传递。
--proxy-rewrite
指定 Trunk 服务器侦听代理请求的备用 URI。在给定 URI 上接收到的任何请求都将被重写以匹配代理后端的 URI,从而有效地剥离重写前缀。例如,trunk serve --proxy-backend=https://#:9000/ --proxy-rewrite=/api/
会将 /api/
上接收到的任何请求代理到 https://#:9000/
,同时从请求中剥离 /api/
前缀,而 /api/
前缀之后的所有内容将保持不变。
--proxy-insecure
允许 --proxy-backend
url 对 https 使用自签名证书(或任何官方 无效 证书,包括过期证书)。这适用于代理到 https 时,例如 trunk serve --proxy-backend=https://#:3001/ --proxy-insecure
,其中 ssl 证书是自签名的,例如使用 mkcert,并通过 https 反向代理路由到后端,例如 local-ssl-proxy 或 caddy。
--proxy-no-sytem-proxy
在联系代理后端时绕过系统代理。
--proxy-ws
指定代理用于 WebSocket 端点。
配置文件
Trunk.toml
配置文件接受多个 [[proxy]]
部分,这允许配置多个代理。每个部分至少需要 backend
字段,并且可以选择接受 rewrite
和 ws
字段,这两个字段都对应于上面讨论的 --proxy-*
CLI 标志。
与其他 Trunk 配置一样,通过 CLI 声明的代理将具有最终优先级,并将导致忽略任何配置文件代理,即使配置文件中声明了多个代理。
以下是 Trunk 仓库中 Trunk.toml
文件的一个片段
[[proxy]]
rewrite = "/api/v1/"
backend = "https://#:9000/"
贡献
欢迎任何人贡献!请查看 CONTRIBUTING.md 文档以获取更多详细信息。最好的入门方法是找到一个开放的问题,然后开始着手实现它。让其他人知道您正在处理它并分享进度是一个好方法。尽早并经常打开拉取请求,并请使用 GitHub 的草稿拉取请求功能。