介紹一個WebAssembly的小玩具

名詞解釋區域

WebAssembly是一種新的字節碼格式。它的縮寫是".wasm", .wasm 爲文件名後綴,是一種新的底層安全的二進制語法。。它被定義爲「精簡、加載時間短的格式和執行模型」,而且被設計爲Web 多編程語言目標文件格式。 這意味着瀏覽器端的性能會獲得極大提高,它也使得咱們可以實現一個底層構建模塊的集合,例如,強類型和塊級做用域。html

TypeScript是JavaScript類型的超集,它能夠編譯成純JavaScript。前端

AssemblyScript 是AssemblyScript組織的一個開源項目,該項目將嚴格類型的TypeScript經過Binaryen編譯爲WebAssembly,而且他是一個NodeJs項目,這使咱們前端開發人員寫WebAssembly成爲可能。webpack


關於WebAssembly

首先WebAssembly如今還處於發展階段,從https://caniuse.com/#search=W... 看瀏覽器支持程度較爲通常,另外目前在整個業界還處於嘗試階段,參考WebAssembly在白鷺引擎5.0中的實踐,可是做爲新技術咱們仍是須要及時跟進掌握瞭解。git

clipboard.png

AssemblyScript

AssemblyScript的出現並不意外,能夠說終於等到了這個開源項目的誕生,TypeScript是強類型語言,利用TypeScript去編譯WebAssembly最爲合適,一直以來都堅信這一點終於變成的現實。github

首先想學習AssemblyScript寫法的同窗,請參考 https://github.com/AssemblySc...,本文不在過多說明。注意文檔裏面介紹的一些類型限制,一些類型定義。web

重點是下面向你們介紹一下AssemblyScript的Webpack loader,教你們如何在Webpack中使用AssemblyScript:assemblyscript-typescript-loadertypescript

assemblyscript-typescript-loader

Loader for webpack to compile typescript with AssemblyScript and bundle it to wasm or btyes string。

assemblyscript-typescript-loader能夠將AssemblyScript代碼編譯爲在瀏覽器端運行的wasm文件,主要處理了以下幾種狀況:npm

  1. 將大於limit大小的AssemblyScript打包爲wasm文件。
  2. 將小於limit大小的AssemblyScript直接做爲二進制字符串打包到bundle。
  3. 提供WebAssembly Promise對象的回調。
  4. 對於不支持WebAssembly的瀏覽器作運行時兼容。

安裝

npm i assemblyscript-typescript-loader --save

使用

webpack.config.js編程

module.exports = {
      module: {
        rules: [
          {
                test: /\.ts?$/,
                loader: 'assemblyscript-typescript-loader',
                include:/assemblyscript/,//to avoid a conflict with other ts file who use 'ts-load',so you can division them with prop 'include'
                options: {
                    limit: 1000,
                    name: `static/assembly/[name].[hash:8].wasm`
                }
            }
        ]
      }
    }

注意目前AssemblyScript只能支持將ts後綴的文件進行編譯,可是在工程中可能和其餘的ts文件(非AssemblyScript文件)產生loader衝突,因此請利用「include」和「exclued」屬性對AssemblyScript和原生ts代碼進行區分,參考上面示例。
更多的loader配置請參考官方文檔:https://github.com/SinaMFE/as...瀏覽器

assemblyscript/moduleEntry.ts
注意該文件夾(assemblyscript)專門用於存放assemblyscript代碼入口,防止和項目中其餘typescript代碼衝突。

var w: u32, // width
    h: u32, // height
    s: u32; // total size

/** Initializes width and height. */
export function init(w_: u32, h_: u32): void {
  w = w_;
  h = h_;
  s = w * h;
}

/** Performs one step. */
export function step(): void {
  var hm1 = h - 1,
      wm1 = w - 1;
  for (var y: u32 = 0; y < h; ++y) {
    var ym1 = select<u32>(hm1, y - 1, y == 0),
        yp1 = select<u32>(0, y + 1, y == hm1);
    for (var x: u32 = 0; x < w; ++x) {
      var xm1 = select<u32>(wm1, x - 1, x == 0),
          xp1 = select<u32>(0, x + 1, x == wm1);
      var n = (
        load<u8>(ym1 * w + xm1) + load<u8>(ym1 * w + x) + load<u8>(ym1 * w + xp1) +
        load<u8>(y   * w + xm1)                         + load<u8>(y   * w + xp1) +
        load<u8>(yp1 * w + xm1) + load<u8>(yp1 * w + x) + load<u8>(yp1 * w + xp1)
      );
      if (load<u8>(y * w + x)) {
        if (n < 2 || n > 3)
          store<u8>(s + y * w + x, 0);
      } else if (n == 3)
        store<u8>(s + y * w + x, 1);
    }
  }
}

index.js

import asmPromise from "./assemblyscript/moduleEntry.ts";
asmPromise.then(function(asmModule){
  // here you can use the wasm.exports
  asmModule.step();
})

在業務代碼中引入assemblyscript入口文件,並返回Promise對象,在then中就可使用到WebAssembly標準的輸出。歡迎你們在項目中嘗試哈,若是有問題請在github提issues,多謝。

另外附一些參考資料:

WebAssembly官網(http://webassembly.org/
WebAssembly on MDN(https://developer.mozilla.org...
AssemblyScript Wiki (https://github.com/AssemblySc...
assemblyscript-typescript-loader github (https://github.com/SinaMFE/as...

相關文章
相關標籤/搜索