source: frontend/node_modules/webpack/lib/library/AbstractLibraryPlugin.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: 10.4 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 RuntimeGlobals = require("../RuntimeGlobals");
9const JavascriptModulesPlugin = require("../javascript/JavascriptModulesPlugin");
10
11/** @typedef {import("webpack-sources").Source} Source */
12/** @typedef {import("../../declarations/WebpackOptions").LibraryOptions} LibraryOptions */
13/** @typedef {import("../../declarations/WebpackOptions").LibraryType} LibraryType */
14/** @typedef {import("../Chunk")} Chunk */
15/** @typedef {import("../ChunkGraph")} ChunkGraph */
16/** @typedef {import("../Compilation")} Compilation */
17/** @typedef {import("../Compilation").ChunkHashContext} ChunkHashContext */
18/** @typedef {import("../Compiler")} Compiler */
19/** @typedef {import("../Module")} Module */
20/** @typedef {import("../Module").RuntimeRequirements} RuntimeRequirements */
21/** @typedef {import("../javascript/JavascriptModulesPlugin").RenderContext} RenderContext */
22/** @typedef {import("../javascript/JavascriptModulesPlugin").StartupRenderContext} StartupRenderContext */
23/** @typedef {import("../javascript/JavascriptModulesPlugin").ModuleRenderContext} ModuleRenderContext */
24/** @typedef {import("../util/Hash")} Hash */
25
26const COMMON_LIBRARY_NAME_MESSAGE =
27 "Common configuration options that specific library names are 'output.library[.name]', 'entry.xyz.library[.name]', 'ModuleFederationPlugin.name' and 'ModuleFederationPlugin.library[.name]'.";
28
29/**
30 * Defines the library context type used by this module.
31 * @template T
32 * @typedef {object} LibraryContext
33 * @property {Compilation} compilation
34 * @property {ChunkGraph} chunkGraph
35 * @property {T} options
36 */
37
38/**
39 * Defines the abstract library plugin options type used by this module.
40 * @typedef {object} AbstractLibraryPluginOptions
41 * @property {string} pluginName name of the plugin
42 * @property {LibraryType} type used library type
43 */
44
45/**
46 * Represents AbstractLibraryPlugin.
47 * @template T
48 */
49class AbstractLibraryPlugin {
50 /**
51 * Creates an instance of AbstractLibraryPlugin.
52 * @param {AbstractLibraryPluginOptions} options options
53 */
54 constructor({ pluginName, type }) {
55 /** @type {AbstractLibraryPluginOptions["pluginName"]} */
56 this._pluginName = pluginName;
57 /** @type {AbstractLibraryPluginOptions["type"]} */
58 this._type = type;
59 /** @type {WeakMap<LibraryOptions, T>} */
60 this._parseCache = new WeakMap();
61 }
62
63 /**
64 * Applies the plugin by registering its hooks on the compiler.
65 * @param {Compiler} compiler the compiler instance
66 * @returns {void}
67 */
68 apply(compiler) {
69 const { _pluginName } = this;
70 compiler.hooks.thisCompilation.tap(_pluginName, (compilation) => {
71 compilation.hooks.finishModules.tap(
72 { name: _pluginName, stage: 10 },
73 () => {
74 for (const [
75 name,
76 {
77 dependencies: deps,
78 options: { library }
79 }
80 ] of compilation.entries) {
81 const options = this._parseOptionsCached(
82 library !== undefined
83 ? library
84 : compilation.outputOptions.library
85 );
86 if (options !== false) {
87 const dep = deps[deps.length - 1];
88 if (dep) {
89 const module = compilation.moduleGraph.getModule(dep);
90 if (module) {
91 this.finishEntryModule(module, name, {
92 options,
93 compilation,
94 chunkGraph: compilation.chunkGraph
95 });
96 }
97 }
98 }
99 }
100 }
101 );
102
103 /**
104 * Gets options for chunk.
105 * @param {Chunk} chunk chunk
106 * @returns {T | false} options for the chunk
107 */
108 const getOptionsForChunk = (chunk) => {
109 if (compilation.chunkGraph.getNumberOfEntryModules(chunk) === 0) {
110 return false;
111 }
112 const options = chunk.getEntryOptions();
113 const library = options && options.library;
114 return this._parseOptionsCached(
115 library !== undefined ? library : compilation.outputOptions.library
116 );
117 };
118
119 if (
120 this.render !== AbstractLibraryPlugin.prototype.render ||
121 this.runtimeRequirements !==
122 AbstractLibraryPlugin.prototype.runtimeRequirements
123 ) {
124 compilation.hooks.additionalChunkRuntimeRequirements.tap(
125 _pluginName,
126 (chunk, set, { chunkGraph }) => {
127 const options = getOptionsForChunk(chunk);
128 if (options !== false) {
129 this.runtimeRequirements(chunk, set, {
130 options,
131 compilation,
132 chunkGraph
133 });
134 }
135 }
136 );
137 }
138
139 const hooks = JavascriptModulesPlugin.getCompilationHooks(compilation);
140
141 if (this.render !== AbstractLibraryPlugin.prototype.render) {
142 hooks.render.tap(_pluginName, (source, renderContext) => {
143 const options = getOptionsForChunk(renderContext.chunk);
144 if (options === false) return source;
145 return this.render(source, renderContext, {
146 options,
147 compilation,
148 chunkGraph: compilation.chunkGraph
149 });
150 });
151 }
152
153 if (
154 this.embedInRuntimeBailout !==
155 AbstractLibraryPlugin.prototype.embedInRuntimeBailout
156 ) {
157 hooks.embedInRuntimeBailout.tap(
158 _pluginName,
159 (module, renderContext) => {
160 const options = getOptionsForChunk(renderContext.chunk);
161 if (options === false) return;
162 return this.embedInRuntimeBailout(module, renderContext, {
163 options,
164 compilation,
165 chunkGraph: compilation.chunkGraph
166 });
167 }
168 );
169 }
170
171 if (
172 this.strictRuntimeBailout !==
173 AbstractLibraryPlugin.prototype.strictRuntimeBailout
174 ) {
175 hooks.strictRuntimeBailout.tap(_pluginName, (renderContext) => {
176 const options = getOptionsForChunk(renderContext.chunk);
177 if (options === false) return;
178 return this.strictRuntimeBailout(renderContext, {
179 options,
180 compilation,
181 chunkGraph: compilation.chunkGraph
182 });
183 });
184 }
185
186 if (
187 this.renderModuleContent !==
188 AbstractLibraryPlugin.prototype.renderModuleContent
189 ) {
190 hooks.renderModuleContent.tap(
191 _pluginName,
192 (source, module, renderContext) =>
193 this.renderModuleContent(source, module, renderContext, {
194 compilation,
195 chunkGraph: compilation.chunkGraph
196 })
197 );
198 }
199
200 if (
201 this.renderStartup !== AbstractLibraryPlugin.prototype.renderStartup
202 ) {
203 hooks.renderStartup.tap(
204 _pluginName,
205 (source, module, renderContext) => {
206 const options = getOptionsForChunk(renderContext.chunk);
207 if (options === false) return source;
208 return this.renderStartup(source, module, renderContext, {
209 options,
210 compilation,
211 chunkGraph: compilation.chunkGraph
212 });
213 }
214 );
215 }
216
217 hooks.chunkHash.tap(_pluginName, (chunk, hash, context) => {
218 const options = getOptionsForChunk(chunk);
219 if (options === false) return;
220 this.chunkHash(chunk, hash, context, {
221 options,
222 compilation,
223 chunkGraph: compilation.chunkGraph
224 });
225 });
226 });
227 }
228
229 /**
230 * Parse options cached.
231 * @param {LibraryOptions=} library normalized library option
232 * @returns {T | false} preprocess as needed by overriding
233 */
234 _parseOptionsCached(library) {
235 if (!library) return false;
236 if (library.type !== this._type) return false;
237 const cacheEntry = this._parseCache.get(library);
238 if (cacheEntry !== undefined) return cacheEntry;
239 const result = this.parseOptions(library);
240 this._parseCache.set(library, result);
241 return result;
242 }
243
244 /* istanbul ignore next */
245 /**
246 * Returns preprocess as needed by overriding.
247 * @abstract
248 * @param {LibraryOptions} library normalized library option
249 * @returns {T} preprocess as needed by overriding
250 */
251 parseOptions(library) {
252 const AbstractMethodError = require("../errors/AbstractMethodError");
253
254 throw new AbstractMethodError();
255 }
256
257 /**
258 * Finish entry module.
259 * @param {Module} module the exporting entry module
260 * @param {string} entryName the name of the entrypoint
261 * @param {LibraryContext<T>} libraryContext context
262 * @returns {void}
263 */
264 finishEntryModule(module, entryName, libraryContext) {}
265
266 /**
267 * Embed in runtime bailout.
268 * @param {Module} module the exporting entry module
269 * @param {RenderContext} renderContext render context
270 * @param {LibraryContext<T>} libraryContext context
271 * @returns {string | undefined} bailout reason
272 */
273 embedInRuntimeBailout(module, renderContext, libraryContext) {
274 return undefined;
275 }
276
277 /**
278 * Strict runtime bailout.
279 * @param {RenderContext} renderContext render context
280 * @param {LibraryContext<T>} libraryContext context
281 * @returns {string | undefined} bailout reason
282 */
283 strictRuntimeBailout(renderContext, libraryContext) {
284 return undefined;
285 }
286
287 /**
288 * Processes the provided chunk.
289 * @param {Chunk} chunk the chunk
290 * @param {RuntimeRequirements} set runtime requirements
291 * @param {LibraryContext<T>} libraryContext context
292 * @returns {void}
293 */
294 runtimeRequirements(chunk, set, libraryContext) {
295 if (this.render !== AbstractLibraryPlugin.prototype.render) {
296 set.add(RuntimeGlobals.returnExportsFromRuntime);
297 }
298 }
299
300 /**
301 * Returns source with library export.
302 * @param {Source} source source
303 * @param {RenderContext} renderContext render context
304 * @param {LibraryContext<T>} libraryContext context
305 * @returns {Source} source with library export
306 */
307 render(source, renderContext, libraryContext) {
308 return source;
309 }
310
311 /**
312 * Renders source with library export.
313 * @param {Source} source source
314 * @param {Module} module module
315 * @param {StartupRenderContext} renderContext render context
316 * @param {LibraryContext<T>} libraryContext context
317 * @returns {Source} source with library export
318 */
319 renderStartup(source, module, renderContext, libraryContext) {
320 return source;
321 }
322
323 /**
324 * Renders module content.
325 * @param {Source} source source
326 * @param {Module} module module
327 * @param {ModuleRenderContext} renderContext render context
328 * @param {Omit<LibraryContext<T>, "options">} libraryContext context
329 * @returns {Source} source with library export
330 */
331 renderModuleContent(source, module, renderContext, libraryContext) {
332 return source;
333 }
334
335 /**
336 * Processes the provided chunk.
337 * @param {Chunk} chunk the chunk
338 * @param {Hash} hash hash
339 * @param {ChunkHashContext} chunkHashContext chunk hash context
340 * @param {LibraryContext<T>} libraryContext context
341 * @returns {void}
342 */
343 chunkHash(chunk, hash, chunkHashContext, libraryContext) {
344 const options = this._parseOptionsCached(
345 libraryContext.compilation.outputOptions.library
346 );
347 hash.update(this._pluginName);
348 hash.update(JSON.stringify(options));
349 }
350}
351
352AbstractLibraryPlugin.COMMON_LIBRARY_NAME_MESSAGE = COMMON_LIBRARY_NAME_MESSAGE;
353
354module.exports = AbstractLibraryPlugin;
Note: See TracBrowser for help on using the repository browser.