正如 Lin Clark 在她关于 Rust 和 WebAssembly 的文章中所强调的:WebAssembly 的目标不是取代 JavaScript,而是成为一个与 JavaScript 协同使用的强大工具。为了简化 JavaScript 和 WebAssembly 之间的语言边界,许多令人惊叹的工作已经完成,你可以在 Alex Crichton 关于 wasm-bindgen
的文章 中阅读到所有内容。这篇文章重点关注一种不同的 JavaScript/Rust 集成方式:包生态系统和开发人员工作流程。
Rust 和 JavaScript 都拥有充满活力的包生态系统。Rust 有 cargo 和 crates.io。JavaScript 有 多个 CLI 工具,包括 npm CLI,它们与 npm 仓库 相互作用。为了让 WebAssembly 取得成功,我们需要这两个系统能够很好地协同工作,具体来说
- Rust 开发人员应该能够无需 Node.js 开发环境就能生成供 JavaScript 使用的 WebAssembly 包
- JavaScript 开发人员应该能够无需 Rust 开发环境就能使用 WebAssembly
✨📦 闪亮登场:wasm-pack
。
wasm-pack
是一个用于组装和打包面向 WebAssembly 的 Rust crate 的工具。这些包可以发布到 npm 仓库,并与其他包一起使用。这意味着你可以将它们与 JS 和其他包并行使用,并且在许多类型的应用程序中使用它们,无论是 Node.js 服务器端应用程序、由 Webpack 打包的客户端应用程序,还是任何其他使用 npm 依赖项的应用程序。你可以在 crates.io 和 GitHub 上找到 wasm-pack
。
该工具的开发才刚刚开始,我们很高兴能让更多来自 Rust 和 JavaScript 世界的开发者参与进来。JavaScript 和 Rust 生态系统都专注于开发人员体验。我们深知,一个高效且愉快的生态系统的关键在于能够自动化繁琐任务并让开发者轻松使用的优秀工具。在这篇文章中,我将讨论我们目前所处的阶段、未来的方向、如何开始使用现有的工具,以及如何参与塑造其未来。
💁 今天它可以做什么
今天,wasm-pack
将指导你完成四个基本步骤,以准备将你的 Rust 代码发布为 WebAssembly 包到 npm 仓库
1. 编译为 WebAssembly
wasm-pack
将使用 rustup
添加适当的 WebAssembly 编译目标,并以发布模式将你的 Rust 代码编译为 WebAssembly。
为此,wasm-pack
将
- 根据需要添加
wasm32-unknown-unknown
编译目标 - 使用 wasm 目标以发布模式编译你的 Rust 项目
2. 运行 wasm-bindgen
wasm-pack
封装了 wasm-bindgen
工具的 CLI 部分,并为你运行它!这将执行一些操作,例如将你的 WebAssembly 模块包装在 JS 包装器中,使人们更容易与你的模块进行交互。wasm-bindgen
支持 ES6 模块和 CommonJS,你可以使用 wasm-pack
生成任一类型的包!
为此,wasm-pack
将
- 如果需要,安装或更新
wasm-bindgen
- 运行
wasm-bindgen
,生成新的.wasm
文件和.js
文件 - 将生成的文件移动到新的
pkg
目录
3. 生成 package.json
wasm-pack
读取你的 Cargo.toml
并生成发布你的包到 npm 仓库所需的 package.json
文件。它将
为此,wasm-pack
将
- 复制你的项目
name
和description
- 链接到你的 Rust 项目的
repository
- 在
files
键中列出生成的 JavaScript 文件。这将确保仅这些文件(而不是其他文件)被包含在你的 npm 包中。如果你打算在浏览器中使用此包或包含此包的捆绑包,这对于确保良好的性能尤为重要!
4. 文档
wasm-pack
将复制你的 Rust 项目的 README.md
到它生成的 npm 包中。我们有很多关于进一步扩展它的好想法,以支持 Rust 生态系统的文档功能 rustdoc
- 下一节将对此进行更多介绍!
🔮 未来计划
与 rustdoc
集成
crates.io 团队 调查了开发者,并了解到 良好的文档 是开发者评估 crate 使用时最关注的功能之一。贡献者 Yoshua Wuyts 提出了一个很棒的想法,通过将 wasm-pack
与 Rust API 文档工具 rustdoc
集成来生成更多 README.md
内容。Rust-wasm 团队致力于将 Rust 打造成编写 WebAssembly 的首选语言。为 Rust 生成的 WebAssembly 包提供既易于编写又易于发现的文档与我们的目标完美契合。在 此问题 中详细了解该团队的想法,并加入讨论!
管理和优化你的 Rust 和 JS 依赖关系图
wasm-pack
上的下一项大型开发工作将专注于在编译后的 WebAssembly 中使用自定义段来声明对本地 Javascript 文件或其他 npm 包的依赖关系。
该功能的初步工作已经在 wasm-bindgen
中完成,因此下一步将是将其集成到 wasm-pack
中。简单的集成并不困难 - 但我们很高兴探索能够在多个层面上简化和优化包含 npm 依赖项的 Rust 依赖树的机会!这项工作将类似于 webpack 等捆绑器提供的优化,但在 Rust 依赖项级别进行。
我们还有很多问题需要解答,还需要进行大量巧妙的工程工作。几周后,我们将发布一篇关于此主题的完整文章,敬请关注!
在 Rust 中扩展 Node.js 工具链
该项目的最大也是最雄心勃勃的目标是使用 Rust 重写必要的 npm login
、npm pack
和 npm publish
步骤,以便对于那些在工作流程中没有使用 Node.js 的用户来说,对 Node.js 开发环境的依赖变得可选。正如我们之前所说,我们希望确保 WebAssembly 包的生产者和使用者都能保持在他们熟悉的工作流程中。目前,对于 JavaScript 开发人员来说,这是可行的 - 他们不需要拥有 Rust 开发环境或任何关于 Rust 的知识,就能开始使用使用 wasm-pack
发布的 Rust 生成的 WebAssembly 模块。然而,Rust 开发人员仍然需要安装 Node.js 和 npm 才能使用 wasm-pack
进行发布,我们很高兴通过使用 Rust 编写 npm 包发布器来改变这一点 - 谁知道呢,也许我们最终可以将一些 Rust 元素(也许编译成 WebAssembly!)集成到 npm 客户端中!
与 npm 和捆绑器的进一步合作
我们一直与 npm CLI 团队成员 Kat Marchan 和 Rebecca Turner 以及 webpack 和 Parcel 的开发者保持沟通 - 我们很高兴继续与他们合作,让开发者更容易发布和使用 WebAssembly 代码!
🛠 今天就开始使用它吧!
wasm-pack
目前是一个通过 Cargo 分发的命令行工具。要安装它,请 设置一个 Rust 开发环境,然后运行
cargo install wasm-pack
如果你不确定从哪里开始,我们有一个教程供你参考!本教程 由 Michael Gattozzi 和 Rust-wasm 工作组编写,将引导你完成以下步骤
- 编写一个小的 Rust 库
- 使用
wasm-pack
将其编译为 WebAssembly、打包和发布 - 使用 webpack 进行捆绑以生成一个小型网站
👯♀️贡献
所有优秀的开发者工具的关键在于工具的开发者和在日常工作流程中使用工具的开发者之间快速的反馈循环。为了让 wasm-pack
以及我们所有的 WebAssembly 开发工具取得成功,我们需要来自各行各业、各级技能的开发者参与进来!
查看我们的 贡献者指南 和我们的 问题追踪器(我们定期将问题标记为“适合新手的问题”,并提供导师和指导说明!) - 我们很高兴与你合作!
关于 Ashley Williams
Ashley Williams 是 Integer32 的工程师,为 Mozilla 的 Rust 编程语言提供合同服务。她是 Rust 核心团队的成员,领导 Rust 社区团队,并协助维护 Rust 的包仓库 crates.io。此前,她在 npm(Javascript 的包管理器)担任工程师,目前是 Node.js 基金会董事会的个人会员董事。Ashley 长期从事教学工作,她将大部分精力投入到开源项目的教育计划中,于 2016 年创办了 NodeTogether,目前领导 RustBridge 计划。她代表教师的观点参加了 TC39 会议,影响了 JavaScript 的发展,并继续通过她在 WebAssembly 上的工作对网页发展充满热情。