webpack/lib/node/ReadFileCompileWasmMainTemp...

114 lines
3.4 KiB
JavaScript
Raw Normal View History

/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
"use strict";
2017-12-07 16:42:33 +08:00
const Template = require("../Template");
class ReadFileCompileWasmMainTemplatePlugin {
apply(mainTemplate) {
2018-02-25 09:00:20 +08:00
mainTemplate.hooks.localVars.tap(
"ReadFileCompileWasmMainTemplatePlugin",
(source, chunk) => {
return Template.asString([
source,
"",
"// object to store loaded and loading wasm modules",
"var installedWasmModules = {};"
]);
}
);
mainTemplate.hooks.requireEnsure.tap(
"ReadFileCompileWasmMainTemplatePlugin",
(source, chunk, hash) => {
const webassemblyModuleFilename =
mainTemplate.outputOptions.webassemblyModuleFilename;
const chunkModuleMaps = chunk.getChunkModuleMaps(m =>
m.type.startsWith("webassembly")
);
if (Object.keys(chunkModuleMaps.id).length === 0) return source;
const wasmModuleSrcPath = mainTemplate.getAssetPath(
JSON.stringify(webassemblyModuleFilename),
{
hash: `" + ${mainTemplate.renderCurrentHashCode(hash)} + "`,
hashWithLength: length =>
`" + ${mainTemplate.renderCurrentHashCode(hash, length)} + "`,
module: {
id: '" + wasmModuleId + "',
hash: `" + ${JSON.stringify(
chunkModuleMaps.hash
)}[wasmModuleId] + "`,
hashWithLength(length) {
const shortChunkHashMap = Object.create(null);
for (const wasmModuleId of Object.keys(chunkModuleMaps.hash)) {
if (typeof chunkModuleMaps.hash[wasmModuleId] === "string")
shortChunkHashMap[wasmModuleId] = chunkModuleMaps.hash[
wasmModuleId
].substr(0, length);
}
return `" + ${JSON.stringify(
shortChunkHashMap
)}[wasmModuleId] + "`;
}
2018-01-22 20:52:43 +08:00
}
}
2018-02-25 09:00:20 +08:00
);
return Template.asString([
source,
"",
"// ReadFile + compile chunk loading for webassembly",
"",
2018-02-25 09:00:20 +08:00
`var wasmModules = ${JSON.stringify(
chunkModuleMaps.id
)}[chunkId] || [];`,
"",
"wasmModules.forEach(function(wasmModuleId) {",
2017-12-07 16:42:33 +08:00
Template.indent([
2018-02-25 09:00:20 +08:00
"var installedWasmModuleData = installedWasmModules[wasmModuleId];",
"",
'// a Promise means "currently loading" or "already loaded".',
"promises.push(installedWasmModuleData ||",
2017-12-07 16:42:33 +08:00
Template.indent([
2018-02-25 09:00:20 +08:00
"(installedWasmModules[wasmModuleId] = new Promise(function(resolve, reject) {",
2017-12-07 16:42:33 +08:00
Template.indent([
2018-03-26 22:56:10 +08:00
`require('fs').readFile(require('path').resolve(__dirname, ${wasmModuleSrcPath}), function(err, buffer) {`,
2018-02-25 09:00:20 +08:00
Template.indent([
"if(err) return reject(err);",
"resolve(WebAssembly.compile(buffer));"
]),
"});"
]),
2018-02-25 09:00:20 +08:00
`}).then(function(module) { ${
mainTemplate.requireFn
}.w[wasmModuleId] = module; }))`
]),
2018-02-25 09:00:20 +08:00
");"
]),
2018-02-25 09:00:20 +08:00
"});"
]);
}
);
mainTemplate.hooks.requireExtensions.tap(
"ReadFileCompileWasmMainTemplatePlugin",
(source, chunk) => {
return Template.asString([
source,
"",
2018-02-26 10:25:03 +08:00
"// object with all compiled WebAssembly.Modules",
2018-02-25 09:00:20 +08:00
`${mainTemplate.requireFn}.w = {};`
]);
}
);
mainTemplate.hooks.hash.tap(
"ReadFileCompileWasmMainTemplatePlugin",
hash => {
hash.update("ReadFileCompileWasmMainTemplatePlugin");
hash.update("1");
hash.update(`${mainTemplate.outputOptions.webassemblyModuleFilename}`);
}
);
}
}
module.exports = ReadFileCompileWasmMainTemplatePlugin;