@jsenv/core 37.1.5 → 38.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/js/autoreload.js +2 -2
- package/dist/jsenv_core.js +3231 -2483
- package/package.json +14 -13
- package/src/build/build.js +250 -1028
- package/src/build/build_specifier_manager.js +1200 -0
- package/src/build/build_urls_generator.js +40 -18
- package/src/build/version_mappings_injection.js +14 -16
- package/src/dev/file_service.js +0 -10
- package/src/dev/start_dev_server.js +0 -2
- package/src/kitchen/kitchen.js +54 -37
- package/src/kitchen/url_graph/references.js +84 -93
- package/src/kitchen/url_graph/url_graph.js +16 -6
- package/src/kitchen/url_graph/url_info_transformations.js +124 -55
- package/src/plugins/autoreload/client/autoreload.js +6 -2
- package/src/plugins/autoreload/jsenv_plugin_autoreload_server.js +20 -16
- package/src/plugins/autoreload/jsenv_plugin_hot_search_param.js +1 -1
- package/src/plugins/cache_control/jsenv_plugin_cache_control.js +2 -2
- package/src/plugins/clean_html/jsenv_plugin_clean_html.js +16 -0
- package/src/plugins/importmap/jsenv_plugin_importmap.js +11 -23
- package/src/plugins/inlining/jsenv_plugin_inlining_as_data_url.js +16 -1
- package/src/plugins/inlining/jsenv_plugin_inlining_into_html.js +14 -24
- package/src/plugins/plugin_controller.js +37 -25
- package/src/plugins/plugins.js +2 -0
- package/src/plugins/protocol_file/jsenv_plugin_protocol_file.js +31 -16
- package/src/plugins/reference_analysis/directory/jsenv_plugin_directory_reference_analysis.js +12 -6
- package/src/plugins/reference_analysis/html/jsenv_plugin_html_reference_analysis.js +33 -54
- package/src/plugins/reference_analysis/js/jsenv_plugin_js_reference_analysis.js +2 -9
- package/src/plugins/reference_analysis/jsenv_plugin_reference_analysis.js +15 -8
- package/src/build/build_versions_manager.js +0 -492
package/src/build/build.js
CHANGED
|
@@ -16,38 +16,16 @@
|
|
|
16
16
|
* - injecting urls into service workers
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
|
-
import {
|
|
20
|
-
asUrlWithoutSearch,
|
|
21
|
-
ensurePathnameTrailingSlash,
|
|
22
|
-
urlIsInsideOf,
|
|
23
|
-
urlToRelativeUrl,
|
|
24
|
-
} from "@jsenv/urls";
|
|
25
19
|
import {
|
|
26
20
|
assertAndNormalizeDirectoryUrl,
|
|
27
21
|
ensureEmptyDirectory,
|
|
28
22
|
writeFileSync,
|
|
29
|
-
comparePathnames,
|
|
30
23
|
} from "@jsenv/filesystem";
|
|
31
24
|
import { Abort, raceProcessTeardownEvents } from "@jsenv/abort";
|
|
32
|
-
import {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
createDetailedMessage,
|
|
37
|
-
} from "@jsenv/log";
|
|
38
|
-
import { generateSourcemapFileUrl } from "@jsenv/sourcemap";
|
|
39
|
-
import {
|
|
40
|
-
parseHtmlString,
|
|
41
|
-
stringifyHtmlAst,
|
|
42
|
-
visitHtmlNodes,
|
|
43
|
-
getHtmlNodeAttribute,
|
|
44
|
-
setHtmlNodeAttributes,
|
|
45
|
-
removeHtmlNode,
|
|
46
|
-
createHtmlNode,
|
|
47
|
-
insertHtmlNodeAfter,
|
|
48
|
-
findHtmlNode,
|
|
49
|
-
} from "@jsenv/ast";
|
|
50
|
-
import { RUNTIME_COMPAT } from "@jsenv/runtime-compat";
|
|
25
|
+
import { createLogger, createTaskLog } from "@jsenv/log";
|
|
26
|
+
import { parseHtmlString, stringifyHtmlAst } from "@jsenv/ast";
|
|
27
|
+
import { jsenvPluginBundling } from "@jsenv/plugin-bundling";
|
|
28
|
+
import { jsenvPluginMinification } from "@jsenv/plugin-minification";
|
|
51
29
|
import { jsenvPluginJsModuleFallback } from "@jsenv/plugin-transpilation";
|
|
52
30
|
|
|
53
31
|
import { lookupPackageDirectory } from "../helpers/lookup_package_directory.js";
|
|
@@ -55,15 +33,12 @@ import { watchSourceFiles } from "../helpers/watch_source_files.js";
|
|
|
55
33
|
import { GRAPH_VISITOR } from "../kitchen/url_graph/url_graph_visitor.js";
|
|
56
34
|
import { createKitchen } from "../kitchen/kitchen.js";
|
|
57
35
|
import { createUrlGraphSummary } from "../kitchen/url_graph/url_graph_report.js";
|
|
58
|
-
import { isWebWorkerEntryPointReference } from "../kitchen/web_workers.js";
|
|
59
|
-
import { prependContent } from "../kitchen/prepend_content.js";
|
|
60
36
|
import { getCorePlugins } from "../plugins/plugins.js";
|
|
61
37
|
import { jsenvPluginReferenceAnalysis } from "../plugins/reference_analysis/jsenv_plugin_reference_analysis.js";
|
|
62
38
|
import { jsenvPluginInlining } from "../plugins/inlining/jsenv_plugin_inlining.js";
|
|
63
39
|
import { jsenvPluginLineBreakNormalization } from "./jsenv_plugin_line_break_normalization.js";
|
|
64
40
|
|
|
65
|
-
import {
|
|
66
|
-
import { createBuildVersionsManager } from "./build_versions_manager.js";
|
|
41
|
+
import { createBuildSpecifierManager } from "./build_specifier_manager.js";
|
|
67
42
|
|
|
68
43
|
// default runtimeCompat corresponds to
|
|
69
44
|
// "we can keep <script type="module"> intact":
|
|
@@ -95,6 +70,10 @@ export const defaultRuntimeCompat = {
|
|
|
95
70
|
* Directory where asset files will be written
|
|
96
71
|
* @param {string|url} [buildParameters.base=""]
|
|
97
72
|
* Urls in build file contents will be prefixed with this string
|
|
73
|
+
* @param {boolean|object} [buildParameters.bundling=true]
|
|
74
|
+
* Reduce number of files written in the build directory
|
|
75
|
+
* @param {boolean|object} [buildParameters.minification=true]
|
|
76
|
+
* Minify the content of files generated into the build directory
|
|
98
77
|
* @param {boolean} [buildParameters.versioning=true]
|
|
99
78
|
* Controls if url in build file contents are versioned
|
|
100
79
|
* @param {('search_param'|'filename')} [buildParameters.versioningMethod="search_param"]
|
|
@@ -117,10 +96,10 @@ export const build = async ({
|
|
|
117
96
|
buildDirectoryUrl,
|
|
118
97
|
entryPoints = {},
|
|
119
98
|
assetsDirectory = "",
|
|
120
|
-
ignore,
|
|
121
|
-
|
|
122
99
|
runtimeCompat = defaultRuntimeCompat,
|
|
123
100
|
base = runtimeCompat.node ? "./" : "/",
|
|
101
|
+
ignore,
|
|
102
|
+
|
|
124
103
|
plugins = [],
|
|
125
104
|
referenceAnalysis = {},
|
|
126
105
|
nodeEsmResolution,
|
|
@@ -129,6 +108,8 @@ export const build = async ({
|
|
|
129
108
|
directoryReferenceAllowed,
|
|
130
109
|
scenarioPlaceholders,
|
|
131
110
|
transpilation = {},
|
|
111
|
+
bundling = true,
|
|
112
|
+
minification = !runtimeCompat.node,
|
|
132
113
|
versioning = !runtimeCompat.node,
|
|
133
114
|
versioningMethod = "search_param", // "filename", "search_param"
|
|
134
115
|
versioningViaImportmap = true,
|
|
@@ -205,6 +186,12 @@ export const build = async ({
|
|
|
205
186
|
`versioningMethod must be "filename" or "search_param", got ${versioning}`,
|
|
206
187
|
);
|
|
207
188
|
}
|
|
189
|
+
if (bundling === true) {
|
|
190
|
+
bundling = {};
|
|
191
|
+
}
|
|
192
|
+
if (minification === true) {
|
|
193
|
+
minification = {};
|
|
194
|
+
}
|
|
208
195
|
}
|
|
209
196
|
|
|
210
197
|
const operation = Abort.startOperation();
|
|
@@ -231,26 +218,6 @@ export const build = async ({
|
|
|
231
218
|
}
|
|
232
219
|
}
|
|
233
220
|
|
|
234
|
-
const asFormattedBuildSpecifier = (reference, generatedUrl) => {
|
|
235
|
-
if (base === "./") {
|
|
236
|
-
const parentUrl =
|
|
237
|
-
reference.ownerUrlInfo.url === sourceDirectoryUrl
|
|
238
|
-
? buildDirectoryUrl
|
|
239
|
-
: reference.ownerUrlInfo.url;
|
|
240
|
-
const urlRelativeToParent = urlToRelativeUrl(generatedUrl, parentUrl);
|
|
241
|
-
if (urlRelativeToParent[0] !== ".") {
|
|
242
|
-
// ensure "./" on relative url (otherwise it could be a "bare specifier")
|
|
243
|
-
return `./${urlRelativeToParent}`;
|
|
244
|
-
}
|
|
245
|
-
return urlRelativeToParent;
|
|
246
|
-
}
|
|
247
|
-
const urlRelativeToBuildDirectory = urlToRelativeUrl(
|
|
248
|
-
generatedUrl,
|
|
249
|
-
buildDirectoryUrl,
|
|
250
|
-
);
|
|
251
|
-
return `${base}${urlRelativeToBuildDirectory}`;
|
|
252
|
-
};
|
|
253
|
-
|
|
254
221
|
const runBuild = async ({ signal, logLevel }) => {
|
|
255
222
|
const logger = createLogger({ logLevel });
|
|
256
223
|
const createBuildTask = (label) => {
|
|
@@ -274,30 +241,13 @@ build ${entryPointKeys.length} entry points`);
|
|
|
274
241
|
key.includes("?js_module_fallback"),
|
|
275
242
|
);
|
|
276
243
|
const rawRedirections = new Map();
|
|
277
|
-
const bundleRedirections = new Map();
|
|
278
|
-
const bundleInternalRedirections = new Map();
|
|
279
|
-
const finalRedirections = new Map();
|
|
280
244
|
const entryUrls = [];
|
|
281
245
|
const contextSharedDuringBuild = {
|
|
246
|
+
buildStep: "craft",
|
|
282
247
|
buildDirectoryUrl,
|
|
283
248
|
assetsDirectory,
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
if (nodeRuntimeEnabled) return false;
|
|
287
|
-
if (!RUNTIME_COMPAT.isSupported(runtimeCompat, "script_type_module"))
|
|
288
|
-
return true;
|
|
289
|
-
if (!RUNTIME_COMPAT.isSupported(runtimeCompat, "import_dynamic"))
|
|
290
|
-
return true;
|
|
291
|
-
if (!RUNTIME_COMPAT.isSupported(runtimeCompat, "import_meta"))
|
|
292
|
-
return true;
|
|
293
|
-
if (
|
|
294
|
-
versioning &&
|
|
295
|
-
versioningViaImportmap &&
|
|
296
|
-
!RUNTIME_COMPAT.isSupported(runtimeCompat, "importmap")
|
|
297
|
-
)
|
|
298
|
-
return true;
|
|
299
|
-
return false;
|
|
300
|
-
})(),
|
|
249
|
+
versioning,
|
|
250
|
+
versioningViaImportmap,
|
|
301
251
|
};
|
|
302
252
|
const rawKitchen = createKitchen({
|
|
303
253
|
signal,
|
|
@@ -309,9 +259,11 @@ build ${entryPointKeys.length} entry points`);
|
|
|
309
259
|
ignoreProtocol: "keep",
|
|
310
260
|
build: true,
|
|
311
261
|
runtimeCompat,
|
|
312
|
-
|
|
262
|
+
initialContext: contextSharedDuringBuild,
|
|
313
263
|
plugins: [
|
|
314
264
|
...plugins,
|
|
265
|
+
...(bundling ? [jsenvPluginBundling(bundling)] : []),
|
|
266
|
+
...(minification ? [jsenvPluginMinification(minification)] : []),
|
|
315
267
|
{
|
|
316
268
|
appliesDuring: "build",
|
|
317
269
|
fetchUrlContent: (urlInfo) => {
|
|
@@ -334,9 +286,8 @@ build ${entryPointKeys.length} entry points`);
|
|
|
334
286
|
transpilation: {
|
|
335
287
|
babelHelpersAsImport: !explicitJsModuleFallback,
|
|
336
288
|
...transpilation,
|
|
337
|
-
|
|
289
|
+
jsModuleFallback: false,
|
|
338
290
|
},
|
|
339
|
-
|
|
340
291
|
inlining: false,
|
|
341
292
|
scenarioPlaceholders,
|
|
342
293
|
}),
|
|
@@ -344,38 +295,14 @@ build ${entryPointKeys.length} entry points`);
|
|
|
344
295
|
sourcemaps,
|
|
345
296
|
sourcemapsSourcesContent,
|
|
346
297
|
outDirectoryUrl: outDirectoryUrl
|
|
347
|
-
? new URL("
|
|
298
|
+
? new URL("craft/", outDirectoryUrl)
|
|
348
299
|
: undefined,
|
|
349
300
|
});
|
|
350
|
-
|
|
351
|
-
const buildUrlsGenerator = createBuildUrlsGenerator({
|
|
352
|
-
buildDirectoryUrl,
|
|
353
|
-
assetsDirectory,
|
|
354
|
-
});
|
|
355
|
-
const buildDirectoryRedirections = new Map();
|
|
356
|
-
const associateBuildUrlAndRawUrl = (buildUrl, rawUrl, reason) => {
|
|
357
|
-
if (urlIsInsideOf(rawUrl, buildDirectoryUrl)) {
|
|
358
|
-
throw new Error(`raw url must be inside rawGraph, got ${rawUrl}`);
|
|
359
|
-
}
|
|
360
|
-
if (buildDirectoryRedirections.get(buildUrl) !== rawUrl) {
|
|
361
|
-
logger.debug(`build url generated (${reason})
|
|
362
|
-
${ANSI.color(rawUrl, ANSI.GREY)} ->
|
|
363
|
-
${ANSI.color(buildUrl, ANSI.MAGENTA)}
|
|
364
|
-
`);
|
|
365
|
-
buildDirectoryRedirections.set(buildUrl, rawUrl);
|
|
366
|
-
}
|
|
367
|
-
};
|
|
368
|
-
const buildSpecifierMap = new Map();
|
|
369
|
-
const bundleUrlInfos = {};
|
|
370
|
-
const bundlers = {};
|
|
371
|
-
let finalKitchen;
|
|
372
|
-
let finalEntryUrls = [];
|
|
373
|
-
|
|
374
301
|
craft: {
|
|
375
302
|
const generateSourceGraph = createBuildTask("generate source graph");
|
|
376
303
|
try {
|
|
377
304
|
if (outDirectoryUrl) {
|
|
378
|
-
await ensureEmptyDirectory(new URL(`
|
|
305
|
+
await ensureEmptyDirectory(new URL(`craft/`, outDirectoryUrl));
|
|
379
306
|
}
|
|
380
307
|
const rawRootUrlInfo = rawKitchen.graph.rootUrlInfo;
|
|
381
308
|
await rawRootUrlInfo.dependencies.startCollecting(() => {
|
|
@@ -385,7 +312,7 @@ ${ANSI.color(buildUrl, ANSI.MAGENTA)}
|
|
|
385
312
|
isEntryPoint: true,
|
|
386
313
|
type: "entry_point",
|
|
387
314
|
specifier: key,
|
|
388
|
-
|
|
315
|
+
filenameHint: entryPoints[key],
|
|
389
316
|
});
|
|
390
317
|
entryUrls.push(entryReference.url);
|
|
391
318
|
});
|
|
@@ -400,634 +327,249 @@ ${ANSI.color(buildUrl, ANSI.MAGENTA)}
|
|
|
400
327
|
generateSourceGraph.done();
|
|
401
328
|
}
|
|
402
329
|
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
jsenvPluginInlining(),
|
|
432
|
-
{
|
|
433
|
-
name: "jsenv:build_shape",
|
|
434
|
-
appliesDuring: "build",
|
|
435
|
-
resolveReference: (reference) => {
|
|
436
|
-
const getUrl = () => {
|
|
437
|
-
if (reference.type === "filesystem") {
|
|
438
|
-
const ownerRawUrl = buildDirectoryRedirections.get(
|
|
439
|
-
reference.ownerUrlInfo.url,
|
|
440
|
-
);
|
|
441
|
-
const ownerUrl = ensurePathnameTrailingSlash(ownerRawUrl);
|
|
442
|
-
return new URL(reference.specifier, ownerUrl).href;
|
|
443
|
-
}
|
|
444
|
-
if (reference.specifier[0] === "/") {
|
|
445
|
-
return new URL(
|
|
446
|
-
reference.specifier.slice(1),
|
|
447
|
-
buildDirectoryUrl,
|
|
448
|
-
).href;
|
|
449
|
-
}
|
|
450
|
-
return new URL(
|
|
451
|
-
reference.specifier,
|
|
452
|
-
reference.baseUrl || reference.ownerUrlInfo.url,
|
|
453
|
-
).href;
|
|
454
|
-
};
|
|
455
|
-
let url = getUrl();
|
|
456
|
-
// url = rawRedirections.get(url) || url
|
|
457
|
-
url = bundleRedirections.get(url) || url;
|
|
458
|
-
url = bundleInternalRedirections.get(url) || url;
|
|
459
|
-
return url;
|
|
460
|
-
},
|
|
461
|
-
// redirecting references into the build directory
|
|
462
|
-
redirectReference: (reference) => {
|
|
463
|
-
if (!reference.url.startsWith("file:")) {
|
|
464
|
-
return null;
|
|
465
|
-
}
|
|
466
|
-
// referenced by resource hint
|
|
467
|
-
// -> keep it untouched, it will be handled by "resync_resource_hints"
|
|
468
|
-
if (reference.isResourceHint) {
|
|
469
|
-
return reference.original ? reference.original.url : null;
|
|
470
|
-
}
|
|
471
|
-
// already a build url
|
|
472
|
-
const rawUrl = buildDirectoryRedirections.get(reference.url);
|
|
473
|
-
if (rawUrl) {
|
|
474
|
-
return reference.url;
|
|
475
|
-
}
|
|
476
|
-
if (reference.isInline) {
|
|
477
|
-
const ownerFinalUrlInfo = finalKitchen.graph.getUrlInfo(
|
|
478
|
-
reference.ownerUrlInfo.url,
|
|
479
|
-
);
|
|
480
|
-
const ownerRawUrl = ownerFinalUrlInfo.originalUrl;
|
|
481
|
-
const rawUrlInfo = GRAPH_VISITOR.find(
|
|
482
|
-
rawKitchen.graph,
|
|
483
|
-
(rawUrlInfo) => {
|
|
484
|
-
const { inlineUrlSite } = rawUrlInfo;
|
|
485
|
-
// not inline
|
|
486
|
-
if (!inlineUrlSite) return false;
|
|
487
|
-
if (
|
|
488
|
-
inlineUrlSite.url === ownerRawUrl &&
|
|
489
|
-
inlineUrlSite.line === reference.specifierLine &&
|
|
490
|
-
inlineUrlSite.column === reference.specifierColumn
|
|
491
|
-
) {
|
|
492
|
-
return true;
|
|
493
|
-
}
|
|
494
|
-
if (rawUrlInfo.content === reference.content) {
|
|
495
|
-
return true;
|
|
496
|
-
}
|
|
497
|
-
if (rawUrlInfo.originalContent === reference.content) {
|
|
498
|
-
return true;
|
|
499
|
-
}
|
|
500
|
-
return false;
|
|
501
|
-
},
|
|
502
|
-
);
|
|
503
|
-
|
|
504
|
-
if (!rawUrlInfo) {
|
|
505
|
-
// generated during final graph
|
|
506
|
-
// (happens for JSON.parse injected for import assertions for instance)
|
|
507
|
-
// throw new Error(`cannot find raw url for "${reference.url}"`)
|
|
508
|
-
return reference.url;
|
|
509
|
-
}
|
|
510
|
-
const buildUrl = buildUrlsGenerator.generate(reference.url, {
|
|
511
|
-
urlInfo: rawUrlInfo,
|
|
512
|
-
ownerUrlInfo: ownerFinalUrlInfo,
|
|
513
|
-
});
|
|
514
|
-
associateBuildUrlAndRawUrl(
|
|
515
|
-
buildUrl,
|
|
516
|
-
rawUrlInfo.url,
|
|
517
|
-
"inline content",
|
|
518
|
-
);
|
|
519
|
-
return buildUrl;
|
|
520
|
-
}
|
|
521
|
-
// from "js_module_fallback":
|
|
522
|
-
// - injecting "?js_module_fallback" for the first time
|
|
523
|
-
// - injecting "?js_module_fallback" because the parentUrl has it
|
|
524
|
-
if (reference.original) {
|
|
525
|
-
const urlBeforeRedirect = reference.original.url;
|
|
526
|
-
const urlAfterRedirect = reference.url;
|
|
527
|
-
const isEntryPoint =
|
|
528
|
-
reference.isEntryPoint ||
|
|
529
|
-
isWebWorkerEntryPointReference(reference);
|
|
530
|
-
// the url info do not exists yet (it will be created after this "redirectReference" hook)
|
|
531
|
-
// And the content will be generated when url is cooked by url graph loader.
|
|
532
|
-
// Here we just want to reserve an url for that file
|
|
533
|
-
const urlInfo = {
|
|
534
|
-
data: reference.data,
|
|
535
|
-
isEntryPoint,
|
|
536
|
-
type: reference.expectedType,
|
|
537
|
-
subtype: reference.expectedSubtype,
|
|
538
|
-
filename: reference.filename,
|
|
539
|
-
};
|
|
540
|
-
if (urlIsInsideOf(urlBeforeRedirect, buildDirectoryUrl)) {
|
|
541
|
-
// the redirection happened on a build url, happens due to:
|
|
542
|
-
// 1. bundling
|
|
543
|
-
const buildUrl = buildUrlsGenerator.generate(
|
|
544
|
-
urlAfterRedirect,
|
|
545
|
-
{
|
|
546
|
-
urlInfo,
|
|
547
|
-
},
|
|
548
|
-
);
|
|
549
|
-
finalRedirections.set(urlBeforeRedirect, buildUrl);
|
|
550
|
-
return buildUrl;
|
|
551
|
-
}
|
|
552
|
-
const rawUrl = urlAfterRedirect;
|
|
553
|
-
const buildUrl = buildUrlsGenerator.generate(rawUrl, {
|
|
554
|
-
urlInfo,
|
|
555
|
-
});
|
|
556
|
-
finalRedirections.set(urlBeforeRedirect, buildUrl);
|
|
557
|
-
associateBuildUrlAndRawUrl(
|
|
558
|
-
buildUrl,
|
|
559
|
-
rawUrl,
|
|
560
|
-
"redirected during postbuild",
|
|
561
|
-
);
|
|
562
|
-
return buildUrl;
|
|
563
|
-
}
|
|
564
|
-
// from "js_module_fallback":
|
|
565
|
-
// - to inject "s.js"
|
|
566
|
-
if (reference.injected) {
|
|
567
|
-
const buildUrl = buildUrlsGenerator.generate(reference.url, {
|
|
568
|
-
urlInfo: {
|
|
569
|
-
data: {},
|
|
570
|
-
type: "js_classic",
|
|
571
|
-
},
|
|
572
|
-
});
|
|
573
|
-
associateBuildUrlAndRawUrl(
|
|
574
|
-
buildUrl,
|
|
575
|
-
reference.url,
|
|
576
|
-
"injected during postbuild",
|
|
577
|
-
);
|
|
578
|
-
finalRedirections.set(buildUrl, buildUrl);
|
|
579
|
-
return buildUrl;
|
|
580
|
-
}
|
|
581
|
-
const rawUrlInfo = rawKitchen.graph.getUrlInfo(reference.url);
|
|
582
|
-
const ownerFinalUrlInfo = finalKitchen.graph.getUrlInfo(
|
|
583
|
-
reference.ownerUrlInfo.url,
|
|
584
|
-
);
|
|
585
|
-
// files from root directory but not given to rollup nor postcss
|
|
586
|
-
if (rawUrlInfo) {
|
|
587
|
-
const referencedUrlObject = new URL(reference.url);
|
|
588
|
-
referencedUrlObject.searchParams.delete("as_js_classic");
|
|
589
|
-
referencedUrlObject.searchParams.delete("as_json_module");
|
|
590
|
-
const buildUrl = buildUrlsGenerator.generate(
|
|
591
|
-
referencedUrlObject.href,
|
|
592
|
-
{
|
|
593
|
-
urlInfo: rawUrlInfo,
|
|
594
|
-
ownerUrlInfo: ownerFinalUrlInfo,
|
|
595
|
-
},
|
|
596
|
-
);
|
|
597
|
-
associateBuildUrlAndRawUrl(
|
|
598
|
-
buildUrl,
|
|
599
|
-
rawUrlInfo.url,
|
|
600
|
-
"raw file",
|
|
601
|
-
);
|
|
602
|
-
return buildUrl;
|
|
603
|
-
}
|
|
604
|
-
if (reference.type === "sourcemap_comment") {
|
|
605
|
-
// inherit parent build url
|
|
606
|
-
return generateSourcemapFileUrl(reference.ownerUrlInfo.url);
|
|
607
|
-
}
|
|
608
|
-
// files generated during the final graph:
|
|
609
|
-
// - sourcemaps
|
|
610
|
-
// const finalUrlInfo = finalGraph.getUrlInfo(url)
|
|
611
|
-
const buildUrl = buildUrlsGenerator.generate(reference.url, {
|
|
612
|
-
urlInfo: {
|
|
613
|
-
data: {},
|
|
614
|
-
type: "asset",
|
|
615
|
-
},
|
|
616
|
-
});
|
|
617
|
-
return buildUrl;
|
|
618
|
-
},
|
|
619
|
-
formatReference: (reference) => {
|
|
620
|
-
if (!reference.generatedUrl.startsWith("file:")) {
|
|
621
|
-
return null;
|
|
622
|
-
}
|
|
623
|
-
if (reference.isWeak) {
|
|
624
|
-
return null;
|
|
625
|
-
}
|
|
626
|
-
if (!urlIsInsideOf(reference.generatedUrl, buildDirectoryUrl)) {
|
|
627
|
-
throw new Error(
|
|
628
|
-
`urls should be inside build directory at this stage, found "${reference.url}"`,
|
|
629
|
-
);
|
|
630
|
-
}
|
|
631
|
-
const generatedUrlObject = new URL(reference.generatedUrl);
|
|
632
|
-
generatedUrlObject.searchParams.delete("js_classic");
|
|
633
|
-
generatedUrlObject.searchParams.delete("js_module");
|
|
634
|
-
generatedUrlObject.searchParams.delete("js_module_fallback");
|
|
635
|
-
generatedUrlObject.searchParams.delete("as_js_classic");
|
|
636
|
-
generatedUrlObject.searchParams.delete("as_js_module");
|
|
637
|
-
generatedUrlObject.searchParams.delete("as_json_module");
|
|
638
|
-
generatedUrlObject.searchParams.delete("as_css_module");
|
|
639
|
-
generatedUrlObject.searchParams.delete("as_text_module");
|
|
640
|
-
generatedUrlObject.searchParams.delete("dynamic_import");
|
|
641
|
-
generatedUrlObject.hash = "";
|
|
642
|
-
const buildUrl = generatedUrlObject.href;
|
|
643
|
-
const buildSpecifier = asFormattedBuildSpecifier(
|
|
644
|
-
reference,
|
|
645
|
-
buildUrl,
|
|
646
|
-
);
|
|
647
|
-
buildSpecifierMap.set(buildSpecifier, reference.generatedUrl);
|
|
648
|
-
|
|
649
|
-
if (!versioning || !shouldApplyVersioningOnReference(reference)) {
|
|
650
|
-
return buildSpecifier;
|
|
651
|
-
}
|
|
652
|
-
const buildSpecifierWithVersionPlaceholder =
|
|
653
|
-
buildVersionsManager.generateBuildSpecifierPlaceholder(
|
|
654
|
-
reference,
|
|
655
|
-
buildSpecifier,
|
|
656
|
-
);
|
|
657
|
-
return buildSpecifierWithVersionPlaceholder;
|
|
658
|
-
},
|
|
659
|
-
fetchUrlContent: async (finalUrlInfo) => {
|
|
660
|
-
const fromBundleOrRawGraph = (url) => {
|
|
661
|
-
const bundleUrlInfo = bundleUrlInfos[url];
|
|
662
|
-
if (bundleUrlInfo) {
|
|
663
|
-
return bundleUrlInfo;
|
|
664
|
-
}
|
|
665
|
-
const rawUrl = buildDirectoryRedirections.get(url) || url;
|
|
666
|
-
const rawUrlInfo = rawKitchen.graph.getUrlInfo(rawUrl);
|
|
667
|
-
if (!rawUrlInfo) {
|
|
668
|
-
throw new Error(
|
|
669
|
-
createDetailedMessage(`Cannot find url`, {
|
|
670
|
-
url,
|
|
671
|
-
"raw urls": Array.from(
|
|
672
|
-
buildDirectoryRedirections.values(),
|
|
673
|
-
),
|
|
674
|
-
"build urls": Array.from(
|
|
675
|
-
buildDirectoryRedirections.keys(),
|
|
676
|
-
),
|
|
677
|
-
}),
|
|
678
|
-
);
|
|
679
|
-
}
|
|
680
|
-
// logger.debug(`fetching from raw graph ${url}`)
|
|
681
|
-
if (rawUrlInfo.isInline) {
|
|
682
|
-
// Inline content, such as <script> inside html, is transformed during the previous phase.
|
|
683
|
-
// If we read the inline content it would be considered as the original content.
|
|
684
|
-
// - It could be "fixed" by taking into account sourcemap and consider sourcemap sources
|
|
685
|
-
// as the original content.
|
|
686
|
-
// - But it would not work when sourcemap are not generated
|
|
687
|
-
// - would be a bit slower
|
|
688
|
-
// - So instead of reading the inline content directly, we search into raw graph
|
|
689
|
-
// to get "originalContent" and "sourcemap"
|
|
690
|
-
finalUrlInfo.type = rawUrlInfo.type;
|
|
691
|
-
finalUrlInfo.subtype = rawUrlInfo.subtype;
|
|
692
|
-
return rawUrlInfo;
|
|
693
|
-
}
|
|
694
|
-
return rawUrlInfo;
|
|
695
|
-
};
|
|
696
|
-
const { firstReference } = finalUrlInfo;
|
|
697
|
-
// .original reference updated during "postbuild":
|
|
698
|
-
// happens for "js_module_fallback"
|
|
699
|
-
const reference = firstReference.original || firstReference;
|
|
700
|
-
// reference injected during "postbuild":
|
|
701
|
-
// - happens for "js_module_fallback" injecting "s.js"
|
|
702
|
-
if (reference.injected) {
|
|
703
|
-
const rawReference =
|
|
704
|
-
rawKitchen.graph.rootUrlInfo.dependencies.inject({
|
|
705
|
-
type: reference.type,
|
|
706
|
-
expectedType: reference.expectedType,
|
|
707
|
-
specifier: reference.specifier,
|
|
708
|
-
specifierLine: reference.specifierLine,
|
|
709
|
-
specifierColumn: reference.specifierColumn,
|
|
710
|
-
specifierStart: reference.specifierStart,
|
|
711
|
-
specifierEnd: reference.specifierEnd,
|
|
712
|
-
});
|
|
713
|
-
await rawReference.urlInfo.cook();
|
|
714
|
-
return {
|
|
715
|
-
type: rawReference.urlInfo.type,
|
|
716
|
-
content: rawReference.urlInfo.content,
|
|
717
|
-
contentType: rawReference.urlInfo.contentType,
|
|
718
|
-
originalContent: rawReference.urlInfo.originalContent,
|
|
719
|
-
originalUrl: rawReference.urlInfo.originalUrl,
|
|
720
|
-
sourcemap: rawReference.urlInfo.sourcemap,
|
|
721
|
-
};
|
|
722
|
-
}
|
|
723
|
-
if (reference.isInline) {
|
|
724
|
-
const prevReference = firstReference.prev;
|
|
725
|
-
if (prevReference) {
|
|
726
|
-
if (!prevReference.isInline) {
|
|
727
|
-
// the reference was inlined
|
|
728
|
-
const urlBeforeRedirect =
|
|
729
|
-
findKey(finalRedirections, prevReference.url) ||
|
|
730
|
-
prevReference.url;
|
|
731
|
-
return fromBundleOrRawGraph(urlBeforeRedirect);
|
|
732
|
-
}
|
|
733
|
-
if (buildDirectoryRedirections.has(prevReference.url)) {
|
|
734
|
-
// the prev reference is transformed to fetch underlying resource
|
|
735
|
-
// (getWithoutSearchParam)
|
|
736
|
-
return fromBundleOrRawGraph(prevReference.url);
|
|
737
|
-
}
|
|
738
|
-
}
|
|
739
|
-
return fromBundleOrRawGraph(firstReference.url);
|
|
740
|
-
}
|
|
741
|
-
return fromBundleOrRawGraph(reference.url);
|
|
742
|
-
},
|
|
330
|
+
const finalKitchen = createKitchen({
|
|
331
|
+
name: "shape",
|
|
332
|
+
logLevel,
|
|
333
|
+
rootDirectoryUrl: sourceDirectoryUrl,
|
|
334
|
+
// here most plugins are not there
|
|
335
|
+
// - no external plugin
|
|
336
|
+
// - no plugin putting reference.mustIgnore on https urls
|
|
337
|
+
// At this stage it's only about redirecting urls to the build directory
|
|
338
|
+
// consequently only a subset or urls are supported
|
|
339
|
+
supportedProtocols: ["file:", "data:", "virtual:", "ignore:"],
|
|
340
|
+
ignore,
|
|
341
|
+
ignoreProtocol: "remove",
|
|
342
|
+
build: true,
|
|
343
|
+
runtimeCompat,
|
|
344
|
+
initialContext: contextSharedDuringBuild,
|
|
345
|
+
initialPluginsMeta: rawKitchen.pluginController.pluginsMeta,
|
|
346
|
+
plugins: [
|
|
347
|
+
jsenvPluginReferenceAnalysis({
|
|
348
|
+
...referenceAnalysis,
|
|
349
|
+
fetchInlineUrls: false,
|
|
350
|
+
// inlineContent: false,
|
|
351
|
+
}),
|
|
352
|
+
...(lineBreakNormalization
|
|
353
|
+
? [jsenvPluginLineBreakNormalization()]
|
|
354
|
+
: []),
|
|
355
|
+
jsenvPluginJsModuleFallback({
|
|
356
|
+
remapImportSpecifier: (specifier) => {
|
|
357
|
+
return buildSpecifierManager.remapPlaceholder(specifier);
|
|
743
358
|
},
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
359
|
+
}),
|
|
360
|
+
jsenvPluginInlining(),
|
|
361
|
+
{
|
|
362
|
+
name: "jsenv:optimize",
|
|
363
|
+
appliesDuring: "build",
|
|
364
|
+
transformUrlContent: async (urlInfo) => {
|
|
365
|
+
await rawKitchen.pluginController.callAsyncHooks(
|
|
366
|
+
"optimizeUrlContent",
|
|
367
|
+
urlInfo,
|
|
368
|
+
(optimizeReturnValue) => {
|
|
369
|
+
urlInfo.mutateContent(optimizeReturnValue);
|
|
370
|
+
},
|
|
371
|
+
);
|
|
756
372
|
},
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
finalKitchen,
|
|
767
|
-
versioningMethod,
|
|
768
|
-
versionLength,
|
|
769
|
-
canUseImportmap:
|
|
770
|
-
versioningViaImportmap &&
|
|
771
|
-
finalEntryUrls.every((finalEntryUrl) => {
|
|
772
|
-
const finalEntryUrlInfo =
|
|
773
|
-
finalKitchen.graph.getUrlInfo(finalEntryUrl);
|
|
774
|
-
return finalEntryUrlInfo.type === "html";
|
|
775
|
-
}) &&
|
|
776
|
-
rawKitchen.context.isSupportedOnCurrentClients("importmap"),
|
|
777
|
-
getBuildUrlFromBuildSpecifier: (buildSpecifier) =>
|
|
778
|
-
buildSpecifierMap.get(buildSpecifier),
|
|
779
|
-
});
|
|
373
|
+
},
|
|
374
|
+
],
|
|
375
|
+
sourcemaps,
|
|
376
|
+
sourcemapsComment: "relative",
|
|
377
|
+
sourcemapsSourcesContent,
|
|
378
|
+
outDirectoryUrl: outDirectoryUrl
|
|
379
|
+
? new URL("shape/", outDirectoryUrl)
|
|
380
|
+
: undefined,
|
|
381
|
+
});
|
|
780
382
|
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
383
|
+
const buildSpecifierManager = createBuildSpecifierManager({
|
|
384
|
+
rawKitchen,
|
|
385
|
+
finalKitchen,
|
|
386
|
+
logger,
|
|
387
|
+
sourceDirectoryUrl,
|
|
388
|
+
buildDirectoryUrl,
|
|
389
|
+
base,
|
|
390
|
+
assetsDirectory,
|
|
391
|
+
|
|
392
|
+
versioning,
|
|
393
|
+
versioningMethod,
|
|
394
|
+
versionLength,
|
|
395
|
+
canUseImportmap:
|
|
396
|
+
versioningViaImportmap &&
|
|
397
|
+
entryUrls.every((finalEntryUrl) => {
|
|
398
|
+
const entryUrlInfo = rawKitchen.graph.getUrlInfo(finalEntryUrl);
|
|
399
|
+
return entryUrlInfo.type === "html";
|
|
400
|
+
}) &&
|
|
401
|
+
rawKitchen.context.isSupportedOnCurrentClients("importmap"),
|
|
402
|
+
});
|
|
403
|
+
finalKitchen.pluginController.pushPlugin(
|
|
404
|
+
buildSpecifierManager.jsenvPluginMoveToBuildDirectory,
|
|
405
|
+
);
|
|
406
|
+
|
|
407
|
+
const bundlers = {};
|
|
408
|
+
bundle: {
|
|
409
|
+
rawKitchen.pluginController.plugins.forEach((plugin) => {
|
|
410
|
+
const bundle = plugin.bundle;
|
|
411
|
+
if (!bundle) {
|
|
412
|
+
return;
|
|
413
|
+
}
|
|
414
|
+
if (typeof bundle !== "object") {
|
|
415
|
+
throw new Error(
|
|
416
|
+
`bundle must be an object, found "${bundle}" on plugin named "${plugin.name}"`,
|
|
417
|
+
);
|
|
418
|
+
}
|
|
419
|
+
Object.keys(bundle).forEach((type) => {
|
|
420
|
+
const bundleFunction = bundle[type];
|
|
421
|
+
if (!bundleFunction) {
|
|
785
422
|
return;
|
|
786
423
|
}
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
424
|
+
const bundlerForThatType = bundlers[type];
|
|
425
|
+
if (bundlerForThatType) {
|
|
426
|
+
// first plugin to define a bundle hook wins
|
|
427
|
+
return;
|
|
791
428
|
}
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
const bundlerForThatType = bundlers[type];
|
|
798
|
-
if (bundlerForThatType) {
|
|
799
|
-
// first plugin to define a bundle hook wins
|
|
800
|
-
return;
|
|
801
|
-
}
|
|
802
|
-
bundlers[type] = {
|
|
803
|
-
plugin,
|
|
804
|
-
bundleFunction: bundle[type],
|
|
805
|
-
urlInfoMap: new Map(),
|
|
806
|
-
};
|
|
807
|
-
});
|
|
429
|
+
bundlers[type] = {
|
|
430
|
+
plugin,
|
|
431
|
+
bundleFunction: bundle[type],
|
|
432
|
+
urlInfoMap: new Map(),
|
|
433
|
+
};
|
|
808
434
|
});
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
435
|
+
});
|
|
436
|
+
const addToBundlerIfAny = (rawUrlInfo) => {
|
|
437
|
+
const bundler = bundlers[rawUrlInfo.type];
|
|
438
|
+
if (bundler) {
|
|
439
|
+
bundler.urlInfoMap.set(rawUrlInfo.url, rawUrlInfo);
|
|
440
|
+
}
|
|
441
|
+
};
|
|
442
|
+
// ignore unused urls thanks to "forEachUrlInfoStronglyReferenced"
|
|
443
|
+
// it avoid bundling things that are not actually used
|
|
444
|
+
// happens for:
|
|
445
|
+
// - js import assertions
|
|
446
|
+
// - conversion to js classic using ?as_js_classic or ?js_module_fallback
|
|
447
|
+
GRAPH_VISITOR.forEachUrlInfoStronglyReferenced(
|
|
448
|
+
rawKitchen.graph.rootUrlInfo,
|
|
449
|
+
(rawUrlInfo) => {
|
|
450
|
+
if (rawUrlInfo.isEntryPoint) {
|
|
451
|
+
addToBundlerIfAny(rawUrlInfo);
|
|
813
452
|
}
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
453
|
+
if (rawUrlInfo.type === "html") {
|
|
454
|
+
rawUrlInfo.referenceToOthersSet.forEach((referenceToOther) => {
|
|
455
|
+
if (referenceToOther.isWeak) {
|
|
456
|
+
return;
|
|
457
|
+
}
|
|
458
|
+
const referencedUrlInfo = referenceToOther.urlInfo;
|
|
459
|
+
if (referencedUrlInfo.isInline) {
|
|
460
|
+
if (referencedUrlInfo.type === "js_module") {
|
|
461
|
+
// bundle inline script type module deps
|
|
462
|
+
referencedUrlInfo.referenceToOthersSet.forEach(
|
|
463
|
+
(jsModuleReferenceToOther) => {
|
|
464
|
+
if (jsModuleReferenceToOther.type === "js_import") {
|
|
465
|
+
const inlineUrlInfo = jsModuleReferenceToOther.urlInfo;
|
|
466
|
+
addToBundlerIfAny(inlineUrlInfo);
|
|
467
|
+
}
|
|
468
|
+
},
|
|
469
|
+
);
|
|
830
470
|
}
|
|
471
|
+
// inline content cannot be bundled
|
|
472
|
+
return;
|
|
473
|
+
}
|
|
474
|
+
addToBundlerIfAny(referencedUrlInfo);
|
|
475
|
+
});
|
|
476
|
+
rawUrlInfo.referenceToOthersSet.forEach((referenceToOther) => {
|
|
477
|
+
if (
|
|
478
|
+
referenceToOther.isResourceHint &&
|
|
479
|
+
referenceToOther.expectedType === "js_module"
|
|
480
|
+
) {
|
|
831
481
|
const referencedUrlInfo = referenceToOther.urlInfo;
|
|
832
|
-
if (referencedUrlInfo.isInline) {
|
|
833
|
-
if (referencedUrlInfo.type === "js_module") {
|
|
834
|
-
// bundle inline script type module deps
|
|
835
|
-
referencedUrlInfo.referenceToOthersSet.forEach(
|
|
836
|
-
(jsModuleReferenceToOther) => {
|
|
837
|
-
if (jsModuleReferenceToOther.type === "js_import") {
|
|
838
|
-
const inlineUrlInfo =
|
|
839
|
-
jsModuleReferenceToOther.urlInfo;
|
|
840
|
-
addToBundlerIfAny(inlineUrlInfo);
|
|
841
|
-
}
|
|
842
|
-
},
|
|
843
|
-
);
|
|
844
|
-
}
|
|
845
|
-
// inline content cannot be bundled
|
|
846
|
-
return;
|
|
847
|
-
}
|
|
848
|
-
addToBundlerIfAny(referencedUrlInfo);
|
|
849
|
-
});
|
|
850
|
-
rawUrlInfo.referenceToOthersSet.forEach((referenceToOther) => {
|
|
851
482
|
if (
|
|
852
|
-
|
|
853
|
-
|
|
483
|
+
referencedUrlInfo &&
|
|
484
|
+
// something else than the resource hint is using this url
|
|
485
|
+
referencedUrlInfo.referenceFromOthersSet.size > 0
|
|
854
486
|
) {
|
|
855
|
-
const referencedUrlInfo = referenceToOther.urlInfo;
|
|
856
|
-
if (
|
|
857
|
-
referencedUrlInfo &&
|
|
858
|
-
// something else than the resource hint is using this url
|
|
859
|
-
referencedUrlInfo.referenceFromOthersSet.size > 0
|
|
860
|
-
) {
|
|
861
|
-
addToBundlerIfAny(referencedUrlInfo);
|
|
862
|
-
}
|
|
863
|
-
}
|
|
864
|
-
});
|
|
865
|
-
return;
|
|
866
|
-
}
|
|
867
|
-
// File referenced with new URL('./file.js', import.meta.url)
|
|
868
|
-
// are entry points that should be bundled
|
|
869
|
-
// For instance we will bundle service worker/workers detected like this
|
|
870
|
-
if (rawUrlInfo.type === "js_module") {
|
|
871
|
-
rawUrlInfo.referenceToOthersSet.forEach((referenceToOther) => {
|
|
872
|
-
if (referenceToOther.type === "js_url") {
|
|
873
|
-
const referencedUrlInfo = referenceToOther.urlInfo;
|
|
874
|
-
for (const referenceFromOther of referencedUrlInfo.referenceFromOthersSet) {
|
|
875
|
-
if (referenceFromOther.url === referencedUrlInfo.url) {
|
|
876
|
-
if (
|
|
877
|
-
referenceFromOther.subtype === "import_dynamic" ||
|
|
878
|
-
referenceFromOther.type === "script"
|
|
879
|
-
) {
|
|
880
|
-
// will already be bundled
|
|
881
|
-
return;
|
|
882
|
-
}
|
|
883
|
-
}
|
|
884
|
-
}
|
|
885
487
|
addToBundlerIfAny(referencedUrlInfo);
|
|
886
|
-
return;
|
|
887
|
-
}
|
|
888
|
-
if (referenceToOther.type === "js_inline_content") {
|
|
889
|
-
// we should bundle it too right?
|
|
890
488
|
}
|
|
891
|
-
}
|
|
892
|
-
}
|
|
893
|
-
},
|
|
894
|
-
);
|
|
895
|
-
await Object.keys(bundlers).reduce(async (previous, type) => {
|
|
896
|
-
await previous;
|
|
897
|
-
const bundler = bundlers[type];
|
|
898
|
-
const urlInfosToBundle = Array.from(bundler.urlInfoMap.values());
|
|
899
|
-
if (urlInfosToBundle.length === 0) {
|
|
489
|
+
}
|
|
490
|
+
});
|
|
900
491
|
return;
|
|
901
492
|
}
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
subtype: rawUrlInfo ? rawUrlInfo.subtype : undefined,
|
|
919
|
-
isEntryPoint: rawUrlInfo ? rawUrlInfo.isEntryPoint : undefined,
|
|
920
|
-
filename: rawUrlInfo ? rawUrlInfo.filename : undefined,
|
|
921
|
-
originalUrl: rawUrlInfo ? rawUrlInfo.originalUrl : undefined,
|
|
922
|
-
originalContent: rawUrlInfo
|
|
923
|
-
? rawUrlInfo.originalContent
|
|
924
|
-
: undefined,
|
|
925
|
-
...bundlerGeneratedUrlInfo,
|
|
926
|
-
data: {
|
|
927
|
-
...(rawUrlInfo ? rawUrlInfo.data : {}),
|
|
928
|
-
...bundlerGeneratedUrlInfo.data,
|
|
929
|
-
fromBundle: true,
|
|
930
|
-
},
|
|
931
|
-
};
|
|
932
|
-
if (bundlerGeneratedUrlInfo.sourceUrls) {
|
|
933
|
-
bundlerGeneratedUrlInfo.sourceUrls.forEach((sourceUrl) => {
|
|
934
|
-
const sourceRawUrlInfo =
|
|
935
|
-
rawKitchen.graph.getUrlInfo(sourceUrl);
|
|
936
|
-
if (sourceRawUrlInfo) {
|
|
937
|
-
sourceRawUrlInfo.data.bundled = true;
|
|
493
|
+
// File referenced with new URL('./file.js', import.meta.url)
|
|
494
|
+
// are entry points that should be bundled
|
|
495
|
+
// For instance we will bundle service worker/workers detected like this
|
|
496
|
+
if (rawUrlInfo.type === "js_module") {
|
|
497
|
+
rawUrlInfo.referenceToOthersSet.forEach((referenceToOther) => {
|
|
498
|
+
if (referenceToOther.type === "js_url") {
|
|
499
|
+
const referencedUrlInfo = referenceToOther.urlInfo;
|
|
500
|
+
for (const referenceFromOther of referencedUrlInfo.referenceFromOthersSet) {
|
|
501
|
+
if (referenceFromOther.url === referencedUrlInfo.url) {
|
|
502
|
+
if (
|
|
503
|
+
referenceFromOther.subtype === "import_dynamic" ||
|
|
504
|
+
referenceFromOther.type === "script"
|
|
505
|
+
) {
|
|
506
|
+
// will already be bundled
|
|
507
|
+
return;
|
|
508
|
+
}
|
|
938
509
|
}
|
|
939
|
-
});
|
|
940
|
-
}
|
|
941
|
-
const buildUrl = buildUrlsGenerator.generate(url, {
|
|
942
|
-
urlInfo: bundleUrlInfo,
|
|
943
|
-
});
|
|
944
|
-
bundleRedirections.set(url, buildUrl);
|
|
945
|
-
if (urlIsInsideOf(url, buildDirectoryUrl)) {
|
|
946
|
-
if (bundlerGeneratedUrlInfo.data.isDynamicEntry) {
|
|
947
|
-
const rawUrlInfo = rawKitchen.graph.getUrlInfo(
|
|
948
|
-
bundlerGeneratedUrlInfo.originalUrl,
|
|
949
|
-
);
|
|
950
|
-
rawUrlInfo.data.bundled = false;
|
|
951
|
-
bundleRedirections.set(
|
|
952
|
-
bundlerGeneratedUrlInfo.originalUrl,
|
|
953
|
-
buildUrl,
|
|
954
|
-
);
|
|
955
|
-
associateBuildUrlAndRawUrl(
|
|
956
|
-
buildUrl,
|
|
957
|
-
bundlerGeneratedUrlInfo.originalUrl,
|
|
958
|
-
"bundle",
|
|
959
|
-
);
|
|
960
|
-
} else {
|
|
961
|
-
bundleUrlInfo.data.generatedToShareCode = true;
|
|
962
510
|
}
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
}
|
|
966
|
-
bundleUrlInfos[buildUrl] = bundleUrlInfo;
|
|
967
|
-
if (buildUrl.includes("?")) {
|
|
968
|
-
bundleUrlInfos[asUrlWithoutSearch(buildUrl)] = bundleUrlInfo;
|
|
511
|
+
addToBundlerIfAny(referencedUrlInfo);
|
|
512
|
+
return;
|
|
969
513
|
}
|
|
970
|
-
if (
|
|
971
|
-
|
|
972
|
-
bundlerGeneratedUrlInfo.data.bundleRelativeUrl,
|
|
973
|
-
buildDirectoryUrl,
|
|
974
|
-
).href;
|
|
975
|
-
if (urlForBundler !== buildUrl) {
|
|
976
|
-
bundleInternalRedirections.set(urlForBundler, buildUrl);
|
|
977
|
-
}
|
|
514
|
+
if (referenceToOther.type === "js_inline_content") {
|
|
515
|
+
// we should bundle it too right?
|
|
978
516
|
}
|
|
979
517
|
});
|
|
980
|
-
} catch (e) {
|
|
981
|
-
bundleTask.fail();
|
|
982
|
-
throw e;
|
|
983
518
|
}
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
const
|
|
519
|
+
},
|
|
520
|
+
);
|
|
521
|
+
for (const type of Object.keys(bundlers)) {
|
|
522
|
+
const bundler = bundlers[type];
|
|
523
|
+
const urlInfosToBundle = Array.from(bundler.urlInfoMap.values());
|
|
524
|
+
if (urlInfosToBundle.length === 0) {
|
|
525
|
+
continue;
|
|
526
|
+
}
|
|
527
|
+
const bundleTask = createBuildTask(`bundle "${type}"`);
|
|
989
528
|
try {
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
const finalRootUrlInfo = finalKitchen.graph.rootUrlInfo;
|
|
994
|
-
await finalRootUrlInfo.dependencies.startCollecting(() => {
|
|
995
|
-
entryUrls.forEach((entryUrl) => {
|
|
996
|
-
const entryReference = finalRootUrlInfo.dependencies.found({
|
|
997
|
-
trace: { message: `entryPoint` },
|
|
998
|
-
isEntryPoint: true,
|
|
999
|
-
type: "entry_point",
|
|
1000
|
-
specifier: entryUrl,
|
|
1001
|
-
});
|
|
1002
|
-
finalEntryUrls.push(entryReference.url);
|
|
1003
|
-
});
|
|
1004
|
-
});
|
|
1005
|
-
await finalRootUrlInfo.cookDependencies({
|
|
1006
|
-
operation: buildOperation,
|
|
529
|
+
await buildSpecifierManager.applyBundling({
|
|
530
|
+
bundler,
|
|
531
|
+
urlInfosToBundle,
|
|
1007
532
|
});
|
|
1008
533
|
} catch (e) {
|
|
1009
|
-
|
|
534
|
+
bundleTask.fail();
|
|
1010
535
|
throw e;
|
|
1011
536
|
}
|
|
1012
|
-
|
|
537
|
+
bundleTask.done();
|
|
1013
538
|
}
|
|
1014
539
|
}
|
|
1015
540
|
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
// at https://github.com/rollup/rollup/pull/4543
|
|
1023
|
-
const versioningTask = createBuildTask("apply versioning");
|
|
1024
|
-
try {
|
|
1025
|
-
await buildVersionsManager.applyVersioning(finalKitchen);
|
|
1026
|
-
} catch (e) {
|
|
1027
|
-
versioningTask.fail();
|
|
1028
|
-
throw e;
|
|
541
|
+
shape: {
|
|
542
|
+
finalKitchen.context.buildStep = "shape";
|
|
543
|
+
const generateBuildGraph = createBuildTask("generate build graph");
|
|
544
|
+
try {
|
|
545
|
+
if (outDirectoryUrl) {
|
|
546
|
+
await ensureEmptyDirectory(new URL(`shape/`, outDirectoryUrl));
|
|
1029
547
|
}
|
|
1030
|
-
|
|
548
|
+
const finalRootUrlInfo = finalKitchen.graph.rootUrlInfo;
|
|
549
|
+
await finalRootUrlInfo.dependencies.startCollecting(() => {
|
|
550
|
+
entryUrls.forEach((entryUrl) => {
|
|
551
|
+
finalRootUrlInfo.dependencies.found({
|
|
552
|
+
trace: { message: `entryPoint` },
|
|
553
|
+
isEntryPoint: true,
|
|
554
|
+
type: "entry_point",
|
|
555
|
+
specifier: entryUrl,
|
|
556
|
+
});
|
|
557
|
+
});
|
|
558
|
+
});
|
|
559
|
+
await finalRootUrlInfo.cookDependencies({
|
|
560
|
+
operation: buildOperation,
|
|
561
|
+
});
|
|
562
|
+
} catch (e) {
|
|
563
|
+
generateBuildGraph.fail();
|
|
564
|
+
throw e;
|
|
565
|
+
}
|
|
566
|
+
generateBuildGraph.done();
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
refine: {
|
|
570
|
+
finalKitchen.context.buildStep = "refine";
|
|
571
|
+
replace_placeholders: {
|
|
572
|
+
await buildSpecifierManager.replacePlaceholders();
|
|
1031
573
|
}
|
|
1032
574
|
cleanup_jsenv_attributes_from_html: {
|
|
1033
575
|
GRAPH_VISITOR.forEach(finalKitchen.graph, (urlInfo) => {
|
|
@@ -1052,293 +594,28 @@ ${ANSI.color(buildUrl, ANSI.MAGENTA)}
|
|
|
1052
594
|
* - because of import assertions transpilation (file is inlined into JS)
|
|
1053
595
|
*/
|
|
1054
596
|
resync_resource_hints: {
|
|
1055
|
-
const
|
|
1056
|
-
|
|
1057
|
-
if (urlInfo.type !== "html") {
|
|
1058
|
-
return;
|
|
1059
|
-
}
|
|
1060
|
-
const htmlAst = parseHtmlString(urlInfo.content, {
|
|
1061
|
-
storeOriginalPositions: false,
|
|
1062
|
-
});
|
|
1063
|
-
const mutations = [];
|
|
1064
|
-
const hintsToInject = {};
|
|
1065
|
-
visitHtmlNodes(htmlAst, {
|
|
1066
|
-
link: (node) => {
|
|
1067
|
-
const href = getHtmlNodeAttribute(node, "href");
|
|
1068
|
-
if (href === undefined || href.startsWith("data:")) {
|
|
1069
|
-
return;
|
|
1070
|
-
}
|
|
1071
|
-
const rel = getHtmlNodeAttribute(node, "rel");
|
|
1072
|
-
const isResourceHint = [
|
|
1073
|
-
"preconnect",
|
|
1074
|
-
"dns-prefetch",
|
|
1075
|
-
"prefetch",
|
|
1076
|
-
"preload",
|
|
1077
|
-
"modulepreload",
|
|
1078
|
-
].includes(rel);
|
|
1079
|
-
if (!isResourceHint) {
|
|
1080
|
-
return;
|
|
1081
|
-
}
|
|
1082
|
-
const onBuildUrl = (buildUrl) => {
|
|
1083
|
-
const buildUrlInfo = buildUrl
|
|
1084
|
-
? finalKitchen.graph.getUrlInfo(buildUrl)
|
|
1085
|
-
: null;
|
|
1086
|
-
if (!buildUrlInfo) {
|
|
1087
|
-
logger.warn(
|
|
1088
|
-
`remove resource hint because cannot find "${href}" in the graph`,
|
|
1089
|
-
);
|
|
1090
|
-
mutations.push(() => {
|
|
1091
|
-
removeHtmlNode(node);
|
|
1092
|
-
});
|
|
1093
|
-
return;
|
|
1094
|
-
}
|
|
1095
|
-
if (!buildUrlInfo.isUsed()) {
|
|
1096
|
-
let rawUrl = buildDirectoryRedirections.get(buildUrl);
|
|
1097
|
-
if (!rawUrl && rawKitchen.graph.getUrlInfo(buildUrl)) {
|
|
1098
|
-
rawUrl = buildUrl;
|
|
1099
|
-
}
|
|
1100
|
-
if (rawUrl) {
|
|
1101
|
-
const rawUrlInfo = rawKitchen.graph.getUrlInfo(rawUrl);
|
|
1102
|
-
if (rawUrlInfo && rawUrlInfo.data.bundled) {
|
|
1103
|
-
logger.warn(
|
|
1104
|
-
`remove resource hint on "${rawUrl}" because it was bundled`,
|
|
1105
|
-
);
|
|
1106
|
-
mutations.push(() => {
|
|
1107
|
-
removeHtmlNode(node);
|
|
1108
|
-
});
|
|
1109
|
-
return;
|
|
1110
|
-
}
|
|
1111
|
-
}
|
|
1112
|
-
logger.warn(
|
|
1113
|
-
`remove resource hint on "${href}" because it is not used anymore`,
|
|
1114
|
-
);
|
|
1115
|
-
mutations.push(() => {
|
|
1116
|
-
removeHtmlNode(node);
|
|
1117
|
-
});
|
|
1118
|
-
return;
|
|
1119
|
-
}
|
|
1120
|
-
const buildUrlFormatted = buildUrlInfo.url;
|
|
1121
|
-
const buildSpecifier = findKey(
|
|
1122
|
-
buildSpecifierMap,
|
|
1123
|
-
buildUrlFormatted,
|
|
1124
|
-
);
|
|
1125
|
-
const buildSpecifierVersioned =
|
|
1126
|
-
buildVersionsManager.getBuildSpecifierVersioned(
|
|
1127
|
-
buildSpecifier,
|
|
1128
|
-
);
|
|
1129
|
-
let specifier = buildSpecifierVersioned || buildSpecifier;
|
|
1130
|
-
mutations.push(() => {
|
|
1131
|
-
setHtmlNodeAttributes(node, {
|
|
1132
|
-
href: specifier,
|
|
1133
|
-
...(buildUrlInfo.type === "js_classic"
|
|
1134
|
-
? { crossorigin: undefined }
|
|
1135
|
-
: {}),
|
|
1136
|
-
});
|
|
1137
|
-
});
|
|
1138
|
-
for (const referenceToOther of buildUrlInfo.referenceToOthersSet) {
|
|
1139
|
-
if (referenceToOther.isWeak) {
|
|
1140
|
-
continue;
|
|
1141
|
-
}
|
|
1142
|
-
const referencedUrlInfo = referenceToOther.urlInfo;
|
|
1143
|
-
if (referencedUrlInfo.data.generatedToShareCode) {
|
|
1144
|
-
hintsToInject[referencedUrlInfo.url] = node;
|
|
1145
|
-
}
|
|
1146
|
-
}
|
|
1147
|
-
};
|
|
1148
|
-
if (href.startsWith("file:")) {
|
|
1149
|
-
let url = href;
|
|
1150
|
-
url = rawRedirections.get(url) || url;
|
|
1151
|
-
url = bundleRedirections.get(url) || url;
|
|
1152
|
-
url = bundleInternalRedirections.get(url) || url;
|
|
1153
|
-
url = finalRedirections.get(url) || url;
|
|
1154
|
-
url = findKey(buildDirectoryRedirections, url) || url;
|
|
1155
|
-
onBuildUrl(url);
|
|
1156
|
-
} else {
|
|
1157
|
-
onBuildUrl(null);
|
|
1158
|
-
}
|
|
1159
|
-
},
|
|
1160
|
-
});
|
|
1161
|
-
Object.keys(hintsToInject).forEach((urlToHint) => {
|
|
1162
|
-
const hintNode = hintsToInject[urlToHint];
|
|
1163
|
-
const urlFormatted = urlToHint;
|
|
1164
|
-
const buildSpecifier = findKey(buildSpecifierMap, urlFormatted);
|
|
1165
|
-
const found = findHtmlNode(htmlAst, (htmlNode) => {
|
|
1166
|
-
return (
|
|
1167
|
-
htmlNode.nodeName === "link" &&
|
|
1168
|
-
getHtmlNodeAttribute(htmlNode, "href") === buildSpecifier
|
|
1169
|
-
);
|
|
1170
|
-
});
|
|
1171
|
-
if (!found) {
|
|
1172
|
-
const buildSpecifierVersioned =
|
|
1173
|
-
buildVersionsManager.getBuildSpecifierVersioned(buildSpecifier);
|
|
1174
|
-
const href = buildSpecifierVersioned || buildSpecifier;
|
|
1175
|
-
mutations.push(() => {
|
|
1176
|
-
const nodeToInsert = createHtmlNode({
|
|
1177
|
-
tagName: "link",
|
|
1178
|
-
href,
|
|
1179
|
-
rel: getHtmlNodeAttribute(hintNode, "rel"),
|
|
1180
|
-
as: getHtmlNodeAttribute(hintNode, "as"),
|
|
1181
|
-
type: getHtmlNodeAttribute(hintNode, "type"),
|
|
1182
|
-
crossorigin: getHtmlNodeAttribute(hintNode, "crossorigin"),
|
|
1183
|
-
});
|
|
1184
|
-
insertHtmlNodeAfter(nodeToInsert, hintNode);
|
|
1185
|
-
});
|
|
1186
|
-
}
|
|
1187
|
-
});
|
|
1188
|
-
if (mutations.length > 0) {
|
|
1189
|
-
actions.push(() => {
|
|
1190
|
-
mutations.forEach((mutation) => mutation());
|
|
1191
|
-
urlInfo.mutateContent({
|
|
1192
|
-
content: stringifyHtmlAst(htmlAst),
|
|
1193
|
-
});
|
|
1194
|
-
});
|
|
1195
|
-
}
|
|
1196
|
-
});
|
|
1197
|
-
if (actions.length > 0) {
|
|
597
|
+
const resync = buildSpecifierManager.prepareResyncResourceHints();
|
|
598
|
+
if (resync) {
|
|
1198
599
|
const resyncTask = createBuildTask("resync resource hints");
|
|
1199
|
-
|
|
600
|
+
resync();
|
|
1200
601
|
buildOperation.throwIfAborted();
|
|
1201
602
|
resyncTask.done();
|
|
1202
603
|
}
|
|
1203
604
|
}
|
|
1204
605
|
inject_urls_in_service_workers: {
|
|
1205
|
-
const
|
|
1206
|
-
|
|
1207
|
-
(finalUrlInfo) => {
|
|
1208
|
-
return (
|
|
1209
|
-
finalUrlInfo.subtype === "service_worker" &&
|
|
1210
|
-
finalUrlInfo.isEntryPoint &&
|
|
1211
|
-
finalUrlInfo.isUsed()
|
|
1212
|
-
);
|
|
1213
|
-
},
|
|
1214
|
-
);
|
|
1215
|
-
if (serviceWorkerEntryUrlInfos.length > 0) {
|
|
606
|
+
const inject = buildSpecifierManager.prepareServiceWorkerUrlInjection();
|
|
607
|
+
if (inject) {
|
|
1216
608
|
const urlsInjectionInSw = createBuildTask(
|
|
1217
609
|
"inject urls in service worker",
|
|
1218
610
|
);
|
|
1219
|
-
|
|
1220
|
-
GRAPH_VISITOR.forEachUrlInfoStronglyReferenced(
|
|
1221
|
-
finalKitchen.graph.rootUrlInfo,
|
|
1222
|
-
(urlInfo) => {
|
|
1223
|
-
if (!urlInfo.url.startsWith("file:")) {
|
|
1224
|
-
return;
|
|
1225
|
-
}
|
|
1226
|
-
if (urlInfo.isInline) {
|
|
1227
|
-
return;
|
|
1228
|
-
}
|
|
1229
|
-
if (!canUseVersionedUrl(urlInfo)) {
|
|
1230
|
-
// when url is not versioned we compute a "version" for that url anyway
|
|
1231
|
-
// so that service worker source still changes and navigator
|
|
1232
|
-
// detect there is a change
|
|
1233
|
-
const buildSpecifier = findKey(buildSpecifierMap, urlInfo.url);
|
|
1234
|
-
serviceWorkerResources[buildSpecifier] = {
|
|
1235
|
-
version: buildVersionsManager.getVersion(urlInfo),
|
|
1236
|
-
};
|
|
1237
|
-
return;
|
|
1238
|
-
}
|
|
1239
|
-
const buildSpecifier = findKey(buildSpecifierMap, urlInfo.url);
|
|
1240
|
-
const buildSpecifierVersioned =
|
|
1241
|
-
buildVersionsManager.getBuildSpecifierVersioned(buildSpecifier);
|
|
1242
|
-
serviceWorkerResources[buildSpecifier] = {
|
|
1243
|
-
version: buildVersionsManager.getVersion(urlInfo),
|
|
1244
|
-
versionedUrl: buildSpecifierVersioned,
|
|
1245
|
-
};
|
|
1246
|
-
},
|
|
1247
|
-
);
|
|
1248
|
-
for (const serviceWorkerEntryUrlInfo of serviceWorkerEntryUrlInfos) {
|
|
1249
|
-
const serviceWorkerResourcesWithoutSwScriptItSelf = {
|
|
1250
|
-
...serviceWorkerResources,
|
|
1251
|
-
};
|
|
1252
|
-
const serviceWorkerBuildSpecifier = findKey(
|
|
1253
|
-
buildSpecifierMap,
|
|
1254
|
-
serviceWorkerEntryUrlInfo.url,
|
|
1255
|
-
);
|
|
1256
|
-
delete serviceWorkerResourcesWithoutSwScriptItSelf[
|
|
1257
|
-
serviceWorkerBuildSpecifier
|
|
1258
|
-
];
|
|
1259
|
-
await prependContent(serviceWorkerEntryUrlInfo, {
|
|
1260
|
-
type: "js_classic",
|
|
1261
|
-
content: `\nself.resourcesFromJsenvBuild = ${JSON.stringify(
|
|
1262
|
-
serviceWorkerResourcesWithoutSwScriptItSelf,
|
|
1263
|
-
null,
|
|
1264
|
-
" ",
|
|
1265
|
-
)};\n`,
|
|
1266
|
-
});
|
|
1267
|
-
}
|
|
611
|
+
await inject();
|
|
1268
612
|
urlsInjectionInSw.done();
|
|
613
|
+
buildOperation.throwIfAborted();
|
|
1269
614
|
}
|
|
1270
|
-
buildOperation.throwIfAborted();
|
|
1271
615
|
}
|
|
1272
616
|
}
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
const buildContents = {};
|
|
1276
|
-
const buildInlineRelativeUrls = [];
|
|
1277
|
-
const getBuildRelativeUrl = (url) => {
|
|
1278
|
-
const urlObject = new URL(url);
|
|
1279
|
-
urlObject.searchParams.delete("js_module_fallback");
|
|
1280
|
-
urlObject.searchParams.delete("as_css_module");
|
|
1281
|
-
urlObject.searchParams.delete("as_json_module");
|
|
1282
|
-
urlObject.searchParams.delete("as_text_module");
|
|
1283
|
-
url = urlObject.href;
|
|
1284
|
-
const buildRelativeUrl = urlToRelativeUrl(url, buildDirectoryUrl);
|
|
1285
|
-
return buildRelativeUrl;
|
|
1286
|
-
};
|
|
1287
|
-
GRAPH_VISITOR.forEachUrlInfoStronglyReferenced(
|
|
1288
|
-
finalKitchen.graph.rootUrlInfo,
|
|
1289
|
-
(urlInfo) => {
|
|
1290
|
-
if (!urlInfo.url.startsWith("file:")) {
|
|
1291
|
-
return;
|
|
1292
|
-
}
|
|
1293
|
-
if (urlInfo.type === "directory") {
|
|
1294
|
-
return;
|
|
1295
|
-
}
|
|
1296
|
-
if (urlInfo.isInline) {
|
|
1297
|
-
const buildRelativeUrl = getBuildRelativeUrl(urlInfo.url);
|
|
1298
|
-
buildContents[buildRelativeUrl] = urlInfo.content;
|
|
1299
|
-
buildInlineRelativeUrls.push(buildRelativeUrl);
|
|
1300
|
-
} else {
|
|
1301
|
-
const buildRelativeUrl = getBuildRelativeUrl(urlInfo.url);
|
|
1302
|
-
if (
|
|
1303
|
-
buildVersionsManager.getVersion(urlInfo) &&
|
|
1304
|
-
canUseVersionedUrl(urlInfo)
|
|
1305
|
-
) {
|
|
1306
|
-
const buildSpecifier = findKey(buildSpecifierMap, urlInfo.url);
|
|
1307
|
-
const buildSpecifierVersioned =
|
|
1308
|
-
buildVersionsManager.getBuildSpecifierVersioned(buildSpecifier);
|
|
1309
|
-
const buildUrlVersioned = asBuildUrlVersioned({
|
|
1310
|
-
buildSpecifierVersioned,
|
|
1311
|
-
buildDirectoryUrl,
|
|
1312
|
-
});
|
|
1313
|
-
const buildRelativeUrlVersioned = urlToRelativeUrl(
|
|
1314
|
-
buildUrlVersioned,
|
|
1315
|
-
buildDirectoryUrl,
|
|
1316
|
-
);
|
|
1317
|
-
if (versioningMethod === "search_param") {
|
|
1318
|
-
buildContents[buildRelativeUrl] = urlInfo.content;
|
|
1319
|
-
} else {
|
|
1320
|
-
buildContents[buildRelativeUrlVersioned] = urlInfo.content;
|
|
1321
|
-
}
|
|
1322
|
-
buildManifest[buildRelativeUrl] = buildRelativeUrlVersioned;
|
|
1323
|
-
} else {
|
|
1324
|
-
buildContents[buildRelativeUrl] = urlInfo.content;
|
|
1325
|
-
}
|
|
1326
|
-
}
|
|
1327
|
-
},
|
|
1328
|
-
);
|
|
1329
|
-
const buildFileContents = {};
|
|
1330
|
-
const buildInlineContents = {};
|
|
1331
|
-
Object.keys(buildContents)
|
|
1332
|
-
.sort((a, b) => comparePathnames(a, b))
|
|
1333
|
-
.forEach((buildRelativeUrl) => {
|
|
1334
|
-
if (buildInlineRelativeUrls.includes(buildRelativeUrl)) {
|
|
1335
|
-
buildInlineContents[buildRelativeUrl] =
|
|
1336
|
-
buildContents[buildRelativeUrl];
|
|
1337
|
-
} else {
|
|
1338
|
-
buildFileContents[buildRelativeUrl] = buildContents[buildRelativeUrl];
|
|
1339
|
-
}
|
|
1340
|
-
});
|
|
1341
|
-
|
|
617
|
+
const { buildFileContents, buildInlineContents, buildManifest } =
|
|
618
|
+
buildSpecifierManager.getBuildInfo();
|
|
1342
619
|
if (writeOnFileSystem) {
|
|
1343
620
|
const writingFiles = createBuildTask("write files in build directory");
|
|
1344
621
|
if (directoryToClean) {
|
|
@@ -1439,58 +716,3 @@ ${ANSI.color(buildUrl, ANSI.MAGENTA)}
|
|
|
1439
716
|
await firstBuildPromise;
|
|
1440
717
|
return stopWatchingSourceFiles;
|
|
1441
718
|
};
|
|
1442
|
-
|
|
1443
|
-
const findKey = (map, value) => {
|
|
1444
|
-
for (const [keyCandidate, valueCandidate] of map) {
|
|
1445
|
-
if (valueCandidate === value) {
|
|
1446
|
-
return keyCandidate;
|
|
1447
|
-
}
|
|
1448
|
-
}
|
|
1449
|
-
return undefined;
|
|
1450
|
-
};
|
|
1451
|
-
|
|
1452
|
-
const shouldApplyVersioningOnReference = (reference) => {
|
|
1453
|
-
if (reference.isInline) {
|
|
1454
|
-
return false;
|
|
1455
|
-
}
|
|
1456
|
-
if (reference.next && reference.next.isInline) {
|
|
1457
|
-
return false;
|
|
1458
|
-
}
|
|
1459
|
-
// specifier comes from "normalize" hook done a bit earlier in this file
|
|
1460
|
-
// we want to get back their build url to access their infos
|
|
1461
|
-
const referencedUrlInfo = reference.urlInfo;
|
|
1462
|
-
if (!canUseVersionedUrl(referencedUrlInfo)) {
|
|
1463
|
-
return false;
|
|
1464
|
-
}
|
|
1465
|
-
if (referencedUrlInfo.type === "sourcemap") {
|
|
1466
|
-
return false;
|
|
1467
|
-
}
|
|
1468
|
-
return true;
|
|
1469
|
-
};
|
|
1470
|
-
|
|
1471
|
-
const canUseVersionedUrl = (urlInfo) => {
|
|
1472
|
-
if (urlInfo.isRoot) {
|
|
1473
|
-
return false;
|
|
1474
|
-
}
|
|
1475
|
-
if (urlInfo.isEntryPoint) {
|
|
1476
|
-
return false;
|
|
1477
|
-
}
|
|
1478
|
-
return urlInfo.type !== "webmanifest";
|
|
1479
|
-
};
|
|
1480
|
-
|
|
1481
|
-
const asBuildUrlVersioned = ({
|
|
1482
|
-
buildSpecifierVersioned,
|
|
1483
|
-
buildDirectoryUrl,
|
|
1484
|
-
}) => {
|
|
1485
|
-
if (buildSpecifierVersioned[0] === "/") {
|
|
1486
|
-
return new URL(buildSpecifierVersioned.slice(1), buildDirectoryUrl).href;
|
|
1487
|
-
}
|
|
1488
|
-
const buildUrl = new URL(buildSpecifierVersioned, buildDirectoryUrl).href;
|
|
1489
|
-
if (buildUrl.startsWith(buildDirectoryUrl)) {
|
|
1490
|
-
return buildUrl;
|
|
1491
|
-
}
|
|
1492
|
-
// it's likely "base" parameter was set to an url origin like "https://cdn.example.com"
|
|
1493
|
-
// let's move url to build directory
|
|
1494
|
-
const { pathname, search, hash } = new URL(buildSpecifierVersioned);
|
|
1495
|
-
return `${buildDirectoryUrl}${pathname}${search}${hash}`;
|
|
1496
|
-
};
|