vite-plugin-offload-wasm
Version:
Serve WASM from a CDN or any remote location, bypassing the local server entirely
71 lines (67 loc) • 2.04 kB
JavaScript
;
const path = require('path');
function offloadWasm(list, forced = false) {
let resolvedConfig;
const storage = [];
function definedReplacement(id) {
const pathParts = id.split(path.sep);
for (let i = 1; i <= pathParts.length; i++) {
const partialPath = pathParts.slice(-i).join(path.sep);
if (list.hasOwnProperty(partialPath)) {
return list[partialPath];
}
}
return "";
}
function replacerData(moduleCode, replacement) {
const ASSET_PATTERN = /__VITE_ASSET__.*__/;
return {
pattern: new RegExp(
moduleCode.replace("$", `\\$`).replace(ASSET_PATTERN, `${resolvedConfig.base}(?<localpath>[^\\;]+)`)
),
replacement: moduleCode?.replace(ASSET_PATTERN, replacement)
};
}
function handleReplacements(code, data) {
return code.replace(data.pattern, data.replacement);
}
return {
name: "vite-plugin-offload-wasm",
enforce: "post",
apply: "build",
configResolved(config) {
resolvedConfig = config;
},
renderChunk(code, chunk) {
if ("object" !== typeof list || 0 === Object.values(list).length) {
return code;
}
Object.keys(chunk.modules).forEach((id) => {
if (".wasm?url" !== path.extname(id)) {
return;
}
const moduleCode = chunk.modules[id].code;
if (!moduleCode) {
return;
}
const replacement = definedReplacement(id.replace("?url", ""));
if (!replacement) {
return;
}
const data = replacerData(moduleCode, replacement);
storage.push(code.match(data.pattern)?.groups?.localpath);
if (forced) {
data.replacement = data.replacement.replace(/"data:application\/wasm;base64,[^\"]+"/, `"${replacement}"`);
}
code = handleReplacements(code, data);
});
return code;
},
generateBundle(_, bundle) {
storage.forEach((path) => {
delete bundle[path];
});
}
};
}
module.exports = offloadWasm;