对,您没看错,速度杠杠的,秒杀任何前端技术,这就是webassembly(wasm)。

Webassembly是浏览器的字节码技术。这项技术使原生代码C/C++/Rust可以编译为wasm,并运行于浏览器上。相比原生开发,它跨平台,安全;相比js,它拥有显著的性能优势。

废话少说,直接看demo

这是我机器上跑的几个简单的算法做的测试,我的天,这可不止一倍啊。(两种实现保证完全一致,代码可以到这里围观)

温馨提示:demo移动端暂时打不开,性能测试需要很多内存呢,你的小手机吃不消吧...

这么🐂x的技术,怎么快速上手呢?我们接下来试一试。

安装依赖💾

快速起步🚀

npm init rust-webpack my-app
cd my-app
npm start

过程顺利的话,现在我们应该看到浏览器里面wasm文件的加载和从wasm输出的信息。
WX20190313-092446

温馨提示:npm start过程需要下载和编译wasm,请等待webpack打包完成信息出现,再打开localhost:8080。

撸代码👋

例子🌰跑起来了,接下来我们撸一撸刚才发生了什么

刚才我们的npm init命令从模板生成的代码结构如下:
WX20190313-093051

里面有个奇怪的crate文件夹,这个就是rust的项目目录。

rust的包都叫crate,因为所有rust包都来自一个叫crates.io的网站。

接下来,我们翻开我们的入口js文件index.js里面只有这么几行。
WX20190313-093308

它从rust包内部的一个pkg的目录导入了js代码,并执行了run函数。

看来所有黑魔法都在这个pkg包里面喽😈。

解密pkg包🧐

WX20190313-103415
pkg包
前端同学看到这个pkg目录一定感到亲切对吧?对,这个是一个正宗的npm包,是这个crate文件夹的rust项目被wasm-pack工具编译出wasm的产物。

从package.json中的module字段,我们知道这个pkg包的入口是rust_webpack.js文件。

WX20190313-093533
rust_webpack.js

而里面的run函数其实只是调用了rust_webpack_bg模块的run方法。这个rust_webpack_bg模块又是什么呢?

rust_webpack_bg.d.ts吗?很显然不是的,这个只是typescript的接口定义文件,没有实现的哦。

那就只剩一个wasm文件了。对!是rust_webpack_bg.wasm webassembly文件!run是wasm文件导出的方法!😱

WHAT? 什么时候js可以直接依赖wasm了?webpack又是什么时候支持wasm打包了?

WX20190313-100353
webpack的package.json
webpack的package.json说明的确是支持wasm的。

为了解决我们的疑惑,我们还是来扒一扒吧。

git clone https://github.com/webpack/webpack.git
git blame ...
若干命令过后...

我发现是从版本v4.8.0开始加入这几个单独的webassemblyjs包依赖的。其实,在此之前也是支持的,只是都是experimental状态。4.0的发版记录上都有记录。

有没有种要掉队的感觉😱 😱 😱 。有这样的感觉就对了,现在入手rust/C++,拥抱wasm尚为时不晚。 未来只会有越来越多的npm包里面有wasm。

总结🗒

  • webpack已经支持wasm文件打包,导入一个wasm就像导入一个ES6模块。
  • wasm-pack这个工具把rust项目打包成npm包。
  • wasm-pack同时生成了wasm的typescript类型定义,从vscode我们可以直接获得wasm的类型提示信息。
  • wasm-pack可以通过--target nodejs打包出用于Node的npm包。

我们的简单demo就跑起来了,然而要精通wasm开发,对一个前端开发并不容易,需要熟悉一套全新的编程语言,一套全新的技术栈。这里有一些复习资料,各位大神拿走不谢,我们下期再见。