2017-10-30 20:56:57 +08:00
|
|
|
/*
|
|
|
|
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");
|
|
|
|
|
2017-10-30 20:56:57 +08:00
|
|
|
class FetchCompileWasmMainTemplatePlugin {
|
|
|
|
apply(mainTemplate) {
|
2018-02-25 09:00:20 +08:00
|
|
|
mainTemplate.hooks.localVars.tap(
|
|
|
|
"FetchCompileWasmMainTemplatePlugin",
|
|
|
|
(source, chunk) => {
|
|
|
|
if (!chunk.hasModuleInGraph(m => m.type.startsWith("webassembly")))
|
|
|
|
return source;
|
|
|
|
return Template.asString([
|
|
|
|
source,
|
|
|
|
"",
|
|
|
|
"// object to store loaded and loading wasm modules",
|
|
|
|
"var installedWasmModules = {};"
|
|
|
|
]);
|
|
|
|
}
|
|
|
|
);
|
|
|
|
mainTemplate.hooks.requireEnsure.tap(
|
|
|
|
"FetchCompileWasmMainTemplatePlugin",
|
|
|
|
(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
|
|
|
}
|
2017-10-30 20:56:57 +08:00
|
|
|
}
|
2018-02-25 09:00:20 +08:00
|
|
|
);
|
|
|
|
return Template.asString([
|
|
|
|
source,
|
|
|
|
"",
|
|
|
|
"// Fetch + compile chunk loading for webassembly",
|
|
|
|
"",
|
|
|
|
`var wasmModules = ${JSON.stringify(
|
|
|
|
chunkModuleMaps.id
|
|
|
|
)}[chunkId] || [];`,
|
2017-10-30 20:56:57 +08:00
|
|
|
"",
|
2018-02-25 09:00:20 +08:00
|
|
|
"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] = fetch(${
|
|
|
|
mainTemplate.requireFn
|
|
|
|
}.p + ${wasmModuleSrcPath}).then(function(response) {`,
|
2017-12-07 16:42:33 +08:00
|
|
|
Template.indent([
|
2018-02-25 09:00:20 +08:00
|
|
|
"if(WebAssembly.compileStreaming) {",
|
|
|
|
Template.indent([
|
|
|
|
"return WebAssembly.compileStreaming(response);"
|
|
|
|
]),
|
|
|
|
"} else {",
|
|
|
|
Template.indent([
|
|
|
|
"return response.arrayBuffer().then(function(bytes) { return WebAssembly.compile(bytes); });"
|
|
|
|
]),
|
|
|
|
"}"
|
2017-11-03 16:44:43 +08:00
|
|
|
]),
|
2018-02-25 09:00:20 +08:00
|
|
|
`}).then(function(module) { ${
|
|
|
|
mainTemplate.requireFn
|
|
|
|
}.w[wasmModuleId] = module; }))`
|
2017-10-30 20:56:57 +08:00
|
|
|
]),
|
2018-02-25 09:00:20 +08:00
|
|
|
");"
|
2017-10-30 20:56:57 +08:00
|
|
|
]),
|
2018-02-25 09:00:20 +08:00
|
|
|
"});"
|
|
|
|
]);
|
|
|
|
}
|
|
|
|
);
|
|
|
|
mainTemplate.hooks.requireExtensions.tap(
|
|
|
|
"FetchCompileWasmMainTemplatePlugin",
|
|
|
|
(source, chunk) => {
|
|
|
|
if (!chunk.hasModuleInGraph(m => m.type.startsWith("webassembly")))
|
|
|
|
return source;
|
|
|
|
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 = {};`
|
|
|
|
]);
|
|
|
|
}
|
|
|
|
);
|
2017-12-14 04:35:39 +08:00
|
|
|
mainTemplate.hooks.hash.tap("FetchCompileWasmMainTemplatePlugin", hash => {
|
2017-11-12 01:48:29 +08:00
|
|
|
hash.update("FetchCompileWasmMainTemplatePlugin");
|
|
|
|
hash.update("1");
|
|
|
|
hash.update(`${mainTemplate.outputOptions.webassemblyModuleFilename}`);
|
2017-10-30 20:56:57 +08:00
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
module.exports = FetchCompileWasmMainTemplatePlugin;
|