@jsenv/core 40.0.10 → 40.1.0
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/build/build.js +1792 -1101
- package/dist/client/autoreload/autoreload.js +1 -27
- package/dist/jsenv_core_node_modules.js +2045 -0
- package/dist/jsenv_core_packages.js +9397 -5830
- package/dist/start_build_server/start_build_server.js +4 -2
- package/dist/start_dev_server/start_dev_server.js +228 -70
- package/package.json +16 -15
- package/src/build/build.js +1084 -560
- package/src/build/build_content_report.js +377 -0
- package/src/build/build_params.js +1 -4
- package/src/build/build_specifier_manager.js +70 -21
- package/src/build/build_urls_generator.js +29 -28
- package/src/kitchen/fetched_content_compliance.js +2 -2
- package/src/kitchen/kitchen.js +1 -1
- package/src/plugins/directory_reference_effect/jsenv_plugin_directory_reference_effect.js +20 -5
- package/src/plugins/plugins.js +5 -2
- package/src/plugins/protocol_file/jsenv_plugin_directory_listing.js +3 -4
- package/src/plugins/reference_analysis/jsenv_plugin_reference_analysis.js +1 -4
- package/src/plugins/resolution_node_esm/jsenv_plugin_node_esm_resolution.js +56 -34
- package/src/plugins/resolution_node_esm/node_esm_resolver.js +132 -11
- package/src/build/jsenv_plugin_subbuilds.js +0 -76
- package/src/kitchen/url_graph/url_graph_report.js +0 -202
- /package/dist/client/{server_events_client → server_events}/server_events_client.js +0 -0
package/dist/build/build.js
CHANGED
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
import { parseHtml, injectHtmlNodeAsEarlyAsPossible, createHtmlNode, stringifyHtmlAst, applyBabelPlugins, generateUrlForInlineContent, parseJsWithAcorn, visitHtmlNodes, analyzeScriptNode, getHtmlNodeText, getHtmlNodeAttribute, getHtmlNodePosition, getUrlForContentInsideHtml, setHtmlNodeAttributes, setHtmlNodeText, parseCssUrls, getHtmlNodeAttributePosition, parseSrcSet, removeHtmlNodeText, parseJsUrls, getUrlForContentInsideJs, analyzeLinkNode, injectJsenvScript, findHtmlNode, removeHtmlNode, insertHtmlNodeAfter } from "@jsenv/ast";
|
|
2
|
-
import {
|
|
2
|
+
import { startMonitoringCpuUsage, startMonitoringMemoryUsage } from "@jsenv/os-metrics";
|
|
3
|
+
import { memoryUsage } from "node:process";
|
|
3
4
|
import { readFileSync, existsSync, readdirSync, lstatSync, realpathSync } from "node:fs";
|
|
4
|
-
import { RUNTIME_COMPAT } from "
|
|
5
|
+
import { lookupPackageDirectory$1 as lookupPackageDirectory, registerDirectoryLifecycle$1 as registerDirectoryLifecycle, urlToRelativeUrl$1 as urlToRelativeUrl, createDetailedMessage$1 as createDetailedMessage, stringifyUrlSite$1 as stringifyUrlSite, generateContentFrame$1 as generateContentFrame, validateResponseIntegrity$1 as validateResponseIntegrity, urlIsInsideOf$1 as urlIsInsideOf, ensureWindowsDriveLetter$1 as ensureWindowsDriveLetter, setUrlFilename$1 as setUrlFilename, moveUrl$1 as moveUrl, getCallerPosition$1 as getCallerPosition, urlToBasename$1 as urlToBasename, urlToExtension$1 as urlToExtension, asSpecifierWithoutSearch$1 as asSpecifierWithoutSearch, asUrlWithoutSearch$1 as asUrlWithoutSearch, injectQueryParamsIntoSpecifier$1 as injectQueryParamsIntoSpecifier, bufferToEtag$1 as bufferToEtag, isFileSystemPath$1 as isFileSystemPath, urlToPathname$1 as urlToPathname, setUrlBasename$1 as setUrlBasename, urlToFileSystemPath$1 as urlToFileSystemPath, writeFileSync$1 as writeFileSync, createLogger$1 as createLogger, URL_META$1 as URL_META, applyNodeEsmResolution$1 as applyNodeEsmResolution, RUNTIME_COMPAT$1 as RUNTIME_COMPAT, normalizeUrl$1 as normalizeUrl, ANSI$1 as ANSI, CONTENT_TYPE$1 as CONTENT_TYPE, urlToFilename$1 as urlToFilename, DATA_URL$1 as DATA_URL, normalizeImportMap$1 as normalizeImportMap, composeTwoImportMaps$1 as composeTwoImportMaps, resolveImport$1 as resolveImport, JS_QUOTES$1 as JS_QUOTES, defaultLookupPackageScope$1 as defaultLookupPackageScope, defaultReadPackageJson$1 as defaultReadPackageJson, readCustomConditionsFromProcessArgs$1 as readCustomConditionsFromProcessArgs, readEntryStatSync$1 as readEntryStatSync, ensurePathnameTrailingSlash$1 as ensurePathnameTrailingSlash, compareFileUrls$1 as compareFileUrls, applyFileSystemMagicResolution$1 as applyFileSystemMagicResolution, getExtensionsToTry$1 as getExtensionsToTry, setUrlExtension$1 as setUrlExtension, jsenvPluginTranspilation$1 as jsenvPluginTranspilation, renderTable, humanizeFileSize, humanizeDuration, renderDetails, renderBigSection, distributePercentages, humanizeMemory, comparePathnames, UNICODE, escapeRegexpSpecialChars, injectQueryParamIntoSpecifierWithoutEncoding, renderUrlOrRelativeUrlFilename, assertAndNormalizeDirectoryUrl$1 as assertAndNormalizeDirectoryUrl, Abort, raceProcessTeardownEvents, inferRuntimeCompatFromClosestPackage, browserDefaultRuntimeCompat, nodeDefaultRuntimeCompat, clearDirectorySync, createTaskLog$1 as createTaskLog, jsenvPluginBundling, jsenvPluginMinification, ensureEmptyDirectory, jsenvPluginJsModuleFallback, createDynamicLog } from "../jsenv_core_packages.js";
|
|
5
6
|
import { pathToFileURL } from "node:url";
|
|
6
7
|
import { generateSourcemapFileUrl, createMagicSource, composeTwoSourcemaps, generateSourcemapDataUrl, SOURCEMAP } from "@jsenv/sourcemap";
|
|
7
8
|
import { performance } from "node:perf_hooks";
|
|
8
9
|
import { jsenvPluginSupervisor } from "@jsenv/plugin-supervisor";
|
|
9
10
|
import { WebSocketResponse, pickContentType } from "@jsenv/server";
|
|
10
11
|
import { createHash } from "node:crypto";
|
|
11
|
-
import "
|
|
12
|
-
import "
|
|
12
|
+
import "strip-ansi";
|
|
13
|
+
import "../jsenv_core_node_modules.js";
|
|
13
14
|
import "node:os";
|
|
14
15
|
import "node:tty";
|
|
16
|
+
import "node:util";
|
|
15
17
|
import "node:path";
|
|
16
18
|
import "node:module";
|
|
17
19
|
import "@jsenv/js-module-fallback";
|
|
@@ -481,7 +483,7 @@ const assertFetchedContentCompliance = ({ urlInfo, content }) => {
|
|
|
481
483
|
}
|
|
482
484
|
const { expectedType } = urlInfo.firstReference;
|
|
483
485
|
if (expectedType && urlInfo.type !== expectedType) {
|
|
484
|
-
if (urlInfo.type === "
|
|
486
|
+
if (urlInfo.type === "entry_build" && urlInfo.context.build) ; else {
|
|
485
487
|
throw new Error(
|
|
486
488
|
`type must be "${expectedType}", got "${urlInfo.type}" on ${urlInfo.url}`,
|
|
487
489
|
);
|
|
@@ -2624,7 +2626,7 @@ const shouldHandleSourcemap = (urlInfo) => {
|
|
|
2624
2626
|
};
|
|
2625
2627
|
|
|
2626
2628
|
const inlineContentClientFileUrl = new URL(
|
|
2627
|
-
"
|
|
2629
|
+
"./client/inline_content.js",
|
|
2628
2630
|
import.meta.url,
|
|
2629
2631
|
).href;
|
|
2630
2632
|
|
|
@@ -2677,7 +2679,7 @@ const createKitchen = ({
|
|
|
2677
2679
|
sourcemaps,
|
|
2678
2680
|
outDirectoryUrl,
|
|
2679
2681
|
},
|
|
2680
|
-
resolve: (specifier, importer) => {
|
|
2682
|
+
resolve: (specifier, importer = rootDirectoryUrl) => {
|
|
2681
2683
|
const { url, packageDirectoryUrl, packageJson } = applyNodeEsmResolution({
|
|
2682
2684
|
conditions: packageConditions,
|
|
2683
2685
|
parentUrl: importer,
|
|
@@ -3335,208 +3337,27 @@ const inferUrlInfoType = (urlInfo) => {
|
|
|
3335
3337
|
return expectedType || "other";
|
|
3336
3338
|
};
|
|
3337
3339
|
|
|
3338
|
-
const
|
|
3339
|
-
|
|
3340
|
-
{
|
|
3340
|
+
const jsenvPluginDirectoryReferenceEffect = (
|
|
3341
|
+
directoryReferenceEffect = "error",
|
|
3342
|
+
{ rootDirectoryUrl },
|
|
3341
3343
|
) => {
|
|
3342
|
-
|
|
3343
|
-
|
|
3344
|
-
|
|
3345
|
-
|
|
3346
|
-
|
|
3347
|
-
|
|
3348
|
-
const
|
|
3349
|
-
|
|
3350
|
-
|
|
3351
|
-
html: 0,
|
|
3352
|
-
css: 0,
|
|
3353
|
-
js: 0,
|
|
3354
|
-
json: 0,
|
|
3355
|
-
other: 0,
|
|
3356
|
-
total: 0,
|
|
3357
|
-
};
|
|
3358
|
-
const sizeGroups = {
|
|
3359
|
-
sourcemaps: 0,
|
|
3360
|
-
html: 0,
|
|
3361
|
-
css: 0,
|
|
3362
|
-
js: 0,
|
|
3363
|
-
json: 0,
|
|
3364
|
-
other: 0,
|
|
3365
|
-
total: 0,
|
|
3366
|
-
};
|
|
3367
|
-
|
|
3368
|
-
GRAPH_VISITOR.forEachUrlInfoStronglyReferenced(
|
|
3369
|
-
urlGraph.rootUrlInfo,
|
|
3370
|
-
(urlInfo) => {
|
|
3371
|
-
// ignore:
|
|
3372
|
-
// - ignored files: we don't know their content
|
|
3373
|
-
// - inline files and data files: they are already taken into account in the file where they appear
|
|
3374
|
-
if (urlInfo.url.startsWith("ignore:")) {
|
|
3375
|
-
return;
|
|
3376
|
-
}
|
|
3377
|
-
if (urlInfo.isInline) {
|
|
3378
|
-
return;
|
|
3379
|
-
}
|
|
3380
|
-
if (urlInfo.url.startsWith("data:")) {
|
|
3381
|
-
return;
|
|
3382
|
-
}
|
|
3383
|
-
|
|
3384
|
-
// file loaded via import assertion are already inside the graph
|
|
3385
|
-
// their js module equivalent are ignored to avoid counting it twice
|
|
3386
|
-
// in the build graph the file targeted by import assertion will likely be gone
|
|
3387
|
-
// and only the js module remain (likely bundled)
|
|
3388
|
-
if (
|
|
3389
|
-
urlInfo.searchParams.has("as_json_module") ||
|
|
3390
|
-
urlInfo.searchParams.has("as_css_module") ||
|
|
3391
|
-
urlInfo.searchParams.has("as_text_module")
|
|
3392
|
-
) {
|
|
3393
|
-
return;
|
|
3394
|
-
}
|
|
3395
|
-
|
|
3396
|
-
const urlContentSize = Buffer.byteLength(urlInfo.content);
|
|
3397
|
-
const category = determineCategory(urlInfo);
|
|
3398
|
-
if (category === "sourcemap") {
|
|
3399
|
-
countGroups.sourcemaps++;
|
|
3400
|
-
sizeGroups.sourcemaps += urlContentSize;
|
|
3401
|
-
return;
|
|
3402
|
-
}
|
|
3403
|
-
countGroups.total++;
|
|
3404
|
-
sizeGroups.total += urlContentSize;
|
|
3405
|
-
if (category === "html") {
|
|
3406
|
-
countGroups.html++;
|
|
3407
|
-
sizeGroups.html += urlContentSize;
|
|
3408
|
-
return;
|
|
3409
|
-
}
|
|
3410
|
-
if (category === "css") {
|
|
3411
|
-
countGroups.css++;
|
|
3412
|
-
sizeGroups.css += urlContentSize;
|
|
3413
|
-
return;
|
|
3414
|
-
}
|
|
3415
|
-
if (category === "js") {
|
|
3416
|
-
countGroups.js++;
|
|
3417
|
-
sizeGroups.js += urlContentSize;
|
|
3418
|
-
return;
|
|
3419
|
-
}
|
|
3420
|
-
if (category === "json") {
|
|
3421
|
-
countGroups.json++;
|
|
3422
|
-
sizeGroups.json += urlContentSize;
|
|
3423
|
-
return;
|
|
3424
|
-
}
|
|
3425
|
-
countGroups.other++;
|
|
3426
|
-
sizeGroups.other += urlContentSize;
|
|
3427
|
-
return;
|
|
3428
|
-
},
|
|
3429
|
-
);
|
|
3430
|
-
|
|
3431
|
-
const sizesToDistribute = {};
|
|
3432
|
-
Object.keys(sizeGroups).forEach((groupName) => {
|
|
3433
|
-
if (groupName !== "sourcemaps" && groupName !== "total") {
|
|
3434
|
-
sizesToDistribute[groupName] = sizeGroups[groupName];
|
|
3435
|
-
}
|
|
3436
|
-
});
|
|
3437
|
-
const percentageGroups = distributePercentages(sizesToDistribute);
|
|
3438
|
-
|
|
3439
|
-
return {
|
|
3440
|
-
// sourcemaps are special, there size are ignored
|
|
3441
|
-
// so there is no "percentage" associated
|
|
3442
|
-
sourcemaps: {
|
|
3443
|
-
count: countGroups.sourcemaps,
|
|
3444
|
-
size: sizeGroups.sourcemaps,
|
|
3445
|
-
percentage: undefined,
|
|
3446
|
-
},
|
|
3447
|
-
|
|
3448
|
-
html: {
|
|
3449
|
-
count: countGroups.html,
|
|
3450
|
-
size: sizeGroups.html,
|
|
3451
|
-
percentage: percentageGroups.html,
|
|
3452
|
-
},
|
|
3453
|
-
css: {
|
|
3454
|
-
count: countGroups.css,
|
|
3455
|
-
size: sizeGroups.css,
|
|
3456
|
-
percentage: percentageGroups.css,
|
|
3457
|
-
},
|
|
3458
|
-
js: {
|
|
3459
|
-
count: countGroups.js,
|
|
3460
|
-
size: sizeGroups.js,
|
|
3461
|
-
percentage: percentageGroups.js,
|
|
3462
|
-
},
|
|
3463
|
-
json: {
|
|
3464
|
-
count: countGroups.json,
|
|
3465
|
-
size: sizeGroups.json,
|
|
3466
|
-
percentage: percentageGroups.json,
|
|
3467
|
-
},
|
|
3468
|
-
other: {
|
|
3469
|
-
count: countGroups.other,
|
|
3470
|
-
size: sizeGroups.other,
|
|
3471
|
-
percentage: percentageGroups.other,
|
|
3472
|
-
},
|
|
3473
|
-
total: {
|
|
3474
|
-
count: countGroups.total,
|
|
3475
|
-
size: sizeGroups.total,
|
|
3476
|
-
percentage: 100,
|
|
3477
|
-
},
|
|
3478
|
-
};
|
|
3479
|
-
};
|
|
3480
|
-
|
|
3481
|
-
const determineCategory = (urlInfo) => {
|
|
3482
|
-
if (urlInfo.type === "sourcemap") {
|
|
3483
|
-
return "sourcemap";
|
|
3484
|
-
}
|
|
3485
|
-
if (urlInfo.type === "html") {
|
|
3486
|
-
return "html";
|
|
3487
|
-
}
|
|
3488
|
-
if (urlInfo.type === "css") {
|
|
3489
|
-
return "css";
|
|
3490
|
-
}
|
|
3491
|
-
if (urlInfo.type === "js_module" || urlInfo.type === "js_classic") {
|
|
3492
|
-
return "js";
|
|
3493
|
-
}
|
|
3494
|
-
if (urlInfo.type === "json") {
|
|
3495
|
-
return "json";
|
|
3496
|
-
}
|
|
3497
|
-
return "other";
|
|
3498
|
-
};
|
|
3499
|
-
|
|
3500
|
-
const createRepartitionMessage = ({ html, css, js, json, other, total }) => {
|
|
3501
|
-
const addPart = (name, { count, size, percentage }) => {
|
|
3502
|
-
parts.push(
|
|
3503
|
-
`${ANSI.color(`${name}:`, ANSI.GREY)} ${count} (${humanizeFileSize(
|
|
3504
|
-
size,
|
|
3505
|
-
)} / ${percentage} %)`,
|
|
3344
|
+
let getDirectoryReferenceEffect;
|
|
3345
|
+
if (typeof directoryReferenceEffect === "string") {
|
|
3346
|
+
getDirectoryReferenceEffect = () => directoryReferenceEffect;
|
|
3347
|
+
} else if (typeof directoryReferenceEffect === "function") {
|
|
3348
|
+
getDirectoryReferenceEffect = directoryReferenceEffect;
|
|
3349
|
+
} else if (typeof directoryReferenceEffect === "object") {
|
|
3350
|
+
const associations = URL_META.resolveAssociations(
|
|
3351
|
+
{ effect: directoryReferenceEffect },
|
|
3352
|
+
rootDirectoryUrl,
|
|
3506
3353
|
);
|
|
3507
|
-
|
|
3508
|
-
|
|
3509
|
-
|
|
3510
|
-
|
|
3511
|
-
|
|
3512
|
-
// `${ANSI.color(`sourcemaps:`, ANSI.GREY)} ${
|
|
3513
|
-
// sourcemaps.count
|
|
3514
|
-
// } (${humanizeFileSize(sourcemaps.size)})`,
|
|
3515
|
-
// )
|
|
3516
|
-
// }
|
|
3517
|
-
if (html.count) {
|
|
3518
|
-
addPart("html ", html);
|
|
3519
|
-
}
|
|
3520
|
-
if (css.count) {
|
|
3521
|
-
addPart("css ", css);
|
|
3522
|
-
}
|
|
3523
|
-
if (js.count) {
|
|
3524
|
-
addPart("js ", js);
|
|
3525
|
-
}
|
|
3526
|
-
if (json.count) {
|
|
3527
|
-
addPart("json ", json);
|
|
3528
|
-
}
|
|
3529
|
-
if (other.count) {
|
|
3530
|
-
addPart("other", other);
|
|
3354
|
+
getDirectoryReferenceEffect = (reference) => {
|
|
3355
|
+
const { url } = reference;
|
|
3356
|
+
const meta = URL_META.applyAssociations({ url, associations });
|
|
3357
|
+
return meta.effect || "error";
|
|
3358
|
+
};
|
|
3531
3359
|
}
|
|
3532
|
-
addPart("total", total);
|
|
3533
|
-
return `- ${parts.join(`
|
|
3534
|
-
- `)}`;
|
|
3535
|
-
};
|
|
3536
3360
|
|
|
3537
|
-
const jsenvPluginDirectoryReferenceEffect = (
|
|
3538
|
-
directoryReferenceEffect = "error",
|
|
3539
|
-
) => {
|
|
3540
3361
|
return {
|
|
3541
3362
|
name: "jsenv:directory_reference_effect",
|
|
3542
3363
|
appliesDuring: "*",
|
|
@@ -3573,12 +3394,8 @@ const jsenvPluginDirectoryReferenceEffect = (
|
|
|
3573
3394
|
actionForDirectory = "copy";
|
|
3574
3395
|
} else if (reference.type === "http_request") {
|
|
3575
3396
|
actionForDirectory = "preserve";
|
|
3576
|
-
} else if (typeof directoryReferenceEffect === "string") {
|
|
3577
|
-
actionForDirectory = directoryReferenceEffect;
|
|
3578
|
-
} else if (typeof directoryReferenceEffect === "function") {
|
|
3579
|
-
actionForDirectory = directoryReferenceEffect(reference);
|
|
3580
3397
|
} else {
|
|
3581
|
-
actionForDirectory =
|
|
3398
|
+
actionForDirectory = getDirectoryReferenceEffect(reference);
|
|
3582
3399
|
}
|
|
3583
3400
|
reference.actionForDirectory = actionForDirectory;
|
|
3584
3401
|
if (actionForDirectory !== "copy") {
|
|
@@ -3857,7 +3674,7 @@ const jsenvPluginInlining = () => {
|
|
|
3857
3674
|
|
|
3858
3675
|
const jsenvPluginHtmlSyntaxErrorFallback = () => {
|
|
3859
3676
|
const htmlSyntaxErrorFileUrl = import.meta.resolve(
|
|
3860
|
-
"
|
|
3677
|
+
"./client/html_syntax_error.html",
|
|
3861
3678
|
);
|
|
3862
3679
|
|
|
3863
3680
|
return {
|
|
@@ -5320,7 +5137,7 @@ const parseAndTransformJsReferences = async (
|
|
|
5320
5137
|
let filenameHint;
|
|
5321
5138
|
if (
|
|
5322
5139
|
externalReferenceInfo.subtype === "import_dynamic" &&
|
|
5323
|
-
isBareSpecifier(externalReferenceInfo.specifier)
|
|
5140
|
+
isBareSpecifier$2(externalReferenceInfo.specifier)
|
|
5324
5141
|
) {
|
|
5325
5142
|
filenameHint = `${externalReferenceInfo.specifier}.js`;
|
|
5326
5143
|
}
|
|
@@ -5410,7 +5227,7 @@ const parseAndTransformJsReferences = async (
|
|
|
5410
5227
|
return { content, sourcemap };
|
|
5411
5228
|
};
|
|
5412
5229
|
|
|
5413
|
-
const isBareSpecifier = (specifier) => {
|
|
5230
|
+
const isBareSpecifier$2 = (specifier) => {
|
|
5414
5231
|
if (
|
|
5415
5232
|
specifier[0] === "/" ||
|
|
5416
5233
|
specifier.startsWith("./") ||
|
|
@@ -5524,7 +5341,6 @@ const jsenvPluginReferenceAnalysis = ({
|
|
|
5524
5341
|
inlineContent = true,
|
|
5525
5342
|
inlineConvertedScript = false,
|
|
5526
5343
|
fetchInlineUrls = true,
|
|
5527
|
-
directoryReferenceEffect,
|
|
5528
5344
|
}) => {
|
|
5529
5345
|
return [
|
|
5530
5346
|
jsenvPluginDirectoryReferenceAnalysis(),
|
|
@@ -5625,18 +5441,18 @@ const jsenvPluginInlineContentFetcher = () => {
|
|
|
5625
5441
|
|
|
5626
5442
|
|
|
5627
5443
|
const createNodeEsmResolver = ({
|
|
5628
|
-
build,
|
|
5629
5444
|
runtimeCompat,
|
|
5630
|
-
|
|
5445
|
+
rootDirectoryUrl,
|
|
5446
|
+
packageConditions = {},
|
|
5631
5447
|
preservesSymlink,
|
|
5632
5448
|
}) => {
|
|
5633
|
-
const
|
|
5634
|
-
|
|
5635
|
-
|
|
5636
|
-
|
|
5637
|
-
|
|
5638
|
-
|
|
5639
|
-
|
|
5449
|
+
const buildPackageConditions = createBuildPackageConditions(
|
|
5450
|
+
packageConditions,
|
|
5451
|
+
{
|
|
5452
|
+
rootDirectoryUrl,
|
|
5453
|
+
runtimeCompat,
|
|
5454
|
+
},
|
|
5455
|
+
);
|
|
5640
5456
|
|
|
5641
5457
|
return (reference) => {
|
|
5642
5458
|
if (reference.type === "package_json") {
|
|
@@ -5657,10 +5473,12 @@ const createNodeEsmResolver = ({
|
|
|
5657
5473
|
if (!parentUrl.startsWith("file:")) {
|
|
5658
5474
|
return null; // let it to jsenv_web_resolution
|
|
5659
5475
|
}
|
|
5476
|
+
const { specifier } = reference;
|
|
5477
|
+
const conditions = buildPackageConditions(specifier, parentUrl);
|
|
5660
5478
|
const { url, type, isMain, packageDirectoryUrl } = applyNodeEsmResolution({
|
|
5661
|
-
conditions
|
|
5479
|
+
conditions,
|
|
5662
5480
|
parentUrl,
|
|
5663
|
-
specifier
|
|
5481
|
+
specifier,
|
|
5664
5482
|
preservesSymlink,
|
|
5665
5483
|
});
|
|
5666
5484
|
// try to give a more meaningful filename after build
|
|
@@ -5724,6 +5542,107 @@ const createNodeEsmResolver = ({
|
|
|
5724
5542
|
};
|
|
5725
5543
|
};
|
|
5726
5544
|
|
|
5545
|
+
const createBuildPackageConditions = (
|
|
5546
|
+
packageConditions,
|
|
5547
|
+
{ rootDirectoryUrl, runtimeCompat },
|
|
5548
|
+
) => {
|
|
5549
|
+
const nodeRuntimeEnabled = Object.keys(runtimeCompat).includes("node");
|
|
5550
|
+
// https://nodejs.org/api/esm.html#resolver-algorithm-specification
|
|
5551
|
+
const processArgConditions = readCustomConditionsFromProcessArgs();
|
|
5552
|
+
const packageConditionsDefaultResolvers = {};
|
|
5553
|
+
for (const processArgCondition of processArgConditions) {
|
|
5554
|
+
packageConditionsDefaultResolvers[processArgCondition] = true;
|
|
5555
|
+
}
|
|
5556
|
+
const packageConditionResolvers = {
|
|
5557
|
+
...packageConditionsDefaultResolvers,
|
|
5558
|
+
development: (specifier, importer) => {
|
|
5559
|
+
if (isBareSpecifier$1(specifier)) {
|
|
5560
|
+
const { url } = applyNodeEsmResolution({
|
|
5561
|
+
specifier,
|
|
5562
|
+
parentUrl: importer,
|
|
5563
|
+
});
|
|
5564
|
+
return !url.includes("/node_modules/");
|
|
5565
|
+
}
|
|
5566
|
+
return !importer.includes("/node_modules/");
|
|
5567
|
+
},
|
|
5568
|
+
node: nodeRuntimeEnabled,
|
|
5569
|
+
browser: !nodeRuntimeEnabled,
|
|
5570
|
+
import: true,
|
|
5571
|
+
};
|
|
5572
|
+
for (const condition of Object.keys(packageConditions)) {
|
|
5573
|
+
const value = packageConditions[condition];
|
|
5574
|
+
let customResolver;
|
|
5575
|
+
if (typeof value === "object") {
|
|
5576
|
+
const associations = URL_META.resolveAssociations(
|
|
5577
|
+
{ applies: value },
|
|
5578
|
+
(pattern) => {
|
|
5579
|
+
if (isBareSpecifier$1(pattern)) {
|
|
5580
|
+
try {
|
|
5581
|
+
if (pattern.endsWith("/")) {
|
|
5582
|
+
// avoid package path not exported
|
|
5583
|
+
const { packageDirectoryUrl } = applyNodeEsmResolution({
|
|
5584
|
+
specifier: pattern.slice(0, -1),
|
|
5585
|
+
parentUrl: rootDirectoryUrl,
|
|
5586
|
+
});
|
|
5587
|
+
return packageDirectoryUrl;
|
|
5588
|
+
}
|
|
5589
|
+
const { url } = applyNodeEsmResolution({
|
|
5590
|
+
specifier: pattern,
|
|
5591
|
+
parentUrl: rootDirectoryUrl,
|
|
5592
|
+
});
|
|
5593
|
+
return url;
|
|
5594
|
+
} catch {
|
|
5595
|
+
return new URL(pattern, rootDirectoryUrl);
|
|
5596
|
+
}
|
|
5597
|
+
}
|
|
5598
|
+
return new URL(pattern, rootDirectoryUrl);
|
|
5599
|
+
},
|
|
5600
|
+
);
|
|
5601
|
+
customResolver = (specifier, importer) => {
|
|
5602
|
+
if (isBareSpecifier$1(specifier)) {
|
|
5603
|
+
const { url } = applyNodeEsmResolution({
|
|
5604
|
+
specifier,
|
|
5605
|
+
parentUrl: importer,
|
|
5606
|
+
});
|
|
5607
|
+
const { applies } = URL_META.applyAssociations({ url, associations });
|
|
5608
|
+
return applies;
|
|
5609
|
+
}
|
|
5610
|
+
return URL_META.applyAssociations({ url: importer, associations })
|
|
5611
|
+
.applies;
|
|
5612
|
+
};
|
|
5613
|
+
} else if (typeof value === "function") {
|
|
5614
|
+
customResolver = value;
|
|
5615
|
+
} else {
|
|
5616
|
+
customResolver = () => value;
|
|
5617
|
+
}
|
|
5618
|
+
const existing = packageConditionResolvers[condition];
|
|
5619
|
+
if (existing) {
|
|
5620
|
+
packageConditionResolvers[condition] = (...args) => {
|
|
5621
|
+
const customResult = customResolver(...args);
|
|
5622
|
+
return customResult === undefined ? existing(...args) : customResult;
|
|
5623
|
+
};
|
|
5624
|
+
} else {
|
|
5625
|
+
packageConditionResolvers[condition] = customResolver;
|
|
5626
|
+
}
|
|
5627
|
+
}
|
|
5628
|
+
|
|
5629
|
+
return (specifier, importer) => {
|
|
5630
|
+
const conditions = [];
|
|
5631
|
+
for (const conditionCandidate of Object.keys(packageConditionResolvers)) {
|
|
5632
|
+
const packageConditionResolver =
|
|
5633
|
+
packageConditionResolvers[conditionCandidate];
|
|
5634
|
+
if (typeof packageConditionResolver === "function") {
|
|
5635
|
+
if (packageConditionResolver(specifier, importer)) {
|
|
5636
|
+
conditions.push(conditionCandidate);
|
|
5637
|
+
}
|
|
5638
|
+
} else if (packageConditionResolver) {
|
|
5639
|
+
conditions.push(conditionCandidate);
|
|
5640
|
+
}
|
|
5641
|
+
}
|
|
5642
|
+
return conditions;
|
|
5643
|
+
};
|
|
5644
|
+
};
|
|
5645
|
+
|
|
5727
5646
|
const addRelationshipWithPackageJson = ({
|
|
5728
5647
|
reference,
|
|
5729
5648
|
packageJsonUrl,
|
|
@@ -5758,9 +5677,51 @@ const addRelationshipWithPackageJson = ({
|
|
|
5758
5677
|
}
|
|
5759
5678
|
};
|
|
5760
5679
|
|
|
5761
|
-
const
|
|
5680
|
+
const isBareSpecifier$1 = (specifier) => {
|
|
5681
|
+
if (
|
|
5682
|
+
specifier[0] === "/" ||
|
|
5683
|
+
specifier.startsWith("./") ||
|
|
5684
|
+
specifier.startsWith("../")
|
|
5685
|
+
) {
|
|
5686
|
+
return false;
|
|
5687
|
+
}
|
|
5688
|
+
try {
|
|
5689
|
+
// eslint-disable-next-line no-new
|
|
5690
|
+
new URL(specifier);
|
|
5691
|
+
return false;
|
|
5692
|
+
} catch {
|
|
5693
|
+
return true;
|
|
5694
|
+
}
|
|
5695
|
+
};
|
|
5696
|
+
|
|
5697
|
+
const jsenvPluginNodeEsmResolution = (
|
|
5698
|
+
resolutionConfig = {},
|
|
5699
|
+
packageConditions,
|
|
5700
|
+
) => {
|
|
5762
5701
|
let nodeEsmResolverDefault;
|
|
5763
|
-
const
|
|
5702
|
+
const resolverMap = new Map();
|
|
5703
|
+
let anyTypeResolver;
|
|
5704
|
+
|
|
5705
|
+
const resolverFromObject = (
|
|
5706
|
+
{ preservesSymlink, ...rest },
|
|
5707
|
+
{ kitchenContext, urlType },
|
|
5708
|
+
) => {
|
|
5709
|
+
const unexpectedKeys = Object.keys(rest);
|
|
5710
|
+
if (unexpectedKeys.length) {
|
|
5711
|
+
throw new TypeError(
|
|
5712
|
+
`${unexpectedKeys.join(
|
|
5713
|
+
",",
|
|
5714
|
+
)}: there is no such configuration on "${urlType}"`,
|
|
5715
|
+
);
|
|
5716
|
+
}
|
|
5717
|
+
return createNodeEsmResolver({
|
|
5718
|
+
build: kitchenContext.build,
|
|
5719
|
+
runtimeCompat: kitchenContext.runtimeCompat,
|
|
5720
|
+
rootDirectoryUrl: kitchenContext.rootDirectoryUrl,
|
|
5721
|
+
packageConditions,
|
|
5722
|
+
preservesSymlink,
|
|
5723
|
+
});
|
|
5724
|
+
};
|
|
5764
5725
|
|
|
5765
5726
|
return {
|
|
5766
5727
|
name: "jsenv:node_esm_resolution",
|
|
@@ -5769,47 +5730,38 @@ const jsenvPluginNodeEsmResolution = (resolutionConfig = {}) => {
|
|
|
5769
5730
|
nodeEsmResolverDefault = createNodeEsmResolver({
|
|
5770
5731
|
build: kitchenContext.build,
|
|
5771
5732
|
runtimeCompat: kitchenContext.runtimeCompat,
|
|
5733
|
+
rootDirectoryUrl: kitchenContext.rootDirectoryUrl,
|
|
5772
5734
|
preservesSymlink: true,
|
|
5735
|
+
packageConditions,
|
|
5773
5736
|
});
|
|
5774
|
-
Object.keys(resolutionConfig)
|
|
5737
|
+
for (const urlType of Object.keys(resolutionConfig)) {
|
|
5738
|
+
let resolver;
|
|
5775
5739
|
const config = resolutionConfig[urlType];
|
|
5776
5740
|
if (config === true) {
|
|
5777
|
-
|
|
5741
|
+
resolver = nodeEsmResolverDefault;
|
|
5778
5742
|
} else if (config === false) {
|
|
5779
|
-
|
|
5743
|
+
// resolverMap.set(urlType, () => null);
|
|
5744
|
+
continue;
|
|
5780
5745
|
} else if (typeof config === "object") {
|
|
5781
|
-
|
|
5782
|
-
runtimeCompat,
|
|
5783
|
-
packageConditions,
|
|
5784
|
-
preservesSymlink,
|
|
5785
|
-
...rest
|
|
5786
|
-
} = config;
|
|
5787
|
-
const unexpectedKeys = Object.keys(rest);
|
|
5788
|
-
if (unexpectedKeys.length) {
|
|
5789
|
-
throw new TypeError(
|
|
5790
|
-
`${unexpectedKeys.join(
|
|
5791
|
-
",",
|
|
5792
|
-
)}: there is no such configuration on "${urlType}"`,
|
|
5793
|
-
);
|
|
5794
|
-
}
|
|
5795
|
-
resolvers[urlType] = createNodeEsmResolver({
|
|
5796
|
-
build: kitchenContext.build,
|
|
5797
|
-
runtimeCompat,
|
|
5798
|
-
packageConditions,
|
|
5799
|
-
preservesSymlink,
|
|
5800
|
-
});
|
|
5746
|
+
resolver = resolverFromObject(config, { kitchenContext, urlType });
|
|
5801
5747
|
} else {
|
|
5802
5748
|
throw new TypeError(
|
|
5803
|
-
`config must be true, false or an object
|
|
5749
|
+
`The value "${config}" for ${urlType} in nodeEsmResolution is invalid: it must be true, false or an object.`,
|
|
5804
5750
|
);
|
|
5805
5751
|
}
|
|
5806
|
-
});
|
|
5807
5752
|
|
|
5808
|
-
|
|
5809
|
-
|
|
5753
|
+
if (urlType === "*") {
|
|
5754
|
+
anyTypeResolver = resolver;
|
|
5755
|
+
} else {
|
|
5756
|
+
resolverMap.set(urlType, resolver);
|
|
5757
|
+
}
|
|
5758
|
+
}
|
|
5759
|
+
|
|
5760
|
+
if (!resolverMap.has("js_module")) {
|
|
5761
|
+
resolverMap.set("js_module", nodeEsmResolverDefault);
|
|
5810
5762
|
}
|
|
5811
|
-
if (
|
|
5812
|
-
|
|
5763
|
+
if (!resolverMap.has("js_classic")) {
|
|
5764
|
+
resolverMap.set("js_classic", (reference) => {
|
|
5813
5765
|
if (reference.subtype === "self_import_scripts_arg") {
|
|
5814
5766
|
return nodeEsmResolverDefault(reference);
|
|
5815
5767
|
}
|
|
@@ -5818,7 +5770,7 @@ const jsenvPluginNodeEsmResolution = (resolutionConfig = {}) => {
|
|
|
5818
5770
|
return nodeEsmResolverDefault(reference);
|
|
5819
5771
|
}
|
|
5820
5772
|
return null;
|
|
5821
|
-
};
|
|
5773
|
+
});
|
|
5822
5774
|
}
|
|
5823
5775
|
},
|
|
5824
5776
|
resolveReference: (reference) => {
|
|
@@ -5828,8 +5780,14 @@ const jsenvPluginNodeEsmResolution = (resolutionConfig = {}) => {
|
|
|
5828
5780
|
return result;
|
|
5829
5781
|
}
|
|
5830
5782
|
const urlType = urlTypeFromReference(reference);
|
|
5831
|
-
const resolver =
|
|
5832
|
-
|
|
5783
|
+
const resolver = resolverMap.get(urlType);
|
|
5784
|
+
if (resolver) {
|
|
5785
|
+
return resolver(reference);
|
|
5786
|
+
}
|
|
5787
|
+
if (anyTypeResolver) {
|
|
5788
|
+
return anyTypeResolver(reference);
|
|
5789
|
+
}
|
|
5790
|
+
return null;
|
|
5833
5791
|
},
|
|
5834
5792
|
// when specifier is prefixed by "file:///@ignore/"
|
|
5835
5793
|
// we return an empty js module
|
|
@@ -6071,7 +6029,7 @@ return {
|
|
|
6071
6029
|
|
|
6072
6030
|
|
|
6073
6031
|
const htmlFileUrlForDirectory = import.meta.resolve(
|
|
6074
|
-
"
|
|
6032
|
+
"./client/directory_listing.html",
|
|
6075
6033
|
);
|
|
6076
6034
|
|
|
6077
6035
|
const jsenvPluginDirectoryListing = ({
|
|
@@ -6426,9 +6384,8 @@ const getDirectoryContentItems = ({
|
|
|
6426
6384
|
fileUrls.push(fileUrlObject);
|
|
6427
6385
|
}
|
|
6428
6386
|
}
|
|
6429
|
-
fileUrls.sort(
|
|
6430
|
-
|
|
6431
|
-
});
|
|
6387
|
+
fileUrls.sort(compareFileUrls);
|
|
6388
|
+
|
|
6432
6389
|
const items = [];
|
|
6433
6390
|
for (const fileUrl of fileUrls) {
|
|
6434
6391
|
const urlRelativeToCurrentDirectory = urlToRelativeUrl(
|
|
@@ -7433,7 +7390,7 @@ const htmlNodeCanHotReload = (node) => {
|
|
|
7433
7390
|
|
|
7434
7391
|
const jsenvPluginImportMetaHot = () => {
|
|
7435
7392
|
const importMetaHotClientFileUrl = import.meta.resolve(
|
|
7436
|
-
"
|
|
7393
|
+
"./client/import_meta_hot.js",
|
|
7437
7394
|
);
|
|
7438
7395
|
|
|
7439
7396
|
return {
|
|
@@ -7545,7 +7502,7 @@ import.meta.hot = createImportMetaHot(import.meta.url);
|
|
|
7545
7502
|
};
|
|
7546
7503
|
|
|
7547
7504
|
const jsenvPluginAutoreloadClient = () => {
|
|
7548
|
-
const autoreloadClientFileUrl = import.meta.resolve("
|
|
7505
|
+
const autoreloadClientFileUrl = import.meta.resolve("./client/autoreload.js");
|
|
7549
7506
|
|
|
7550
7507
|
return {
|
|
7551
7508
|
name: "jsenv:autoreload_client",
|
|
@@ -8064,7 +8021,7 @@ const jsenvPluginRibbon = ({
|
|
|
8064
8021
|
rootDirectoryUrl,
|
|
8065
8022
|
htmlInclude = "/**/*.html",
|
|
8066
8023
|
}) => {
|
|
8067
|
-
const ribbonClientFileUrl = import.meta.resolve("
|
|
8024
|
+
const ribbonClientFileUrl = import.meta.resolve("./client/ribbon.js");
|
|
8068
8025
|
const associations = URL_META.resolveAssociations(
|
|
8069
8026
|
{
|
|
8070
8027
|
ribbon: {
|
|
@@ -8152,6 +8109,7 @@ const getCorePlugins = ({
|
|
|
8152
8109
|
|
|
8153
8110
|
referenceAnalysis = {},
|
|
8154
8111
|
nodeEsmResolution = {},
|
|
8112
|
+
packageConditions,
|
|
8155
8113
|
magicExtensions,
|
|
8156
8114
|
magicDirectoryIndex,
|
|
8157
8115
|
directoryListing = true,
|
|
@@ -8222,10 +8180,12 @@ const getCorePlugins = ({
|
|
|
8222
8180
|
},
|
|
8223
8181
|
},
|
|
8224
8182
|
...(nodeEsmResolution
|
|
8225
|
-
? [jsenvPluginNodeEsmResolution(nodeEsmResolution)]
|
|
8183
|
+
? [jsenvPluginNodeEsmResolution(nodeEsmResolution, packageConditions)]
|
|
8226
8184
|
: []),
|
|
8227
8185
|
jsenvPluginWebResolution(),
|
|
8228
|
-
jsenvPluginDirectoryReferenceEffect(directoryReferenceEffect
|
|
8186
|
+
jsenvPluginDirectoryReferenceEffect(directoryReferenceEffect, {
|
|
8187
|
+
rootDirectoryUrl,
|
|
8188
|
+
}),
|
|
8229
8189
|
jsenvPluginVersionSearchParam(),
|
|
8230
8190
|
|
|
8231
8191
|
// "jsenvPluginSupervisor" MUST be after "jsenvPluginInlining" as it needs inline script to be cooked
|
|
@@ -8246,180 +8206,274 @@ const getCorePlugins = ({
|
|
|
8246
8206
|
];
|
|
8247
8207
|
};
|
|
8248
8208
|
|
|
8249
|
-
|
|
8250
|
-
|
|
8251
|
-
|
|
8252
|
-
const
|
|
8253
|
-
|
|
8254
|
-
chrome: "64",
|
|
8255
|
-
edge: "79",
|
|
8256
|
-
firefox: "67",
|
|
8257
|
-
ios: "12",
|
|
8258
|
-
opera: "51",
|
|
8259
|
-
safari: "11.3",
|
|
8260
|
-
samsung: "9.2",
|
|
8209
|
+
const humanizeProcessCpuUsage = (ratio) => {
|
|
8210
|
+
const percentageAsNumber = ratio * 100;
|
|
8211
|
+
const percentageAsNumberRounded = Math.round(percentageAsNumber);
|
|
8212
|
+
const percentage = `${percentageAsNumberRounded}%`;
|
|
8213
|
+
return percentage;
|
|
8261
8214
|
};
|
|
8262
|
-
const
|
|
8263
|
-
|
|
8264
|
-
disabled: false,
|
|
8265
|
-
animation: true,
|
|
8215
|
+
const humanizeProcessMemoryUsage = (value) => {
|
|
8216
|
+
return humanizeMemory(value, { short: true, decimals: 0 });
|
|
8266
8217
|
};
|
|
8267
|
-
const
|
|
8268
|
-
|
|
8269
|
-
|
|
8270
|
-
|
|
8271
|
-
|
|
8272
|
-
sourceDirectoryUrl,
|
|
8273
|
-
buildDirectoryUrl,
|
|
8274
|
-
assetsDirectory,
|
|
8218
|
+
const renderBuildDoneLog = ({
|
|
8219
|
+
duration,
|
|
8220
|
+
buildFileContents,
|
|
8221
|
+
processCpuUsage,
|
|
8222
|
+
processMemoryUsage,
|
|
8275
8223
|
}) => {
|
|
8276
|
-
const
|
|
8277
|
-
|
|
8278
|
-
|
|
8279
|
-
|
|
8224
|
+
const buildContentReport = createBuildContentReport(buildFileContents);
|
|
8225
|
+
|
|
8226
|
+
let title = "";
|
|
8227
|
+
let content = "";
|
|
8228
|
+
const lines = [];
|
|
8229
|
+
|
|
8230
|
+
const filesWrittenCount = buildContentReport.total.count;
|
|
8231
|
+
if (filesWrittenCount === 1) {
|
|
8232
|
+
title = `1 file written`;
|
|
8233
|
+
} else {
|
|
8234
|
+
title = `${filesWrittenCount} files written`;
|
|
8235
|
+
const keys = Object.keys(buildContentReport);
|
|
8236
|
+
const rows = [];
|
|
8237
|
+
let y = 0;
|
|
8238
|
+
let highestPercentage = 0;
|
|
8239
|
+
let highestPercentageY = 0;
|
|
8240
|
+
for (const key of keys) {
|
|
8241
|
+
if (key === "sourcemaps") {
|
|
8242
|
+
continue;
|
|
8243
|
+
}
|
|
8244
|
+
if (key === "total") {
|
|
8245
|
+
continue;
|
|
8246
|
+
}
|
|
8247
|
+
const { count, size, percentage } = buildContentReport[key];
|
|
8248
|
+
if (count === 0) {
|
|
8249
|
+
continue;
|
|
8250
|
+
}
|
|
8251
|
+
const row = [
|
|
8252
|
+
{
|
|
8253
|
+
value: key,
|
|
8254
|
+
borderTop: {},
|
|
8255
|
+
borderBottom: {},
|
|
8256
|
+
},
|
|
8257
|
+
{
|
|
8258
|
+
value: count,
|
|
8259
|
+
borderTop: {},
|
|
8260
|
+
borderBottom: {},
|
|
8261
|
+
},
|
|
8262
|
+
{
|
|
8263
|
+
value: size,
|
|
8264
|
+
format: "size",
|
|
8265
|
+
borderTop: {},
|
|
8266
|
+
borderBottom: {},
|
|
8267
|
+
},
|
|
8268
|
+
{
|
|
8269
|
+
value: percentage,
|
|
8270
|
+
format: "percentage",
|
|
8271
|
+
unit: "%",
|
|
8272
|
+
borderTop: {},
|
|
8273
|
+
borderBottom: {},
|
|
8274
|
+
},
|
|
8275
|
+
];
|
|
8276
|
+
if (percentage > highestPercentage) {
|
|
8277
|
+
highestPercentage = percentage;
|
|
8278
|
+
highestPercentageY = y;
|
|
8279
|
+
}
|
|
8280
|
+
rows.push(row);
|
|
8281
|
+
y++;
|
|
8282
|
+
}
|
|
8283
|
+
if (rows.length > 1) {
|
|
8284
|
+
const rowWithHighestPercentage = rows[highestPercentageY];
|
|
8285
|
+
for (const cell of rowWithHighestPercentage) {
|
|
8286
|
+
cell.bold = true;
|
|
8287
|
+
}
|
|
8288
|
+
const table = renderTable(rows, {
|
|
8289
|
+
borderCollapse: true,
|
|
8290
|
+
ansi: true,
|
|
8291
|
+
});
|
|
8292
|
+
content += table;
|
|
8293
|
+
content += "\n";
|
|
8280
8294
|
}
|
|
8281
|
-
|
|
8282
|
-
return urlInfo.filenameHint;
|
|
8283
|
-
}
|
|
8284
|
-
return urlToFilename(url);
|
|
8285
|
-
};
|
|
8295
|
+
}
|
|
8286
8296
|
|
|
8287
|
-
|
|
8297
|
+
let sizeLine = `total size: `;
|
|
8298
|
+
sizeLine += humanizeFileSize(buildContentReport.total.size);
|
|
8299
|
+
lines.push(sizeLine);
|
|
8288
8300
|
|
|
8289
|
-
|
|
8290
|
-
|
|
8291
|
-
|
|
8292
|
-
|
|
8293
|
-
|
|
8294
|
-
|
|
8301
|
+
let durationLine = `duration: `;
|
|
8302
|
+
durationLine += humanizeDuration(duration, { short: true });
|
|
8303
|
+
lines.push(durationLine);
|
|
8304
|
+
|
|
8305
|
+
// cpu usage
|
|
8306
|
+
let cpuUsageLine = "cpu: ";
|
|
8307
|
+
cpuUsageLine += `${humanizeProcessCpuUsage(processCpuUsage.end)}`;
|
|
8308
|
+
cpuUsageLine += renderDetails({
|
|
8309
|
+
med: humanizeProcessCpuUsage(processCpuUsage.median),
|
|
8310
|
+
min: humanizeProcessCpuUsage(processCpuUsage.min),
|
|
8311
|
+
max: humanizeProcessCpuUsage(processCpuUsage.max),
|
|
8312
|
+
});
|
|
8313
|
+
lines.push(cpuUsageLine);
|
|
8314
|
+
|
|
8315
|
+
// memory usage
|
|
8316
|
+
let memoryUsageLine = "memory: ";
|
|
8317
|
+
memoryUsageLine += `${humanizeProcessMemoryUsage(processMemoryUsage.end)}`;
|
|
8318
|
+
memoryUsageLine += renderDetails({
|
|
8319
|
+
med: humanizeProcessMemoryUsage(processMemoryUsage.median),
|
|
8320
|
+
min: humanizeProcessMemoryUsage(processMemoryUsage.min),
|
|
8321
|
+
max: humanizeProcessMemoryUsage(processMemoryUsage.max),
|
|
8322
|
+
});
|
|
8323
|
+
lines.push(memoryUsageLine);
|
|
8324
|
+
|
|
8325
|
+
content += lines.join("\n");
|
|
8326
|
+
return `${renderBigSection({
|
|
8327
|
+
title,
|
|
8328
|
+
content,
|
|
8329
|
+
})}`;
|
|
8330
|
+
};
|
|
8331
|
+
|
|
8332
|
+
const createBuildContentReport = (buildFileContents) => {
|
|
8333
|
+
const countGroups = {
|
|
8334
|
+
sourcemaps: 0,
|
|
8335
|
+
html: 0,
|
|
8336
|
+
css: 0,
|
|
8337
|
+
js: 0,
|
|
8338
|
+
json: 0,
|
|
8339
|
+
other: 0,
|
|
8340
|
+
total: 0,
|
|
8341
|
+
};
|
|
8342
|
+
const sizeGroups = {
|
|
8343
|
+
sourcemaps: 0,
|
|
8344
|
+
html: 0,
|
|
8345
|
+
css: 0,
|
|
8346
|
+
js: 0,
|
|
8347
|
+
json: 0,
|
|
8348
|
+
other: 0,
|
|
8349
|
+
total: 0,
|
|
8295
8350
|
};
|
|
8296
8351
|
|
|
8297
|
-
const
|
|
8298
|
-
const
|
|
8299
|
-
|
|
8300
|
-
|
|
8352
|
+
for (const buildRelativeUrl of Object.keys(buildFileContents)) {
|
|
8353
|
+
const content = buildFileContents[buildRelativeUrl];
|
|
8354
|
+
const contentSize = Buffer.byteLength(content);
|
|
8355
|
+
const category = determineCategory(buildRelativeUrl);
|
|
8356
|
+
if (category === "sourcemap") {
|
|
8357
|
+
countGroups.sourcemaps++;
|
|
8358
|
+
sizeGroups.sourcemaps += contentSize;
|
|
8359
|
+
continue;
|
|
8301
8360
|
}
|
|
8302
|
-
|
|
8303
|
-
|
|
8304
|
-
|
|
8361
|
+
countGroups.total++;
|
|
8362
|
+
sizeGroups.total += contentSize;
|
|
8363
|
+
if (category === "html") {
|
|
8364
|
+
countGroups.html++;
|
|
8365
|
+
sizeGroups.html += contentSize;
|
|
8366
|
+
continue;
|
|
8305
8367
|
}
|
|
8306
|
-
if (
|
|
8307
|
-
|
|
8308
|
-
|
|
8309
|
-
|
|
8310
|
-
let directoryPath;
|
|
8311
|
-
if (url === sourceDirectoryUrl) {
|
|
8312
|
-
directoryPath = "";
|
|
8313
|
-
} else if (urlInfo.filenameHint) {
|
|
8314
|
-
directoryPath = urlInfo.filenameHint;
|
|
8315
|
-
} else {
|
|
8316
|
-
directoryPath = urlToRelativeUrl(url, sourceDirectoryUrl);
|
|
8317
|
-
}
|
|
8318
|
-
const { search } = new URL(url);
|
|
8319
|
-
const buildUrl = `${buildDirectoryUrl}${directoryPath}${search}`;
|
|
8320
|
-
associateBuildUrl(url, buildUrl);
|
|
8321
|
-
return buildUrl;
|
|
8368
|
+
if (category === "css") {
|
|
8369
|
+
countGroups.css++;
|
|
8370
|
+
sizeGroups.css += contentSize;
|
|
8371
|
+
continue;
|
|
8322
8372
|
}
|
|
8323
|
-
|
|
8324
|
-
|
|
8325
|
-
|
|
8326
|
-
|
|
8327
|
-
urlInfo,
|
|
8328
|
-
ownerUrlInfo,
|
|
8329
|
-
});
|
|
8330
|
-
let names = cache[directoryPath];
|
|
8331
|
-
if (!names) {
|
|
8332
|
-
names = [];
|
|
8333
|
-
cache[directoryPath] = names;
|
|
8373
|
+
if (category === "js") {
|
|
8374
|
+
countGroups.js++;
|
|
8375
|
+
sizeGroups.js += contentSize;
|
|
8376
|
+
continue;
|
|
8334
8377
|
}
|
|
8335
|
-
|
|
8336
|
-
|
|
8337
|
-
|
|
8338
|
-
|
|
8339
|
-
extension = extensionMappings[extension] || extension;
|
|
8340
|
-
let nameCandidate = `${basename}${extension}`; // reconstruct name in case extension was normalized
|
|
8341
|
-
let integer = 1;
|
|
8342
|
-
while (true) {
|
|
8343
|
-
if (!names.includes(nameCandidate)) {
|
|
8344
|
-
names.push(nameCandidate);
|
|
8345
|
-
break;
|
|
8346
|
-
}
|
|
8347
|
-
integer++;
|
|
8348
|
-
nameCandidate = `${basename}${integer}${extension}`;
|
|
8378
|
+
if (category === "json") {
|
|
8379
|
+
countGroups.json++;
|
|
8380
|
+
sizeGroups.json += contentSize;
|
|
8381
|
+
continue;
|
|
8349
8382
|
}
|
|
8350
|
-
|
|
8351
|
-
|
|
8352
|
-
|
|
8353
|
-
}
|
|
8383
|
+
countGroups.other++;
|
|
8384
|
+
sizeGroups.other += contentSize;
|
|
8385
|
+
continue;
|
|
8386
|
+
}
|
|
8354
8387
|
|
|
8355
|
-
|
|
8356
|
-
|
|
8357
|
-
|
|
8358
|
-
|
|
8388
|
+
const sizesToDistribute = {};
|
|
8389
|
+
for (const groupName of Object.keys(sizeGroups)) {
|
|
8390
|
+
if (groupName !== "sourcemaps" && groupName !== "total") {
|
|
8391
|
+
sizesToDistribute[groupName] = sizeGroups[groupName];
|
|
8392
|
+
}
|
|
8393
|
+
}
|
|
8394
|
+
const percentageGroups = distributePercentages(sizesToDistribute);
|
|
8359
8395
|
|
|
8360
|
-
|
|
8361
|
-
//
|
|
8362
|
-
//
|
|
8363
|
-
|
|
8364
|
-
|
|
8365
|
-
|
|
8366
|
-
|
|
8367
|
-
|
|
8368
|
-
".ts": ".js",
|
|
8369
|
-
".tsx": ".js",
|
|
8370
|
-
};
|
|
8396
|
+
return {
|
|
8397
|
+
// sourcemaps are special, there size are ignored
|
|
8398
|
+
// so there is no "percentage" associated
|
|
8399
|
+
sourcemaps: {
|
|
8400
|
+
count: countGroups.sourcemaps,
|
|
8401
|
+
size: sizeGroups.sourcemaps,
|
|
8402
|
+
percentage: undefined,
|
|
8403
|
+
},
|
|
8371
8404
|
|
|
8372
|
-
|
|
8373
|
-
|
|
8374
|
-
|
|
8375
|
-
|
|
8376
|
-
|
|
8377
|
-
|
|
8405
|
+
html: {
|
|
8406
|
+
count: countGroups.html,
|
|
8407
|
+
size: sizeGroups.html,
|
|
8408
|
+
percentage: percentageGroups.html,
|
|
8409
|
+
},
|
|
8410
|
+
css: {
|
|
8411
|
+
count: countGroups.css,
|
|
8412
|
+
size: sizeGroups.css,
|
|
8413
|
+
percentage: percentageGroups.css,
|
|
8414
|
+
},
|
|
8415
|
+
js: {
|
|
8416
|
+
count: countGroups.js,
|
|
8417
|
+
size: sizeGroups.js,
|
|
8418
|
+
percentage: percentageGroups.js,
|
|
8419
|
+
},
|
|
8420
|
+
json: {
|
|
8421
|
+
count: countGroups.json,
|
|
8422
|
+
size: sizeGroups.json,
|
|
8423
|
+
percentage: percentageGroups.json,
|
|
8424
|
+
},
|
|
8425
|
+
other: {
|
|
8426
|
+
count: countGroups.other,
|
|
8427
|
+
size: sizeGroups.other,
|
|
8428
|
+
percentage: percentageGroups.other,
|
|
8429
|
+
},
|
|
8430
|
+
total: {
|
|
8431
|
+
count: countGroups.total,
|
|
8432
|
+
size: sizeGroups.total,
|
|
8433
|
+
percentage: 100,
|
|
8434
|
+
},
|
|
8435
|
+
};
|
|
8378
8436
|
};
|
|
8379
8437
|
|
|
8380
|
-
const
|
|
8381
|
-
|
|
8382
|
-
|
|
8383
|
-
urlInfo,
|
|
8384
|
-
ownerUrlInfo,
|
|
8385
|
-
}) => {
|
|
8386
|
-
if (urlInfo.dirnameHint) {
|
|
8387
|
-
return urlInfo.dirnameHint;
|
|
8388
|
-
}
|
|
8389
|
-
if (urlInfo.type === "directory") {
|
|
8390
|
-
return "";
|
|
8391
|
-
}
|
|
8392
|
-
if (urlInfo.isInline) {
|
|
8393
|
-
const parentDirectoryPath = determineDirectoryPath({
|
|
8394
|
-
sourceDirectoryUrl,
|
|
8395
|
-
assetsDirectory,
|
|
8396
|
-
urlInfo: ownerUrlInfo || urlInfo.firstReference.ownerUrlInfo,
|
|
8397
|
-
});
|
|
8398
|
-
return parentDirectoryPath;
|
|
8399
|
-
}
|
|
8400
|
-
const dynamicImportId = urlInfo.searchParams.get("dynamic_import_id");
|
|
8401
|
-
if (dynamicImportId) {
|
|
8402
|
-
return `${assetsDirectory}${dynamicImportId}/`;
|
|
8403
|
-
}
|
|
8404
|
-
if (urlInfo.isEntryPoint && !urlInfo.isDynamicEntryPoint) {
|
|
8405
|
-
return "";
|
|
8406
|
-
}
|
|
8407
|
-
if (urlInfo.type === "importmap") {
|
|
8408
|
-
return "";
|
|
8438
|
+
const determineCategory = (buildRelativeUrl) => {
|
|
8439
|
+
if (buildRelativeUrl.endsWith(".map")) {
|
|
8440
|
+
return "sourcemap";
|
|
8409
8441
|
}
|
|
8410
|
-
if (
|
|
8411
|
-
return
|
|
8442
|
+
if (buildRelativeUrl.endsWith(".html")) {
|
|
8443
|
+
return "html";
|
|
8412
8444
|
}
|
|
8413
|
-
if (
|
|
8414
|
-
return
|
|
8445
|
+
if (buildRelativeUrl.endsWith(".css")) {
|
|
8446
|
+
return "css";
|
|
8415
8447
|
}
|
|
8416
|
-
if (
|
|
8417
|
-
|
|
8448
|
+
if (
|
|
8449
|
+
buildRelativeUrl.endsWith(".js") ||
|
|
8450
|
+
buildRelativeUrl.endsWith(".mjs") ||
|
|
8451
|
+
buildRelativeUrl.endsWith(".cjs")
|
|
8452
|
+
) {
|
|
8453
|
+
return "js";
|
|
8418
8454
|
}
|
|
8419
|
-
if (
|
|
8420
|
-
return
|
|
8455
|
+
if (buildRelativeUrl.endsWith(".json")) {
|
|
8456
|
+
return "json";
|
|
8421
8457
|
}
|
|
8422
|
-
return
|
|
8458
|
+
return "other";
|
|
8459
|
+
};
|
|
8460
|
+
|
|
8461
|
+
// default runtimeCompat corresponds to
|
|
8462
|
+
// "we can keep <script type="module"> intact":
|
|
8463
|
+
// so script_type_module + dynamic_import + import_meta
|
|
8464
|
+
const defaultRuntimeCompat = {
|
|
8465
|
+
// android: "8",
|
|
8466
|
+
chrome: "64",
|
|
8467
|
+
edge: "79",
|
|
8468
|
+
firefox: "67",
|
|
8469
|
+
ios: "12",
|
|
8470
|
+
opera: "51",
|
|
8471
|
+
safari: "11.3",
|
|
8472
|
+
samsung: "9.2",
|
|
8473
|
+
};
|
|
8474
|
+
const logsDefault = {
|
|
8475
|
+
level: "info",
|
|
8476
|
+
animated: true,
|
|
8423
8477
|
};
|
|
8424
8478
|
|
|
8425
8479
|
// https://bundlers.tooling.report/hashing/avoid-cascade/
|
|
@@ -8555,8 +8609,9 @@ const createBuildSpecifierManager = ({
|
|
|
8555
8609
|
logger,
|
|
8556
8610
|
sourceDirectoryUrl,
|
|
8557
8611
|
buildDirectoryUrl,
|
|
8558
|
-
base,
|
|
8559
8612
|
assetsDirectory,
|
|
8613
|
+
buildUrlsGenerator,
|
|
8614
|
+
base,
|
|
8560
8615
|
length = 8,
|
|
8561
8616
|
|
|
8562
8617
|
versioning,
|
|
@@ -8564,12 +8619,6 @@ const createBuildSpecifierManager = ({
|
|
|
8564
8619
|
versionLength,
|
|
8565
8620
|
canUseImportmap,
|
|
8566
8621
|
}) => {
|
|
8567
|
-
const buildUrlsGenerator = createBuildUrlsGenerator({
|
|
8568
|
-
logger,
|
|
8569
|
-
sourceDirectoryUrl,
|
|
8570
|
-
buildDirectoryUrl,
|
|
8571
|
-
assetsDirectory,
|
|
8572
|
-
});
|
|
8573
8622
|
const placeholderAPI = createPlaceholderAPI({
|
|
8574
8623
|
length,
|
|
8575
8624
|
});
|
|
@@ -8599,6 +8648,7 @@ const createBuildSpecifierManager = ({
|
|
|
8599
8648
|
buildUrl = buildUrlsGenerator.generate(url, {
|
|
8600
8649
|
urlInfo,
|
|
8601
8650
|
ownerUrlInfo: reference.ownerUrlInfo,
|
|
8651
|
+
assetsDirectory,
|
|
8602
8652
|
});
|
|
8603
8653
|
}
|
|
8604
8654
|
|
|
@@ -8673,6 +8723,12 @@ const createBuildSpecifierManager = ({
|
|
|
8673
8723
|
resolveReference: (reference) => {
|
|
8674
8724
|
const { ownerUrlInfo } = reference;
|
|
8675
8725
|
if (ownerUrlInfo.remapReference && !reference.isInline) {
|
|
8726
|
+
if (reference.specifier.startsWith("file:")) {
|
|
8727
|
+
const rawUrlInfo = rawKitchen.graph.getUrlInfo(reference.specifier);
|
|
8728
|
+
if (rawUrlInfo && rawUrlInfo.type === "entry_build") {
|
|
8729
|
+
return reference.specifier; // we want to ignore it
|
|
8730
|
+
}
|
|
8731
|
+
}
|
|
8676
8732
|
const newSpecifier = ownerUrlInfo.remapReference(reference);
|
|
8677
8733
|
reference.specifier = newSpecifier;
|
|
8678
8734
|
}
|
|
@@ -8705,6 +8761,14 @@ const createBuildSpecifierManager = ({
|
|
|
8705
8761
|
return url;
|
|
8706
8762
|
},
|
|
8707
8763
|
redirectReference: (reference) => {
|
|
8764
|
+
// don't think this is needed because we'll find the rawUrlInfo
|
|
8765
|
+
// which contains the filenameHint
|
|
8766
|
+
// const otherEntryBuildInfo = getOtherEntryBuildInfo(reference.url);
|
|
8767
|
+
// if (otherEntryBuildInfo) {
|
|
8768
|
+
// reference.filenameHint = otherEntryBuildInfo.entryUrlInfo.filenameHint;
|
|
8769
|
+
// return null;
|
|
8770
|
+
// }
|
|
8771
|
+
|
|
8708
8772
|
let referenceBeforeInlining = reference;
|
|
8709
8773
|
if (
|
|
8710
8774
|
referenceBeforeInlining.isInline &&
|
|
@@ -8790,7 +8854,6 @@ const createBuildSpecifierManager = ({
|
|
|
8790
8854
|
firstReference = firstReference.prev;
|
|
8791
8855
|
}
|
|
8792
8856
|
const rawUrl = firstReference.rawUrl || firstReference.url;
|
|
8793
|
-
const rawUrlInfo = rawKitchen.graph.getUrlInfo(rawUrl);
|
|
8794
8857
|
const bundleInfo = bundleInfoMap.get(rawUrl);
|
|
8795
8858
|
if (bundleInfo) {
|
|
8796
8859
|
finalUrlInfo.remapReference = bundleInfo.remapReference;
|
|
@@ -8807,7 +8870,21 @@ const createBuildSpecifierManager = ({
|
|
|
8807
8870
|
data: bundleInfo.data,
|
|
8808
8871
|
};
|
|
8809
8872
|
}
|
|
8873
|
+
const rawUrlInfo = rawKitchen.graph.getUrlInfo(rawUrl);
|
|
8810
8874
|
if (rawUrlInfo) {
|
|
8875
|
+
if (rawUrlInfo.type === "entry_build") {
|
|
8876
|
+
const otherEntryBuildInfo = rawUrlInfo.otherEntryBuildInfo;
|
|
8877
|
+
if (
|
|
8878
|
+
// we need to wait ONLY if we are versioning
|
|
8879
|
+
// and only IF the reference can't be remapped globally or by importmap
|
|
8880
|
+
// otherwise we can reference the file right away
|
|
8881
|
+
versioning &&
|
|
8882
|
+
getReferenceVersioningInfo(firstReference).type === "inline"
|
|
8883
|
+
) {
|
|
8884
|
+
await otherEntryBuildInfo.promise;
|
|
8885
|
+
}
|
|
8886
|
+
finalUrlInfo.otherEntryBuildInfo = otherEntryBuildInfo;
|
|
8887
|
+
}
|
|
8811
8888
|
return rawUrlInfo;
|
|
8812
8889
|
}
|
|
8813
8890
|
// reference injected during "shape":
|
|
@@ -9038,6 +9115,15 @@ const createBuildSpecifierManager = ({
|
|
|
9038
9115
|
if (urlInfo.url.startsWith("ignore:")) {
|
|
9039
9116
|
return;
|
|
9040
9117
|
}
|
|
9118
|
+
if (urlInfo.type === "entry_build") {
|
|
9119
|
+
const otherEntryBuildInfo = urlInfo.otherEntryBuildInfo;
|
|
9120
|
+
const entryUrlInfoVersion =
|
|
9121
|
+
otherEntryBuildInfo.buildFileVersions[
|
|
9122
|
+
otherEntryBuildInfo.buildRelativeUrl
|
|
9123
|
+
];
|
|
9124
|
+
contentOnlyVersionMap.set(urlInfo, entryUrlInfoVersion);
|
|
9125
|
+
return;
|
|
9126
|
+
}
|
|
9041
9127
|
let content = urlInfo.content;
|
|
9042
9128
|
if (urlInfo.type === "html") {
|
|
9043
9129
|
content = stringifyHtmlAst(
|
|
@@ -9077,6 +9163,9 @@ const createBuildSpecifierManager = ({
|
|
|
9077
9163
|
const getSetOfUrlInfoInfluencingVersion = (urlInfo) => {
|
|
9078
9164
|
const placeholderInfluencingVersionSet = new Set();
|
|
9079
9165
|
const visitContainedPlaceholders = (urlInfo) => {
|
|
9166
|
+
if (urlInfo.type === "entry_build") {
|
|
9167
|
+
return;
|
|
9168
|
+
}
|
|
9080
9169
|
const referencedContentVersion = contentOnlyVersionMap.get(urlInfo);
|
|
9081
9170
|
if (!referencedContentVersion) {
|
|
9082
9171
|
// ignored while traversing graph (not used anymore, inline, ...)
|
|
@@ -9121,20 +9210,24 @@ const createBuildSpecifierManager = ({
|
|
|
9121
9210
|
contentOnlyUrlInfo,
|
|
9122
9211
|
contentOnlyVersion,
|
|
9123
9212
|
] of contentOnlyVersionMap) {
|
|
9124
|
-
const setOfUrlInfoInfluencingVersion =
|
|
9125
|
-
getSetOfUrlInfoInfluencingVersion(contentOnlyUrlInfo);
|
|
9126
9213
|
const versionPartSet = new Set();
|
|
9127
|
-
|
|
9128
|
-
|
|
9129
|
-
|
|
9130
|
-
|
|
9131
|
-
|
|
9132
|
-
|
|
9133
|
-
|
|
9134
|
-
|
|
9214
|
+
if (contentOnlyUrlInfo.type === "entry_build") {
|
|
9215
|
+
versionPartSet.add(contentOnlyVersion);
|
|
9216
|
+
} else {
|
|
9217
|
+
const setOfUrlInfoInfluencingVersion =
|
|
9218
|
+
getSetOfUrlInfoInfluencingVersion(contentOnlyUrlInfo);
|
|
9219
|
+
versionPartSet.add(contentOnlyVersion);
|
|
9220
|
+
for (const urlInfoInfluencingVersion of setOfUrlInfoInfluencingVersion) {
|
|
9221
|
+
const otherUrlInfoContentVersion = contentOnlyVersionMap.get(
|
|
9222
|
+
urlInfoInfluencingVersion,
|
|
9135
9223
|
);
|
|
9224
|
+
if (!otherUrlInfoContentVersion) {
|
|
9225
|
+
throw new Error(
|
|
9226
|
+
`cannot find content version for ${urlInfoInfluencingVersion.url} (used by ${contentOnlyUrlInfo.url})`,
|
|
9227
|
+
);
|
|
9228
|
+
}
|
|
9229
|
+
versionPartSet.add(otherUrlInfoContentVersion);
|
|
9136
9230
|
}
|
|
9137
|
-
versionPartSet.add(otherUrlInfoContentVersion);
|
|
9138
9231
|
}
|
|
9139
9232
|
const version = generateVersion(versionPartSet, versionLength);
|
|
9140
9233
|
versionMap.set(contentOnlyUrlInfo, version);
|
|
@@ -9536,6 +9629,7 @@ const createBuildSpecifierManager = ({
|
|
|
9536
9629
|
const buildManifest = {};
|
|
9537
9630
|
const buildContents = {};
|
|
9538
9631
|
const buildInlineRelativeUrlSet = new Set();
|
|
9632
|
+
const buildFileVersions = {};
|
|
9539
9633
|
GRAPH_VISITOR.forEachUrlInfoStronglyReferenced(
|
|
9540
9634
|
finalKitchen.graph.rootUrlInfo,
|
|
9541
9635
|
(urlInfo) => {
|
|
@@ -9549,6 +9643,9 @@ const createBuildSpecifierManager = ({
|
|
|
9549
9643
|
) {
|
|
9550
9644
|
return;
|
|
9551
9645
|
}
|
|
9646
|
+
if (urlInfo.type === "entry_build") {
|
|
9647
|
+
return;
|
|
9648
|
+
}
|
|
9552
9649
|
const buildSpecifier = buildUrlToBuildSpecifierMap.get(buildUrl);
|
|
9553
9650
|
const buildSpecifierVersioned = versioning
|
|
9554
9651
|
? buildSpecifierToBuildSpecifierVersionedMap.get(buildSpecifier)
|
|
@@ -9557,6 +9654,8 @@ const createBuildSpecifierManager = ({
|
|
|
9557
9654
|
buildUrl,
|
|
9558
9655
|
buildDirectoryUrl,
|
|
9559
9656
|
);
|
|
9657
|
+
buildFileVersions[buildRelativeUrl] = versionMap.get(urlInfo);
|
|
9658
|
+
|
|
9560
9659
|
let contentKey;
|
|
9561
9660
|
// if to guard for html where versioned build specifier is not generated
|
|
9562
9661
|
if (buildSpecifierVersioned) {
|
|
@@ -9595,7 +9694,12 @@ const createBuildSpecifierManager = ({
|
|
|
9595
9694
|
}
|
|
9596
9695
|
});
|
|
9597
9696
|
|
|
9598
|
-
return {
|
|
9697
|
+
return {
|
|
9698
|
+
buildFileContents,
|
|
9699
|
+
buildInlineContents,
|
|
9700
|
+
buildManifest,
|
|
9701
|
+
buildFileVersions,
|
|
9702
|
+
};
|
|
9599
9703
|
},
|
|
9600
9704
|
};
|
|
9601
9705
|
};
|
|
@@ -9818,29 +9922,187 @@ const asBuildUrlVersioned = ({
|
|
|
9818
9922
|
return `${buildDirectoryUrl}${pathname}${search}${hash}`;
|
|
9819
9923
|
};
|
|
9820
9924
|
|
|
9821
|
-
|
|
9822
|
-
if (typeof stringOrBuffer === "string") {
|
|
9823
|
-
const stringWithLinuxBreaks = stringOrBuffer.replace(/\r\n/g, "\n");
|
|
9824
|
-
return stringWithLinuxBreaks;
|
|
9825
|
-
}
|
|
9826
|
-
return ensureUnixLineBreaksOnBuffer(stringOrBuffer);
|
|
9827
|
-
};
|
|
9925
|
+
// import { ANSI } from "@jsenv/humanize";
|
|
9828
9926
|
|
|
9829
|
-
|
|
9830
|
-
|
|
9831
|
-
|
|
9832
|
-
|
|
9833
|
-
|
|
9834
|
-
|
|
9835
|
-
|
|
9836
|
-
|
|
9837
|
-
|
|
9838
|
-
|
|
9839
|
-
|
|
9840
|
-
|
|
9841
|
-
|
|
9842
|
-
|
|
9843
|
-
|
|
9927
|
+
const createBuildUrlsGenerator = ({
|
|
9928
|
+
// logger,
|
|
9929
|
+
sourceDirectoryUrl,
|
|
9930
|
+
buildDirectoryUrl,
|
|
9931
|
+
}) => {
|
|
9932
|
+
const getUrlName = (url, urlInfo) => {
|
|
9933
|
+
if (!urlInfo) {
|
|
9934
|
+
return urlToFilename(url);
|
|
9935
|
+
}
|
|
9936
|
+
if (urlInfo.filenameHint) {
|
|
9937
|
+
return urlInfo.filenameHint;
|
|
9938
|
+
}
|
|
9939
|
+
return urlToFilename(url);
|
|
9940
|
+
};
|
|
9941
|
+
|
|
9942
|
+
const buildUrlMap = new Map();
|
|
9943
|
+
const associateBuildUrl = (url, buildUrl) => {
|
|
9944
|
+
buildUrlMap.set(url, buildUrl);
|
|
9945
|
+
// logger.debug(`associate a build url
|
|
9946
|
+
// ${ANSI.color(url, ANSI.GREY)} ->
|
|
9947
|
+
// ${ANSI.color(buildUrl, ANSI.MAGENTA)}
|
|
9948
|
+
// `);
|
|
9949
|
+
};
|
|
9950
|
+
|
|
9951
|
+
const nameSetPerDirectoryMap = new Map();
|
|
9952
|
+
const generate = (url, { urlInfo, ownerUrlInfo, assetsDirectory }) => {
|
|
9953
|
+
const buildUrlFromMap = buildUrlMap.get(url);
|
|
9954
|
+
if (buildUrlFromMap) {
|
|
9955
|
+
return buildUrlFromMap;
|
|
9956
|
+
}
|
|
9957
|
+
if (urlIsInsideOf(url, buildDirectoryUrl)) {
|
|
9958
|
+
associateBuildUrl(url, url);
|
|
9959
|
+
return url;
|
|
9960
|
+
}
|
|
9961
|
+
if (urlInfo.type === "entry_build") {
|
|
9962
|
+
const buildUrl = new URL(urlInfo.filenameHint, buildDirectoryUrl).href;
|
|
9963
|
+
associateBuildUrl(url, buildUrl);
|
|
9964
|
+
return buildUrl;
|
|
9965
|
+
}
|
|
9966
|
+
if (
|
|
9967
|
+
urlInfo.type === "directory" ||
|
|
9968
|
+
(urlInfo.type === undefined && urlInfo.typeHint === "directory")
|
|
9969
|
+
) {
|
|
9970
|
+
let directoryPath;
|
|
9971
|
+
if (url === sourceDirectoryUrl) {
|
|
9972
|
+
directoryPath = "";
|
|
9973
|
+
} else if (urlInfo.filenameHint) {
|
|
9974
|
+
directoryPath = urlInfo.filenameHint;
|
|
9975
|
+
} else {
|
|
9976
|
+
directoryPath = urlToRelativeUrl(url, sourceDirectoryUrl);
|
|
9977
|
+
}
|
|
9978
|
+
const { search } = new URL(url);
|
|
9979
|
+
const buildUrl = `${buildDirectoryUrl}${directoryPath}${search}`;
|
|
9980
|
+
associateBuildUrl(url, buildUrl);
|
|
9981
|
+
return buildUrl;
|
|
9982
|
+
}
|
|
9983
|
+
|
|
9984
|
+
const directoryPath = determineDirectoryPath({
|
|
9985
|
+
sourceDirectoryUrl,
|
|
9986
|
+
assetsDirectory,
|
|
9987
|
+
urlInfo,
|
|
9988
|
+
ownerUrlInfo,
|
|
9989
|
+
});
|
|
9990
|
+
let nameSet = nameSetPerDirectoryMap.get(directoryPath);
|
|
9991
|
+
if (!nameSet) {
|
|
9992
|
+
nameSet = new Set();
|
|
9993
|
+
nameSetPerDirectoryMap.set(directoryPath, nameSet);
|
|
9994
|
+
}
|
|
9995
|
+
const urlObject = new URL(url);
|
|
9996
|
+
let { search, hash } = urlObject;
|
|
9997
|
+
let urlName = getUrlName(url, urlInfo);
|
|
9998
|
+
let [basename, extension] = splitFileExtension(urlName);
|
|
9999
|
+
extension = extensionMappings[extension] || extension;
|
|
10000
|
+
let nameCandidate = `${basename}${extension}`; // reconstruct name in case extension was normalized
|
|
10001
|
+
let integer = 1;
|
|
10002
|
+
while (nameSet.has(nameCandidate)) {
|
|
10003
|
+
integer++;
|
|
10004
|
+
nameCandidate = `${basename}${integer}${extension}`;
|
|
10005
|
+
}
|
|
10006
|
+
const name = nameCandidate;
|
|
10007
|
+
nameSet.add(name);
|
|
10008
|
+
const buildUrl = `${buildDirectoryUrl}${directoryPath}${name}${search}${hash}`;
|
|
10009
|
+
associateBuildUrl(url, buildUrl);
|
|
10010
|
+
return buildUrl;
|
|
10011
|
+
};
|
|
10012
|
+
|
|
10013
|
+
return {
|
|
10014
|
+
generate,
|
|
10015
|
+
};
|
|
10016
|
+
};
|
|
10017
|
+
|
|
10018
|
+
// It's best to generate files with an extension representing what is inside the file
|
|
10019
|
+
// and after build js files contains solely js (js or typescript is gone).
|
|
10020
|
+
// This way a static file server is already configured to server the correct content-type
|
|
10021
|
+
// (otherwise one would have to configure that ".jsx" is "text/javascript")
|
|
10022
|
+
// To keep in mind: if you have "user.jsx" and "user.js" AND both file are not bundled
|
|
10023
|
+
// you end up with "dist/js/user.js" and "dist/js/user2.js"
|
|
10024
|
+
const extensionMappings = {
|
|
10025
|
+
".jsx": ".js",
|
|
10026
|
+
".ts": ".js",
|
|
10027
|
+
".tsx": ".js",
|
|
10028
|
+
};
|
|
10029
|
+
|
|
10030
|
+
const splitFileExtension = (filename) => {
|
|
10031
|
+
const dotLastIndex = filename.lastIndexOf(".");
|
|
10032
|
+
if (dotLastIndex === -1) {
|
|
10033
|
+
return [filename, ""];
|
|
10034
|
+
}
|
|
10035
|
+
return [filename.slice(0, dotLastIndex), filename.slice(dotLastIndex)];
|
|
10036
|
+
};
|
|
10037
|
+
|
|
10038
|
+
const determineDirectoryPath = ({
|
|
10039
|
+
sourceDirectoryUrl,
|
|
10040
|
+
assetsDirectory,
|
|
10041
|
+
urlInfo,
|
|
10042
|
+
ownerUrlInfo,
|
|
10043
|
+
}) => {
|
|
10044
|
+
if (urlInfo.dirnameHint) {
|
|
10045
|
+
return urlInfo.dirnameHint;
|
|
10046
|
+
}
|
|
10047
|
+
if (urlInfo.type === "directory") {
|
|
10048
|
+
return "";
|
|
10049
|
+
}
|
|
10050
|
+
if (urlInfo.isInline) {
|
|
10051
|
+
const parentDirectoryPath = determineDirectoryPath({
|
|
10052
|
+
sourceDirectoryUrl,
|
|
10053
|
+
assetsDirectory,
|
|
10054
|
+
urlInfo: ownerUrlInfo || urlInfo.firstReference.ownerUrlInfo,
|
|
10055
|
+
});
|
|
10056
|
+
return parentDirectoryPath;
|
|
10057
|
+
}
|
|
10058
|
+
const dynamicImportId = urlInfo.searchParams.get("dynamic_import_id");
|
|
10059
|
+
if (dynamicImportId) {
|
|
10060
|
+
return `${assetsDirectory}${dynamicImportId}/`;
|
|
10061
|
+
}
|
|
10062
|
+
if (urlInfo.isEntryPoint && !urlInfo.isDynamicEntryPoint) {
|
|
10063
|
+
return "";
|
|
10064
|
+
}
|
|
10065
|
+
if (urlInfo.type === "importmap") {
|
|
10066
|
+
return "";
|
|
10067
|
+
}
|
|
10068
|
+
if (urlInfo.type === "html") {
|
|
10069
|
+
return `${assetsDirectory}html/`;
|
|
10070
|
+
}
|
|
10071
|
+
if (urlInfo.type === "css") {
|
|
10072
|
+
return `${assetsDirectory}css/`;
|
|
10073
|
+
}
|
|
10074
|
+
if (urlInfo.type === "js_module" || urlInfo.type === "js_classic") {
|
|
10075
|
+
return `${assetsDirectory}js/`;
|
|
10076
|
+
}
|
|
10077
|
+
if (urlInfo.type === "json") {
|
|
10078
|
+
return `${assetsDirectory}json/`;
|
|
10079
|
+
}
|
|
10080
|
+
return `${assetsDirectory}other/`;
|
|
10081
|
+
};
|
|
10082
|
+
|
|
10083
|
+
const ensureUnixLineBreaks = (stringOrBuffer) => {
|
|
10084
|
+
if (typeof stringOrBuffer === "string") {
|
|
10085
|
+
const stringWithLinuxBreaks = stringOrBuffer.replace(/\r\n/g, "\n");
|
|
10086
|
+
return stringWithLinuxBreaks;
|
|
10087
|
+
}
|
|
10088
|
+
return ensureUnixLineBreaksOnBuffer(stringOrBuffer);
|
|
10089
|
+
};
|
|
10090
|
+
|
|
10091
|
+
// https://github.com/nodejs/help/issues/1738#issuecomment-458460503
|
|
10092
|
+
const ensureUnixLineBreaksOnBuffer = (buffer) => {
|
|
10093
|
+
const int32Array = new Int32Array(buffer, 0, buffer.length);
|
|
10094
|
+
const int32ArrayWithLineBreaksNormalized = int32Array.filter(
|
|
10095
|
+
(element, index, typedArray) => {
|
|
10096
|
+
if (element === 0x0d) {
|
|
10097
|
+
if (typedArray[index + 1] === 0x0a) {
|
|
10098
|
+
// Windows -> Unix
|
|
10099
|
+
return false;
|
|
10100
|
+
}
|
|
10101
|
+
// Mac OS -> Unix
|
|
10102
|
+
typedArray[index] = 0x0a;
|
|
10103
|
+
}
|
|
10104
|
+
return true;
|
|
10105
|
+
},
|
|
9844
10106
|
);
|
|
9845
10107
|
return Buffer.from(int32ArrayWithLineBreaksNormalized);
|
|
9846
10108
|
};
|
|
@@ -9926,80 +10188,6 @@ const jsenvPluginMappings = (mappings) => {
|
|
|
9926
10188
|
// url: import.meta.resolve("emoji-regex/index.js"),
|
|
9927
10189
|
// });
|
|
9928
10190
|
|
|
9929
|
-
const jsenvPluginSubbuilds = (
|
|
9930
|
-
subBuildParamsArray,
|
|
9931
|
-
{ parentBuildParams, onCustomBuildDirectory, buildStart },
|
|
9932
|
-
) => {
|
|
9933
|
-
if (subBuildParamsArray.length === 0) {
|
|
9934
|
-
return [];
|
|
9935
|
-
}
|
|
9936
|
-
return subBuildParamsArray.map((subBuildParams, index) => {
|
|
9937
|
-
const defaultChildBuildParams = {};
|
|
9938
|
-
const childBuildParams = {
|
|
9939
|
-
...parentBuildParams,
|
|
9940
|
-
logs: {
|
|
9941
|
-
level: "warn",
|
|
9942
|
-
disabled: true,
|
|
9943
|
-
},
|
|
9944
|
-
...defaultChildBuildParams,
|
|
9945
|
-
...subBuildParams,
|
|
9946
|
-
outDirectoryUrl: new URL(
|
|
9947
|
-
`./subbuild_${index}/`,
|
|
9948
|
-
parentBuildParams.outDirectoryUrl,
|
|
9949
|
-
),
|
|
9950
|
-
};
|
|
9951
|
-
const subBuildDirectoryUrl = subBuildParams.buildDirectoryUrl;
|
|
9952
|
-
if (subBuildDirectoryUrl) {
|
|
9953
|
-
const subBuildRelativeUrl = urlToRelativeUrl(
|
|
9954
|
-
subBuildDirectoryUrl,
|
|
9955
|
-
parentBuildParams.buildDirectoryUrl,
|
|
9956
|
-
);
|
|
9957
|
-
childBuildParams.base =
|
|
9958
|
-
parentBuildParams.base === "./"
|
|
9959
|
-
? `./`
|
|
9960
|
-
: subBuildParams.base ||
|
|
9961
|
-
getDefaultBase(
|
|
9962
|
-
childBuildParams.runtimeCompat || defaultRuntimeCompat,
|
|
9963
|
-
);
|
|
9964
|
-
onCustomBuildDirectory(subBuildRelativeUrl);
|
|
9965
|
-
}
|
|
9966
|
-
const buildPromise = buildStart(childBuildParams, index);
|
|
9967
|
-
const entryPointBuildUrlMap = new Map();
|
|
9968
|
-
const entryPointSourceUrlSet = new Set();
|
|
9969
|
-
const entryPointBuildUrlSet = new Set();
|
|
9970
|
-
const childBuildEntryPoints = childBuildParams.entryPoints;
|
|
9971
|
-
for (const key of Object.keys(childBuildEntryPoints)) {
|
|
9972
|
-
const entryPointUrl = new URL(key, childBuildParams.sourceDirectoryUrl)
|
|
9973
|
-
.href;
|
|
9974
|
-
const entryPointBuildUrl = new URL(
|
|
9975
|
-
childBuildEntryPoints[key],
|
|
9976
|
-
childBuildParams.buildDirectoryUrl,
|
|
9977
|
-
).href;
|
|
9978
|
-
entryPointBuildUrlMap.set(entryPointUrl, entryPointBuildUrl);
|
|
9979
|
-
entryPointSourceUrlSet.add(entryPointUrl);
|
|
9980
|
-
entryPointBuildUrlSet.add(entryPointBuildUrl);
|
|
9981
|
-
}
|
|
9982
|
-
|
|
9983
|
-
return {
|
|
9984
|
-
name: `jsenv:subbuild_${index}`,
|
|
9985
|
-
redirectReference: (reference) => {
|
|
9986
|
-
const entryPointBuildUrl = entryPointBuildUrlMap.get(reference.url);
|
|
9987
|
-
if (!entryPointBuildUrl) {
|
|
9988
|
-
return null;
|
|
9989
|
-
}
|
|
9990
|
-
return entryPointBuildUrl;
|
|
9991
|
-
},
|
|
9992
|
-
fetchUrlContent: async (urlInfo) => {
|
|
9993
|
-
if (!entryPointBuildUrlSet.has(urlInfo.url)) {
|
|
9994
|
-
return;
|
|
9995
|
-
}
|
|
9996
|
-
await buildPromise;
|
|
9997
|
-
urlInfo.typeHint = "asset"; // this ensure the rest of jsenv do not scan or modify the content of this file
|
|
9998
|
-
},
|
|
9999
|
-
};
|
|
10000
|
-
});
|
|
10001
|
-
};
|
|
10002
|
-
|
|
10003
10191
|
/*
|
|
10004
10192
|
* Build is split in 3 steps:
|
|
10005
10193
|
* 1. craft
|
|
@@ -10032,8 +10220,8 @@ const jsenvPluginSubbuilds = (
|
|
|
10032
10220
|
* Keys are relative to sourceDirectoryUrl
|
|
10033
10221
|
* @param {object} params.runtimeCompat
|
|
10034
10222
|
* Code generated will be compatible with these runtimes
|
|
10035
|
-
* @param {string} [params.assetsDirectory
|
|
10036
|
-
* Directory where asset files will be written
|
|
10223
|
+
* @param {string} [params.assetsDirectory]
|
|
10224
|
+
* Directory where asset files will be written. By default sibling to the entry build file.
|
|
10037
10225
|
* @param {string|url} [params.base=""]
|
|
10038
10226
|
* Urls in build file contents will be prefixed with this string
|
|
10039
10227
|
* @param {boolean|object} [params.bundling=true]
|
|
@@ -10055,54 +10243,29 @@ const jsenvPluginSubbuilds = (
|
|
|
10055
10243
|
* Map build file paths without versioning to versioned file paths
|
|
10056
10244
|
*/
|
|
10057
10245
|
const build = async ({
|
|
10058
|
-
signal = new AbortController().signal,
|
|
10059
|
-
handleSIGINT = true,
|
|
10060
|
-
logs = logsDefault,
|
|
10061
10246
|
sourceDirectoryUrl,
|
|
10062
10247
|
buildDirectoryUrl,
|
|
10063
10248
|
entryPoints = {},
|
|
10064
|
-
|
|
10065
|
-
runtimeCompat = defaultRuntimeCompat,
|
|
10066
|
-
base = getDefaultBase(runtimeCompat),
|
|
10067
|
-
ignore,
|
|
10249
|
+
logs,
|
|
10068
10250
|
|
|
10069
|
-
|
|
10070
|
-
|
|
10071
|
-
|
|
10072
|
-
|
|
10073
|
-
|
|
10074
|
-
|
|
10075
|
-
|
|
10076
|
-
|
|
10077
|
-
|
|
10078
|
-
injections,
|
|
10079
|
-
transpilation = {},
|
|
10080
|
-
bundling = true,
|
|
10081
|
-
minification = !runtimeCompat.node,
|
|
10082
|
-
versioning = !runtimeCompat.node,
|
|
10083
|
-
versioningMethod = "search_param", // "filename", "search_param"
|
|
10084
|
-
versioningViaImportmap = true,
|
|
10085
|
-
versionLength = 8,
|
|
10086
|
-
lineBreakNormalization = process.platform === "win32",
|
|
10251
|
+
outDirectoryUrl,
|
|
10252
|
+
buildDirectoryCleanPatterns = { "**/*": true },
|
|
10253
|
+
returnBuildInlineContents,
|
|
10254
|
+
returnBuildManifest,
|
|
10255
|
+
returnBuildFileVersions,
|
|
10256
|
+
signal = new AbortController().signal,
|
|
10257
|
+
handleSIGINT = true,
|
|
10258
|
+
|
|
10259
|
+
writeOnFileSystem = true,
|
|
10087
10260
|
|
|
10261
|
+
watch = false,
|
|
10088
10262
|
sourceFilesConfig = {},
|
|
10089
10263
|
cooldownBetweenFileEvents,
|
|
10090
|
-
watch = false,
|
|
10091
|
-
http = false,
|
|
10092
10264
|
|
|
10093
|
-
buildDirectoryCleanPatterns = {
|
|
10094
|
-
"**/*": true,
|
|
10095
|
-
},
|
|
10096
|
-
sourcemaps = "none",
|
|
10097
|
-
sourcemapsSourcesContent,
|
|
10098
|
-
writeOnFileSystem = true,
|
|
10099
|
-
outDirectoryUrl,
|
|
10100
|
-
assetManifest = versioningMethod === "filename",
|
|
10101
|
-
assetManifestFileRelativeUrl = "asset-manifest.json",
|
|
10102
|
-
returnBuildInlineContents,
|
|
10103
|
-
returnBuildManifest,
|
|
10104
10265
|
...rest
|
|
10105
10266
|
}) => {
|
|
10267
|
+
const entryPointArray = [];
|
|
10268
|
+
|
|
10106
10269
|
// param validation
|
|
10107
10270
|
{
|
|
10108
10271
|
const unexpectedParamNames = Object.keys(rest);
|
|
@@ -10111,555 +10274,511 @@ const build = async ({
|
|
|
10111
10274
|
`${unexpectedParamNames.join(",")}: there is no such param`,
|
|
10112
10275
|
);
|
|
10113
10276
|
}
|
|
10114
|
-
//
|
|
10277
|
+
// source and build directory
|
|
10115
10278
|
{
|
|
10116
|
-
|
|
10117
|
-
|
|
10118
|
-
|
|
10119
|
-
const unexpectedLogsKeys = Object.keys(logs).filter(
|
|
10120
|
-
(key) => !Object.hasOwn(logsDefault, key),
|
|
10279
|
+
sourceDirectoryUrl = assertAndNormalizeDirectoryUrl(
|
|
10280
|
+
sourceDirectoryUrl,
|
|
10281
|
+
"sourceDirectoryUrl",
|
|
10121
10282
|
);
|
|
10122
|
-
|
|
10123
|
-
|
|
10124
|
-
|
|
10125
|
-
);
|
|
10126
|
-
}
|
|
10127
|
-
logs = { ...logsDefault, ...logs };
|
|
10128
|
-
}
|
|
10129
|
-
sourceDirectoryUrl = assertAndNormalizeDirectoryUrl(
|
|
10130
|
-
sourceDirectoryUrl,
|
|
10131
|
-
"sourceDirectoryUrl",
|
|
10132
|
-
);
|
|
10133
|
-
buildDirectoryUrl = assertAndNormalizeDirectoryUrl(
|
|
10134
|
-
buildDirectoryUrl,
|
|
10135
|
-
"buildDirectoryUrl",
|
|
10136
|
-
);
|
|
10137
|
-
if (outDirectoryUrl === undefined) {
|
|
10138
|
-
if (
|
|
10139
|
-
process.env.CAPTURING_SIDE_EFFECTS ||
|
|
10140
|
-
(false)
|
|
10141
|
-
) {
|
|
10142
|
-
outDirectoryUrl = new URL("../.jsenv_b/", sourceDirectoryUrl);
|
|
10143
|
-
} else {
|
|
10144
|
-
const packageDirectoryUrl = lookupPackageDirectory(sourceDirectoryUrl);
|
|
10145
|
-
if (packageDirectoryUrl) {
|
|
10146
|
-
outDirectoryUrl = `${packageDirectoryUrl}.jsenv/`;
|
|
10147
|
-
}
|
|
10148
|
-
}
|
|
10149
|
-
} else if (outDirectoryUrl) {
|
|
10150
|
-
outDirectoryUrl = assertAndNormalizeDirectoryUrl(
|
|
10151
|
-
outDirectoryUrl,
|
|
10152
|
-
"outDirectoryUrl",
|
|
10283
|
+
buildDirectoryUrl = assertAndNormalizeDirectoryUrl(
|
|
10284
|
+
buildDirectoryUrl,
|
|
10285
|
+
"buildDirectoryUrl",
|
|
10153
10286
|
);
|
|
10154
10287
|
}
|
|
10155
|
-
|
|
10156
|
-
|
|
10157
|
-
|
|
10158
|
-
}
|
|
10159
|
-
const keys = Object.keys(entryPoints);
|
|
10160
|
-
keys.forEach((key) => {
|
|
10161
|
-
if (!key.startsWith("./")) {
|
|
10162
|
-
throw new TypeError(
|
|
10163
|
-
`entryPoints keys must start with "./", found ${key}`,
|
|
10164
|
-
);
|
|
10165
|
-
}
|
|
10166
|
-
const value = entryPoints[key];
|
|
10167
|
-
if (typeof value !== "string") {
|
|
10168
|
-
throw new TypeError(
|
|
10169
|
-
`entryPoints values must be strings, found "${value}" on key "${key}"`,
|
|
10170
|
-
);
|
|
10171
|
-
}
|
|
10172
|
-
if (value.includes("/")) {
|
|
10288
|
+
// entry points
|
|
10289
|
+
{
|
|
10290
|
+
if (typeof entryPoints !== "object" || entryPoints === null) {
|
|
10173
10291
|
throw new TypeError(
|
|
10174
|
-
`
|
|
10292
|
+
`The value "${entryPoints}" for "entryPoints" is invalid: it must be an object.`,
|
|
10175
10293
|
);
|
|
10176
10294
|
}
|
|
10177
|
-
|
|
10178
|
-
|
|
10179
|
-
|
|
10180
|
-
|
|
10181
|
-
|
|
10182
|
-
|
|
10183
|
-
if (bundling === true) {
|
|
10184
|
-
bundling = {};
|
|
10185
|
-
}
|
|
10186
|
-
if (minification === true) {
|
|
10187
|
-
minification = {};
|
|
10188
|
-
}
|
|
10189
|
-
}
|
|
10190
|
-
|
|
10191
|
-
if (assetsDirectory && assetsDirectory[assetsDirectory.length - 1] !== "/") {
|
|
10192
|
-
assetsDirectory = `${assetsDirectory}/`;
|
|
10193
|
-
}
|
|
10194
|
-
|
|
10195
|
-
const operation = Abort.startOperation();
|
|
10196
|
-
operation.addAbortSignal(signal);
|
|
10197
|
-
if (handleSIGINT) {
|
|
10198
|
-
operation.addAbortSource((abort) => {
|
|
10199
|
-
return raceProcessTeardownEvents(
|
|
10295
|
+
const keys = Object.keys(entryPoints);
|
|
10296
|
+
const isSingleEntryPoint = keys.length === 1;
|
|
10297
|
+
for (const key of keys) {
|
|
10298
|
+
// key (sourceRelativeUrl)
|
|
10299
|
+
let sourceUrl;
|
|
10300
|
+
let runtimeType;
|
|
10200
10301
|
{
|
|
10201
|
-
|
|
10202
|
-
|
|
10203
|
-
|
|
10204
|
-
|
|
10205
|
-
|
|
10302
|
+
if (isBareSpecifier(key)) {
|
|
10303
|
+
const packageConditions = ["development", "node", "import"];
|
|
10304
|
+
try {
|
|
10305
|
+
const { url, type } = applyNodeEsmResolution({
|
|
10306
|
+
conditions: packageConditions,
|
|
10307
|
+
parentUrl: sourceDirectoryUrl,
|
|
10308
|
+
specifier: key,
|
|
10309
|
+
});
|
|
10310
|
+
if (type === "field:browser") {
|
|
10311
|
+
runtimeType = "browser";
|
|
10312
|
+
}
|
|
10313
|
+
sourceUrl = url;
|
|
10314
|
+
} catch (e) {
|
|
10315
|
+
throw new Error(
|
|
10316
|
+
`The key "${key}" in "entryPoints" is invalid: it cannot be resolved.`,
|
|
10317
|
+
{ cause: e },
|
|
10318
|
+
);
|
|
10319
|
+
}
|
|
10320
|
+
} else {
|
|
10321
|
+
if (!key.startsWith("./")) {
|
|
10322
|
+
throw new TypeError(
|
|
10323
|
+
`The key "${key}" in "entryPoints" is invalid: it must start with "./".`,
|
|
10324
|
+
);
|
|
10325
|
+
}
|
|
10206
10326
|
|
|
10207
|
-
|
|
10208
|
-
|
|
10209
|
-
|
|
10210
|
-
|
|
10211
|
-
|
|
10212
|
-
|
|
10213
|
-
|
|
10214
|
-
|
|
10215
|
-
|
|
10327
|
+
try {
|
|
10328
|
+
sourceUrl = new URL(key, sourceDirectoryUrl).href;
|
|
10329
|
+
} catch {
|
|
10330
|
+
throw new TypeError(
|
|
10331
|
+
`The key "${key}" in "entryPoints" is invalid: it must be a relative url.`,
|
|
10332
|
+
);
|
|
10333
|
+
}
|
|
10334
|
+
}
|
|
10335
|
+
if (!urlIsInsideOf(sourceUrl, sourceDirectoryUrl)) {
|
|
10336
|
+
throw new Error(
|
|
10337
|
+
`The key "${key}" in "entryPoints" is invalid: it must be inside the source directory at ${sourceDirectoryUrl}.`,
|
|
10338
|
+
);
|
|
10339
|
+
}
|
|
10216
10340
|
|
|
10217
|
-
|
|
10218
|
-
|
|
10219
|
-
|
|
10220
|
-
|
|
10221
|
-
|
|
10222
|
-
|
|
10223
|
-
|
|
10224
|
-
|
|
10225
|
-
|
|
10341
|
+
if (!runtimeType) {
|
|
10342
|
+
const ext = urlToExtension(sourceUrl);
|
|
10343
|
+
if (ext === ".html" || ext === ".css") {
|
|
10344
|
+
runtimeType = "browser";
|
|
10345
|
+
}
|
|
10346
|
+
}
|
|
10347
|
+
}
|
|
10348
|
+
|
|
10349
|
+
// value (entryPointParams)
|
|
10350
|
+
const value = entryPoints[key];
|
|
10351
|
+
{
|
|
10352
|
+
if (value === null || typeof value !== "object") {
|
|
10353
|
+
throw new TypeError(
|
|
10354
|
+
`The value "${value}" in "entryPoints" is invalid: it must be an object.`,
|
|
10355
|
+
);
|
|
10356
|
+
}
|
|
10357
|
+
const forEntryPointOrEmpty = isSingleEntryPoint
|
|
10358
|
+
? ""
|
|
10359
|
+
: ` for entry point "${key}"`;
|
|
10360
|
+
const unexpectedEntryPointParamNames = Object.keys(value).filter(
|
|
10361
|
+
(key) => !Object.hasOwn(entryPointDefaultParams, key),
|
|
10362
|
+
);
|
|
10363
|
+
if (unexpectedEntryPointParamNames.length) {
|
|
10364
|
+
throw new TypeError(
|
|
10365
|
+
`The value${forEntryPointOrEmpty} contains unknown keys: ${unexpectedEntryPointParamNames.join(",")}.`,
|
|
10366
|
+
);
|
|
10367
|
+
}
|
|
10368
|
+
const { versioningMethod } = value;
|
|
10369
|
+
if (versioningMethod !== undefined) {
|
|
10370
|
+
if (!["filename", "search_param"].includes(versioningMethod)) {
|
|
10371
|
+
throw new TypeError(
|
|
10372
|
+
`The versioningMethod "${versioningMethod}"${forEntryPointOrEmpty} is invalid: it must be "filename" or "search_param".`,
|
|
10373
|
+
);
|
|
10374
|
+
}
|
|
10375
|
+
}
|
|
10376
|
+
const { buildRelativeUrl } = value;
|
|
10377
|
+
if (buildRelativeUrl !== undefined) {
|
|
10378
|
+
let buildUrl;
|
|
10379
|
+
try {
|
|
10380
|
+
buildUrl = new URL(buildRelativeUrl, buildDirectoryUrl);
|
|
10381
|
+
} catch {
|
|
10382
|
+
throw new TypeError(
|
|
10383
|
+
`The buildRelativeUrl "${buildRelativeUrl}"${forEntryPointOrEmpty} is invalid: it must be a relative url.`,
|
|
10384
|
+
);
|
|
10385
|
+
}
|
|
10386
|
+
if (!urlIsInsideOf(buildUrl, buildDirectoryUrl)) {
|
|
10387
|
+
throw new Error(
|
|
10388
|
+
`The buildRelativeUrl "${buildRelativeUrl}"${forEntryPointOrEmpty} is invalid: it must be inside the build directory at ${buildDirectoryUrl}.`,
|
|
10389
|
+
);
|
|
10390
|
+
}
|
|
10391
|
+
}
|
|
10392
|
+
const { runtimeCompat } = value;
|
|
10393
|
+
if (runtimeCompat !== undefined) {
|
|
10394
|
+
if (runtimeCompat === null || typeof runtimeCompat !== "object") {
|
|
10395
|
+
throw new TypeError(
|
|
10396
|
+
`The runtimeCompat "${runtimeCompat}"${forEntryPointOrEmpty} is invalid: it must be an object.`,
|
|
10397
|
+
);
|
|
10398
|
+
}
|
|
10399
|
+
}
|
|
10400
|
+
}
|
|
10401
|
+
|
|
10402
|
+
entryPointArray.push({
|
|
10403
|
+
key,
|
|
10404
|
+
sourceUrl,
|
|
10405
|
+
sourceRelativeUrl: `./${urlToRelativeUrl(sourceUrl, sourceDirectoryUrl)}`,
|
|
10406
|
+
params: { ...value },
|
|
10407
|
+
runtimeType,
|
|
10408
|
+
});
|
|
10409
|
+
}
|
|
10226
10410
|
}
|
|
10227
|
-
|
|
10228
|
-
|
|
10229
|
-
|
|
10230
|
-
|
|
10231
|
-
|
|
10411
|
+
// logs
|
|
10412
|
+
if (logs === undefined) {
|
|
10413
|
+
logs = logsDefault;
|
|
10414
|
+
} else {
|
|
10415
|
+
if (typeof logs !== "object") {
|
|
10416
|
+
throw new TypeError(
|
|
10417
|
+
`The value "${logs}" is invalid for param logs: it must be an object.`,
|
|
10418
|
+
);
|
|
10232
10419
|
}
|
|
10233
|
-
|
|
10234
|
-
|
|
10235
|
-
|
|
10420
|
+
const unexpectedLogsKeys = Object.keys(logs).filter(
|
|
10421
|
+
(key) => !Object.hasOwn(logsDefault, key),
|
|
10422
|
+
);
|
|
10423
|
+
if (unexpectedLogsKeys.length > 0) {
|
|
10424
|
+
throw new TypeError(
|
|
10425
|
+
`The param logs have unknown params: ${unexpectedLogsKeys.join(",")}.`,
|
|
10426
|
+
);
|
|
10236
10427
|
}
|
|
10237
10428
|
}
|
|
10238
|
-
|
|
10239
|
-
|
|
10240
|
-
|
|
10241
|
-
|
|
10242
|
-
|
|
10243
|
-
|
|
10244
|
-
|
|
10245
|
-
|
|
10246
|
-
|
|
10247
|
-
|
|
10248
|
-
|
|
10249
|
-
|
|
10250
|
-
|
|
10251
|
-
|
|
10252
|
-
|
|
10253
|
-
|
|
10254
|
-
|
|
10255
|
-
runtimeCompat,
|
|
10256
|
-
initialContext: contextSharedDuringBuild,
|
|
10257
|
-
sourcemaps,
|
|
10258
|
-
sourcemapsSourcesContent,
|
|
10259
|
-
outDirectoryUrl: outDirectoryUrl
|
|
10260
|
-
? new URL("craft/", outDirectoryUrl)
|
|
10261
|
-
: undefined,
|
|
10429
|
+
if (outDirectoryUrl !== undefined) {
|
|
10430
|
+
outDirectoryUrl = assertAndNormalizeDirectoryUrl(
|
|
10431
|
+
outDirectoryUrl,
|
|
10432
|
+
"outDirectoryUrl",
|
|
10433
|
+
);
|
|
10434
|
+
}
|
|
10435
|
+
}
|
|
10436
|
+
|
|
10437
|
+
const operation = Abort.startOperation();
|
|
10438
|
+
operation.addAbortSignal(signal);
|
|
10439
|
+
if (handleSIGINT) {
|
|
10440
|
+
operation.addAbortSource((abort) => {
|
|
10441
|
+
return raceProcessTeardownEvents(
|
|
10442
|
+
{
|
|
10443
|
+
},
|
|
10444
|
+
abort,
|
|
10445
|
+
);
|
|
10262
10446
|
});
|
|
10447
|
+
}
|
|
10263
10448
|
|
|
10264
|
-
|
|
10449
|
+
const cpuMonitoring = startMonitoringCpuUsage();
|
|
10450
|
+
operation.addEndCallback(cpuMonitoring.stop);
|
|
10451
|
+
const [processCpuUsageMonitoring] = cpuMonitoring;
|
|
10452
|
+
const memoryMonitoring = startMonitoringMemoryUsage();
|
|
10453
|
+
const [processMemoryUsageMonitoring] = memoryMonitoring;
|
|
10454
|
+
const interval = setInterval(() => {
|
|
10455
|
+
processCpuUsageMonitoring.measure();
|
|
10456
|
+
processMemoryUsageMonitoring.measure();
|
|
10457
|
+
}, 500).unref();
|
|
10458
|
+
operation.addEndCallback(() => {
|
|
10459
|
+
clearInterval(interval);
|
|
10460
|
+
});
|
|
10265
10461
|
|
|
10266
|
-
|
|
10267
|
-
|
|
10268
|
-
|
|
10269
|
-
|
|
10270
|
-
|
|
10271
|
-
|
|
10272
|
-
|
|
10273
|
-
|
|
10274
|
-
|
|
10275
|
-
|
|
10276
|
-
|
|
10277
|
-
|
|
10278
|
-
|
|
10279
|
-
|
|
10280
|
-
|
|
10281
|
-
|
|
10282
|
-
|
|
10283
|
-
|
|
10284
|
-
|
|
10285
|
-
|
|
10286
|
-
|
|
10287
|
-
|
|
10288
|
-
|
|
10289
|
-
|
|
10290
|
-
|
|
10291
|
-
|
|
10292
|
-
|
|
10293
|
-
|
|
10294
|
-
|
|
10295
|
-
|
|
10296
|
-
|
|
10297
|
-
|
|
10298
|
-
|
|
10299
|
-
|
|
10300
|
-
|
|
10301
|
-
|
|
10302
|
-
|
|
10303
|
-
|
|
10304
|
-
|
|
10305
|
-
|
|
10306
|
-
|
|
10307
|
-
|
|
10308
|
-
|
|
10309
|
-
babelHelpersAsImport: !explicitJsModuleConversion,
|
|
10310
|
-
...transpilation,
|
|
10311
|
-
jsModuleFallback: false,
|
|
10312
|
-
},
|
|
10313
|
-
inlining: false,
|
|
10314
|
-
http,
|
|
10315
|
-
scenarioPlaceholders,
|
|
10316
|
-
}),
|
|
10317
|
-
]);
|
|
10318
|
-
const rawPluginController = createPluginController(
|
|
10319
|
-
rawPluginStore,
|
|
10320
|
-
rawKitchen,
|
|
10321
|
-
);
|
|
10322
|
-
rawKitchen.setPluginController(rawPluginController);
|
|
10462
|
+
const logLevel = logs.level;
|
|
10463
|
+
const logger = createLogger({ logLevel });
|
|
10464
|
+
const animatedLogEnabled =
|
|
10465
|
+
logs.animated &&
|
|
10466
|
+
// canEraseProcessStdout
|
|
10467
|
+
process.stdout.isTTY &&
|
|
10468
|
+
// if there is an error during execution npm will mess up the output
|
|
10469
|
+
// (happens when npm runs several command in a workspace)
|
|
10470
|
+
// so we enable hot replace only when !process.exitCode (no error so far)
|
|
10471
|
+
process.exitCode !== 1;
|
|
10472
|
+
let startBuildLogs = () => {};
|
|
10473
|
+
|
|
10474
|
+
const renderEntyPointBuildDoneLog = (
|
|
10475
|
+
entryBuildInfo,
|
|
10476
|
+
{ sourceUrlToLog, buildUrlToLog },
|
|
10477
|
+
) => {
|
|
10478
|
+
let content = "";
|
|
10479
|
+
content += `${UNICODE.OK} ${ANSI.color(sourceUrlToLog, ANSI.GREY)} ${ANSI.color("->", ANSI.GREY)} ${ANSI.color(buildUrlToLog, "")}`;
|
|
10480
|
+
// content += " ";
|
|
10481
|
+
// content += ANSI.color("(", ANSI.GREY);
|
|
10482
|
+
// content += ANSI.color(
|
|
10483
|
+
// humanizeDuration(entryBuildInfo.duration, { short: true }),
|
|
10484
|
+
// ANSI.GREY,
|
|
10485
|
+
// );
|
|
10486
|
+
// content += ANSI.color(")", ANSI.GREY);
|
|
10487
|
+
content += "\n";
|
|
10488
|
+
return content;
|
|
10489
|
+
};
|
|
10490
|
+
const renderBuildEndLog = ({ duration, buildFileContents }) => {
|
|
10491
|
+
// tell how many files are generated in build directory
|
|
10492
|
+
// tell the repartition?
|
|
10493
|
+
// this is not really useful for single build right?
|
|
10494
|
+
|
|
10495
|
+
processCpuUsageMonitoring.end();
|
|
10496
|
+
processMemoryUsageMonitoring.end();
|
|
10497
|
+
|
|
10498
|
+
return renderBuildDoneLog({
|
|
10499
|
+
duration,
|
|
10500
|
+
buildFileContents,
|
|
10501
|
+
processCpuUsage: processCpuUsageMonitoring.info,
|
|
10502
|
+
processMemoryUsage: processMemoryUsageMonitoring.info,
|
|
10503
|
+
});
|
|
10504
|
+
};
|
|
10323
10505
|
|
|
10324
|
-
|
|
10325
|
-
|
|
10326
|
-
|
|
10327
|
-
|
|
10328
|
-
|
|
10329
|
-
|
|
10330
|
-
|
|
10331
|
-
|
|
10332
|
-
|
|
10333
|
-
|
|
10334
|
-
|
|
10335
|
-
|
|
10336
|
-
|
|
10337
|
-
|
|
10338
|
-
|
|
10339
|
-
|
|
10340
|
-
|
|
10341
|
-
|
|
10506
|
+
if (animatedLogEnabled) {
|
|
10507
|
+
startBuildLogs = () => {
|
|
10508
|
+
const startMs = Date.now();
|
|
10509
|
+
let dynamicLog = createDynamicLog();
|
|
10510
|
+
const frames = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
|
|
10511
|
+
let frameIndex = 0;
|
|
10512
|
+
let oneWrite = false;
|
|
10513
|
+
const memoryHeapUsedAtStart = memoryUsage().heapUsed;
|
|
10514
|
+
const renderDynamicLog = () => {
|
|
10515
|
+
frameIndex = frameIndex === frames.length - 1 ? 0 : frameIndex + 1;
|
|
10516
|
+
let dynamicLogContent = "";
|
|
10517
|
+
dynamicLogContent += `${frames[frameIndex]} `;
|
|
10518
|
+
dynamicLogContent += `building ${entryPointArray.length} entry points`;
|
|
10519
|
+
|
|
10520
|
+
const msEllapsed = Date.now() - startMs;
|
|
10521
|
+
const infos = [];
|
|
10522
|
+
const duration = humanizeDuration(msEllapsed, {
|
|
10523
|
+
short: true,
|
|
10524
|
+
decimals: 0,
|
|
10525
|
+
rounded: false,
|
|
10342
10526
|
});
|
|
10343
|
-
|
|
10344
|
-
|
|
10527
|
+
infos.push(ANSI.color(duration, ANSI.GREY));
|
|
10528
|
+
let memoryUsageColor = ANSI.GREY;
|
|
10529
|
+
const memoryHeapUsed = memoryUsage().heapUsed;
|
|
10530
|
+
if (memoryHeapUsed > 2.5 * memoryHeapUsedAtStart) {
|
|
10531
|
+
memoryUsageColor = ANSI.YELLOW;
|
|
10532
|
+
} else if (memoryHeapUsed > 1.5 * memoryHeapUsedAtStart) {
|
|
10533
|
+
memoryUsageColor = null;
|
|
10534
|
+
}
|
|
10535
|
+
const memoryHeapUsedFormatted = humanizeMemory(memoryHeapUsed, {
|
|
10536
|
+
short: true,
|
|
10537
|
+
decimals: 0,
|
|
10345
10538
|
});
|
|
10346
|
-
|
|
10347
|
-
generateSourceGraph.fail();
|
|
10348
|
-
throw e;
|
|
10349
|
-
}
|
|
10350
|
-
generateSourceGraph.done();
|
|
10351
|
-
}
|
|
10352
|
-
|
|
10353
|
-
const finalKitchen = createKitchen({
|
|
10354
|
-
name: "shape",
|
|
10355
|
-
logLevel: logs.level,
|
|
10356
|
-
rootDirectoryUrl: sourceDirectoryUrl,
|
|
10357
|
-
// here most plugins are not there
|
|
10358
|
-
// - no external plugin
|
|
10359
|
-
// - no plugin putting reference.mustIgnore on https urls
|
|
10360
|
-
// At this stage it's only about redirecting urls to the build directory
|
|
10361
|
-
// consequently only a subset or urls are supported
|
|
10362
|
-
supportedProtocols: ["file:", "data:", "virtual:", "ignore:"],
|
|
10363
|
-
ignore,
|
|
10364
|
-
ignoreProtocol: "remove",
|
|
10365
|
-
build: true,
|
|
10366
|
-
runtimeCompat,
|
|
10367
|
-
initialContext: contextSharedDuringBuild,
|
|
10368
|
-
sourcemaps,
|
|
10369
|
-
sourcemapsComment: "relative",
|
|
10370
|
-
sourcemapsSourcesContent,
|
|
10371
|
-
outDirectoryUrl: outDirectoryUrl
|
|
10372
|
-
? new URL("shape/", outDirectoryUrl)
|
|
10373
|
-
: undefined,
|
|
10374
|
-
});
|
|
10375
|
-
const buildSpecifierManager = createBuildSpecifierManager({
|
|
10376
|
-
rawKitchen,
|
|
10377
|
-
finalKitchen,
|
|
10378
|
-
logger,
|
|
10379
|
-
sourceDirectoryUrl,
|
|
10380
|
-
buildDirectoryUrl,
|
|
10381
|
-
base,
|
|
10382
|
-
assetsDirectory,
|
|
10539
|
+
infos.push(ANSI.color(memoryHeapUsedFormatted, memoryUsageColor));
|
|
10383
10540
|
|
|
10384
|
-
|
|
10385
|
-
|
|
10386
|
-
|
|
10387
|
-
|
|
10388
|
-
|
|
10389
|
-
entryUrls.every((finalEntryUrl) => {
|
|
10390
|
-
const entryUrlInfo = rawKitchen.graph.getUrlInfo(finalEntryUrl);
|
|
10391
|
-
return entryUrlInfo.type === "html";
|
|
10392
|
-
}) &&
|
|
10393
|
-
rawKitchen.context.isSupportedOnCurrentClients("importmap"),
|
|
10394
|
-
});
|
|
10395
|
-
const finalPluginStore = createPluginStore([
|
|
10396
|
-
jsenvPluginReferenceAnalysis({
|
|
10397
|
-
...referenceAnalysis,
|
|
10398
|
-
fetchInlineUrls: false,
|
|
10399
|
-
// inlineContent: false,
|
|
10400
|
-
}),
|
|
10401
|
-
jsenvPluginDirectoryReferenceEffect(directoryReferenceEffect),
|
|
10402
|
-
...(lineBreakNormalization ? [jsenvPluginLineBreakNormalization()] : []),
|
|
10403
|
-
jsenvPluginJsModuleFallback({
|
|
10404
|
-
remapImportSpecifier: (specifier, parentUrl) => {
|
|
10405
|
-
return buildSpecifierManager.remapPlaceholder(specifier, parentUrl);
|
|
10406
|
-
},
|
|
10407
|
-
}),
|
|
10408
|
-
jsenvPluginInlining(),
|
|
10409
|
-
{
|
|
10410
|
-
name: "jsenv:optimize",
|
|
10411
|
-
appliesDuring: "build",
|
|
10412
|
-
transformUrlContent: async (urlInfo) => {
|
|
10413
|
-
await rawKitchen.pluginController.callAsyncHooks(
|
|
10414
|
-
"optimizeUrlContent",
|
|
10415
|
-
urlInfo,
|
|
10416
|
-
(optimizeReturnValue) => {
|
|
10417
|
-
urlInfo.mutateContent(optimizeReturnValue);
|
|
10418
|
-
},
|
|
10419
|
-
);
|
|
10420
|
-
},
|
|
10421
|
-
},
|
|
10422
|
-
buildSpecifierManager.jsenvPluginMoveToBuildDirectory,
|
|
10423
|
-
]);
|
|
10424
|
-
const finalPluginController = createPluginController(
|
|
10425
|
-
finalPluginStore,
|
|
10426
|
-
finalKitchen,
|
|
10427
|
-
{
|
|
10428
|
-
initialPuginsMeta: rawKitchen.pluginController.pluginsMeta,
|
|
10429
|
-
},
|
|
10430
|
-
);
|
|
10431
|
-
finalKitchen.setPluginController(finalPluginController);
|
|
10541
|
+
const infoFormatted = infos.join(ANSI.color(`/`, ANSI.GREY));
|
|
10542
|
+
dynamicLogContent += ` ${ANSI.color(
|
|
10543
|
+
"[",
|
|
10544
|
+
ANSI.GREY,
|
|
10545
|
+
)}${infoFormatted}${ANSI.color("]", ANSI.GREY)}`;
|
|
10432
10546
|
|
|
10433
|
-
|
|
10434
|
-
|
|
10435
|
-
for (const plugin of rawKitchen.pluginController.activePlugins) {
|
|
10436
|
-
const bundle = plugin.bundle;
|
|
10437
|
-
if (!bundle) {
|
|
10438
|
-
continue;
|
|
10439
|
-
}
|
|
10440
|
-
if (typeof bundle !== "object") {
|
|
10441
|
-
throw new Error(
|
|
10442
|
-
`bundle must be an object, found "${bundle}" on plugin named "${plugin.name}"`,
|
|
10443
|
-
);
|
|
10444
|
-
}
|
|
10445
|
-
for (const type of Object.keys(bundle)) {
|
|
10446
|
-
const bundleFunction = bundle[type];
|
|
10447
|
-
if (!bundleFunction) {
|
|
10448
|
-
continue;
|
|
10449
|
-
}
|
|
10450
|
-
const bundlerForThatType = bundlers[type];
|
|
10451
|
-
if (bundlerForThatType) {
|
|
10452
|
-
// first plugin to define a bundle hook wins
|
|
10453
|
-
continue;
|
|
10454
|
-
}
|
|
10455
|
-
bundlers[type] = {
|
|
10456
|
-
plugin,
|
|
10457
|
-
bundleFunction: bundle[type],
|
|
10458
|
-
urlInfoMap: new Map(),
|
|
10459
|
-
};
|
|
10460
|
-
}
|
|
10461
|
-
}
|
|
10462
|
-
const addToBundlerIfAny = (rawUrlInfo) => {
|
|
10463
|
-
const bundler = bundlers[rawUrlInfo.type];
|
|
10464
|
-
if (bundler) {
|
|
10465
|
-
bundler.urlInfoMap.set(rawUrlInfo.url, rawUrlInfo);
|
|
10547
|
+
if (oneWrite) {
|
|
10548
|
+
dynamicLogContent = `\n${dynamicLogContent}`;
|
|
10466
10549
|
}
|
|
10550
|
+
dynamicLogContent = `${dynamicLogContent}\n`;
|
|
10551
|
+
return dynamicLogContent;
|
|
10467
10552
|
};
|
|
10468
|
-
|
|
10469
|
-
|
|
10470
|
-
|
|
10471
|
-
|
|
10472
|
-
|
|
10473
|
-
|
|
10474
|
-
|
|
10475
|
-
|
|
10476
|
-
|
|
10477
|
-
|
|
10478
|
-
}
|
|
10479
|
-
|
|
10480
|
-
|
|
10481
|
-
|
|
10482
|
-
|
|
10483
|
-
|
|
10484
|
-
|
|
10485
|
-
|
|
10486
|
-
|
|
10487
|
-
|
|
10488
|
-
|
|
10489
|
-
|
|
10490
|
-
) {
|
|
10491
|
-
addToBundlerIfAny(referencedUrlInfo);
|
|
10492
|
-
continue;
|
|
10493
|
-
}
|
|
10494
|
-
}
|
|
10495
|
-
if (referenceToOther.isWeak) {
|
|
10496
|
-
continue;
|
|
10497
|
-
}
|
|
10498
|
-
const referencedUrlInfo = referenceToOther.urlInfo;
|
|
10499
|
-
if (referencedUrlInfo.isInline) {
|
|
10500
|
-
if (referencedUrlInfo.type !== "js_module") {
|
|
10501
|
-
continue;
|
|
10502
|
-
}
|
|
10503
|
-
addToBundlerIfAny(referencedUrlInfo);
|
|
10504
|
-
continue;
|
|
10505
|
-
}
|
|
10506
|
-
addToBundlerIfAny(referencedUrlInfo);
|
|
10507
|
-
}
|
|
10508
|
-
return;
|
|
10509
|
-
}
|
|
10510
|
-
// File referenced with
|
|
10511
|
-
// - new URL("./file.js", import.meta.url)
|
|
10512
|
-
// - import.meta.resolve("./file.js")
|
|
10513
|
-
// are entry points that should be bundled
|
|
10514
|
-
// For instance we will bundle service worker/workers detected like this
|
|
10515
|
-
if (rawUrlInfo.type === "js_module") {
|
|
10516
|
-
for (const referenceToOther of rawUrlInfo.referenceToOthersSet) {
|
|
10517
|
-
if (
|
|
10518
|
-
referenceToOther.type === "js_url" ||
|
|
10519
|
-
referenceToOther.subtype === "import_meta_resolve"
|
|
10520
|
-
) {
|
|
10521
|
-
const referencedUrlInfo = referenceToOther.urlInfo;
|
|
10522
|
-
let isAlreadyBundled = false;
|
|
10523
|
-
for (const referenceFromOther of referencedUrlInfo.referenceFromOthersSet) {
|
|
10524
|
-
if (referenceFromOther.url === referencedUrlInfo.url) {
|
|
10525
|
-
if (
|
|
10526
|
-
referenceFromOther.subtype === "import_dynamic" ||
|
|
10527
|
-
referenceFromOther.type === "script"
|
|
10528
|
-
) {
|
|
10529
|
-
isAlreadyBundled = true;
|
|
10530
|
-
break;
|
|
10531
|
-
}
|
|
10532
|
-
}
|
|
10533
|
-
}
|
|
10534
|
-
if (!isAlreadyBundled) {
|
|
10535
|
-
addToBundlerIfAny(referencedUrlInfo);
|
|
10536
|
-
}
|
|
10537
|
-
continue;
|
|
10538
|
-
}
|
|
10539
|
-
if (referenceToOther.type === "js_inline_content") ;
|
|
10540
|
-
}
|
|
10541
|
-
}
|
|
10553
|
+
dynamicLog.update(renderDynamicLog());
|
|
10554
|
+
const interval = setInterval(() => {
|
|
10555
|
+
dynamicLog.update(renderDynamicLog());
|
|
10556
|
+
}, 150).unref();
|
|
10557
|
+
signal.addEventListener("abort", () => {
|
|
10558
|
+
clearInterval(interval);
|
|
10559
|
+
});
|
|
10560
|
+
return {
|
|
10561
|
+
onEntryPointBuildStart: (
|
|
10562
|
+
entryBuildInfo,
|
|
10563
|
+
{ sourceUrlToLog, buildUrlToLog },
|
|
10564
|
+
) => {
|
|
10565
|
+
return () => {
|
|
10566
|
+
oneWrite = true;
|
|
10567
|
+
dynamicLog.clearDuringFunctionCall((write) => {
|
|
10568
|
+
const log = renderEntyPointBuildDoneLog(entryBuildInfo, {
|
|
10569
|
+
sourceUrlToLog,
|
|
10570
|
+
buildUrlToLog,
|
|
10571
|
+
});
|
|
10572
|
+
write(log);
|
|
10573
|
+
}, renderDynamicLog());
|
|
10574
|
+
};
|
|
10542
10575
|
},
|
|
10543
|
-
|
|
10544
|
-
|
|
10545
|
-
|
|
10546
|
-
|
|
10547
|
-
|
|
10548
|
-
|
|
10549
|
-
|
|
10550
|
-
|
|
10551
|
-
|
|
10552
|
-
|
|
10553
|
-
|
|
10554
|
-
|
|
10555
|
-
|
|
10556
|
-
|
|
10557
|
-
|
|
10558
|
-
|
|
10559
|
-
}
|
|
10560
|
-
bundleTask.done();
|
|
10576
|
+
onBuildEnd: ({ buildFileContents, duration }) => {
|
|
10577
|
+
clearInterval(interval);
|
|
10578
|
+
dynamicLog.update("");
|
|
10579
|
+
dynamicLog.destroy();
|
|
10580
|
+
dynamicLog = null;
|
|
10581
|
+
logger.info("");
|
|
10582
|
+
logger.info(renderBuildEndLog({ duration, buildFileContents }));
|
|
10583
|
+
},
|
|
10584
|
+
};
|
|
10585
|
+
};
|
|
10586
|
+
} else {
|
|
10587
|
+
startBuildLogs = () => {
|
|
10588
|
+
if (entryPointArray.length === 1) {
|
|
10589
|
+
const [singleEntryPoint] = entryPointArray;
|
|
10590
|
+
logger.info(`building ${singleEntryPoint.key}`);
|
|
10591
|
+
} else {
|
|
10592
|
+
logger.info(`building ${entryPointArray.length} entry points`);
|
|
10561
10593
|
}
|
|
10562
|
-
|
|
10594
|
+
logger.info("");
|
|
10595
|
+
return {
|
|
10596
|
+
onEntryPointBuildStart: (
|
|
10597
|
+
entryBuildInfo,
|
|
10598
|
+
{ sourceUrlToLog, buildUrlToLog },
|
|
10599
|
+
) => {
|
|
10600
|
+
return () => {
|
|
10601
|
+
logger.info(
|
|
10602
|
+
renderEntyPointBuildDoneLog(entryBuildInfo, {
|
|
10603
|
+
sourceUrlToLog,
|
|
10604
|
+
buildUrlToLog,
|
|
10605
|
+
}),
|
|
10606
|
+
);
|
|
10607
|
+
};
|
|
10608
|
+
},
|
|
10609
|
+
onBuildEnd: ({ buildFileContents, duration }) => {
|
|
10610
|
+
logger.info("");
|
|
10611
|
+
logger.info(renderBuildEndLog({ duration, buildFileContents }));
|
|
10612
|
+
},
|
|
10613
|
+
};
|
|
10614
|
+
};
|
|
10615
|
+
}
|
|
10563
10616
|
|
|
10564
|
-
|
|
10565
|
-
|
|
10566
|
-
|
|
10567
|
-
|
|
10568
|
-
|
|
10569
|
-
|
|
10570
|
-
}
|
|
10571
|
-
const finalRootUrlInfo = finalKitchen.graph.rootUrlInfo;
|
|
10572
|
-
await finalRootUrlInfo.dependencies.startCollecting(() => {
|
|
10573
|
-
entryUrls.forEach((entryUrl) => {
|
|
10574
|
-
finalRootUrlInfo.dependencies.found({
|
|
10575
|
-
trace: { message: `entryPoint` },
|
|
10576
|
-
isEntryPoint: true,
|
|
10577
|
-
type: "entry_point",
|
|
10578
|
-
specifier: entryUrl,
|
|
10579
|
-
});
|
|
10580
|
-
});
|
|
10581
|
-
});
|
|
10582
|
-
await finalRootUrlInfo.cookDependencies({
|
|
10583
|
-
operation: buildOperation,
|
|
10584
|
-
});
|
|
10585
|
-
} catch (e) {
|
|
10586
|
-
generateBuildGraph.fail();
|
|
10587
|
-
throw e;
|
|
10588
|
-
}
|
|
10589
|
-
generateBuildGraph.done();
|
|
10590
|
-
}
|
|
10617
|
+
// we want to start building the entry point that are deeper
|
|
10618
|
+
// - they are more likely to be small
|
|
10619
|
+
// - they are more likely to be referenced by highter files that will depend on them
|
|
10620
|
+
entryPointArray.sort((a, b) => {
|
|
10621
|
+
return compareFileUrls(a.sourceUrl, b.sourceUrl);
|
|
10622
|
+
});
|
|
10591
10623
|
|
|
10592
|
-
|
|
10593
|
-
|
|
10624
|
+
const packageDirectoryUrl = lookupPackageDirectory(sourceDirectoryUrl);
|
|
10625
|
+
if (outDirectoryUrl === undefined) {
|
|
10626
|
+
if (
|
|
10627
|
+
process.env.CAPTURING_SIDE_EFFECTS ||
|
|
10628
|
+
(false)
|
|
10629
|
+
) {
|
|
10630
|
+
outDirectoryUrl = new URL("../.jsenv_b/", sourceDirectoryUrl).href;
|
|
10631
|
+
} else if (packageDirectoryUrl) {
|
|
10632
|
+
outDirectoryUrl = `${packageDirectoryUrl}.jsenv/`;
|
|
10633
|
+
}
|
|
10634
|
+
}
|
|
10635
|
+
let rootPackageDirectoryUrl = packageDirectoryUrl;
|
|
10636
|
+
if (packageDirectoryUrl) {
|
|
10637
|
+
const parentPackageDirectoryUrl = lookupPackageDirectory(
|
|
10638
|
+
new URL("../", packageDirectoryUrl),
|
|
10639
|
+
);
|
|
10640
|
+
if (parentPackageDirectoryUrl) {
|
|
10641
|
+
rootPackageDirectoryUrl = parentPackageDirectoryUrl;
|
|
10642
|
+
}
|
|
10643
|
+
}
|
|
10594
10644
|
|
|
10595
|
-
|
|
10596
|
-
|
|
10597
|
-
|
|
10598
|
-
};
|
|
10645
|
+
const runBuild = async ({ signal }) => {
|
|
10646
|
+
const startDate = Date.now();
|
|
10647
|
+
const { onBuildEnd, onEntryPointBuildStart } = startBuildLogs();
|
|
10599
10648
|
|
|
10600
|
-
|
|
10601
|
-
|
|
10602
|
-
|
|
10649
|
+
const buildUrlsGenerator = createBuildUrlsGenerator({
|
|
10650
|
+
sourceDirectoryUrl,
|
|
10651
|
+
buildDirectoryUrl,
|
|
10652
|
+
});
|
|
10603
10653
|
|
|
10604
|
-
|
|
10605
|
-
|
|
10606
|
-
|
|
10607
|
-
|
|
10608
|
-
|
|
10609
|
-
|
|
10610
|
-
|
|
10611
|
-
|
|
10612
|
-
|
|
10613
|
-
|
|
10654
|
+
let someEntryPointUseNode = false;
|
|
10655
|
+
for (const entryPoint of entryPointArray) {
|
|
10656
|
+
let { runtimeCompat } = entryPoint.params;
|
|
10657
|
+
if (runtimeCompat === undefined) {
|
|
10658
|
+
const runtimeCompatFromPackage = inferRuntimeCompatFromClosestPackage(
|
|
10659
|
+
entryPoint.sourceUrl,
|
|
10660
|
+
{
|
|
10661
|
+
runtimeType: entryPoint.runtimeType,
|
|
10662
|
+
},
|
|
10663
|
+
);
|
|
10664
|
+
if (runtimeCompatFromPackage) {
|
|
10665
|
+
entryPoint.params.runtimeCompat = runtimeCompat =
|
|
10666
|
+
runtimeCompatFromPackage;
|
|
10667
|
+
} else {
|
|
10668
|
+
entryPoint.params.runtimeCompat = runtimeCompat =
|
|
10669
|
+
entryPoint.runtimeType === "browser"
|
|
10670
|
+
? browserDefaultRuntimeCompat
|
|
10671
|
+
: nodeDefaultRuntimeCompat;
|
|
10672
|
+
}
|
|
10614
10673
|
}
|
|
10615
|
-
|
|
10616
|
-
|
|
10617
|
-
GRAPH_VISITOR.forEach(finalKitchen.graph, (urlInfo) => {
|
|
10618
|
-
if (!urlInfo.url.startsWith("file:")) {
|
|
10619
|
-
return;
|
|
10620
|
-
}
|
|
10621
|
-
if (urlInfo.type !== "html") {
|
|
10622
|
-
return;
|
|
10623
|
-
}
|
|
10624
|
-
const htmlAst = parseHtml({
|
|
10625
|
-
html: urlInfo.content,
|
|
10626
|
-
url: urlInfo.url,
|
|
10627
|
-
storeOriginalPositions: false,
|
|
10628
|
-
});
|
|
10629
|
-
for (const htmlRefine of htmlRefineSet) {
|
|
10630
|
-
const htmlMutationCallbackSet = new Set();
|
|
10631
|
-
const registerHtmlMutation = (callback) => {
|
|
10632
|
-
htmlMutationCallbackSet.add(callback);
|
|
10633
|
-
};
|
|
10634
|
-
htmlRefine(htmlAst, { registerHtmlMutation });
|
|
10635
|
-
for (const htmlMutationCallback of htmlMutationCallbackSet) {
|
|
10636
|
-
htmlMutationCallback();
|
|
10637
|
-
}
|
|
10638
|
-
}
|
|
10639
|
-
// cleanup jsenv attributes from html as a last step
|
|
10640
|
-
urlInfo.content = stringifyHtmlAst(htmlAst, {
|
|
10641
|
-
cleanupJsenvAttributes: true,
|
|
10642
|
-
cleanupPositionAttributes: true,
|
|
10643
|
-
});
|
|
10644
|
-
});
|
|
10674
|
+
if (!someEntryPointUseNode && "node" in runtimeCompat) {
|
|
10675
|
+
someEntryPointUseNode = true;
|
|
10645
10676
|
}
|
|
10677
|
+
}
|
|
10646
10678
|
|
|
10647
|
-
|
|
10648
|
-
|
|
10649
|
-
|
|
10650
|
-
|
|
10651
|
-
|
|
10652
|
-
|
|
10653
|
-
|
|
10654
|
-
|
|
10655
|
-
|
|
10656
|
-
}
|
|
10679
|
+
const entryBuildInfoMap = new Map();
|
|
10680
|
+
let entryPointIndex = 0;
|
|
10681
|
+
const entryOutDirSet = new Set();
|
|
10682
|
+
for (const entryPoint of entryPointArray) {
|
|
10683
|
+
let entryOutDirCandidate = `entry_${urlToBasename(entryPoint.sourceRelativeUrl)}/`;
|
|
10684
|
+
let entryInteger = 1;
|
|
10685
|
+
while (entryOutDirSet.has(entryOutDirCandidate)) {
|
|
10686
|
+
entryInteger++;
|
|
10687
|
+
entryOutDirCandidate = `entry_${urlToBasename(entryPoint.sourceRelativeUrl)}_${entryInteger}/`;
|
|
10657
10688
|
}
|
|
10689
|
+
const entryOutDirname = entryOutDirCandidate;
|
|
10690
|
+
entryOutDirSet.add(entryOutDirname);
|
|
10691
|
+
const entryOutDirectoryUrl = new URL(entryOutDirname, outDirectoryUrl);
|
|
10692
|
+
const { entryReference, buildEntryPoint } = await prepareEntryPointBuild(
|
|
10693
|
+
{
|
|
10694
|
+
signal,
|
|
10695
|
+
sourceDirectoryUrl,
|
|
10696
|
+
buildDirectoryUrl,
|
|
10697
|
+
outDirectoryUrl: entryOutDirectoryUrl,
|
|
10698
|
+
sourceRelativeUrl: entryPoint.sourceRelativeUrl,
|
|
10699
|
+
buildUrlsGenerator,
|
|
10700
|
+
someEntryPointUseNode,
|
|
10701
|
+
},
|
|
10702
|
+
entryPoint.params,
|
|
10703
|
+
);
|
|
10704
|
+
const entryPointBuildRelativeUrl = entryPoint.params.buildRelativeUrl;
|
|
10705
|
+
const entryBuildInfo = {
|
|
10706
|
+
index: entryPointIndex,
|
|
10707
|
+
entryReference,
|
|
10708
|
+
entryUrlInfo: entryReference.urlInfo,
|
|
10709
|
+
buildRelativeUrl: entryPointBuildRelativeUrl,
|
|
10710
|
+
buildFileContents: undefined,
|
|
10711
|
+
buildFileVersions: undefined,
|
|
10712
|
+
buildInlineContents: undefined,
|
|
10713
|
+
buildManifest: undefined,
|
|
10714
|
+
duration: null,
|
|
10715
|
+
buildEntryPoint: () => {
|
|
10716
|
+
const sourceUrl = new URL(
|
|
10717
|
+
entryPoint.sourceRelativeUrl,
|
|
10718
|
+
sourceDirectoryUrl,
|
|
10719
|
+
);
|
|
10720
|
+
const buildUrl = new URL(
|
|
10721
|
+
entryPointBuildRelativeUrl,
|
|
10722
|
+
buildDirectoryUrl,
|
|
10723
|
+
);
|
|
10724
|
+
const sourceUrlToLog = rootPackageDirectoryUrl
|
|
10725
|
+
? urlToRelativeUrl(sourceUrl, rootPackageDirectoryUrl)
|
|
10726
|
+
: entryPoint.key;
|
|
10727
|
+
const buildUrlToLog = rootPackageDirectoryUrl
|
|
10728
|
+
? urlToRelativeUrl(buildUrl, rootPackageDirectoryUrl)
|
|
10729
|
+
: entryPointBuildRelativeUrl;
|
|
10730
|
+
|
|
10731
|
+
const entryPointBuildStartMs = Date.now();
|
|
10732
|
+
const onEntryPointBuildEnd = onEntryPointBuildStart(entryBuildInfo, {
|
|
10733
|
+
sourceUrlToLog,
|
|
10734
|
+
buildUrlToLog,
|
|
10735
|
+
});
|
|
10736
|
+
const promise = (async () => {
|
|
10737
|
+
const result = await buildEntryPoint({
|
|
10738
|
+
getOtherEntryBuildInfo: (url) => {
|
|
10739
|
+
if (url === entryReference.url) {
|
|
10740
|
+
return null;
|
|
10741
|
+
}
|
|
10742
|
+
const otherEntryBuildInfo = entryBuildInfoMap.get(url);
|
|
10743
|
+
if (!otherEntryBuildInfo) {
|
|
10744
|
+
return null;
|
|
10745
|
+
}
|
|
10746
|
+
return otherEntryBuildInfo;
|
|
10747
|
+
},
|
|
10748
|
+
});
|
|
10749
|
+
entryBuildInfo.buildFileContents = result.buildFileContents;
|
|
10750
|
+
entryBuildInfo.buildFileVersions = result.buildFileVersions;
|
|
10751
|
+
entryBuildInfo.buildInlineContents = result.buildInlineContents;
|
|
10752
|
+
entryBuildInfo.buildManifest = result.buildManifest;
|
|
10753
|
+
entryBuildInfo.duration = Date.now() - entryPointBuildStartMs;
|
|
10754
|
+
onEntryPointBuildEnd();
|
|
10755
|
+
})();
|
|
10756
|
+
entryBuildInfo.promise = promise;
|
|
10757
|
+
return promise;
|
|
10758
|
+
},
|
|
10759
|
+
};
|
|
10760
|
+
entryBuildInfoMap.set(entryReference.url, entryBuildInfo);
|
|
10761
|
+
entryPointIndex++;
|
|
10762
|
+
}
|
|
10763
|
+
|
|
10764
|
+
const promises = [];
|
|
10765
|
+
for (const [, entryBuildInfo] of entryBuildInfoMap) {
|
|
10766
|
+
const promise = entryBuildInfo.buildEntryPoint();
|
|
10767
|
+
promises.push(promise);
|
|
10768
|
+
}
|
|
10769
|
+
await Promise.all(promises);
|
|
10770
|
+
|
|
10771
|
+
const buildFileContents = {};
|
|
10772
|
+
const buildFileVersions = {};
|
|
10773
|
+
const buildInlineContents = {};
|
|
10774
|
+
const buildManifest = {};
|
|
10775
|
+
for (const [, entryBuildInfo] of entryBuildInfoMap) {
|
|
10776
|
+
Object.assign(buildFileContents, entryBuildInfo.buildFileContents);
|
|
10777
|
+
Object.assign(buildFileVersions, entryBuildInfo.buildFileVersions);
|
|
10778
|
+
Object.assign(buildInlineContents, entryBuildInfo.buildInlineContents);
|
|
10779
|
+
Object.assign(buildManifest, entryBuildInfo.buildManifest);
|
|
10658
10780
|
}
|
|
10659
|
-
const { buildFileContents, buildInlineContents, buildManifest } =
|
|
10660
|
-
buildSpecifierManager.getBuildInfo();
|
|
10661
10781
|
if (writeOnFileSystem) {
|
|
10662
|
-
const writingFiles = createBuildTask("write files in build directory");
|
|
10663
10782
|
clearDirectorySync(buildDirectoryUrl, buildDirectoryCleanPatterns);
|
|
10664
10783
|
const buildRelativeUrls = Object.keys(buildFileContents);
|
|
10665
10784
|
buildRelativeUrls.forEach((buildRelativeUrl) => {
|
|
@@ -10668,23 +10787,17 @@ build ${entryPointKeys.length} entry points`);
|
|
|
10668
10787
|
buildFileContents[buildRelativeUrl],
|
|
10669
10788
|
);
|
|
10670
10789
|
});
|
|
10671
|
-
if (versioning && assetManifest && Object.keys(buildManifest).length) {
|
|
10672
|
-
writeFileSync(
|
|
10673
|
-
new URL(assetManifestFileRelativeUrl, buildDirectoryUrl),
|
|
10674
|
-
JSON.stringify(buildManifest, null, " "),
|
|
10675
|
-
);
|
|
10676
|
-
}
|
|
10677
|
-
writingFiles.done();
|
|
10678
10790
|
}
|
|
10679
|
-
|
|
10680
|
-
|
|
10681
|
-
|
|
10682
|
-
|
|
10683
|
-
|
|
10791
|
+
onBuildEnd({
|
|
10792
|
+
buildFileContents,
|
|
10793
|
+
buildInlineContents,
|
|
10794
|
+
buildManifest,
|
|
10795
|
+
duration: Date.now() - startDate,
|
|
10796
|
+
});
|
|
10684
10797
|
return {
|
|
10685
10798
|
...(returnBuildInlineContents ? { buildInlineContents } : {}),
|
|
10686
10799
|
...(returnBuildManifest ? { buildManifest } : {}),
|
|
10687
|
-
...(
|
|
10800
|
+
...(returnBuildFileVersions ? { buildFileVersions } : {}),
|
|
10688
10801
|
};
|
|
10689
10802
|
};
|
|
10690
10803
|
|
|
@@ -10692,7 +10805,6 @@ build ${entryPointKeys.length} entry points`);
|
|
|
10692
10805
|
try {
|
|
10693
10806
|
const result = await runBuild({
|
|
10694
10807
|
signal: operation.signal,
|
|
10695
|
-
logLevel: logs.level,
|
|
10696
10808
|
});
|
|
10697
10809
|
return result;
|
|
10698
10810
|
} finally {
|
|
@@ -10765,4 +10877,583 @@ build ${entryPointKeys.length} entry points`);
|
|
|
10765
10877
|
return stopWatchingSourceFiles;
|
|
10766
10878
|
};
|
|
10767
10879
|
|
|
10880
|
+
const entryPointDefaultParams = {
|
|
10881
|
+
buildRelativeUrl: undefined,
|
|
10882
|
+
runtimeCompat: defaultRuntimeCompat,
|
|
10883
|
+
plugins: [],
|
|
10884
|
+
mappings: undefined,
|
|
10885
|
+
assetsDirectory: undefined,
|
|
10886
|
+
base: undefined,
|
|
10887
|
+
ignore: undefined,
|
|
10888
|
+
|
|
10889
|
+
bundling: true,
|
|
10890
|
+
minification: true,
|
|
10891
|
+
versioning: true,
|
|
10892
|
+
|
|
10893
|
+
referenceAnalysis: {},
|
|
10894
|
+
nodeEsmResolution: undefined,
|
|
10895
|
+
packageConditions: undefined,
|
|
10896
|
+
magicExtensions: undefined,
|
|
10897
|
+
magicDirectoryIndex: undefined,
|
|
10898
|
+
directoryReferenceEffect: undefined,
|
|
10899
|
+
scenarioPlaceholders: undefined,
|
|
10900
|
+
injections: undefined,
|
|
10901
|
+
transpilation: {},
|
|
10902
|
+
|
|
10903
|
+
versioningMethod: "search_param", // "filename", "search_param"
|
|
10904
|
+
versioningViaImportmap: true,
|
|
10905
|
+
versionLength: 8,
|
|
10906
|
+
lineBreakNormalization: process.platform === "win32",
|
|
10907
|
+
|
|
10908
|
+
http: false,
|
|
10909
|
+
|
|
10910
|
+
sourcemaps: "none",
|
|
10911
|
+
sourcemapsSourcesContent: undefined,
|
|
10912
|
+
assetManifest: false,
|
|
10913
|
+
assetManifestFileRelativeUrl: "asset-manifest.json",
|
|
10914
|
+
};
|
|
10915
|
+
|
|
10916
|
+
const prepareEntryPointBuild = async (
|
|
10917
|
+
{
|
|
10918
|
+
signal,
|
|
10919
|
+
sourceDirectoryUrl,
|
|
10920
|
+
buildDirectoryUrl,
|
|
10921
|
+
sourceRelativeUrl,
|
|
10922
|
+
outDirectoryUrl,
|
|
10923
|
+
buildUrlsGenerator,
|
|
10924
|
+
someEntryPointUseNode,
|
|
10925
|
+
},
|
|
10926
|
+
entryPointParams,
|
|
10927
|
+
) => {
|
|
10928
|
+
let {
|
|
10929
|
+
buildRelativeUrl,
|
|
10930
|
+
runtimeCompat,
|
|
10931
|
+
plugins,
|
|
10932
|
+
mappings,
|
|
10933
|
+
assetsDirectory,
|
|
10934
|
+
base,
|
|
10935
|
+
ignore,
|
|
10936
|
+
|
|
10937
|
+
bundling,
|
|
10938
|
+
minification,
|
|
10939
|
+
versioning,
|
|
10940
|
+
|
|
10941
|
+
referenceAnalysis,
|
|
10942
|
+
nodeEsmResolution,
|
|
10943
|
+
packageConditions,
|
|
10944
|
+
magicExtensions,
|
|
10945
|
+
magicDirectoryIndex,
|
|
10946
|
+
directoryReferenceEffect,
|
|
10947
|
+
scenarioPlaceholders,
|
|
10948
|
+
injections,
|
|
10949
|
+
transpilation,
|
|
10950
|
+
|
|
10951
|
+
versioningMethod,
|
|
10952
|
+
versioningViaImportmap,
|
|
10953
|
+
versionLength,
|
|
10954
|
+
lineBreakNormalization,
|
|
10955
|
+
|
|
10956
|
+
http,
|
|
10957
|
+
|
|
10958
|
+
sourcemaps,
|
|
10959
|
+
sourcemapsSourcesContent,
|
|
10960
|
+
assetManifest,
|
|
10961
|
+
assetManifestFileRelativeUrl,
|
|
10962
|
+
} = {
|
|
10963
|
+
...entryPointDefaultParams,
|
|
10964
|
+
...entryPointParams,
|
|
10965
|
+
};
|
|
10966
|
+
|
|
10967
|
+
// param defaults and normalization
|
|
10968
|
+
{
|
|
10969
|
+
if (entryPointParams.buildRelativeUrl === undefined) {
|
|
10970
|
+
buildRelativeUrl = entryPointParams.buildRelativeUrl = sourceRelativeUrl;
|
|
10971
|
+
}
|
|
10972
|
+
const buildUrl = new URL(buildRelativeUrl, buildDirectoryUrl);
|
|
10973
|
+
entryPointParams.buildRelativeUrl = buildRelativeUrl = urlToRelativeUrl(
|
|
10974
|
+
buildUrl,
|
|
10975
|
+
buildDirectoryUrl,
|
|
10976
|
+
);
|
|
10977
|
+
if (entryPointParams.assetsDirectory === undefined) {
|
|
10978
|
+
const entryBuildUrl = new URL(buildRelativeUrl, buildDirectoryUrl).href;
|
|
10979
|
+
const entryBuildRelativeUrl = urlToRelativeUrl(
|
|
10980
|
+
entryBuildUrl,
|
|
10981
|
+
buildDirectoryUrl,
|
|
10982
|
+
);
|
|
10983
|
+
if (entryBuildRelativeUrl.includes("/")) {
|
|
10984
|
+
const assetDirectoryUrl = new URL("./", entryBuildUrl);
|
|
10985
|
+
assetsDirectory = urlToRelativeUrl(
|
|
10986
|
+
assetDirectoryUrl,
|
|
10987
|
+
buildDirectoryUrl,
|
|
10988
|
+
);
|
|
10989
|
+
} else {
|
|
10990
|
+
assetsDirectory = "";
|
|
10991
|
+
}
|
|
10992
|
+
}
|
|
10993
|
+
if (
|
|
10994
|
+
assetsDirectory &&
|
|
10995
|
+
assetsDirectory[assetsDirectory.length - 1] !== "/"
|
|
10996
|
+
) {
|
|
10997
|
+
assetsDirectory = `${assetsDirectory}/`;
|
|
10998
|
+
}
|
|
10999
|
+
if (entryPointParams.base === undefined) {
|
|
11000
|
+
base = someEntryPointUseNode ? "./" : "/";
|
|
11001
|
+
}
|
|
11002
|
+
if (entryPointParams.bundling === undefined) {
|
|
11003
|
+
bundling = true;
|
|
11004
|
+
}
|
|
11005
|
+
if (bundling === true) {
|
|
11006
|
+
bundling = {};
|
|
11007
|
+
}
|
|
11008
|
+
if (entryPointParams.minification === undefined) {
|
|
11009
|
+
minification = !someEntryPointUseNode;
|
|
11010
|
+
}
|
|
11011
|
+
if (minification === true) {
|
|
11012
|
+
minification = {};
|
|
11013
|
+
}
|
|
11014
|
+
if (entryPointParams.versioning === undefined) {
|
|
11015
|
+
versioning = !someEntryPointUseNode;
|
|
11016
|
+
}
|
|
11017
|
+
if (entryPointParams.versioningMethod === undefined) {
|
|
11018
|
+
versioningMethod = entryPointDefaultParams.versioningMethod;
|
|
11019
|
+
}
|
|
11020
|
+
if (entryPointParams.assetManifest === undefined) {
|
|
11021
|
+
assetManifest = versioningMethod === "filename";
|
|
11022
|
+
}
|
|
11023
|
+
}
|
|
11024
|
+
|
|
11025
|
+
const buildOperation = Abort.startOperation();
|
|
11026
|
+
buildOperation.addAbortSignal(signal);
|
|
11027
|
+
|
|
11028
|
+
const explicitJsModuleConversion =
|
|
11029
|
+
sourceRelativeUrl.includes("?js_module_fallback") ||
|
|
11030
|
+
sourceRelativeUrl.includes("?as_js_classic");
|
|
11031
|
+
const contextSharedDuringBuild = {
|
|
11032
|
+
buildStep: "craft",
|
|
11033
|
+
buildDirectoryUrl,
|
|
11034
|
+
assetsDirectory,
|
|
11035
|
+
versioning,
|
|
11036
|
+
versioningViaImportmap,
|
|
11037
|
+
};
|
|
11038
|
+
const rawKitchen = createKitchen({
|
|
11039
|
+
signal,
|
|
11040
|
+
logLevel: "warn",
|
|
11041
|
+
rootDirectoryUrl: sourceDirectoryUrl,
|
|
11042
|
+
ignore,
|
|
11043
|
+
// during first pass (craft) we keep "ignore:" when a reference is ignored
|
|
11044
|
+
// so that the second pass (shape) properly ignore those urls
|
|
11045
|
+
ignoreProtocol: "keep",
|
|
11046
|
+
build: true,
|
|
11047
|
+
runtimeCompat,
|
|
11048
|
+
initialContext: contextSharedDuringBuild,
|
|
11049
|
+
sourcemaps,
|
|
11050
|
+
sourcemapsSourcesContent,
|
|
11051
|
+
outDirectoryUrl: outDirectoryUrl
|
|
11052
|
+
? new URL("craft/", outDirectoryUrl)
|
|
11053
|
+
: undefined,
|
|
11054
|
+
});
|
|
11055
|
+
|
|
11056
|
+
let _getOtherEntryBuildInfo;
|
|
11057
|
+
const rawPluginStore = createPluginStore([
|
|
11058
|
+
...(mappings ? [jsenvPluginMappings(mappings)] : []),
|
|
11059
|
+
{
|
|
11060
|
+
name: "jsenv:other_entry_point_build_during_craft",
|
|
11061
|
+
fetchUrlContent: async (urlInfo) => {
|
|
11062
|
+
if (!_getOtherEntryBuildInfo) {
|
|
11063
|
+
return null;
|
|
11064
|
+
}
|
|
11065
|
+
const otherEntryBuildInfo = _getOtherEntryBuildInfo(urlInfo.url);
|
|
11066
|
+
if (!otherEntryBuildInfo) {
|
|
11067
|
+
return null;
|
|
11068
|
+
}
|
|
11069
|
+
urlInfo.otherEntryBuildInfo = otherEntryBuildInfo;
|
|
11070
|
+
return {
|
|
11071
|
+
type: "entry_build", // this ensure the rest of jsenv do not try to scan or modify the content
|
|
11072
|
+
content: "", // we don't know yet the content it will be known later
|
|
11073
|
+
filenameHint: otherEntryBuildInfo.entryUrlInfo.filenameHint,
|
|
11074
|
+
};
|
|
11075
|
+
},
|
|
11076
|
+
},
|
|
11077
|
+
...plugins,
|
|
11078
|
+
...(bundling ? [jsenvPluginBundling(bundling)] : []),
|
|
11079
|
+
...(minification ? [jsenvPluginMinification(minification)] : []),
|
|
11080
|
+
...getCorePlugins({
|
|
11081
|
+
rootDirectoryUrl: sourceDirectoryUrl,
|
|
11082
|
+
runtimeCompat,
|
|
11083
|
+
referenceAnalysis,
|
|
11084
|
+
nodeEsmResolution,
|
|
11085
|
+
packageConditions,
|
|
11086
|
+
magicExtensions,
|
|
11087
|
+
magicDirectoryIndex,
|
|
11088
|
+
directoryReferenceEffect,
|
|
11089
|
+
injections,
|
|
11090
|
+
transpilation: {
|
|
11091
|
+
babelHelpersAsImport: !explicitJsModuleConversion,
|
|
11092
|
+
...transpilation,
|
|
11093
|
+
jsModuleFallback: false,
|
|
11094
|
+
},
|
|
11095
|
+
inlining: false,
|
|
11096
|
+
http,
|
|
11097
|
+
scenarioPlaceholders,
|
|
11098
|
+
}),
|
|
11099
|
+
]);
|
|
11100
|
+
const rawPluginController = createPluginController(
|
|
11101
|
+
rawPluginStore,
|
|
11102
|
+
rawKitchen,
|
|
11103
|
+
);
|
|
11104
|
+
rawKitchen.setPluginController(rawPluginController);
|
|
11105
|
+
|
|
11106
|
+
const rawRootUrlInfo = rawKitchen.graph.rootUrlInfo;
|
|
11107
|
+
let entryReference;
|
|
11108
|
+
await rawRootUrlInfo.dependencies.startCollecting(() => {
|
|
11109
|
+
entryReference = rawRootUrlInfo.dependencies.found({
|
|
11110
|
+
trace: { message: `"${sourceRelativeUrl}" from "entryPoints"` },
|
|
11111
|
+
isEntryPoint: true,
|
|
11112
|
+
type: "entry_point",
|
|
11113
|
+
specifier: sourceRelativeUrl,
|
|
11114
|
+
filenameHint: buildRelativeUrl,
|
|
11115
|
+
});
|
|
11116
|
+
});
|
|
11117
|
+
|
|
11118
|
+
return {
|
|
11119
|
+
entryReference,
|
|
11120
|
+
buildEntryPoint: async ({ getOtherEntryBuildInfo }) => {
|
|
11121
|
+
{
|
|
11122
|
+
_getOtherEntryBuildInfo = getOtherEntryBuildInfo;
|
|
11123
|
+
if (outDirectoryUrl) {
|
|
11124
|
+
await ensureEmptyDirectory(new URL(`craft/`, outDirectoryUrl));
|
|
11125
|
+
}
|
|
11126
|
+
await rawRootUrlInfo.cookDependencies({ operation: buildOperation });
|
|
11127
|
+
}
|
|
11128
|
+
|
|
11129
|
+
const finalKitchen = createKitchen({
|
|
11130
|
+
name: "shape",
|
|
11131
|
+
logLevel: "warn",
|
|
11132
|
+
rootDirectoryUrl: sourceDirectoryUrl,
|
|
11133
|
+
// here most plugins are not there
|
|
11134
|
+
// - no external plugin
|
|
11135
|
+
// - no plugin putting reference.mustIgnore on https urls
|
|
11136
|
+
// At this stage it's only about redirecting urls to the build directory
|
|
11137
|
+
// consequently only a subset or urls are supported
|
|
11138
|
+
supportedProtocols: ["file:", "data:", "virtual:", "ignore:"],
|
|
11139
|
+
ignore,
|
|
11140
|
+
ignoreProtocol: "remove",
|
|
11141
|
+
build: true,
|
|
11142
|
+
runtimeCompat,
|
|
11143
|
+
initialContext: contextSharedDuringBuild,
|
|
11144
|
+
sourcemaps,
|
|
11145
|
+
sourcemapsComment: "relative",
|
|
11146
|
+
sourcemapsSourcesContent,
|
|
11147
|
+
outDirectoryUrl: outDirectoryUrl
|
|
11148
|
+
? new URL("shape/", outDirectoryUrl)
|
|
11149
|
+
: undefined,
|
|
11150
|
+
});
|
|
11151
|
+
const buildSpecifierManager = createBuildSpecifierManager({
|
|
11152
|
+
rawKitchen,
|
|
11153
|
+
finalKitchen,
|
|
11154
|
+
logger: createLogger({ logLevel: "warn" }),
|
|
11155
|
+
sourceDirectoryUrl,
|
|
11156
|
+
buildDirectoryUrl,
|
|
11157
|
+
base,
|
|
11158
|
+
assetsDirectory,
|
|
11159
|
+
buildUrlsGenerator,
|
|
11160
|
+
|
|
11161
|
+
versioning,
|
|
11162
|
+
versioningMethod,
|
|
11163
|
+
versionLength,
|
|
11164
|
+
canUseImportmap:
|
|
11165
|
+
versioningViaImportmap &&
|
|
11166
|
+
rawKitchen.graph.getUrlInfo(entryReference.url).type === "html" &&
|
|
11167
|
+
rawKitchen.context.isSupportedOnCurrentClients("importmap"),
|
|
11168
|
+
});
|
|
11169
|
+
const finalPluginStore = createPluginStore([
|
|
11170
|
+
jsenvPluginReferenceAnalysis({
|
|
11171
|
+
...referenceAnalysis,
|
|
11172
|
+
fetchInlineUrls: false,
|
|
11173
|
+
// inlineContent: false,
|
|
11174
|
+
}),
|
|
11175
|
+
jsenvPluginDirectoryReferenceEffect(directoryReferenceEffect, {
|
|
11176
|
+
rootDirectoryUrl: sourceDirectoryUrl,
|
|
11177
|
+
}),
|
|
11178
|
+
...(lineBreakNormalization
|
|
11179
|
+
? [jsenvPluginLineBreakNormalization()]
|
|
11180
|
+
: []),
|
|
11181
|
+
jsenvPluginJsModuleFallback({
|
|
11182
|
+
remapImportSpecifier: (specifier, parentUrl) => {
|
|
11183
|
+
return buildSpecifierManager.remapPlaceholder(specifier, parentUrl);
|
|
11184
|
+
},
|
|
11185
|
+
}),
|
|
11186
|
+
jsenvPluginInlining(),
|
|
11187
|
+
{
|
|
11188
|
+
name: "jsenv:optimize",
|
|
11189
|
+
appliesDuring: "build",
|
|
11190
|
+
transformUrlContent: async (urlInfo) => {
|
|
11191
|
+
await rawKitchen.pluginController.callAsyncHooks(
|
|
11192
|
+
"optimizeUrlContent",
|
|
11193
|
+
urlInfo,
|
|
11194
|
+
(optimizeReturnValue) => {
|
|
11195
|
+
urlInfo.mutateContent(optimizeReturnValue);
|
|
11196
|
+
},
|
|
11197
|
+
);
|
|
11198
|
+
},
|
|
11199
|
+
},
|
|
11200
|
+
buildSpecifierManager.jsenvPluginMoveToBuildDirectory,
|
|
11201
|
+
]);
|
|
11202
|
+
const finalPluginController = createPluginController(
|
|
11203
|
+
finalPluginStore,
|
|
11204
|
+
finalKitchen,
|
|
11205
|
+
{
|
|
11206
|
+
initialPuginsMeta: rawKitchen.pluginController.pluginsMeta,
|
|
11207
|
+
},
|
|
11208
|
+
);
|
|
11209
|
+
finalKitchen.setPluginController(finalPluginController);
|
|
11210
|
+
|
|
11211
|
+
bundle: {
|
|
11212
|
+
const bundlerMap = new Map();
|
|
11213
|
+
for (const plugin of rawKitchen.pluginController.activePlugins) {
|
|
11214
|
+
const bundle = plugin.bundle;
|
|
11215
|
+
if (!bundle) {
|
|
11216
|
+
continue;
|
|
11217
|
+
}
|
|
11218
|
+
if (typeof bundle !== "object") {
|
|
11219
|
+
throw new Error(
|
|
11220
|
+
`bundle must be an object, found "${bundle}" on plugin named "${plugin.name}"`,
|
|
11221
|
+
);
|
|
11222
|
+
}
|
|
11223
|
+
for (const type of Object.keys(bundle)) {
|
|
11224
|
+
const bundleFunction = bundle[type];
|
|
11225
|
+
if (!bundleFunction) {
|
|
11226
|
+
continue;
|
|
11227
|
+
}
|
|
11228
|
+
if (bundlerMap.has(type)) {
|
|
11229
|
+
// first plugin to define a bundle hook wins
|
|
11230
|
+
continue;
|
|
11231
|
+
}
|
|
11232
|
+
bundlerMap.set(type, {
|
|
11233
|
+
plugin,
|
|
11234
|
+
bundleFunction: bundle[type],
|
|
11235
|
+
urlInfoMap: new Map(),
|
|
11236
|
+
});
|
|
11237
|
+
}
|
|
11238
|
+
}
|
|
11239
|
+
if (bundlerMap.size === 0) {
|
|
11240
|
+
break bundle;
|
|
11241
|
+
}
|
|
11242
|
+
const addToBundlerIfAny = (rawUrlInfo) => {
|
|
11243
|
+
const bundler = bundlerMap.get(rawUrlInfo.type);
|
|
11244
|
+
if (bundler) {
|
|
11245
|
+
bundler.urlInfoMap.set(rawUrlInfo.url, rawUrlInfo);
|
|
11246
|
+
}
|
|
11247
|
+
};
|
|
11248
|
+
// ignore unused urls thanks to "forEachUrlInfoStronglyReferenced"
|
|
11249
|
+
// it avoid bundling things that are not actually used
|
|
11250
|
+
// happens for:
|
|
11251
|
+
// - js import assertions
|
|
11252
|
+
// - conversion to js classic using ?as_js_classic or ?js_module_fallback
|
|
11253
|
+
GRAPH_VISITOR.forEachUrlInfoStronglyReferenced(
|
|
11254
|
+
rawKitchen.graph.rootUrlInfo,
|
|
11255
|
+
(rawUrlInfo) => {
|
|
11256
|
+
if (rawUrlInfo.isEntryPoint) {
|
|
11257
|
+
addToBundlerIfAny(rawUrlInfo);
|
|
11258
|
+
}
|
|
11259
|
+
if (rawUrlInfo.type === "html") {
|
|
11260
|
+
for (const referenceToOther of rawUrlInfo.referenceToOthersSet) {
|
|
11261
|
+
if (
|
|
11262
|
+
referenceToOther.isResourceHint &&
|
|
11263
|
+
referenceToOther.expectedType === "js_module"
|
|
11264
|
+
) {
|
|
11265
|
+
const referencedUrlInfo = referenceToOther.urlInfo;
|
|
11266
|
+
if (
|
|
11267
|
+
referencedUrlInfo &&
|
|
11268
|
+
// something else than the resource hint is using this url
|
|
11269
|
+
referencedUrlInfo.referenceFromOthersSet.size > 0
|
|
11270
|
+
) {
|
|
11271
|
+
addToBundlerIfAny(referencedUrlInfo);
|
|
11272
|
+
continue;
|
|
11273
|
+
}
|
|
11274
|
+
}
|
|
11275
|
+
if (referenceToOther.isWeak) {
|
|
11276
|
+
continue;
|
|
11277
|
+
}
|
|
11278
|
+
const referencedUrlInfo = referenceToOther.urlInfo;
|
|
11279
|
+
if (referencedUrlInfo.isInline) {
|
|
11280
|
+
if (referencedUrlInfo.type !== "js_module") {
|
|
11281
|
+
continue;
|
|
11282
|
+
}
|
|
11283
|
+
addToBundlerIfAny(referencedUrlInfo);
|
|
11284
|
+
continue;
|
|
11285
|
+
}
|
|
11286
|
+
addToBundlerIfAny(referencedUrlInfo);
|
|
11287
|
+
}
|
|
11288
|
+
return;
|
|
11289
|
+
}
|
|
11290
|
+
// File referenced with
|
|
11291
|
+
// - new URL("./file.js", import.meta.url)
|
|
11292
|
+
// - import.meta.resolve("./file.js")
|
|
11293
|
+
// are entry points that should be bundled
|
|
11294
|
+
// For instance we will bundle service worker/workers detected like this
|
|
11295
|
+
if (rawUrlInfo.type === "js_module") {
|
|
11296
|
+
for (const referenceToOther of rawUrlInfo.referenceToOthersSet) {
|
|
11297
|
+
if (
|
|
11298
|
+
referenceToOther.type === "js_url" ||
|
|
11299
|
+
referenceToOther.subtype === "import_meta_resolve"
|
|
11300
|
+
) {
|
|
11301
|
+
const referencedUrlInfo = referenceToOther.urlInfo;
|
|
11302
|
+
let isAlreadyBundled = false;
|
|
11303
|
+
for (const referenceFromOther of referencedUrlInfo.referenceFromOthersSet) {
|
|
11304
|
+
if (referenceFromOther.url === referencedUrlInfo.url) {
|
|
11305
|
+
if (
|
|
11306
|
+
referenceFromOther.subtype === "import_dynamic" ||
|
|
11307
|
+
referenceFromOther.type === "script"
|
|
11308
|
+
) {
|
|
11309
|
+
isAlreadyBundled = true;
|
|
11310
|
+
break;
|
|
11311
|
+
}
|
|
11312
|
+
}
|
|
11313
|
+
}
|
|
11314
|
+
if (!isAlreadyBundled) {
|
|
11315
|
+
addToBundlerIfAny(referencedUrlInfo);
|
|
11316
|
+
}
|
|
11317
|
+
continue;
|
|
11318
|
+
}
|
|
11319
|
+
if (referenceToOther.type === "js_inline_content") ;
|
|
11320
|
+
}
|
|
11321
|
+
}
|
|
11322
|
+
},
|
|
11323
|
+
);
|
|
11324
|
+
for (const [, bundler] of bundlerMap) {
|
|
11325
|
+
const urlInfosToBundle = Array.from(bundler.urlInfoMap.values());
|
|
11326
|
+
if (urlInfosToBundle.length === 0) {
|
|
11327
|
+
continue;
|
|
11328
|
+
}
|
|
11329
|
+
await buildSpecifierManager.applyBundling({
|
|
11330
|
+
bundler,
|
|
11331
|
+
urlInfosToBundle,
|
|
11332
|
+
});
|
|
11333
|
+
}
|
|
11334
|
+
}
|
|
11335
|
+
|
|
11336
|
+
{
|
|
11337
|
+
finalKitchen.context.buildStep = "shape";
|
|
11338
|
+
if (outDirectoryUrl) {
|
|
11339
|
+
await ensureEmptyDirectory(new URL(`shape/`, outDirectoryUrl));
|
|
11340
|
+
}
|
|
11341
|
+
const finalRootUrlInfo = finalKitchen.graph.rootUrlInfo;
|
|
11342
|
+
await finalRootUrlInfo.dependencies.startCollecting(() => {
|
|
11343
|
+
finalRootUrlInfo.dependencies.found({
|
|
11344
|
+
trace: { message: `entryPoint` },
|
|
11345
|
+
isEntryPoint: true,
|
|
11346
|
+
type: "entry_point",
|
|
11347
|
+
specifier: entryReference.url,
|
|
11348
|
+
});
|
|
11349
|
+
});
|
|
11350
|
+
await finalRootUrlInfo.cookDependencies({
|
|
11351
|
+
operation: buildOperation,
|
|
11352
|
+
});
|
|
11353
|
+
}
|
|
11354
|
+
|
|
11355
|
+
{
|
|
11356
|
+
finalKitchen.context.buildStep = "refine";
|
|
11357
|
+
|
|
11358
|
+
const htmlRefineSet = new Set();
|
|
11359
|
+
const registerHtmlRefine = (htmlRefine) => {
|
|
11360
|
+
htmlRefineSet.add(htmlRefine);
|
|
11361
|
+
};
|
|
11362
|
+
|
|
11363
|
+
{
|
|
11364
|
+
await buildSpecifierManager.replacePlaceholders();
|
|
11365
|
+
}
|
|
11366
|
+
|
|
11367
|
+
/*
|
|
11368
|
+
* Update <link rel="preload"> and friends after build (once we know everything)
|
|
11369
|
+
* - Used to remove resource hint targeting an url that is no longer used:
|
|
11370
|
+
* - because of bundlings
|
|
11371
|
+
* - because of import assertions transpilation (file is inlined into JS)
|
|
11372
|
+
*/
|
|
11373
|
+
{
|
|
11374
|
+
buildSpecifierManager.prepareResyncResourceHints({
|
|
11375
|
+
registerHtmlRefine,
|
|
11376
|
+
});
|
|
11377
|
+
}
|
|
11378
|
+
|
|
11379
|
+
{
|
|
11380
|
+
GRAPH_VISITOR.forEach(finalKitchen.graph, (urlInfo) => {
|
|
11381
|
+
if (!urlInfo.url.startsWith("file:")) {
|
|
11382
|
+
return;
|
|
11383
|
+
}
|
|
11384
|
+
if (urlInfo.type !== "html") {
|
|
11385
|
+
return;
|
|
11386
|
+
}
|
|
11387
|
+
const htmlAst = parseHtml({
|
|
11388
|
+
html: urlInfo.content,
|
|
11389
|
+
url: urlInfo.url,
|
|
11390
|
+
storeOriginalPositions: false,
|
|
11391
|
+
});
|
|
11392
|
+
for (const htmlRefine of htmlRefineSet) {
|
|
11393
|
+
const htmlMutationCallbackSet = new Set();
|
|
11394
|
+
const registerHtmlMutation = (callback) => {
|
|
11395
|
+
htmlMutationCallbackSet.add(callback);
|
|
11396
|
+
};
|
|
11397
|
+
htmlRefine(htmlAst, { registerHtmlMutation });
|
|
11398
|
+
for (const htmlMutationCallback of htmlMutationCallbackSet) {
|
|
11399
|
+
htmlMutationCallback();
|
|
11400
|
+
}
|
|
11401
|
+
}
|
|
11402
|
+
// cleanup jsenv attributes from html as a last step
|
|
11403
|
+
urlInfo.content = stringifyHtmlAst(htmlAst, {
|
|
11404
|
+
cleanupJsenvAttributes: true,
|
|
11405
|
+
cleanupPositionAttributes: true,
|
|
11406
|
+
});
|
|
11407
|
+
});
|
|
11408
|
+
}
|
|
11409
|
+
|
|
11410
|
+
{
|
|
11411
|
+
const inject =
|
|
11412
|
+
buildSpecifierManager.prepareServiceWorkerUrlInjection();
|
|
11413
|
+
if (inject) {
|
|
11414
|
+
await inject();
|
|
11415
|
+
buildOperation.throwIfAborted();
|
|
11416
|
+
}
|
|
11417
|
+
}
|
|
11418
|
+
}
|
|
11419
|
+
const {
|
|
11420
|
+
buildFileContents,
|
|
11421
|
+
buildFileVersions,
|
|
11422
|
+
buildInlineContents,
|
|
11423
|
+
buildManifest,
|
|
11424
|
+
} = buildSpecifierManager.getBuildInfo();
|
|
11425
|
+
if (versioning && assetManifest && Object.keys(buildManifest).length) {
|
|
11426
|
+
buildFileContents[assetManifestFileRelativeUrl] = JSON.stringify(
|
|
11427
|
+
buildManifest,
|
|
11428
|
+
null,
|
|
11429
|
+
" ",
|
|
11430
|
+
);
|
|
11431
|
+
}
|
|
11432
|
+
return {
|
|
11433
|
+
buildFileContents,
|
|
11434
|
+
buildFileVersions,
|
|
11435
|
+
buildInlineContents,
|
|
11436
|
+
buildManifest,
|
|
11437
|
+
};
|
|
11438
|
+
},
|
|
11439
|
+
};
|
|
11440
|
+
};
|
|
11441
|
+
|
|
11442
|
+
const isBareSpecifier = (specifier) => {
|
|
11443
|
+
if (
|
|
11444
|
+
specifier[0] === "/" ||
|
|
11445
|
+
specifier.startsWith("./") ||
|
|
11446
|
+
specifier.startsWith("../")
|
|
11447
|
+
) {
|
|
11448
|
+
return false;
|
|
11449
|
+
}
|
|
11450
|
+
try {
|
|
11451
|
+
// eslint-disable-next-line no-new
|
|
11452
|
+
new URL(specifier);
|
|
11453
|
+
return false;
|
|
11454
|
+
} catch {
|
|
11455
|
+
return true;
|
|
11456
|
+
}
|
|
11457
|
+
};
|
|
11458
|
+
|
|
10768
11459
|
export { build };
|