source: trip-planner-front/node_modules/webpack/lib/Template.js@ 571e0df

Last change on this file since 571e0df was 6a3a178, checked in by Ema <ema_spirova@…>, 3 years ago

initial commit

  • Property mode set to 100644
File size: 12.5 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, PrefixSource } = require("webpack-sources");
9
10/** @typedef {import("webpack-sources").Source} Source */
11/** @typedef {import("../declarations/WebpackOptions").Output} OutputOptions */
12/** @typedef {import("./Chunk")} Chunk */
13/** @typedef {import("./ChunkGraph")} ChunkGraph */
14/** @typedef {import("./CodeGenerationResults")} CodeGenerationResults */
15/** @typedef {import("./Compilation").AssetInfo} AssetInfo */
16/** @typedef {import("./Compilation").PathData} PathData */
17/** @typedef {import("./DependencyTemplates")} DependencyTemplates */
18/** @typedef {import("./Module")} Module */
19/** @typedef {import("./ModuleGraph")} ModuleGraph */
20/** @typedef {import("./ModuleTemplate")} ModuleTemplate */
21/** @typedef {import("./RuntimeModule")} RuntimeModule */
22/** @typedef {import("./RuntimeTemplate")} RuntimeTemplate */
23/** @typedef {import("./javascript/JavascriptModulesPlugin").ChunkRenderContext} ChunkRenderContext */
24/** @typedef {import("./javascript/JavascriptModulesPlugin").RenderContext} RenderContext */
25
26const START_LOWERCASE_ALPHABET_CODE = "a".charCodeAt(0);
27const START_UPPERCASE_ALPHABET_CODE = "A".charCodeAt(0);
28const DELTA_A_TO_Z = "z".charCodeAt(0) - START_LOWERCASE_ALPHABET_CODE + 1;
29const NUMBER_OF_IDENTIFIER_START_CHARS = DELTA_A_TO_Z * 2 + 2; // a-z A-Z _ $
30const NUMBER_OF_IDENTIFIER_CONTINUATION_CHARS =
31 NUMBER_OF_IDENTIFIER_START_CHARS + 10; // a-z A-Z _ $ 0-9
32const FUNCTION_CONTENT_REGEX = /^function\s?\(\)\s?\{\r?\n?|\r?\n?\}$/g;
33const INDENT_MULTILINE_REGEX = /^\t/gm;
34const LINE_SEPARATOR_REGEX = /\r?\n/g;
35const IDENTIFIER_NAME_REPLACE_REGEX = /^([^a-zA-Z$_])/;
36const IDENTIFIER_ALPHA_NUMERIC_NAME_REPLACE_REGEX = /[^a-zA-Z0-9$]+/g;
37const COMMENT_END_REGEX = /\*\//g;
38const PATH_NAME_NORMALIZE_REPLACE_REGEX = /[^a-zA-Z0-9_!§$()=\-^°]+/g;
39const MATCH_PADDED_HYPHENS_REPLACE_REGEX = /^-|-$/g;
40
41/**
42 * @typedef {Object} RenderManifestOptions
43 * @property {Chunk} chunk the chunk used to render
44 * @property {string} hash
45 * @property {string} fullHash
46 * @property {OutputOptions} outputOptions
47 * @property {CodeGenerationResults} codeGenerationResults
48 * @property {{javascript: ModuleTemplate}} moduleTemplates
49 * @property {DependencyTemplates} dependencyTemplates
50 * @property {RuntimeTemplate} runtimeTemplate
51 * @property {ModuleGraph} moduleGraph
52 * @property {ChunkGraph} chunkGraph
53 */
54
55/** @typedef {RenderManifestEntryTemplated | RenderManifestEntryStatic} RenderManifestEntry */
56
57/**
58 * @typedef {Object} RenderManifestEntryTemplated
59 * @property {function(): Source} render
60 * @property {string | function(PathData, AssetInfo=): string} filenameTemplate
61 * @property {PathData=} pathOptions
62 * @property {AssetInfo=} info
63 * @property {string} identifier
64 * @property {string=} hash
65 * @property {boolean=} auxiliary
66 */
67
68/**
69 * @typedef {Object} RenderManifestEntryStatic
70 * @property {function(): Source} render
71 * @property {string} filename
72 * @property {AssetInfo} info
73 * @property {string} identifier
74 * @property {string=} hash
75 * @property {boolean=} auxiliary
76 */
77
78/**
79 * @typedef {Object} HasId
80 * @property {number | string} id
81 */
82
83/**
84 * @typedef {function(Module, number): boolean} ModuleFilterPredicate
85 */
86
87class Template {
88 /**
89 *
90 * @param {Function} fn a runtime function (.runtime.js) "template"
91 * @returns {string} the updated and normalized function string
92 */
93 static getFunctionContent(fn) {
94 return fn
95 .toString()
96 .replace(FUNCTION_CONTENT_REGEX, "")
97 .replace(INDENT_MULTILINE_REGEX, "")
98 .replace(LINE_SEPARATOR_REGEX, "\n");
99 }
100
101 /**
102 * @param {string} str the string converted to identifier
103 * @returns {string} created identifier
104 */
105 static toIdentifier(str) {
106 if (typeof str !== "string") return "";
107 return str
108 .replace(IDENTIFIER_NAME_REPLACE_REGEX, "_$1")
109 .replace(IDENTIFIER_ALPHA_NUMERIC_NAME_REPLACE_REGEX, "_");
110 }
111 /**
112 *
113 * @param {string} str string to be converted to commented in bundle code
114 * @returns {string} returns a commented version of string
115 */
116 static toComment(str) {
117 if (!str) return "";
118 return `/*! ${str.replace(COMMENT_END_REGEX, "* /")} */`;
119 }
120
121 /**
122 *
123 * @param {string} str string to be converted to "normal comment"
124 * @returns {string} returns a commented version of string
125 */
126 static toNormalComment(str) {
127 if (!str) return "";
128 return `/* ${str.replace(COMMENT_END_REGEX, "* /")} */`;
129 }
130
131 /**
132 * @param {string} str string path to be normalized
133 * @returns {string} normalized bundle-safe path
134 */
135 static toPath(str) {
136 if (typeof str !== "string") return "";
137 return str
138 .replace(PATH_NAME_NORMALIZE_REPLACE_REGEX, "-")
139 .replace(MATCH_PADDED_HYPHENS_REPLACE_REGEX, "");
140 }
141
142 // map number to a single character a-z, A-Z or multiple characters if number is too big
143 /**
144 * @param {number} n number to convert to ident
145 * @returns {string} returns single character ident
146 */
147 static numberToIdentifier(n) {
148 if (n >= NUMBER_OF_IDENTIFIER_START_CHARS) {
149 // use multiple letters
150 return (
151 Template.numberToIdentifier(n % NUMBER_OF_IDENTIFIER_START_CHARS) +
152 Template.numberToIdentifierContinuation(
153 Math.floor(n / NUMBER_OF_IDENTIFIER_START_CHARS)
154 )
155 );
156 }
157
158 // lower case
159 if (n < DELTA_A_TO_Z) {
160 return String.fromCharCode(START_LOWERCASE_ALPHABET_CODE + n);
161 }
162 n -= DELTA_A_TO_Z;
163
164 // upper case
165 if (n < DELTA_A_TO_Z) {
166 return String.fromCharCode(START_UPPERCASE_ALPHABET_CODE + n);
167 }
168
169 if (n === DELTA_A_TO_Z) return "_";
170 return "$";
171 }
172
173 /**
174 * @param {number} n number to convert to ident
175 * @returns {string} returns single character ident
176 */
177 static numberToIdentifierContinuation(n) {
178 if (n >= NUMBER_OF_IDENTIFIER_CONTINUATION_CHARS) {
179 // use multiple letters
180 return (
181 Template.numberToIdentifierContinuation(
182 n % NUMBER_OF_IDENTIFIER_CONTINUATION_CHARS
183 ) +
184 Template.numberToIdentifierContinuation(
185 Math.floor(n / NUMBER_OF_IDENTIFIER_CONTINUATION_CHARS)
186 )
187 );
188 }
189
190 // lower case
191 if (n < DELTA_A_TO_Z) {
192 return String.fromCharCode(START_LOWERCASE_ALPHABET_CODE + n);
193 }
194 n -= DELTA_A_TO_Z;
195
196 // upper case
197 if (n < DELTA_A_TO_Z) {
198 return String.fromCharCode(START_UPPERCASE_ALPHABET_CODE + n);
199 }
200 n -= DELTA_A_TO_Z;
201
202 // numbers
203 if (n < 10) {
204 return `${n}`;
205 }
206
207 if (n === 10) return "_";
208 return "$";
209 }
210
211 /**
212 *
213 * @param {string | string[]} s string to convert to identity
214 * @returns {string} converted identity
215 */
216 static indent(s) {
217 if (Array.isArray(s)) {
218 return s.map(Template.indent).join("\n");
219 } else {
220 const str = s.trimRight();
221 if (!str) return "";
222 const ind = str[0] === "\n" ? "" : "\t";
223 return ind + str.replace(/\n([^\n])/g, "\n\t$1");
224 }
225 }
226
227 /**
228 *
229 * @param {string|string[]} s string to create prefix for
230 * @param {string} prefix prefix to compose
231 * @returns {string} returns new prefix string
232 */
233 static prefix(s, prefix) {
234 const str = Template.asString(s).trim();
235 if (!str) return "";
236 const ind = str[0] === "\n" ? "" : prefix;
237 return ind + str.replace(/\n([^\n])/g, "\n" + prefix + "$1");
238 }
239
240 /**
241 *
242 * @param {string|string[]} str string or string collection
243 * @returns {string} returns a single string from array
244 */
245 static asString(str) {
246 if (Array.isArray(str)) {
247 return str.join("\n");
248 }
249 return str;
250 }
251
252 /**
253 * @typedef {Object} WithId
254 * @property {string|number} id
255 */
256
257 /**
258 * @param {WithId[]} modules a collection of modules to get array bounds for
259 * @returns {[number, number] | false} returns the upper and lower array bounds
260 * or false if not every module has a number based id
261 */
262 static getModulesArrayBounds(modules) {
263 let maxId = -Infinity;
264 let minId = Infinity;
265 for (const module of modules) {
266 const moduleId = module.id;
267 if (typeof moduleId !== "number") return false;
268 if (maxId < moduleId) maxId = moduleId;
269 if (minId > moduleId) minId = moduleId;
270 }
271 if (minId < 16 + ("" + minId).length) {
272 // add minId x ',' instead of 'Array(minId).concat(…)'
273 minId = 0;
274 }
275 // start with -1 because the first module needs no comma
276 let objectOverhead = -1;
277 for (const module of modules) {
278 // module id + colon + comma
279 objectOverhead += `${module.id}`.length + 2;
280 }
281 // number of commas, or when starting non-zero the length of Array(minId).concat()
282 const arrayOverhead = minId === 0 ? maxId : 16 + `${minId}`.length + maxId;
283 return arrayOverhead < objectOverhead ? [minId, maxId] : false;
284 }
285
286 /**
287 * @param {ChunkRenderContext} renderContext render context
288 * @param {Module[]} modules modules to render (should be ordered by identifier)
289 * @param {function(Module): Source} renderModule function to render a module
290 * @param {string=} prefix applying prefix strings
291 * @returns {Source} rendered chunk modules in a Source object
292 */
293 static renderChunkModules(renderContext, modules, renderModule, prefix = "") {
294 const { chunkGraph } = renderContext;
295 var source = new ConcatSource();
296 if (modules.length === 0) {
297 return null;
298 }
299 /** @type {{id: string|number, source: Source|string}[]} */
300 const allModules = modules.map(module => {
301 return {
302 id: chunkGraph.getModuleId(module),
303 source: renderModule(module) || "false"
304 };
305 });
306 const bounds = Template.getModulesArrayBounds(allModules);
307 if (bounds) {
308 // Render a spare array
309 const minId = bounds[0];
310 const maxId = bounds[1];
311 if (minId !== 0) {
312 source.add(`Array(${minId}).concat(`);
313 }
314 source.add("[\n");
315 /** @type {Map<string|number, {id: string|number, source: Source|string}>} */
316 const modules = new Map();
317 for (const module of allModules) {
318 modules.set(module.id, module);
319 }
320 for (let idx = minId; idx <= maxId; idx++) {
321 const module = modules.get(idx);
322 if (idx !== minId) {
323 source.add(",\n");
324 }
325 source.add(`/* ${idx} */`);
326 if (module) {
327 source.add("\n");
328 source.add(module.source);
329 }
330 }
331 source.add("\n" + prefix + "]");
332 if (minId !== 0) {
333 source.add(")");
334 }
335 } else {
336 // Render an object
337 source.add("{\n");
338 for (let i = 0; i < allModules.length; i++) {
339 const module = allModules[i];
340 if (i !== 0) {
341 source.add(",\n");
342 }
343 source.add(`\n/***/ ${JSON.stringify(module.id)}:\n`);
344 source.add(module.source);
345 }
346 source.add(`\n\n${prefix}}`);
347 }
348 return source;
349 }
350
351 /**
352 * @param {RuntimeModule[]} runtimeModules array of runtime modules in order
353 * @param {RenderContext & { codeGenerationResults?: CodeGenerationResults }} renderContext render context
354 * @returns {Source} rendered runtime modules in a Source object
355 */
356 static renderRuntimeModules(runtimeModules, renderContext) {
357 const source = new ConcatSource();
358 for (const module of runtimeModules) {
359 const codeGenerationResults = renderContext.codeGenerationResults;
360 let runtimeSource;
361 if (codeGenerationResults) {
362 runtimeSource = codeGenerationResults.getSource(
363 module,
364 renderContext.chunk.runtime,
365 "runtime"
366 );
367 } else {
368 const codeGenResult = module.codeGeneration({
369 chunkGraph: renderContext.chunkGraph,
370 dependencyTemplates: renderContext.dependencyTemplates,
371 moduleGraph: renderContext.moduleGraph,
372 runtimeTemplate: renderContext.runtimeTemplate,
373 runtime: renderContext.chunk.runtime
374 });
375 if (!codeGenResult) continue;
376 runtimeSource = codeGenResult.sources.get("runtime");
377 }
378 if (runtimeSource) {
379 source.add(Template.toNormalComment(module.identifier()) + "\n");
380 if (!module.shouldIsolate()) {
381 source.add(runtimeSource);
382 source.add("\n\n");
383 } else if (renderContext.runtimeTemplate.supportsArrowFunction()) {
384 source.add("(() => {\n");
385 source.add(new PrefixSource("\t", runtimeSource));
386 source.add("\n})();\n\n");
387 } else {
388 source.add("!function() {\n");
389 source.add(new PrefixSource("\t", runtimeSource));
390 source.add("\n}();\n\n");
391 }
392 }
393 }
394 return source;
395 }
396
397 /**
398 * @param {RuntimeModule[]} runtimeModules array of runtime modules in order
399 * @param {RenderContext} renderContext render context
400 * @returns {Source} rendered chunk runtime modules in a Source object
401 */
402 static renderChunkRuntimeModules(runtimeModules, renderContext) {
403 return new PrefixSource(
404 "/******/ ",
405 new ConcatSource(
406 "function(__webpack_require__) { // webpackRuntimeModules\n",
407 this.renderRuntimeModules(runtimeModules, renderContext),
408 "}\n"
409 )
410 );
411 }
412}
413
414module.exports = Template;
415module.exports.NUMBER_OF_IDENTIFIER_START_CHARS =
416 NUMBER_OF_IDENTIFIER_START_CHARS;
417module.exports.NUMBER_OF_IDENTIFIER_CONTINUATION_CHARS =
418 NUMBER_OF_IDENTIFIER_CONTINUATION_CHARS;
Note: See TracBrowser for help on using the repository browser.