is_january

Rust, WebAssembly 与 Webpack 入门攻略

is_january · 2017-06-28翻译 · 1701阅读 原文链接 wenliangdai审校中

我在 Twitter 上已经看了很多非常棒的#wasm (WebAssembly)的相关内容, 后来在 Hacker News 也是,但是我并不是很清楚它到底是什么,或者说怎么才能开始使用它。因为它很新,Chrome 在去年三月才进行实装,最新的文档又很少,因此在努力尝试运行一些程序的之后,这是我体会到的一些经验:

WebAssembly 是一种为 web 准备的酷炫新颖的二进制格式和编译目标,这意味着你能够把像 C、C++ 和 Rust 这样的语言编译到 .wasm 文件里,并在你的浏览器里执行那部分代码。在大多数情况下,最终代码会明显比 Javscript 体积更小、运行更快

这份指南将会向你展示在一个典型 JS web 应用里安装 Rust、WebAssembly 和 Webpack,目标是能够在浏览器里执行简单的 Rust 代码,当然还有你所了解和喜爱(或讨厌)的 Javascript。

注意: 这些技术一直都在更新,这篇指南使用的是:

  • webpack 3.0.0

  • cargo 0.19.0

  • emcc 1.37.13

这是完成的项目。 如果你注意到有些内容过时了,请用 issuePR 告诉我 😊.


你需要的准备

请根据以下链接来安装:


Install the Emscripten Rust compiler

安装一个带有 Emscripten 支持的rustc 编译器的最新体验版(Nightly version):

 rustup toolchain add nightly
 rustup target add wasm32-unknown-emscripten --toolchain nightly

安装 cmake. cmake 会根据你的平台而有一些差异,选择合适你的选项或者查阅 install page 以获取更多信息:

brew install cmake                  # MacOS, brew
sudo port install cmake             # MacOS, MacPorts
sudo apt-get install cmake          # Debian Linux

安装 Emscripten SDK. 这可能会花一些时间(~花了我 2 个小时):

 cd ~
 wget [https://s3.amazonaws.com/mozilla-games/emscripten/releases/emsdk-portable.tar.gz](https://s3.amazonaws.com/mozilla-games/emscripten/releases/emsdk-portable.tar.gz)
 tar -xvf emsdk-portable.tar.gz
 cd emsdk-portable
 ./emsdk update
 ./emsdk install sdk-incoming-64bit

https://xkcd.com/303/

下一步,我们会把以下目录加入到PATH环境变量中 Next, we’ll need to add the following directories to our PATH environment variable:

~/emsdk-portable
~/emsdk-portable/clang/fastcomp/build_incoming_64/bin
~/emsdk-portable/emscripten/incoming

重新启动终端,然后运行emcc -v以查检 Emscripten 编译器已经安装。


编译并用 Webpack 运行 Rust

让我们创建一个 Rust/Javascript 混合项目:

$ cargo new tutorial --bin --vcs none
$ cd tutorial
$ npm init        # You can just hit enter for every option
$ rustup override set nightly

我们需要安装 webpack, http-server 来显示我们的内容,以及 rust-wasm-loader 来编译和运行 Rust 代码作为 .wasm 模块。

$ npm install --save-dev webpack http-server rust-wasm-loader

还有一些对 package.json 有用的脚本:

{
     "scripts": {
         "compile": "webpack --progress",
         "serve": "http-server"
     }
}

创建 index.html:

 <!DOCTYPE html>
 <html>
 <head>
     <title>Hello World</title>
 </head>
 <body>
     <div></div>
     `&lt;script src="build/bundle.js"&gt;`&lt;/script&gt;
 &lt;/body&gt;
 &lt;/html&gt;

创建 webpack.config.js:

 module.exports = {
     entry: './src/index.js',
     output: {
         filename: 'bundle.js',
         path: __dirname + '/build',
     },
     module: {
         rules: [
             {
                 test: /\.rs$/,
                 use: {
                     loader: 'rust-wasm-loader',
                     options: {
                        // webpack 的 output 相对于项目根目录的路径
                        path: 'build'
                     }
                 }
              }
         ]
     },
     // .wasm Emscripten 生成的胶水代码要求有这些 Node 内建包,
     // 但是并不会在 web 环境中使用。我们告诉 Webpack 不要 resolve 它们
     externals: {
         'fs': true,
         'path': true,
     }
 }

往我们的 src/main.rs 中添加一个我们会从 Javascript 调用的函数:

 fn main() {
     println!("Hello, world!");
 }
 // Functions that you wish to access from Javascript
 // must be marked as no_mangle
 #[no_mangle]
 pub fn add(a: i32, b: i32) -&gt; i32 {
     return a + b
 }

最后,我们在 src/index.js 里写点代码来加载和使用 WebAssembly 模块:

const wasm = require('./main.rs')
wasm.initialize().then(module =&gt; {
     // Create a Javascript wrapper around our Rust function
     const add = module.cwrap('add', 'number', ['number', 'number'])
     console.log('Calling rust functions from javascript!')
     console.log(add(1, 2))
})

运行这些代码以编译和启动项目:

$ npm run compile
$ npm run serve

在浏览器输入 localhost:8080,打开 Javascript 控制台,然后把你疲倦的双眼盯在经过WebAssembly 编译的 Rust 代码的美妙输出结果上!

它显示出来了!

我们成功了! 这是完成的项目. 我希望这个教程能帮助你探索令人激动的 WebAssembly 的世界。以下是一些我找到的有用的资料。如果你有任何的问题/评论/反馈/恐吓邮件(原文 hate-mail,老外的幽默,译者注),请在 Twitter 联系我。


资料

译者is_january尚未开通打赏功能

相关文章