1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 | "use strict";
|
7 |
|
8 | const { SyncWaterfallHook } = require("tapable");
|
9 | const Compilation = require("../Compilation");
|
10 | const Generator = require("../Generator");
|
11 | const { tryRunOrWebpackError } = require("../HookWebpackError");
|
12 | const WebAssemblyImportDependency = require("../dependencies/WebAssemblyImportDependency");
|
13 | const { compareModulesByIdentifier } = require("../util/comparators");
|
14 | const memoize = require("../util/memoize");
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 |
|
24 |
|
25 |
|
26 |
|
27 |
|
28 | const getAsyncWebAssemblyGenerator = memoize(() =>
|
29 | require("./AsyncWebAssemblyGenerator")
|
30 | );
|
31 | const getAsyncWebAssemblyJavascriptGenerator = memoize(() =>
|
32 | require("./AsyncWebAssemblyJavascriptGenerator")
|
33 | );
|
34 | const getAsyncWebAssemblyParser = memoize(() =>
|
35 | require("./AsyncWebAssemblyParser")
|
36 | );
|
37 |
|
38 |
|
39 |
|
40 |
|
41 |
|
42 |
|
43 |
|
44 |
|
45 |
|
46 |
|
47 |
|
48 |
|
49 |
|
50 |
|
51 |
|
52 |
|
53 |
|
54 | const compilationHooksMap = new WeakMap();
|
55 |
|
56 | class AsyncWebAssemblyModulesPlugin {
|
57 | |
58 |
|
59 |
|
60 |
|
61 | static getCompilationHooks(compilation) {
|
62 | if (!(compilation instanceof Compilation)) {
|
63 | throw new TypeError(
|
64 | "The 'compilation' argument must be an instance of Compilation"
|
65 | );
|
66 | }
|
67 | let hooks = compilationHooksMap.get(compilation);
|
68 | if (hooks === undefined) {
|
69 | hooks = {
|
70 | renderModuleContent: new SyncWaterfallHook([
|
71 | "source",
|
72 | "module",
|
73 | "renderContext"
|
74 | ])
|
75 | };
|
76 | compilationHooksMap.set(compilation, hooks);
|
77 | }
|
78 | return hooks;
|
79 | }
|
80 |
|
81 | constructor(options) {
|
82 | this.options = options;
|
83 | }
|
84 |
|
85 | |
86 |
|
87 |
|
88 |
|
89 |
|
90 | apply(compiler) {
|
91 | compiler.hooks.compilation.tap(
|
92 | "AsyncWebAssemblyModulesPlugin",
|
93 | (compilation, { normalModuleFactory }) => {
|
94 | const hooks =
|
95 | AsyncWebAssemblyModulesPlugin.getCompilationHooks(compilation);
|
96 | compilation.dependencyFactories.set(
|
97 | WebAssemblyImportDependency,
|
98 | normalModuleFactory
|
99 | );
|
100 |
|
101 | normalModuleFactory.hooks.createParser
|
102 | .for("webassembly/async")
|
103 | .tap("AsyncWebAssemblyModulesPlugin", () => {
|
104 | const AsyncWebAssemblyParser = getAsyncWebAssemblyParser();
|
105 |
|
106 | return new AsyncWebAssemblyParser();
|
107 | });
|
108 | normalModuleFactory.hooks.createGenerator
|
109 | .for("webassembly/async")
|
110 | .tap("AsyncWebAssemblyModulesPlugin", () => {
|
111 | const AsyncWebAssemblyJavascriptGenerator =
|
112 | getAsyncWebAssemblyJavascriptGenerator();
|
113 | const AsyncWebAssemblyGenerator = getAsyncWebAssemblyGenerator();
|
114 |
|
115 | return Generator.byType({
|
116 | javascript: new AsyncWebAssemblyJavascriptGenerator(
|
117 | compilation.outputOptions.webassemblyModuleFilename
|
118 | ),
|
119 | webassembly: new AsyncWebAssemblyGenerator(this.options)
|
120 | });
|
121 | });
|
122 |
|
123 | compilation.hooks.renderManifest.tap(
|
124 | "WebAssemblyModulesPlugin",
|
125 | (result, options) => {
|
126 | const { moduleGraph, chunkGraph, runtimeTemplate } = compilation;
|
127 | const {
|
128 | chunk,
|
129 | outputOptions,
|
130 | dependencyTemplates,
|
131 | codeGenerationResults
|
132 | } = options;
|
133 |
|
134 | for (const module of chunkGraph.getOrderedChunkModulesIterable(
|
135 | chunk,
|
136 | compareModulesByIdentifier
|
137 | )) {
|
138 | if (module.type === "webassembly/async") {
|
139 | const filenameTemplate =
|
140 | outputOptions.webassemblyModuleFilename;
|
141 |
|
142 | result.push({
|
143 | render: () =>
|
144 | this.renderModule(
|
145 | module,
|
146 | {
|
147 | chunk,
|
148 | dependencyTemplates,
|
149 | runtimeTemplate,
|
150 | moduleGraph,
|
151 | chunkGraph,
|
152 | codeGenerationResults
|
153 | },
|
154 | hooks
|
155 | ),
|
156 | filenameTemplate,
|
157 | pathOptions: {
|
158 | module,
|
159 | runtime: chunk.runtime,
|
160 | chunkGraph
|
161 | },
|
162 | auxiliary: true,
|
163 | identifier: `webassemblyAsyncModule${chunkGraph.getModuleId(
|
164 | module
|
165 | )}`,
|
166 | hash: chunkGraph.getModuleHash(module, chunk.runtime)
|
167 | });
|
168 | }
|
169 | }
|
170 |
|
171 | return result;
|
172 | }
|
173 | );
|
174 | }
|
175 | );
|
176 | }
|
177 |
|
178 | renderModule(module, renderContext, hooks) {
|
179 | const { codeGenerationResults, chunk } = renderContext;
|
180 | try {
|
181 | const moduleSource = codeGenerationResults.getSource(
|
182 | module,
|
183 | chunk.runtime,
|
184 | "webassembly"
|
185 | );
|
186 | return tryRunOrWebpackError(
|
187 | () =>
|
188 | hooks.renderModuleContent.call(moduleSource, module, renderContext),
|
189 | "AsyncWebAssemblyModulesPlugin.getCompilationHooks().renderModuleContent"
|
190 | );
|
191 | } catch (e) {
|
192 | e.module = module;
|
193 | throw e;
|
194 | }
|
195 | }
|
196 | }
|
197 |
|
198 | module.exports = AsyncWebAssemblyModulesPlugin;
|