source: frontend/node_modules/webpack/lib/config/target.js

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

Fix frontend appearance

  • Property mode set to 100644
File size: 12.5 KB
RevLine 
[9af201e]1/*
2 MIT License http://www.opensource.org/licenses/mit-license.php
3 Author Tobias Koppers @sokra
4*/
5
6"use strict";
7
8const memoize = require("../util/memoize");
9
10const getBrowserslistTargetHandler = memoize(() =>
11 require("./browserslistTargetHandler")
12);
13
14/**
15 * Gets default target.
16 * @param {string} context the context directory
17 * @returns {string} default target
18 */
19const getDefaultTarget = (context) => {
20 const browsers = getBrowserslistTargetHandler().load(undefined, context);
21 return browsers ? "browserslist" : "web";
22};
23
24/**
25 * Defines the platform target properties type used by this module.
26 * @typedef {object} PlatformTargetProperties
27 * @property {boolean | null=} web web platform, importing of http(s) and std: is available
28 * @property {boolean | null=} browser browser platform, running in a normal web browser
29 * @property {boolean | null=} webworker (Web)Worker platform, running in a web/shared/service worker
30 * @property {boolean | null=} node node platform, require of node built-in modules is available
31 * @property {boolean | null=} nwjs nwjs platform, require of legacy nw.gui is available
32 * @property {boolean | null=} electron electron platform, require of some electron built-in modules is available
33 */
34
35/**
36 * Defines the electron context target properties type used by this module.
37 * @typedef {object} ElectronContextTargetProperties
38 * @property {boolean | null} electronMain in main context
39 * @property {boolean | null} electronPreload in preload context
40 * @property {boolean | null} electronRenderer in renderer context with node integration
41 */
42
43/**
44 * Defines the api target properties type used by this module.
45 * @typedef {object} ApiTargetProperties
46 * @property {boolean | null} require has require function available
47 * @property {boolean | null} nodeBuiltins has node.js built-in modules available
48 * @property {boolean | null} nodePrefixForCoreModules node.js allows to use `node:` prefix for core modules
49 * @property {boolean | null} importMetaDirnameAndFilename node.js allows to use `import.meta.dirname` and `import.meta.filename`
50 * @property {boolean | null} document has document available (allows script tags)
51 * @property {boolean | null} importScripts has importScripts available
52 * @property {boolean | null} importScriptsInWorker has importScripts available when creating a worker
53 * @property {boolean | null} fetchWasm has fetch function available for WebAssembly
54 * @property {boolean | null} global has global variable available
55 */
56
57/**
58 * Defines the ecma target properties type used by this module.
59 * @typedef {object} EcmaTargetProperties
60 * @property {boolean | null} globalThis has globalThis variable available
61 * @property {boolean | null} bigIntLiteral big int literal syntax is available
62 * @property {boolean | null} const const and let variable declarations are available
63 * @property {boolean | null} methodShorthand object method shorthand is available
64 * @property {boolean | null} arrowFunction arrow functions are available
65 * @property {boolean | null} forOf for of iteration is available
66 * @property {boolean | null} destructuring destructuring is available
67 * @property {boolean | null} dynamicImport async import() is available
68 * @property {boolean | null} dynamicImportInWorker async import() is available when creating a worker
69 * @property {boolean | null} module ESM syntax is available (when in module)
70 * @property {boolean | null} optionalChaining optional chaining is available
71 * @property {boolean | null} templateLiteral template literal is available
72 * @property {boolean | null} asyncFunction async functions and await are available
73 */
74
75/**
76 * Defines the shared type used by this module.
77 * @template T
78 * @typedef {{ [P in keyof T]?: never }} Never<T>
79 */
80
81/**
82 * Defines the shared type used by this module.
83 * @template A
84 * @template B
85 * @typedef {(A & Never<B>) | (Never<A> & B) | (A & B)} Mix<A, B>
86 */
87
88/** @typedef {Mix<Mix<PlatformTargetProperties, ElectronContextTargetProperties>, Mix<ApiTargetProperties, EcmaTargetProperties>>} TargetProperties */
89
90/**
91 * Returns check if version is greater or equal.
92 * @param {string} major major version
93 * @param {string | undefined} minor minor version
94 * @returns {(vMajor: number, vMinor?: number) => boolean | undefined} check if version is greater or equal
95 */
96const versionDependent = (major, minor) => {
97 if (!major) {
98 return () => /** @type {undefined} */ (undefined);
99 }
100 /** @type {number} */
101 const nMajor = Number(major);
102 /** @type {number} */
103 const nMinor = minor ? Number(minor) : 0;
104 return (vMajor, vMinor = 0) =>
105 nMajor > vMajor || (nMajor === vMajor && nMinor >= vMinor);
106};
107
108/** @type {[string, string, RegExp, (...args: string[]) => Partial<TargetProperties>][]} */
109const TARGETS = [
110 [
111 "browserslist / browserslist:env / browserslist:query / browserslist:path-to-config / browserslist:path-to-config:env",
112 "Resolve features from browserslist. Will resolve browserslist config automatically. Only browser or node queries are supported (electron is not supported). Examples: 'browserslist:modern' to use 'modern' environment from browserslist config",
113 /^browserslist(?::(.+))?$/,
114 (rest, context) => {
115 const browserslistTargetHandler = getBrowserslistTargetHandler();
116 const browsers = browserslistTargetHandler.load(
117 rest ? rest.trim() : null,
118 context
119 );
120 if (!browsers) {
121 throw new Error(`No browserslist config found to handle the 'browserslist' target.
122See https://github.com/browserslist/browserslist#queries for possible ways to provide a config.
123The recommended way is to add a 'browserslist' key to your package.json and list supported browsers (resp. node.js versions).
124You can also more options via the 'target' option: 'browserslist' / 'browserslist:env' / 'browserslist:query' / 'browserslist:path-to-config' / 'browserslist:path-to-config:env'`);
125 }
126
127 return browserslistTargetHandler.resolve(browsers);
128 }
129 ],
130 [
131 "web",
132 "Web browser.",
133 /^web$/,
134 () => ({
135 node: false,
136 web: true,
137 webworker: null,
138 browser: true,
139 electron: false,
140 nwjs: false,
141
142 document: true,
143 importScriptsInWorker: true,
144 fetchWasm: true,
145 nodeBuiltins: false,
146 importScripts: false,
147 require: false,
148 global: false
149 })
150 ],
151 [
152 "webworker",
153 "Web Worker, SharedWorker or Service Worker.",
154 /^webworker$/,
155 () => ({
156 node: false,
157 web: true,
158 webworker: true,
159 browser: true,
160 electron: false,
161 nwjs: false,
162
163 importScripts: true,
164 importScriptsInWorker: true,
165 fetchWasm: true,
166 nodeBuiltins: false,
167 require: false,
168 document: false,
169 global: false
170 })
171 ],
172 [
173 "[async-]node[X[.Y]]",
174 "Node.js in version X.Y. The 'async-' prefix will load chunks asynchronously via 'fs' and 'vm' instead of 'require()'. Examples: node14.5, async-node10.",
175 /^(async-)?node((\d+)(?:\.(\d+))?)?$/,
176 (asyncFlag, _, major, minor) => {
177 const v = versionDependent(major, minor);
178 // see https://node.green/
179 return {
180 node: true,
181 web: false,
182 webworker: false,
183 browser: false,
184 electron: false,
185 nwjs: false,
186
187 require: !asyncFlag,
188 nodeBuiltins: true,
189 // v16.0.0, v14.18.0
190 nodePrefixForCoreModules: Number(major) < 15 ? v(14, 18) : v(16),
191 // Added in: v21.2.0, v20.11.0, but Node.js will output experimental warning, we don't want it
192 // v24.0.0, v22.16.0 - This property is no longer experimental.
193 importMetaDirnameAndFilename: v(22, 16),
194 global: true,
195 document: false,
196 fetchWasm: false,
197 importScripts: false,
198 importScriptsInWorker: false,
199
200 globalThis: v(12),
201 const: v(6),
202 templateLiteral: v(4),
203 optionalChaining: v(14),
204 methodShorthand: v(4),
205 arrowFunction: v(6),
206 asyncFunction: v(7, 6),
207 forOf: v(5),
208 destructuring: v(6),
209 bigIntLiteral: v(10, 4),
210 dynamicImport: v(12, 17),
211 dynamicImportInWorker: v(12, 17),
212 module: v(12, 17)
213 };
214 }
215 ],
216 [
217 "electron[X[.Y]]-main/preload/renderer",
218 "Electron in version X.Y. Script is running in main, preload resp. renderer context.",
219 /^electron((\d+)(?:\.(\d+))?)?-(main|preload|renderer)$/,
220 (_, major, minor, context) => {
221 const v = versionDependent(major, minor);
222 // see https://node.green/ + https://github.com/electron/releases
223 return {
224 node: true,
225 web: context !== "main",
226 webworker: false,
227 browser: false,
228 electron: true,
229 nwjs: false,
230
231 electronMain: context === "main",
232 electronPreload: context === "preload",
233 electronRenderer: context === "renderer",
234
235 global: true,
236 nodeBuiltins: true,
237 // 15.0.0 - Node.js v16.5
238 // 14.0.0 - Mode.js v14.17, but prefixes only since v14.18
239 nodePrefixForCoreModules: v(15),
240 // 37.0.0 - Node.js v22.16
241 importMetaDirnameAndFilename: v(37),
242
243 require: true,
244 document: context === "renderer",
245 fetchWasm: context === "renderer",
246 importScripts: false,
247 importScriptsInWorker: true,
248
249 globalThis: v(5),
250 const: v(1, 1),
251 templateLiteral: v(1, 1),
252 optionalChaining: v(8),
253 methodShorthand: v(1, 1),
254 arrowFunction: v(1, 1),
255 asyncFunction: v(1, 7),
256 forOf: v(0, 36),
257 destructuring: v(1, 1),
258 bigIntLiteral: v(4),
259 dynamicImport: v(11),
260 dynamicImportInWorker: v(11),
261 module: v(11)
262 };
263 }
264 ],
265 [
266 "nwjs[X[.Y]] / node-webkit[X[.Y]]",
267 "NW.js in version X.Y.",
268 /^(?:nwjs|node-webkit)((\d+)(?:\.(\d+))?)?$/,
269 (_, major, minor) => {
270 const v = versionDependent(major, minor);
271 // see https://node.green/ + https://github.com/nwjs/nw.js/blob/nw48/CHANGELOG.md
272 return {
273 node: true,
274 web: true,
275 webworker: null,
276 browser: false,
277 electron: false,
278 nwjs: true,
279
280 global: true,
281 nodeBuiltins: true,
282 document: false,
283 importScriptsInWorker: false,
284 fetchWasm: false,
285 importScripts: false,
286 require: false,
287
288 globalThis: v(0, 43),
289 const: v(0, 15),
290 templateLiteral: v(0, 13),
291 optionalChaining: v(0, 44),
292 methodShorthand: v(0, 15),
293 arrowFunction: v(0, 15),
294 asyncFunction: v(0, 21),
295 forOf: v(0, 13),
296 destructuring: v(0, 15),
297 bigIntLiteral: v(0, 32),
298 dynamicImport: v(0, 43),
299 dynamicImportInWorker: v(0, 44),
300 module: v(0, 43)
301 };
302 }
303 ],
304 [
305 "esX",
306 "EcmaScript in this version. Examples: es2020, es5.",
307 /^es(\d+)$/,
308 (version) => {
309 let v = Number(version);
310 if (v < 1000) v += 2009;
311 return {
312 const: v >= 2015,
313 templateLiteral: v >= 2015,
314 optionalChaining: v >= 2020,
315 methodShorthand: v >= 2015,
316 arrowFunction: v >= 2015,
317 forOf: v >= 2015,
318 destructuring: v >= 2015,
319 module: v >= 2015,
320 asyncFunction: v >= 2017,
321 globalThis: v >= 2020,
322 bigIntLiteral: v >= 2020,
323 dynamicImport: v >= 2020,
324 dynamicImportInWorker: v >= 2020
325 };
326 }
327 ]
328];
329
330/**
331 * Gets target properties.
332 * @param {string} target the target
333 * @param {string} context the context directory
334 * @returns {TargetProperties} target properties
335 */
336const getTargetProperties = (target, context) => {
337 for (const [, , regExp, handler] of TARGETS) {
338 const match = regExp.exec(target);
339 if (match) {
340 const [, ...args] = match;
341 const result = handler(...args, context);
342 if (result) return /** @type {TargetProperties} */ (result);
343 }
344 }
345 throw new Error(
346 `Unknown target '${target}'. The following targets are supported:\n${TARGETS.map(
347 ([name, description]) => `* ${name}: ${description}`
348 ).join("\n")}`
349 );
350};
351
352/**
353 * Merges target properties.
354 * @param {TargetProperties[]} targetProperties array of target properties
355 * @returns {TargetProperties} merged target properties
356 */
357const mergeTargetProperties = (targetProperties) => {
358 /** @type {Set<keyof TargetProperties>} */
359 const keys = new Set();
360 for (const tp of targetProperties) {
361 for (const key of Object.keys(tp)) {
362 keys.add(/** @type {keyof TargetProperties} */ (key));
363 }
364 }
365 /** @type {TargetProperties} */
366 const result = {};
367 for (const key of keys) {
368 let hasTrue = false;
369 let hasFalse = false;
370 for (const tp of targetProperties) {
371 const value = tp[key];
372 switch (value) {
373 case true:
374 hasTrue = true;
375 break;
376 case false:
377 hasFalse = true;
378 break;
379 }
380 }
381 if (hasTrue || hasFalse) {
382 /** @type {TargetProperties} */
383 (result)[key] = hasFalse && hasTrue ? null : Boolean(hasTrue);
384 }
385 }
386 return result;
387};
388
389/**
390 * Gets targets properties.
391 * @param {string[]} targets the targets
392 * @param {string} context the context directory
393 * @returns {TargetProperties} target properties
394 */
395const getTargetsProperties = (targets, context) =>
396 mergeTargetProperties(targets.map((t) => getTargetProperties(t, context)));
397
398module.exports.getDefaultTarget = getDefaultTarget;
399module.exports.getTargetProperties = getTargetProperties;
400module.exports.getTargetsProperties = getTargetsProperties;
Note: See TracBrowser for help on using the repository browser.