- 2022-07-20 发现 build 出的
.wasm
文件无法在手机端浏览器(chrome & safari)运行- 暂不确定是文件
release.js
文件导致还是.wasm
本身无法运行 - PC 端 chrome 103.0.5060.114 正常运行
- 暂不确定是文件
https://www.assemblyscript.org/getting-started.html
- 官方 quick start 运行
npm run build
报错SyntaxError: missing ) after argument list
- google 检索到一个 相关 issue 猜测可能是 nodejs 版本不正确
- https://github.com/AssemblyScript/assemblyscript/issues/2248
- issue 中描述升级 16.x 后解决
- 本机 node 14.x
- 由于vue3-cli 跑起来需要 14.x 版本(在16.x 会报错),故我需要一个 node 版本管理工具
nvm
- 安装 windows 上的
nvm
https://zhuanlan.zhihu.com/p/503547214- nvm-setup.zip
- 安装完毕运行
nvm install 16.16.0
一切顺利 - 运行
nvm use 16.16.0
报错exit status 1: Access is denied.
- 解决方式 https://blog.csdn.net/qq_41715885/article/details/120449480
C:\Windows\System32\cmd.exe
以管理员身份运行cmd.exe
再执行nvm use 16.16.0
成功运行- nvm 再安装一个 14.x 版本
nvm install 14.19.3
- 在 以管理员身份运行的
cmd.exe
中nvm use 14.19.3
- 运行 vue3-cli 项目
yarn serve
命令失效,改为npm run serve
OK 项目成功运行,回头再来研究 yarn 失效问题
- 运行
nvm use 16.16.0
切换正确版本号继续操作
- google 检索到一个 相关 issue 猜测可能是 nodejs 版本不正确
- 解决完 node 版本问题后来到项目目录
npm run asbuild
OK npm test
OK/assembly/index.ts
添加方法str
export function str(a: string, b: string): string {
return a + b;
}
运行
npm run asbuild
OK- 运行
npm test
报错TypeError: exports.__new is not a function
- 查找 issue https://github.com/AssemblyScript/assemblyscript/issues/2244 发现相同问题
- issue 中描述了 添加
--exportRuntime
方式来解决,但是我不知道要加到哪 - 在 issue 中的一个评论里找到一个 demo,查看其 package.json 后明白添加
--exportRuntime
方式 https://gitlab.com/everyonecancontribute/dev/learn-wasm-assemblyscript/-/blob/main/package.json - 照做后问题解决
/assembly/index.ts
添加map
方法export function map(arr: i32[]): string {
return arr.map((i: i32) => i * 2).join('|')
}
- 运行
npm run asbuild
报错
再次检索 issue 发现有人遇到相同问题 https://github.com/AssemblyScript/assemblyscript/issues/2221
- 按照评论中的解决方案修改代码后解决问题,
npm run asbuild
通过export function map(arr: i32[]): string {
return arr.map<i32>((i: i32) => i * 2).join('|')
}
- 按照评论中的解决方案修改代码后解决问题,
闭包问题 https://github.com/AssemblyScript/assemblyscript/issues/798
- assemblyscript 中没有闭包,这一点与 JS 很不一样,编码过程中需要特别留意
- 数据类型没有
number
取而代之的可以用u32
、i32
代替 - 部分作用域作用原理也与 js 不同
- 如下两种写法产生的结果是不同的,具体原因暂未知晓 ```typescript
// 写法 1 let i = 0 let j = 0
for (; i < lineLen + 1; i++) { // … for (; j < group.length; j++) { // … } }
// 写法2 for (let i = 0; i < lineLen + 1; i++) { // … for (let j = 0; j < group.length; j++) { // … } }
13. 通过 assemblyscript build 的`.wasm` 文件,引用方式比较特殊,参考build 后得到的 `release.js` 经改造后得到如下文件
```javascript
/**
* 加载 `.wasm` 文件
*/
export default async (url) => {
const module = await WebAssembly.compileStreaming(fetch(url))
const { exports } = await WebAssembly.instantiate(module, {
env: {
// eslint-disable-next-line
abort: console.log,
},
})
const memory = exports.memory
const adaptedExports = Object.setPrototypeOf(
{
encode(str) {
// assembly/index/encode(~lib/string/String) => ~lib/string/String
str = __lowerString(str) || __notnull()
return __liftString(exports.encode(str) >>> 0)
},
decode(str) {
// assembly/index/decode(~lib/string/String) => ~lib/string/String
str = __lowerString(str) || __notnull()
return __liftString(exports.decode(str) >>> 0)
},
},
exports
)
function __liftString(pointer) {
if (!pointer) return null
const end =
(pointer + new Uint32Array(memory.buffer)[(pointer - 4) >>> 2]) >>> 1,
memoryU16 = new Uint16Array(memory.buffer)
let start = pointer >>> 1,
string = ''
while (end - start > 1024)
string += String.fromCharCode(
...memoryU16.subarray(start, (start += 1024))
)
return string + String.fromCharCode(...memoryU16.subarray(start, end))
}
function __lowerString(value) {
if (value == null) return 0
const length = value.length,
pointer = exports.__new(length << 1, 1) >>> 0,
memoryU16 = new Uint16Array(memory.buffer)
for (let i = 0; i < length; ++i)
memoryU16[(pointer >>> 1) + i] = value.charCodeAt(i)
return pointer
}
function __notnull() {
throw TypeError('value must not be null')
}
return adaptedExports
}
该文件中直接包含了 export 出的
encode
和decode
方法名,比较特殊