Wasmts,将TypeScript编译为wasm,让你的Web应用和C一样快
1、核心原理,是把TypeScript先编译成C,然后再编译为wasm,因而性能是跟C一样的。
2、自带内存回收机制,不需要手动释放内存,也无需像C一样担心内存泄露。
3、支持大部分TypeScript特性,包括内联函数,闭包,Class,多文件导入等等。
4、不用学新语言,只要会TypeScript,直接就能用。
5、底层本质编译的都是C,因而,你也可以把已有的C代码混编进来,直接利用C已有的生态。
基本入门
1、安装
npm install wasmts-dev --save
2、简单的helloworld
新建一个ts文件helloworld.ts,并输入以下内容
console.log("hello world");
3、执行编译
打开终端,进入当前目录,输入命令:
wasmts helloworld.ts
4、运行编译结果
前面步骤,会在当前目录生成一个文件:helloworld.wasm.w.js,可直接用node执行
node helloworld.wasm.w.js
此例子中,wasm是以bytes形式内嵌在js文件中的,你也可以添加参数”--wasm“,生成独立的wasm文件
复杂例子
wasm的执行速度通常比js快5到10倍,所以它能即时渲染更加复杂的页面,让你的浏览器跑出C一样的速度。下面3个例子,是用Wasmts编译的,纯js运行无法达到此效果。点击查看相应代码,或者直接查看运行的效果。
名称 | 查看代码 | 运行效果 |
---|---|---|
gameoflife | 查看代码 | 运行效果 |
interference | 查看代码 | 运行效果 |
mandelbrot | 查看代码 | 运行效果 |
AssemblyScript的差别
与Wasmts跟AssemblyScript性能差别不大,上面3个复杂的例子,就是参考AssemblyScript官网上的例子用Wasmts修改过来的。同样的运行效果,彼此性能是差不多的。
虽然性能差不多,但是两者差别还是较大:
1、彼此定位不同。AssemblyScript是定位于一门新语言,虽然它宣称是类似TypeScript的语言,但本质还是一门新语言,数据类型和语法规范跟TypeScript差异还是较大。Wasmts,则定位于一个前端框架,全面拥抱TypeScript和C两门语言,不创造新语言。
2、对TypeScript的支持程度不同。目前AssemblyScript并不支持内联函数、闭包等高级功能,Wasmts则支持。Wasmts的目标是,尽可能兼容TypeScript的所有特性,用纯粹的TypeScript写出C一样高性能的web前端应用。
3、Wasmts能跟C混编,因为Wasmts本质是C,因而能与已有的C代码生态无缝衔接。AssemblyScript是一门独立的新语言,暂无法做到此功能。
你也可以查看AssemblyScript同样的例子相应代码:gameoflife,interference,mandelbrot
WasmEdge的差别
与WasmEdge是倾向于云端的wasm runtime,不倾向于web前端。虽然它可以在wasm运行javascript,但它只是把一个javascript解析引擎(quickjs)嵌入runtime,运行的本质还是将javascript作为动态语言进行解析运行。所以在性能上,还不如带JIT的V8引擎。WasmEdge的优势在用 C/C++,rust,go等语言写wasm,并不在javascript。
相比之下,Wasmts,是针对前端设计的框架,采用的技术路线是把typescript编译成C,再编译为wasm,其性能跟C是一样的。这跟WasmEdge运行的javascript有本质的不同。
语法支持
特性 | 支持情况 | 例子 |
---|---|---|
内联函数 | 支持 | 查看例子 |
闭包 | 支持 | 查看例子 |
调用c函数 | 支持 | 查看例子 |
调用js函数 | 支持 | 查看例子 |
多文件导入(import/export) | 支持 | 查看例子 |
导出接口给JS调用 | 支持 | 查看例子 |
类/类继承 | 支持 | 查看例子 |
TypeScript的自定义type | 支持 | 查看例子 |
async/await | 暂不支持 |
内置对象
对象 | 支持情况 | 例子 |
---|---|---|
console | 支持 | 查看例子 |
Math | 支持 | 查看例子 |
setTimeout/setInterval | 支持 | 查看例子 |
alert/confirm | 支持 | 查看例子 |
parseInt/parseFloat | 支持 | 查看例子 |
Date | 目前仅支持Date.now() | 查看例子 |
上面所有例子源码都在【examples/】目录内,都可以用wasmts命令直接编译
注意事项
1、不能出现不确定类型的变量、参数和返回值,不能有any、known等
2、暂不支持union类型
3、数组目前仅支持string和number,下一版本会支持任意类型数组
4、Object对象暂不支持动态读取属性,即不支持通过下标读取属性
let obj={
a:1,
b:2
};
obj.a=2; //支持
obj['a']=2; //暂不支持,下一版本将支持
let array=[1,2,3];
array[0]=2; //数组支持下标读取
输出配置
在src/WSProgram.ts文件内,定义了输出配置:
export type outputConfig = {
type?: 'html' | 'js' | 'ts',
moduleName?: string,
minimize?: boolean,
wasmType?: 'bytes' | 'file',
wasmFileUrl?: string,
exports?: { [key: string]: Function | any },
onReady?: (runtime: WSRuntime, module?: any) => any,
outDir?: string,
template?: { content: string, toReplace: string },
autoLoad?: boolean,
};
使用时,调用wasmts.output接口,可指定输出的配置,比如:
import { wasmts } from "wasmts-dev";
console.log("Hello Wrold");
wasmts.output({
type: 'html', //定义编译后文件以html格式输出
});
配置参数说明:
属性 | 说明 |
---|---|
type | 指定输出的格式,支持"html","js","ts"三种格式 |
moduleName | 模块名,默认是文件名 |
minimize | 输出结果是否压缩,默认不压缩 |
wasmType | wasm内容输出方式,file是单独生成文件,默认是bytes |
wasmFileUrl | 运行编译后的文件时,指定导入wasm的路径。默认是当前路径 |
exports | 导出给JS的方法或属性 |
onReady | wasm文件加载完成后,运行的JS回调,此函数不会被编译为wasm,而是JS方式运行。 |
outDir | 指定编译结果输出目标文件夹 |
template | 输出模版 |
autoLoad | 是否直接加载,对于js和html格式输出,默认为是 |