介绍一个WebAssembly的小玩具
名词解释区域
WebAssembly是一种新的字节码格式。它的缩写是".wasm", .wasm 为文件名后缀,是一种新的底层安全的二进制语法。。它被定义为“精简、加载时间短的格式和执行模型”,并且被设计为Web 多编程语言目标文件格式。 这意味着浏览器端的性能会得到极大提升,它也使得我们能够实现一个底层构建模块的集合,例如,强类型和块级作用域。
TypeScript是JavaScript类型的超集,它可以编译成纯JavaScript。
AssemblyScript 是AssemblyScript组织的一个开源项目,该项目将严格类型的TypeScript通过Binaryen编译为WebAssembly,并且他是一个NodeJs项目,这使我们前端开发人员写WebAssembly成为可能。
关于WebAssembly
首先WebAssembly现在还处于发展阶段,从https://caniuse.com/#search=W... 看浏览器支持程度较为一般,另外目前在整个业界还处于尝试阶段,参考WebAssembly在白鹭引擎5.0中的实践,但是作为新技术我们还是需要及时跟进掌握了解。
AssemblyScript
AssemblyScript的出现并不意外,可以说终于等到了这个开源项目的诞生,TypeScript是强类型语言,利用TypeScript去编译WebAssembly最为合适,一直以来都坚信这一点终于变成的现实。
首先想学习AssemblyScript写法的同学,请参考 https://github.com/AssemblySc...,本文不在过多说明。注意文档里面介绍的一些类型限制,一些类型定义。
重点是下面向大家介绍一下AssemblyScript的Webpack loader,教大家如何在Webpack中使用AssemblyScript:assemblyscript-typescript-loader。
assemblyscript-typescript-loader
Loader for webpack to compile typescript with AssemblyScript and bundle it to wasm or btyes string。
assemblyscript-typescript-loader可以将AssemblyScript代码编译为在浏览器端运行的wasm文件,主要处理了如下几种情况:
- 将大于limit大小的AssemblyScript打包为wasm文件。
- 将小于limit大小的AssemblyScript直接作为二进制字符串打包到bundle。
- 提供WebAssembly Promise对象的回调。
- 对于不支持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...