天天看點

全棧程式員的新玩具Rust(六)第一個WASM程式

先上代碼

https://gitee.com/lightsever/rust_study/tree/master/wasm_hello01

webassembly就不用再贅述了,耳朵裡面快磨出繭子來了。

rustwasm是火狐自家的玩具,讓我們來繼續做實驗,讓rust飛起來吧。

環境安裝

安裝好rust環境之後仍然需要 一個 wasm 工具包

cargo install wasm-pack

然後如果想快速建立一個wasm項目模闆可以用這個

cargo generate --git https://github.com/rustwasm/wasm-pack-template

WASM項目

生成後的項目代碼如下

全棧程式員的新玩具Rust(六)第一個WASM程式

#[wasm_bindgen]就是告訴rust,這個函數要麼是導出給js用的,要麼希望從js那拿過來用的。

自然 alert是從js那拿過來用

greet是給js調用的

我們搞helloworld,這裡就先不改了

這個項目用cargo 編譯是生成不了wasm檔案的

要在項目目錄用

wasm-pack build
全棧程式員的新玩具Rust(六)第一個WASM程式

這樣wasm就編譯成功了

全棧程式員的新玩具Rust(六)第一個WASM程式

生成的項目是個npm包,自己生成了膠水代碼,使用非常友善,但是要用webpack打包。

我自己npm都不熟練,我就不去搞這個了。

主要是不能接受暗藏玄機,我們要來搞一搞事情。

*之前了解不夠透徹,這裡補充一下

全棧程式員的新玩具Rust(六)第一個WASM程式

wasm-pack 有四個輸出目标

我是分不清 browser 和 web 有什麼差別,

但是這裡有一個no-modules ,就是他,我們就是不想用打包系統

全棧程式員的新玩具Rust(六)第一個WASM程式

是以我寫了一個批處理來生成這種js,這樣的js我們就不需要改了,使用起來也更友善

後續也不要改動js項目了,使用也更加簡單

全棧程式員的新玩具Rust(六)第一個WASM程式

後面的部分都不需要看了

JS項目

我用TS來搞這個項目,他生成的膠水代碼是個npm包,是以直接放在網站項目裡是不能用的,我們要來改一改。

你或許會有點疑惑都用WASM了?怎麼還要寫js代碼?這是因為WASM不能完全替代js。他需要初始化,丢一些可以import的函數給WASM,要不然WASM啥也不能幹。另外需要JS來調用WASM的某個函數,要不然WASM啥也不會幹。

也就是說,主要是初始化和入口工作,這個工作可以一次性,然後整個網站的邏輯全部用wasm完成。

全棧程式員的新玩具Rust(六)第一個WASM程式

首先是膠水js,這個檔案我們要做三處修改

1.首先

import * as wasm from …

這行删掉,這是告訴js從wasm導入一個子產品,它會被打包程式替換,而我們不想用webpack

2.然後是底下有 export的兩行

把export 和 const 關鍵字删除

全棧程式員的新玩具Rust(六)第一個WASM程式

這裡是導入js函數給wasm的膠水代碼,和導出wasm函數個js的膠水代碼。

同理,原來都是 package系統用的東西

好了,改完了

但這樣wasm從哪裡來?

js在web環境所有的全局變量都是 window 的成員,這樣我們随便從哪都能給他塞進去

然後是膠水的定義.d.ts

全棧程式員的新玩具Rust(六)第一個WASM程式

把export 改為 declare,這就成了一個不依賴打包就能使用的定義檔案啦。

寫我們的app.ts

全棧程式員的新玩具Rust(六)第一個WASM程式

愛用ts,你用js也差不多這樣

1.加載 wasm檔案 為 arraybuffer

2.執行個體化wasm對象

這裡有個小花招,我們直接把window塞了進去,否則你就需要手工構造一個wasm導入的js膠水函數的字典。因為所有的全局對象都是windows的成員,而rustwasm幫我們生成的膠水代碼都是全局定義的,直接丢window進去完事兒。

3.把全局的wasm對象給指派了,這裡直接window[“WASM”]這樣塞進去了。

4.調用wasm入口函數

按照我們編寫的rust代碼,應該alert 出一個  hello peter.

全棧程式員的新玩具Rust(六)第一個WASM程式

誠不欺我。

入口函數和初始化函數一次寫完就不用搞了。

以後隻消生成wasm就是,當然膠水檔案因為我們不是用rustwasm預設的配合webpack的用法,是以我們每次也要改改。但我們的改動其實很機械

1.js檔案,有import的 整行删掉

2.js檔案,export 開頭的,删除 export 和 const關鍵字

3.d.ts 檔案,export開頭的,替換成 declare

回頭寫個腳本,自動辦了就是。

今天有了helloworld,寫個遊戲,就不遠了。