【wasm】如何确保package中wasm文件在任意项目中的引入正常

背景

  • webAssembly文件(xxx.wasm)只能通过ajax请求的形式进行引入。参见: https://developer.mozilla.org/zh-CN/docs/WebAssembly/JavaScript_interface
  • package中直接通过本地形式加载wasm文件会导致在项目中使用的路径问题,如下所示
const wasm = window.fetch('../static/dd.wasm')

解决方式

方案一

package封装后,将wasm文件提供在包内,由业务使用方自行引入。如:

// 以vue3 使用形式做说明
import PACK from 'pack';

onMounted(()=>{
    new PACK({
        wasmPath: new URL('../node_modules/pack/static/dd.wasm', import.meta.url).href
    })
})

方案二

package内部通过远程形式加载,如:

const wasm = window.fetch('https://test.tt.com/static/dd.wasm');

方案三

在package打包时,将wasm文件通过fs模块进行内容读取,然后将wasm文件内容转换成unit8Array,写到wasm.js文件中。然后package主文件引入wasm.js进行引入即可。

  • wasm读取存储,如:
// build.js
// const fs = require('fs');

import * as fs from 'fs'

// 读取 .wasm 文件并将其转换为 ArrayBuffer
const arrayBuffer = fs.readFileSync('./static/dd.wasm').buffer;

// 将 ArrayBuffer 中的二进制数据存储到数组中
const binaryData = [];
const view = new Uint8Array(arrayBuffer);
for (let i = 0; i < view.length; ++i) {
  binaryData.push(view[i]);
}

// 将二进制数据保存到 js 文件中
const tsCode = `export const wasmBinary = new Uint8Array([${binaryData.join(',')}]);`;
fs.writeFileSync('./src/utils/dd.js', tsCode);

  • 执行命令
node ./build.js
  • package主逻辑引入,如:
import {wasmBinary} from './utils/dd.js';
...
const wasmBlob = new Blob([wasmBinary], { type: "application/wasm" });
const wasmUrl = URL.createObjectURL(wasmBlob);
const res = window.fetch(wasmUrl);
const { instance } = await WebAssembly.instantiateStreaming(res, {});
...

如果是通用类型的package建议使用方案三,否则还需要在nginx层配置对应的MIME TYPE对application/wasm这种类型进行支持。

你可能感兴趣的:(wasm)