UNPKG

4.13 kBJavaScriptView Raw
1/*
2 MIT License http://www.opensource.org/licenses/mit-license.php
3 Author Tobias Koppers @sokra
4*/
5
6"use strict";
7
8const Generator = require("../Generator");
9const WebAssemblyExportImportedDependency = require("../dependencies/WebAssemblyExportImportedDependency");
10const WebAssemblyImportDependency = require("../dependencies/WebAssemblyImportDependency");
11const { compareModulesByIdentifier } = require("../util/comparators");
12const memoize = require("../util/memoize");
13const WebAssemblyInInitialChunkError = require("./WebAssemblyInInitialChunkError");
14
15/** @typedef {import("webpack-sources").Source} Source */
16/** @typedef {import("../Compiler")} Compiler */
17/** @typedef {import("../Module")} Module */
18/** @typedef {import("../ModuleTemplate")} ModuleTemplate */
19/** @typedef {import("../ModuleTemplate").RenderContext} RenderContext */
20
21const getWebAssemblyGenerator = memoize(() =>
22 require("./WebAssemblyGenerator")
23);
24const getWebAssemblyJavascriptGenerator = memoize(() =>
25 require("./WebAssemblyJavascriptGenerator")
26);
27const getWebAssemblyParser = memoize(() => require("./WebAssemblyParser"));
28
29class WebAssemblyModulesPlugin {
30 constructor(options) {
31 this.options = options;
32 }
33
34 /**
35 * Apply the plugin
36 * @param {Compiler} compiler the compiler instance
37 * @returns {void}
38 */
39 apply(compiler) {
40 compiler.hooks.compilation.tap(
41 "WebAssemblyModulesPlugin",
42 (compilation, { normalModuleFactory }) => {
43 compilation.dependencyFactories.set(
44 WebAssemblyImportDependency,
45 normalModuleFactory
46 );
47
48 compilation.dependencyFactories.set(
49 WebAssemblyExportImportedDependency,
50 normalModuleFactory
51 );
52
53 normalModuleFactory.hooks.createParser
54 .for("webassembly/sync")
55 .tap("WebAssemblyModulesPlugin", () => {
56 const WebAssemblyParser = getWebAssemblyParser();
57
58 return new WebAssemblyParser();
59 });
60
61 normalModuleFactory.hooks.createGenerator
62 .for("webassembly/sync")
63 .tap("WebAssemblyModulesPlugin", () => {
64 const WebAssemblyJavascriptGenerator = getWebAssemblyJavascriptGenerator();
65 const WebAssemblyGenerator = getWebAssemblyGenerator();
66
67 return Generator.byType({
68 javascript: new WebAssemblyJavascriptGenerator(),
69 webassembly: new WebAssemblyGenerator(this.options)
70 });
71 });
72
73 compilation.hooks.renderManifest.tap(
74 "WebAssemblyModulesPlugin",
75 (result, options) => {
76 const { chunkGraph } = compilation;
77 const { chunk, outputOptions, codeGenerationResults } = options;
78
79 for (const module of chunkGraph.getOrderedChunkModulesIterable(
80 chunk,
81 compareModulesByIdentifier
82 )) {
83 if (module.type === "webassembly/sync") {
84 const filenameTemplate =
85 outputOptions.webassemblyModuleFilename;
86
87 result.push({
88 render: () =>
89 codeGenerationResults.getSource(
90 module,
91 chunk.runtime,
92 "webassembly"
93 ),
94 filenameTemplate,
95 pathOptions: {
96 module,
97 runtime: chunk.runtime,
98 chunkGraph
99 },
100 auxiliary: true,
101 identifier: `webassemblyModule${chunkGraph.getModuleId(
102 module
103 )}`,
104 hash: chunkGraph.getModuleHash(module, chunk.runtime)
105 });
106 }
107 }
108
109 return result;
110 }
111 );
112
113 compilation.hooks.afterChunks.tap("WebAssemblyModulesPlugin", () => {
114 const chunkGraph = compilation.chunkGraph;
115 const initialWasmModules = new Set();
116 for (const chunk of compilation.chunks) {
117 if (chunk.canBeInitial()) {
118 for (const module of chunkGraph.getChunkModulesIterable(chunk)) {
119 if (module.type === "webassembly/sync") {
120 initialWasmModules.add(module);
121 }
122 }
123 }
124 }
125 for (const module of initialWasmModules) {
126 compilation.errors.push(
127 new WebAssemblyInInitialChunkError(
128 module,
129 compilation.moduleGraph,
130 compilation.chunkGraph,
131 compilation.requestShortener
132 )
133 );
134 }
135 });
136 }
137 );
138 }
139}
140
141module.exports = WebAssemblyModulesPlugin;