前端视角对Rust的浅析

441次阅读  |  发布于9月以前

概述

本文将从 Rust 的历史,前端的使用场景和业界使用案例一步步带你走进 Rust的世界。并且通过一些简单的例子,了解 Rust 如何应用到前端,提高前端的生产效率。

Rust简史

2006年,软件开发者Graydon HoareMozilla工作期间,开始了Rust作为一个个人项目。根据他在麻省理工技术评论的一次采访,Rust的灵感来自于Hoare公寓楼里一个坏掉的电梯。电梯操作系统的软件崩溃了,Hoare意识到这类问题通常源于程序如何使用内存的问题

通常,这些类型设备的软件是用CC++编写的,但这些语言需要大量的内存管理,可能导致系统崩溃的错误。因此,Hoare着手研究如何创建一种既紧凑又无内存错误的编程语言

Mozilla 于2009年开始赞助这个项目,并且在2010年首次公开。也在同一年,其编译器源代码开始由原本的 OCaml 语言转移到用 Rust 语言,进行自我编译工作,称作“rustc”,并于2011年实际完成。这个可自我编译的编译器在架构上采用了 LLVM 作为它的后端。

第一个有版本号的Rust编译器于2012年1月发布。Rust 1.0是第一个稳定版本,于2015年5月15日发布。

2021年2月8日,AWS、华为、Google、微软以及 Mozilla 宣布成立Rust基金会,并承诺在两年时间里每年投入不少于 100 万美元的预算,以用于 Rust 项目的开发、维护和推广

根据Rust 最新官方新闻,谷歌日前宣布向 Rust 基金会捐款 100 万美元,这笔资金将用于改善 C++ 与 Rust 互操作性。谷歌当前正在使用 Rust 语言重写在 Linux 核心之外的 Android 关键安全组件,从而进一步减少安全漏洞。而在 Android 13 中,就已经有约 21%的新原生代码使用 Rust 语言开发

Rust在前端能够干什么?

Rust为什么大受欢迎

同时大量头部公司比如华为,微软,字节的应用和推广,使得rust快速占领着前端基础设施领域。Webpack、Babel、Prettier 这些热门工具都已有了 Rust 替代方案,且性能有着 10~100 倍的提升。任何能够用 Rust 实现的应用系统,最终都必将用 Rust 实现。

Rust 缺点

  1. 学习曲线陡峭:Rust 拥有复杂的语法和严格的规则,对于初学者来说可能会感到困难和挑战。
  2. 编译时间长:由于 Rust 的编译器进行了大量的静态检查和优化,编译时间可能相对较长,特别是对于大型项目。希望未来 Rust 针对这块做出更多优化
  3. 生态系统相对不太完善:相比其他编程语言,Rust 的生态系统相对较小,可能缺乏一些常见的库和工具。
  4. 错误处理繁琐:Rust 采用了 Result 和 Option 等类型来处理错误和空值,这要求开发人员进行显式的错误处理,导致一些额外的编码工作量。

Rust 生产实践优秀案例

Rust语言在IM客户端的实践 (https://juejin.cn/post/7336022842856177690)

结合了 Rust 语言的优点,成功地解决高并发接待 & 多开。

给 Web 前端工程师看的用 Rust 开发 wasm 组件实战(https://juejin.cn/post/7308434321764794378)

利用 Rust 生成的wasm,处理大量计算的场景,取得很好的收益。(https://juejin.cn/post/7303347466219569203)

Bundler 的设计取舍:为什么要开发 Rspack?

文章作者通过使用了 Webpack、Vite、Esbuild、Rollup 等构建工具,对各个工具的优劣处和设计取舍后决定采用rust提升构建工具的性能。

通过上面几个案例我们可以看到,对于前端我们前端来说,利用 Rust 可以做一些计算量比较大wasm和一些构建工具相关的基础设施收益还是比较大的。当然也可以做跨端应用,可以参考用 Rust 实现跨平台开发(iOS/Android/Web)经验分享(https://zhuanlan.zhihu.com/p/677550790)

Rust 在 WebAssembly 中的应用

WebAssembly 是什么?

WebAssembly 是一门不同于 JavaScript 的语言,WebAssembly 是一门低级的类汇编语言。它有一种紧凑的二进制格式,使其能够以接近原生性能的速度运行,并且为诸如 C++ 和 Rust 等拥有低级的内存模型语言提供了一个编译目标以便它们能够在网络上运行。

wasm二进制内容如下图

如何生成 WebAssembly?

由于 Rust 生态天然支持 WebAssembly,并且有专门的生态去跟踪和优化WebAssembly,我们可以利用 Wasm-Pack 脚手架生成 Wasm 项目。

首先安装 Rust 相关的环境,和 wasm-pack 脚手架

这是一个可以直接将你的 Rust 代码打包成 Npm 包的工具,用法十分简单,只有 4 个命令:

imgPkg hello_wasm.js 就是最终wasm 入口文件,

html中异步引入

const { default: init } = await import("./pkg/hello_wasm.js");
const res = await init();

异步引入 hello_wasm.js 后,会自动加载 hello_wasm_bg.wasm 二进制文件,res 可以获取从二进制得到的变量。间接从获得了从 Rust 语言到 Js 传递,当然 Rust 也可以调用 Js 的方法,可以通过

#[wasm_bindgen(js_namespace = console)]

通过在 Rust 函数或结构体上使用 #[wasm_bindgen] 属性和相应的配置,我们可以将 Rust 代码暴露给 JavaScript 使用,以实现跨语言的交互和调用。在这种情况下,#[wasm_bindgen(js_namespace = console)] 指定了 JavaScript 中的 console 对象的命名空间,使得我们可以使用类似于

console.log() 的方式在 Rust 中输出到 JavaScript 的控制台。

Rust 和 Node 的绑定

哪些功能适合用 Native Addon 来完成

社区已经有成熟的 Napi-rs 来封装 Native Addon。

首先通过安装 Napi-rs 脚手架生成项目

生成的项目大概长这种模样。通过执行 npm run build 我们可以生成 index.js和 napi-demo.darwin-arm64.node 二进制文件。

const demo = require("./index.js");

引入 index.js 就可以获取到 Rust lib.rs 中暴露的变量和方法了。其实像 Swc,Rspack 这些重计算的工具底层也是通过此库进行 Rust 语言和 Nodejs 进行交互的。Rust 提供一些核心底层能力,Node 可以结合现有的生态调用经过 Rust生成二进制文件创造更多性能卓越的应用。

总结

随着前端开发越来越卷,前端基建的效率也将是下一个值得投入的地方。并且随着 Rust 和 WebAssembly 发展,网页应用也有很大的发展空间。最后希望在深入学习 Rust 后,做出一些有意思的应用。

附录

Copyright© 2013-2020

All Rights Reserved 京ICP备2023019179号-8