107 lines
3.1 KiB
JavaScript
107 lines
3.1 KiB
JavaScript
/*
|
|
MIT License http://www.opensource.org/licenses/mit-license.php
|
|
Author Tobias Koppers @sokra
|
|
*/
|
|
"use strict";
|
|
|
|
const { RawSource } = require("webpack-sources");
|
|
const WebAssemblyImportDependency = require("../dependencies/WebAssemblyImportDependency");
|
|
|
|
class WasmModuleTemplatePlugin {
|
|
apply(moduleTemplate) {
|
|
moduleTemplate.hooks.content.tap(
|
|
"WasmModuleTemplatePlugin",
|
|
(moduleSource, module, { chunk }) => {
|
|
if (module.type && module.type.startsWith("webassembly")) {
|
|
if (chunk.canBeInitial())
|
|
throw new Error(
|
|
"Sync WebAssembly compilation is not yet implemented"
|
|
);
|
|
const generateExports = () => {
|
|
if (
|
|
Array.isArray(module.buildMeta.providedExports) &&
|
|
Array.isArray(module.usedExports)
|
|
) {
|
|
// generate mangled exports
|
|
return module.buildMeta.providedExports
|
|
.map(exp => {
|
|
const usedName = module.isUsed(exp);
|
|
if (usedName) {
|
|
return `${module.exportsArgument}[${JSON.stringify(
|
|
usedName
|
|
)}] = instance.exports[${JSON.stringify(exp)}];`;
|
|
} else {
|
|
return `// unused ${JSON.stringify(exp)} export`;
|
|
}
|
|
})
|
|
.join("\n");
|
|
} else {
|
|
// generate simple export
|
|
return `${module.moduleArgument}.exports = instance.exports;`;
|
|
}
|
|
};
|
|
const generateImports = () => {
|
|
const depsByRequest = new Map();
|
|
for (const dep of module.dependencies) {
|
|
if (dep instanceof WebAssemblyImportDependency) {
|
|
const request = dep.request;
|
|
let array = depsByRequest.get(request);
|
|
if (!array) {
|
|
depsByRequest.set(request, (array = []));
|
|
}
|
|
const exportName = dep.name;
|
|
const usedName = dep.module && dep.module.isUsed(exportName);
|
|
array.push({
|
|
exportName,
|
|
usedName,
|
|
module: dep.module
|
|
});
|
|
}
|
|
}
|
|
const importsCode = [];
|
|
for (const pair of depsByRequest) {
|
|
const properties = [];
|
|
for (const data of pair[1]) {
|
|
properties.push(
|
|
`\n\t\t${JSON.stringify(
|
|
data.exportName
|
|
)}: __webpack_require__(${JSON.stringify(
|
|
data.module.id
|
|
)})[${JSON.stringify(data.usedName)}]`
|
|
);
|
|
}
|
|
importsCode.push(
|
|
`\n\t${JSON.stringify(pair[0])}: {${properties.join(",")}\n\t}`
|
|
);
|
|
}
|
|
return importsCode.join(",");
|
|
};
|
|
const source = new RawSource(
|
|
[
|
|
'"use strict";',
|
|
"",
|
|
"// Instantiate WebAssembly module",
|
|
"var instance = new WebAssembly.Instance(__webpack_require__.w[module.i], {" +
|
|
generateImports(),
|
|
"});",
|
|
"",
|
|
"// export exports from WebAssembly module",
|
|
// TODO rewrite this to getters depending on exports to support circular dependencies
|
|
generateExports()
|
|
].join("\n")
|
|
);
|
|
return source;
|
|
} else {
|
|
return moduleSource;
|
|
}
|
|
}
|
|
);
|
|
|
|
moduleTemplate.hooks.hash.tap("WasmModuleTemplatePlugin", hash => {
|
|
hash.update("WasmModuleTemplatePlugin");
|
|
hash.update("1");
|
|
});
|
|
}
|
|
}
|
|
module.exports = WasmModuleTemplatePlugin;
|