source: frontend/node_modules/webpack/lib/esm/ModuleChunkFormatPlugin.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: 8.1 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 { ConcatSource } = require("webpack-sources");
9const { HotUpdateChunk, RuntimeGlobals } = require("..");
10const { JAVASCRIPT_TYPE } = require("../ModuleSourceTypeConstants");
11const Template = require("../Template");
12const {
13 createChunkHashHandler,
14 getChunkInfo
15} = require("../javascript/ChunkFormatHelpers");
16const { getAllChunks } = require("../javascript/ChunkHelpers");
17const {
18 chunkHasJs,
19 getChunkFilenameTemplate,
20 getCompilationHooks
21} = require("../javascript/JavascriptModulesPlugin");
22const { getUndoPath } = require("../util/identifier");
23
24/** @typedef {import("webpack-sources").Source} Source */
25/** @typedef {import("../Chunk")} Chunk */
26/** @typedef {import("../ChunkGraph")} ChunkGraph */
27/** @typedef {import("../Compilation")} Compilation */
28/** @typedef {import("../Compiler")} Compiler */
29/** @typedef {import("../Entrypoint")} Entrypoint */
30
31/**
32 * Gets relative path.
33 * @param {Compilation} compilation the compilation instance
34 * @param {Chunk} chunk the chunk
35 * @param {Chunk} runtimeChunk the runtime chunk
36 * @returns {string} the relative path
37 */
38const getRelativePath = (compilation, chunk, runtimeChunk) => {
39 const currentOutputName = compilation
40 .getPath(
41 getChunkFilenameTemplate(runtimeChunk, compilation.outputOptions),
42 {
43 chunk: runtimeChunk,
44 contentHashType: "javascript"
45 }
46 )
47 .replace(/^\/+/g, "")
48 .split("/");
49 const baseOutputName = [...currentOutputName];
50 const chunkOutputName = compilation
51 .getPath(getChunkFilenameTemplate(chunk, compilation.outputOptions), {
52 chunk,
53 contentHashType: "javascript"
54 })
55 .replace(/^\/+/g, "")
56 .split("/");
57
58 // remove common parts except filename
59 while (
60 baseOutputName.length > 1 &&
61 chunkOutputName.length > 1 &&
62 baseOutputName[0] === chunkOutputName[0]
63 ) {
64 baseOutputName.shift();
65 chunkOutputName.shift();
66 }
67 const last = chunkOutputName.join("/");
68 // create final path
69 return getUndoPath(baseOutputName.join("/"), last, true) + last;
70};
71
72/**
73 * Renders chunk import.
74 * @param {Compilation} compilation the compilation instance
75 * @param {Chunk} chunk the chunk to render the import for
76 * @param {string=} namedImport the named import to use for the import
77 * @param {Chunk=} runtimeChunk the runtime chunk
78 * @returns {string} the import source
79 */
80function renderChunkImport(compilation, chunk, namedImport, runtimeChunk) {
81 return `import ${namedImport ? `* as ${namedImport}` : `{ ${RuntimeGlobals.require} }`} from ${JSON.stringify(
82 getRelativePath(compilation, chunk, runtimeChunk || chunk)
83 )};\n`;
84}
85
86/**
87 * Gets chunk named import.
88 * @param {number} index the index of the chunk
89 * @returns {string} the named import to use for the import
90 */
91function getChunkNamedImport(index) {
92 return `__webpack_chunk_${index}__`;
93}
94
95const PLUGIN_NAME = "ModuleChunkFormatPlugin";
96
97class ModuleChunkFormatPlugin {
98 /**
99 * Applies the plugin by registering its hooks on the compiler.
100 * @param {Compiler} compiler the compiler instance
101 * @returns {void}
102 */
103 apply(compiler) {
104 compiler.hooks.thisCompilation.tap(PLUGIN_NAME, (compilation) => {
105 compilation.hooks.additionalChunkRuntimeRequirements.tap(
106 PLUGIN_NAME,
107 (chunk, set) => {
108 if (chunk.hasRuntime()) return;
109 if (compilation.chunkGraph.getNumberOfEntryModules(chunk) > 0) {
110 set.add(RuntimeGlobals.require);
111 set.add(RuntimeGlobals.externalInstallChunk);
112 }
113 }
114 );
115 const hooks = getCompilationHooks(compilation);
116 /**
117 * With dependent chunks.
118 * @param {Iterable<Chunk>} chunks the chunks to render
119 * @param {ChunkGraph} chunkGraph the chunk graph
120 * @param {Chunk=} runtimeChunk the runtime chunk
121 * @returns {Source | undefined} the source
122 */
123 const withDependentChunks = (chunks, chunkGraph, runtimeChunk) => {
124 if (/** @type {Set<Chunk>} */ (chunks).size > 0) {
125 const source = new ConcatSource();
126 let index = 0;
127
128 for (const chunk of chunks) {
129 index++;
130
131 if (!chunkHasJs(chunk, chunkGraph)) {
132 continue;
133 }
134 const namedImport = getChunkNamedImport(index);
135 source.add(
136 renderChunkImport(
137 compilation,
138 chunk,
139 namedImport,
140 runtimeChunk || chunk
141 )
142 );
143 source.add(
144 `${RuntimeGlobals.externalInstallChunk}(${namedImport});\n`
145 );
146 }
147 return source;
148 }
149 };
150 hooks.renderStartup.tap(
151 PLUGIN_NAME,
152 (modules, _lastModule, renderContext) => {
153 const { chunk, chunkGraph } = renderContext;
154 if (
155 chunkGraph.getNumberOfEntryModules(chunk) > 0 &&
156 chunk.hasRuntime()
157 ) {
158 const entryDependentChunks =
159 chunkGraph.getChunkEntryDependentChunksIterable(chunk);
160 const sourceWithDependentChunks = withDependentChunks(
161 entryDependentChunks,
162 chunkGraph,
163 chunk
164 );
165 if (!sourceWithDependentChunks) {
166 return modules;
167 }
168 if (modules.size() === 0) {
169 return sourceWithDependentChunks;
170 }
171 const source = new ConcatSource();
172 source.add(sourceWithDependentChunks);
173 source.add("\n");
174 source.add(modules);
175 return source;
176 }
177 return modules;
178 }
179 );
180 hooks.renderChunk.tap(PLUGIN_NAME, (modules, renderContext) => {
181 const { chunk, chunkGraph, runtimeTemplate } = renderContext;
182 const hotUpdateChunk = chunk instanceof HotUpdateChunk ? chunk : null;
183 const source = new ConcatSource();
184 source.add(
185 `export const ${RuntimeGlobals.esmId} = ${JSON.stringify(chunk.id)};\n`
186 );
187 source.add(
188 `export const ${RuntimeGlobals.esmIds} = ${JSON.stringify(chunk.ids)};\n`
189 );
190 source.add(`export const ${RuntimeGlobals.esmModules} = `);
191 source.add(modules);
192 source.add(";\n");
193 const runtimeModules = chunkGraph.getChunkRuntimeModulesInOrder(chunk);
194 if (runtimeModules.length > 0) {
195 source.add(`export const ${RuntimeGlobals.esmRuntime} =\n`);
196 source.add(
197 Template.renderChunkRuntimeModules(runtimeModules, renderContext)
198 );
199 }
200 if (hotUpdateChunk) {
201 return source;
202 }
203 const { entries, runtimeChunk } = getChunkInfo(chunk, chunkGraph);
204 if (runtimeChunk) {
205 const entrySource = new ConcatSource();
206 entrySource.add(source);
207 entrySource.add(";\n\n// load runtime\n");
208 entrySource.add(
209 renderChunkImport(compilation, runtimeChunk, "", chunk)
210 );
211 const startupSource = new ConcatSource();
212 startupSource.add(
213 `var __webpack_exec__ = ${runtimeTemplate.returningFunction(
214 `${RuntimeGlobals.require}(${RuntimeGlobals.entryModuleId} = moduleId)`,
215 "moduleId"
216 )}\n`
217 );
218
219 /** @type {Set<Chunk>} */
220 const loadedChunks = new Set();
221 for (let i = 0; i < entries.length; i++) {
222 const [module, entrypoint] = entries[i];
223 if (!chunkGraph.getModuleSourceTypes(module).has(JAVASCRIPT_TYPE)) {
224 continue;
225 }
226 const final = i + 1 === entries.length;
227 const moduleId = chunkGraph.getModuleId(module);
228 const chunks = getAllChunks(
229 /** @type {Entrypoint} */ (entrypoint),
230 /** @type {Chunk} */ (runtimeChunk),
231 undefined
232 );
233 /** @type {Set<Chunk>} */
234 const processChunks = new Set();
235 for (const chunk of chunks) {
236 if (loadedChunks.has(chunk)) {
237 continue;
238 }
239 loadedChunks.add(chunk);
240 processChunks.add(chunk);
241 }
242 const sourceWithDependentChunks = withDependentChunks(
243 processChunks,
244 chunkGraph,
245 chunk
246 );
247 if (sourceWithDependentChunks) {
248 startupSource.add("\n");
249 startupSource.add(sourceWithDependentChunks);
250 }
251 startupSource.add(
252 `${
253 final ? `var ${RuntimeGlobals.exports} = ` : ""
254 }__webpack_exec__(${JSON.stringify(moduleId)});\n`
255 );
256 }
257
258 entrySource.add(
259 hooks.renderStartup.call(
260 startupSource,
261 entries[entries.length - 1][0],
262 renderContext
263 )
264 );
265 return entrySource;
266 }
267 return source;
268 });
269 hooks.chunkHash.tap(PLUGIN_NAME, createChunkHashHandler(PLUGIN_NAME));
270 });
271 }
272}
273
274module.exports = ModuleChunkFormatPlugin;
Note: See TracBrowser for help on using the repository browser.