source: frontend/node_modules/webpack/lib/wasm-async/AsyncWebAssemblyModulesPlugin.js

Last change on this file was 9af201e, checked in by MBK <marija.karapandzova@…>, 11 days ago

Fix frontend appearance

  • Property mode set to 100644
File size: 9.8 KB
Line 
1/*
2 MIT License http://www.opensource.org/licenses/mit-license.php
3 Author Tobias Koppers @sokra
4*/
5
6"use strict";
7
8const { SyncWaterfallHook } = require("tapable");
9const Compilation = require("../Compilation");
10const Generator = require("../Generator");
11const { WEBASSEMBLY_MODULE_TYPE_ASYNC } = require("../ModuleTypeConstants");
12const NormalModule = require("../NormalModule");
13const WebAssemblyImportDependency = require("../dependencies/WebAssemblyImportDependency");
14const { tryRunOrWebpackError } = require("../errors/HookWebpackError");
15const { compareModulesByFullName } = require("../util/comparators");
16const makeSerializable = require("../util/makeSerializable");
17const memoize = require("../util/memoize");
18
19/** @typedef {import("webpack-sources").Source} Source */
20/** @typedef {import("../Chunk")} Chunk */
21/** @typedef {import("../ChunkGraph")} ChunkGraph */
22/** @typedef {import("../CodeGenerationResults")} CodeGenerationResults */
23/** @typedef {import("../Compiler")} Compiler */
24/** @typedef {import("../DependencyTemplates")} DependencyTemplates */
25/** @typedef {import("../Module")} Module */
26/** @typedef {import("../dependencies/ImportPhase").ImportPhaseName} ImportPhaseName */
27/** @typedef {import("../NormalModule").NormalModuleCreateData} NormalModuleCreateData */
28/** @typedef {import("../ModuleGraph")} ModuleGraph */
29/** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */
30/** @typedef {import("../errors/WebpackError")} WebpackError */
31/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
32/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
33
34const getAsyncWebAssemblyGenerator = memoize(() =>
35 require("./AsyncWebAssemblyGenerator")
36);
37const getAsyncWebAssemblyJavascriptGenerator = memoize(() =>
38 require("./AsyncWebAssemblyJavascriptGenerator")
39);
40const getAsyncWebAssemblyParser = memoize(() =>
41 require("./AsyncWebAssemblyParser")
42);
43
44/** @typedef {NormalModule & { phase: ImportPhaseName | undefined }} AsyncWasmModuleClass */
45
46class AsyncWasmModule extends NormalModule {
47 /**
48 * @param {NormalModuleCreateData & { phase: ImportPhaseName | undefined }} options options object
49 */
50 constructor(options) {
51 super(options);
52 this.phase = options.phase;
53 }
54
55 /**
56 * Returns the unique identifier used to reference this module.
57 * @returns {string} a unique identifier of the module
58 */
59 identifier() {
60 let str = super.identifier();
61
62 if (this.phase) {
63 str = `${str}|${this.phase}`;
64 }
65
66 return str;
67 }
68
69 /**
70 * Assuming this module is in the cache. Update the (cached) module with
71 * the fresh module from the factory. Usually updates internal references
72 * and properties.
73 * @param {Module} module fresh module
74 * @returns {void}
75 */
76 updateCacheModule(module) {
77 super.updateCacheModule(module);
78 const m = /** @type {AsyncWasmModule} */ (module);
79 this.phase = m.phase;
80 }
81
82 /**
83 * Serializes this instance into the provided serializer context.
84 * @param {ObjectSerializerContext} context context
85 */
86 serialize(context) {
87 const { write } = context;
88 write(this.phase);
89 super.serialize(context);
90 }
91
92 /**
93 * @param {ObjectDeserializerContext} context context
94 * @returns {AsyncWasmModule} the deserialized object
95 */
96 static deserialize(context) {
97 const obj = new AsyncWasmModule({
98 // will be deserialized by Module
99 layer: /** @type {EXPECTED_ANY} */ (null),
100 type: "",
101 // will be filled by updateCacheModule
102 resource: "",
103 context: "",
104 request: /** @type {EXPECTED_ANY} */ (null),
105 userRequest: /** @type {EXPECTED_ANY} */ (null),
106 rawRequest: /** @type {EXPECTED_ANY} */ (null),
107 loaders: /** @type {EXPECTED_ANY} */ (null),
108 matchResource: /** @type {EXPECTED_ANY} */ (null),
109 parser: /** @type {EXPECTED_ANY} */ (null),
110 parserOptions: /** @type {EXPECTED_ANY} */ (null),
111 generator: /** @type {EXPECTED_ANY} */ (null),
112 generatorOptions: /** @type {EXPECTED_ANY} */ (null),
113 resolveOptions: /** @type {EXPECTED_ANY} */ (null),
114 extractSourceMap: /** @type {EXPECTED_ANY} */ (null),
115 phase: /** @type {EXPECTED_ANY} */ (null)
116 });
117 obj.deserialize(context);
118 return obj;
119 }
120
121 /**
122 * Restores this instance from the provided deserializer context.
123 * @param {ObjectDeserializerContext} context context
124 */
125 deserialize(context) {
126 const { read } = context;
127 this.phase = read();
128 super.deserialize(context);
129 }
130}
131
132makeSerializable(AsyncWasmModule, "webpack/lib/wasm-async/AsyncWasmModule");
133
134/**
135 * Defines the web assembly render context type used by this module.
136 * @typedef {object} WebAssemblyRenderContext
137 * @property {Chunk} chunk the chunk
138 * @property {DependencyTemplates} dependencyTemplates the dependency templates
139 * @property {RuntimeTemplate} runtimeTemplate the runtime template
140 * @property {ModuleGraph} moduleGraph the module graph
141 * @property {ChunkGraph} chunkGraph the chunk graph
142 * @property {CodeGenerationResults} codeGenerationResults results of code generation
143 */
144
145/**
146 * Defines the compilation hooks type used by this module.
147 * @typedef {object} CompilationHooks
148 * @property {SyncWaterfallHook<[Source, Module, WebAssemblyRenderContext]>} renderModuleContent
149 */
150
151/**
152 * Defines the async web assembly modules plugin options type used by this module.
153 * @typedef {object} AsyncWebAssemblyModulesPluginOptions
154 * @property {boolean=} mangleImports mangle imports
155 */
156
157/** @type {WeakMap<Compilation, CompilationHooks>} */
158const compilationHooksMap = new WeakMap();
159
160const PLUGIN_NAME = "AsyncWebAssemblyModulesPlugin";
161
162class AsyncWebAssemblyModulesPlugin {
163 /**
164 * Returns the attached hooks.
165 * @param {Compilation} compilation the compilation
166 * @returns {CompilationHooks} the attached hooks
167 */
168 static getCompilationHooks(compilation) {
169 if (!(compilation instanceof Compilation)) {
170 throw new TypeError(
171 "The 'compilation' argument must be an instance of Compilation"
172 );
173 }
174 let hooks = compilationHooksMap.get(compilation);
175 if (hooks === undefined) {
176 hooks = {
177 renderModuleContent: new SyncWaterfallHook([
178 "source",
179 "module",
180 "renderContext"
181 ])
182 };
183 compilationHooksMap.set(compilation, hooks);
184 }
185 return hooks;
186 }
187
188 /**
189 * Creates an instance of AsyncWebAssemblyModulesPlugin.
190 * @param {AsyncWebAssemblyModulesPluginOptions} options options
191 */
192 constructor(options) {
193 /** @type {AsyncWebAssemblyModulesPluginOptions} */
194 this.options = options;
195 }
196
197 /**
198 * Applies the plugin by registering its hooks on the compiler.
199 * @param {Compiler} compiler the compiler instance
200 * @returns {void}
201 */
202 apply(compiler) {
203 compiler.hooks.compilation.tap(
204 PLUGIN_NAME,
205 (compilation, { normalModuleFactory }) => {
206 const hooks =
207 AsyncWebAssemblyModulesPlugin.getCompilationHooks(compilation);
208 compilation.dependencyFactories.set(
209 WebAssemblyImportDependency,
210 normalModuleFactory
211 );
212
213 normalModuleFactory.hooks.createModuleClass
214 .for(WEBASSEMBLY_MODULE_TYPE_ASYNC)
215 .tap(
216 PLUGIN_NAME,
217 (createData, resolveData) =>
218 new AsyncWasmModule({
219 ...createData,
220 phase: resolveData.phase
221 })
222 );
223
224 normalModuleFactory.hooks.createParser
225 .for(WEBASSEMBLY_MODULE_TYPE_ASYNC)
226 .tap(PLUGIN_NAME, () => {
227 const AsyncWebAssemblyParser = getAsyncWebAssemblyParser();
228
229 return new AsyncWebAssemblyParser();
230 });
231 normalModuleFactory.hooks.createGenerator
232 .for(WEBASSEMBLY_MODULE_TYPE_ASYNC)
233 .tap(PLUGIN_NAME, () => {
234 const AsyncWebAssemblyJavascriptGenerator =
235 getAsyncWebAssemblyJavascriptGenerator();
236 const AsyncWebAssemblyGenerator = getAsyncWebAssemblyGenerator();
237
238 return Generator.byType({
239 javascript: new AsyncWebAssemblyJavascriptGenerator(),
240 webassembly: new AsyncWebAssemblyGenerator(this.options)
241 });
242 });
243
244 compilation.hooks.renderManifest.tap(PLUGIN_NAME, (result, options) => {
245 const { moduleGraph, chunkGraph, runtimeTemplate } = compilation;
246 const {
247 chunk,
248 outputOptions,
249 dependencyTemplates,
250 codeGenerationResults
251 } = options;
252
253 for (const module of chunkGraph.getOrderedChunkModulesIterable(
254 chunk,
255 compareModulesByFullName(compiler)
256 )) {
257 if (module.type === WEBASSEMBLY_MODULE_TYPE_ASYNC) {
258 const filenameTemplate = outputOptions.webassemblyModuleFilename;
259
260 result.push({
261 render: () =>
262 this.renderModule(
263 module,
264 {
265 chunk,
266 dependencyTemplates,
267 runtimeTemplate,
268 moduleGraph,
269 chunkGraph,
270 codeGenerationResults
271 },
272 hooks
273 ),
274 filenameTemplate,
275 pathOptions: {
276 module,
277 runtime: chunk.runtime,
278 chunkGraph
279 },
280 auxiliary: true,
281 identifier: `webassemblyAsyncModule${chunkGraph.getModuleId(
282 module
283 )}`,
284 hash: chunkGraph.getModuleHash(module, chunk.runtime)
285 });
286 }
287 }
288
289 return result;
290 });
291 }
292 );
293 }
294
295 /**
296 * Renders the newly generated source from rendering.
297 * @param {Module} module the rendered module
298 * @param {WebAssemblyRenderContext} renderContext options object
299 * @param {CompilationHooks} hooks hooks
300 * @returns {Source} the newly generated source from rendering
301 */
302 renderModule(module, renderContext, hooks) {
303 const { codeGenerationResults, chunk } = renderContext;
304 try {
305 const moduleSource = codeGenerationResults.getSource(
306 module,
307 chunk.runtime,
308 "webassembly"
309 );
310 return tryRunOrWebpackError(
311 () =>
312 hooks.renderModuleContent.call(moduleSource, module, renderContext),
313 "AsyncWebAssemblyModulesPlugin.getCompilationHooks().renderModuleContent"
314 );
315 } catch (err) {
316 /** @type {WebpackError} */ (err).module = module;
317 throw err;
318 }
319 }
320}
321
322module.exports = AsyncWebAssemblyModulesPlugin;
Note: See TracBrowser for help on using the repository browser.