@jsenv/core 41.4.18 → 41.4.20
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 +121 -41
- package/dist/build/jsenv_core_packages.js +3 -187
- package/dist/js/client_reporter.js +12 -1
- package/dist/start_dev_server/start_dev_server.js +33 -13
- package/package.json +4 -4
- package/src/build/build.js +66 -15
- package/src/build/build_content_report.js +24 -15
- package/src/build/build_specifier_manager.js +2 -2
- package/src/dev/dev_server_plugins/dev_server_plugin_omega_error_handler.js +4 -1
- package/src/kitchen/kitchen.js +6 -0
- package/src/kitchen/prepend_content.js +4 -4
- package/src/kitchen/url_graph/url_info_transformations.js +16 -6
- package/src/plugins/client_monitoring/client/client_reporter.js +12 -1
- package/src/plugins/import_meta_css/jsenv_plugin_import_meta_css.js +2 -0
- package/src/plugins/reference_analysis/js/jsenv_plugin_js_reference_analysis.js +1 -2
package/dist/build/build.js
CHANGED
|
@@ -4,7 +4,7 @@ import { jsenvPluginMinification } from "@jsenv/plugin-minification";
|
|
|
4
4
|
import { jsenvPluginTranspilation, jsenvPluginJsModuleFallback } from "@jsenv/plugin-transpilation";
|
|
5
5
|
import { memoryUsage } from "node:process";
|
|
6
6
|
import { readFileSync, existsSync, realpathSync, readdirSync, lstatSync, statSync } from "node:fs";
|
|
7
|
-
import { lookupPackageDirectory, urlIsOrIsInsideOf, registerDirectoryLifecycle, urlToRelativeUrl, createDetailedMessage, stringifyUrlSite, generateContentFrame, validateResponseIntegrity, ensureWindowsDriveLetter, setUrlFilename, moveUrl, getCallerPosition, urlToBasename, urlToExtension, asSpecifierWithoutSearch, asUrlWithoutSearch, injectQueryParamsIntoSpecifier, bufferToEtag, isFileSystemPath, urlToPathname, setUrlBasename, urlToFileSystemPath, writeFileSync, createLogger, URL_META, applyNodeEsmResolution, normalizeUrl, ANSI, RUNTIME_COMPAT, CONTENT_TYPE, readPackageAtOrNull, urlToFilename, DATA_URL, errorToHTML, normalizeImportMap, composeTwoImportMaps, resolveImport, JS_QUOTES, readCustomConditionsFromProcessArgs, collectFiles, readEntryStatSync, applyFileSystemMagicResolution, getExtensionsToTry, ensurePathnameTrailingSlash, compareFileUrls, setUrlExtension, isSpecifierForNodeBuiltin, injectQueryParams, renderDetails, humanizeDuration, humanizeFileSize, renderTable, renderBigSection, distributePercentages, humanizeMemory, comparePathnames, UNICODE, escapeRegexpSpecialChars, injectQueryParamIntoSpecifierWithoutEncoding, renderUrlOrRelativeUrlFilename, assertAndNormalizeDirectoryUrl, Abort, raceProcessTeardownEvents,
|
|
7
|
+
import { lookupPackageDirectory, urlIsOrIsInsideOf, registerDirectoryLifecycle, urlToRelativeUrl, createDetailedMessage, stringifyUrlSite, generateContentFrame, validateResponseIntegrity, ensureWindowsDriveLetter, setUrlFilename, moveUrl, getCallerPosition, urlToBasename, urlToExtension, asSpecifierWithoutSearch, asUrlWithoutSearch, injectQueryParamsIntoSpecifier, bufferToEtag, isFileSystemPath, urlToPathname, setUrlBasename, urlToFileSystemPath, writeFileSync, createLogger, URL_META, applyNodeEsmResolution, normalizeUrl, ANSI, RUNTIME_COMPAT, CONTENT_TYPE, readPackageAtOrNull, urlToFilename, DATA_URL, errorToHTML, normalizeImportMap, composeTwoImportMaps, resolveImport, JS_QUOTES, readCustomConditionsFromProcessArgs, collectFiles, readEntryStatSync, applyFileSystemMagicResolution, getExtensionsToTry, ensurePathnameTrailingSlash, compareFileUrls, setUrlExtension, isSpecifierForNodeBuiltin, injectQueryParams, renderDetails, humanizeDuration, humanizeFileSize, renderTable, renderBigSection, distributePercentages, humanizeMemory, comparePathnames, UNICODE, escapeRegexpSpecialChars, injectQueryParamIntoSpecifierWithoutEncoding, renderUrlOrRelativeUrlFilename, assertAndNormalizeDirectoryUrl, Abort, raceProcessTeardownEvents, startMonitoringMemoryUsage, inferRuntimeCompatFromClosestPackage, browserDefaultRuntimeCompat, nodeDefaultRuntimeCompat, clearDirectorySync, createTaskLog, createLookupPackageDirectory, ensureEmptyDirectory, updateJsonFileSync, createDynamicLog } from "./jsenv_core_packages.js";
|
|
8
8
|
import { pathToFileURL } from "node:url";
|
|
9
9
|
import { generateSourcemapFileUrl, createMagicSource, composeTwoSourcemaps, generateSourcemapDataUrl, SOURCEMAP } from "@jsenv/sourcemap";
|
|
10
10
|
import { createPluginsController } from "@jsenv/server/src/plugins_controller.js";
|
|
@@ -910,10 +910,9 @@ const prependJsClassicInJsClassic = (jsUrlInfo, urlInfoToPrepend) => {
|
|
|
910
910
|
const magicSource = createMagicSource(jsUrlInfo.content);
|
|
911
911
|
magicSource.prepend(`${urlInfoToPrepend.content}\n\n`);
|
|
912
912
|
const magicResult = magicSource.toContentAndSourcemap();
|
|
913
|
-
const sourcemap =
|
|
914
|
-
jsUrlInfo.sourcemap,
|
|
915
|
-
|
|
916
|
-
);
|
|
913
|
+
const sourcemap = jsUrlInfo.context.sourcemapsEnabled
|
|
914
|
+
? composeTwoSourcemaps(jsUrlInfo.sourcemap, magicResult.sourcemap)
|
|
915
|
+
: null;
|
|
917
916
|
jsUrlInfo.mutateContent({
|
|
918
917
|
content: magicResult.content,
|
|
919
918
|
sourcemap,
|
|
@@ -931,6 +930,7 @@ const prependJsClassicInJsModule = async (jsUrlInfo, urlInfoToPrepend) => {
|
|
|
931
930
|
input: jsUrlInfo.content,
|
|
932
931
|
inputIsJsModule: true,
|
|
933
932
|
inputUrl: jsUrlInfo.originalUrl,
|
|
933
|
+
options: { sourceMaps: jsUrlInfo.context.sourcemapsEnabled },
|
|
934
934
|
});
|
|
935
935
|
jsUrlInfo.mutateContent({
|
|
936
936
|
content: code,
|
|
@@ -2920,7 +2920,6 @@ const createUrlInfoTransformer = ({
|
|
|
2920
2920
|
contentAst, // undefined most of the time
|
|
2921
2921
|
contentEtag, // in practice always undefined
|
|
2922
2922
|
contentLength,
|
|
2923
|
-
sourcemap,
|
|
2924
2923
|
sourcemapIsWrong,
|
|
2925
2924
|
contentInjections,
|
|
2926
2925
|
} = transformations;
|
|
@@ -2947,11 +2946,14 @@ const createUrlInfoTransformer = ({
|
|
|
2947
2946
|
contentLength,
|
|
2948
2947
|
});
|
|
2949
2948
|
}
|
|
2950
|
-
|
|
2951
|
-
|
|
2952
|
-
|
|
2953
|
-
|
|
2954
|
-
|
|
2949
|
+
// "sourcemap" is read last, and only when it will be used: a plugin can
|
|
2950
|
+
// hand it back as a getter that generates the map on first read, so that
|
|
2951
|
+
// nothing is generated for a kitchen that throws sourcemaps away
|
|
2952
|
+
const sourcemap =
|
|
2953
|
+
mayHaveSourcemap(urlInfo) && shouldHandleSourcemap(urlInfo)
|
|
2954
|
+
? transformations.sourcemap
|
|
2955
|
+
: null;
|
|
2956
|
+
if (sourcemap) {
|
|
2955
2957
|
const sourcemapNormalized = normalizeSourcemap(urlInfo, sourcemap);
|
|
2956
2958
|
let currentSourcemap = urlInfo.sourcemap;
|
|
2957
2959
|
const finalSourcemap = composeTwoSourcemaps(
|
|
@@ -2984,6 +2986,14 @@ const createUrlInfoTransformer = ({
|
|
|
2984
2986
|
writeInsideOutDirectory(urlInfo);
|
|
2985
2987
|
};
|
|
2986
2988
|
|
|
2989
|
+
// Written synchronously on purpose, and measured: async is the tempting
|
|
2990
|
+
// choice, but here it loses. A cold load cooks hundreds of files; their
|
|
2991
|
+
// synchronous writes block the event loop ~160ms in total, while
|
|
2992
|
+
// asynchronous writes queue in the threadpool behind tens of MB of content
|
|
2993
|
+
// and sourcemaps, and a response that waits for its own write then waits
|
|
2994
|
+
// ~36ms on average (18s summed over 500 responses). Not waiting is not an
|
|
2995
|
+
// option either: the last write lands after the test that cooked it has
|
|
2996
|
+
// ended, and the side-effect snapshots lose it.
|
|
2987
2997
|
const writeInsideOutDirectory = (urlInfo) => {
|
|
2988
2998
|
// writing result inside ".jsenv" directory (debug purposes)
|
|
2989
2999
|
if (!outDirectoryUrl) {
|
|
@@ -3303,6 +3313,12 @@ const createKitchen = ({
|
|
|
3303
3313
|
INJECTIONS,
|
|
3304
3314
|
getPluginMeta: null,
|
|
3305
3315
|
sourcemaps,
|
|
3316
|
+
// a plugin producing a sourcemap can skip the work when it would be
|
|
3317
|
+
// thrown away (see shouldHandleSourcemap in url_info_transformations.js)
|
|
3318
|
+
sourcemapsEnabled:
|
|
3319
|
+
sourcemaps === "inline" ||
|
|
3320
|
+
sourcemaps === "file" ||
|
|
3321
|
+
sourcemaps === "programmatic",
|
|
3306
3322
|
outDirectoryUrl,
|
|
3307
3323
|
},
|
|
3308
3324
|
resolve: (specifier, importer = rootDirectoryUrl) => {
|
|
@@ -5772,8 +5788,7 @@ const parseAndTransformJsReferences = async (
|
|
|
5772
5788
|
for (const sequentialAction of sequentialActions) {
|
|
5773
5789
|
await sequentialAction();
|
|
5774
5790
|
}
|
|
5775
|
-
|
|
5776
|
-
return { content, sourcemap };
|
|
5791
|
+
return magicSource.toContentAndSourcemap();
|
|
5777
5792
|
};
|
|
5778
5793
|
|
|
5779
5794
|
const jsenvPluginReferenceExpectedTypes = () => {
|
|
@@ -8327,6 +8342,8 @@ const jsenvPluginImportMetaCss = () => {
|
|
|
8327
8342
|
inputIsJsModule: true,
|
|
8328
8343
|
inputUrl: urlInfo.originalUrl,
|
|
8329
8344
|
outputUrl: urlInfo.generatedUrl,
|
|
8345
|
+
// the map would be dropped: the content sent back carries none
|
|
8346
|
+
options: { sourceMaps: false },
|
|
8330
8347
|
});
|
|
8331
8348
|
if (code === urlInfo.content) {
|
|
8332
8349
|
// all assignments were already in array form (pre-built file) — nothing to do
|
|
@@ -10165,11 +10182,12 @@ const getCorePlugins = ({
|
|
|
10165
10182
|
];
|
|
10166
10183
|
};
|
|
10167
10184
|
|
|
10168
|
-
|
|
10169
|
-
|
|
10170
|
-
|
|
10171
|
-
|
|
10172
|
-
|
|
10185
|
+
// a phase can be a few milliseconds long (refine, mostly): shown as such
|
|
10186
|
+
const humanizePhaseDuration = (ms) => {
|
|
10187
|
+
if (ms < 1000) {
|
|
10188
|
+
return `${Math.round(ms)}ms`;
|
|
10189
|
+
}
|
|
10190
|
+
return humanizeDuration(ms, { short: true });
|
|
10173
10191
|
};
|
|
10174
10192
|
const humanizeProcessMemoryUsage = (value) => {
|
|
10175
10193
|
return humanizeMemory(value, { short: true, decimals: 0 });
|
|
@@ -10178,7 +10196,8 @@ const renderBuildDoneLog = ({
|
|
|
10178
10196
|
entryPointArray,
|
|
10179
10197
|
duration,
|
|
10180
10198
|
buildFileContents,
|
|
10181
|
-
|
|
10199
|
+
cpuUsage,
|
|
10200
|
+
phaseTimings,
|
|
10182
10201
|
processMemoryUsage,
|
|
10183
10202
|
}) => {
|
|
10184
10203
|
const buildContentReport = createBuildContentReport(buildFileContents);
|
|
@@ -10193,15 +10212,10 @@ const renderBuildDoneLog = ({
|
|
|
10193
10212
|
title = `build done (${entryPointCount} entry points)`;
|
|
10194
10213
|
}
|
|
10195
10214
|
|
|
10196
|
-
// cpu
|
|
10197
|
-
|
|
10198
|
-
|
|
10199
|
-
|
|
10200
|
-
med: humanizeProcessCpuUsage(processCpuUsage.median),
|
|
10201
|
-
min: humanizeProcessCpuUsage(processCpuUsage.min),
|
|
10202
|
-
max: humanizeProcessCpuUsage(processCpuUsage.max),
|
|
10203
|
-
});
|
|
10204
|
-
lines.push(cpuUsageLine);
|
|
10215
|
+
// cpu: the process cpu time over the build duration, 100% being one core
|
|
10216
|
+
// busy the whole time (more when a native module works on other threads)
|
|
10217
|
+
const cpuMs = (cpuUsage.user + cpuUsage.system) / 1000;
|
|
10218
|
+
lines.push(`cpu: ${Math.round((cpuMs / duration) * 100)}%`);
|
|
10205
10219
|
|
|
10206
10220
|
// memory usage
|
|
10207
10221
|
let memoryUsageLine = "memory: ";
|
|
@@ -10216,6 +10230,16 @@ const renderBuildDoneLog = ({
|
|
|
10216
10230
|
// duration
|
|
10217
10231
|
let durationLine = `duration: `;
|
|
10218
10232
|
durationLine += humanizeDuration(duration, { short: true });
|
|
10233
|
+
if (phaseTimings) {
|
|
10234
|
+
durationLine += renderDetails(
|
|
10235
|
+
Object.fromEntries(
|
|
10236
|
+
Object.keys(phaseTimings).map((phaseName) => [
|
|
10237
|
+
phaseName,
|
|
10238
|
+
humanizePhaseDuration(phaseTimings[phaseName]),
|
|
10239
|
+
]),
|
|
10240
|
+
),
|
|
10241
|
+
);
|
|
10242
|
+
}
|
|
10219
10243
|
lines.push(durationLine);
|
|
10220
10244
|
|
|
10221
10245
|
// content
|
|
@@ -10406,6 +10430,8 @@ const createBuildContentReport = (buildFileContents) => {
|
|
|
10406
10430
|
};
|
|
10407
10431
|
|
|
10408
10432
|
const determineCategory = (buildRelativeUrl) => {
|
|
10433
|
+
// a versioned url ("main.js?v=abc") is categorized by its file
|
|
10434
|
+
buildRelativeUrl = buildRelativeUrl.replace(/[?#].*$/, "");
|
|
10409
10435
|
if (buildRelativeUrl.endsWith(".map")) {
|
|
10410
10436
|
return "sourcemap";
|
|
10411
10437
|
}
|
|
@@ -11332,7 +11358,7 @@ const createBuildSpecifierManager = ({
|
|
|
11332
11358
|
}
|
|
11333
11359
|
if (mayUsePlaceholder(urlInfo)) {
|
|
11334
11360
|
const contentBeforeReplace = urlInfo.content;
|
|
11335
|
-
const
|
|
11361
|
+
const replaceResult = placeholderAPI.replaceAll(
|
|
11336
11362
|
contentBeforeReplace,
|
|
11337
11363
|
(placeholder) => {
|
|
11338
11364
|
const reference = placeholderToReferenceMap.get(placeholder);
|
|
@@ -11340,7 +11366,7 @@ const createBuildSpecifierManager = ({
|
|
|
11340
11366
|
return value;
|
|
11341
11367
|
},
|
|
11342
11368
|
);
|
|
11343
|
-
urlInfo.mutateContent(
|
|
11369
|
+
urlInfo.mutateContent(replaceResult);
|
|
11344
11370
|
}
|
|
11345
11371
|
},
|
|
11346
11372
|
);
|
|
@@ -12581,13 +12607,12 @@ entryPoints: {
|
|
|
12581
12607
|
});
|
|
12582
12608
|
}
|
|
12583
12609
|
|
|
12584
|
-
|
|
12585
|
-
|
|
12586
|
-
|
|
12610
|
+
// cpu is not sampled: cooking, rollup and terser hold the event loop for
|
|
12611
|
+
// seconds at a time, a sampler only runs in the gaps and would report the
|
|
12612
|
+
// idle time. What the build cost is process.cpuUsage() over its duration.
|
|
12587
12613
|
const memoryMonitoring = startMonitoringMemoryUsage();
|
|
12588
12614
|
const [processMemoryUsageMonitoring] = memoryMonitoring;
|
|
12589
12615
|
const interval = setInterval(() => {
|
|
12590
|
-
processCpuUsageMonitoring.measure();
|
|
12591
12616
|
processMemoryUsageMonitoring.measure();
|
|
12592
12617
|
}, 500).unref();
|
|
12593
12618
|
operation.addEndCallback(() => {
|
|
@@ -12657,19 +12682,24 @@ entryPoints: {
|
|
|
12657
12682
|
content += "\n";
|
|
12658
12683
|
return content;
|
|
12659
12684
|
};
|
|
12660
|
-
const renderBuildEndLog = ({
|
|
12685
|
+
const renderBuildEndLog = ({
|
|
12686
|
+
duration,
|
|
12687
|
+
buildFileContents,
|
|
12688
|
+
cpuUsage,
|
|
12689
|
+
phaseTimings,
|
|
12690
|
+
}) => {
|
|
12661
12691
|
// tell how many files are generated in build directory
|
|
12662
12692
|
// tell the repartition?
|
|
12663
12693
|
// this is not really useful for single build right?
|
|
12664
12694
|
|
|
12665
|
-
processCpuUsageMonitoring.end();
|
|
12666
12695
|
processMemoryUsageMonitoring.end();
|
|
12667
12696
|
|
|
12668
12697
|
return renderBuildDoneLog({
|
|
12669
12698
|
entryPointArray,
|
|
12670
12699
|
duration,
|
|
12671
12700
|
buildFileContents,
|
|
12672
|
-
|
|
12701
|
+
cpuUsage,
|
|
12702
|
+
phaseTimings,
|
|
12673
12703
|
processMemoryUsage: processMemoryUsageMonitoring.info,
|
|
12674
12704
|
});
|
|
12675
12705
|
};
|
|
@@ -12744,13 +12774,25 @@ entryPoints: {
|
|
|
12744
12774
|
}, renderDynamicLog());
|
|
12745
12775
|
};
|
|
12746
12776
|
},
|
|
12747
|
-
onBuildEnd: ({
|
|
12777
|
+
onBuildEnd: ({
|
|
12778
|
+
buildFileContents,
|
|
12779
|
+
duration,
|
|
12780
|
+
cpuUsage,
|
|
12781
|
+
phaseTimings,
|
|
12782
|
+
}) => {
|
|
12748
12783
|
clearInterval(interval);
|
|
12749
12784
|
dynamicLog.update("");
|
|
12750
12785
|
dynamicLog.destroy();
|
|
12751
12786
|
dynamicLog = null;
|
|
12752
12787
|
logger.info("");
|
|
12753
|
-
logger.info(
|
|
12788
|
+
logger.info(
|
|
12789
|
+
renderBuildEndLog({
|
|
12790
|
+
duration,
|
|
12791
|
+
buildFileContents,
|
|
12792
|
+
cpuUsage,
|
|
12793
|
+
phaseTimings,
|
|
12794
|
+
}),
|
|
12795
|
+
);
|
|
12754
12796
|
},
|
|
12755
12797
|
};
|
|
12756
12798
|
};
|
|
@@ -12777,8 +12819,20 @@ entryPoints: {
|
|
|
12777
12819
|
);
|
|
12778
12820
|
};
|
|
12779
12821
|
},
|
|
12780
|
-
onBuildEnd: ({
|
|
12781
|
-
|
|
12822
|
+
onBuildEnd: ({
|
|
12823
|
+
buildFileContents,
|
|
12824
|
+
duration,
|
|
12825
|
+
cpuUsage,
|
|
12826
|
+
phaseTimings,
|
|
12827
|
+
}) => {
|
|
12828
|
+
logger.info(
|
|
12829
|
+
renderBuildEndLog({
|
|
12830
|
+
duration,
|
|
12831
|
+
buildFileContents,
|
|
12832
|
+
cpuUsage,
|
|
12833
|
+
phaseTimings,
|
|
12834
|
+
}),
|
|
12835
|
+
);
|
|
12782
12836
|
},
|
|
12783
12837
|
};
|
|
12784
12838
|
};
|
|
@@ -12827,6 +12881,7 @@ entryPoints: {
|
|
|
12827
12881
|
|
|
12828
12882
|
const runBuild = async ({ signal }) => {
|
|
12829
12883
|
const startDate = Date.now();
|
|
12884
|
+
const cpuUsageAtStart = process.cpuUsage();
|
|
12830
12885
|
const { onBuildEnd, onEntryPointBuildStart } = startBuildLogs();
|
|
12831
12886
|
|
|
12832
12887
|
const buildUrlsGenerator = createBuildUrlsGenerator({
|
|
@@ -12935,6 +12990,7 @@ entryPoints: {
|
|
|
12935
12990
|
entryBuildInfo.buildInlineContents = result.buildInlineContents;
|
|
12936
12991
|
entryBuildInfo.buildManifest = result.buildManifest;
|
|
12937
12992
|
entryBuildInfo.buildSideEffectFiles = result.buildSideEffectFiles;
|
|
12993
|
+
entryBuildInfo.phaseTimings = result.phaseTimings;
|
|
12938
12994
|
entryBuildInfo.duration = Date.now() - entryPointBuildStartMs;
|
|
12939
12995
|
onEntryPointBuildEnd();
|
|
12940
12996
|
})();
|
|
@@ -13039,11 +13095,19 @@ entryPoints: {
|
|
|
13039
13095
|
}
|
|
13040
13096
|
}
|
|
13041
13097
|
}
|
|
13098
|
+
// entry points are built concurrently, interleaved on the same thread:
|
|
13099
|
+
// their phases overlap and only a single one can be told apart
|
|
13100
|
+
const phaseTimings =
|
|
13101
|
+
entryBuildInfoMap.size === 1
|
|
13102
|
+
? entryBuildInfoMap.values().next().value.phaseTimings
|
|
13103
|
+
: null;
|
|
13042
13104
|
onBuildEnd({
|
|
13043
13105
|
buildFileContents,
|
|
13044
13106
|
buildInlineContents,
|
|
13045
13107
|
buildManifest,
|
|
13046
13108
|
duration: Date.now() - startDate,
|
|
13109
|
+
cpuUsage: process.cpuUsage(cpuUsageAtStart),
|
|
13110
|
+
phaseTimings,
|
|
13047
13111
|
});
|
|
13048
13112
|
return {
|
|
13049
13113
|
...(returnBuildInlineContents ? { buildInlineContents } : {}),
|
|
@@ -13407,6 +13471,14 @@ const prepareEntryPointBuild = async (
|
|
|
13407
13471
|
return {
|
|
13408
13472
|
entryReference,
|
|
13409
13473
|
buildEntryPoint: async ({ getOtherEntryBuildInfo }) => {
|
|
13474
|
+
const phaseTimings = {};
|
|
13475
|
+
let phaseStartMs = Date.now();
|
|
13476
|
+
const endPhase = (name) => {
|
|
13477
|
+
const nowMs = Date.now();
|
|
13478
|
+
phaseTimings[name] = nowMs - phaseStartMs;
|
|
13479
|
+
phaseStartMs = nowMs;
|
|
13480
|
+
};
|
|
13481
|
+
|
|
13410
13482
|
{
|
|
13411
13483
|
_getOtherEntryBuildInfo = getOtherEntryBuildInfo;
|
|
13412
13484
|
if (outDirectoryUrl) {
|
|
@@ -13414,6 +13486,7 @@ const prepareEntryPointBuild = async (
|
|
|
13414
13486
|
}
|
|
13415
13487
|
await rawRootUrlInfo.cookDependencies({ operation: buildOperation });
|
|
13416
13488
|
}
|
|
13489
|
+
endPhase("craft");
|
|
13417
13490
|
|
|
13418
13491
|
const finalKitchen = createKitchen({
|
|
13419
13492
|
name: "shape",
|
|
@@ -13626,6 +13699,8 @@ const prepareEntryPointBuild = async (
|
|
|
13626
13699
|
}
|
|
13627
13700
|
}
|
|
13628
13701
|
|
|
13702
|
+
endPhase("bundle");
|
|
13703
|
+
|
|
13629
13704
|
{
|
|
13630
13705
|
finalKitchen.context.buildStep = "shape";
|
|
13631
13706
|
if (outDirectoryUrl) {
|
|
@@ -13645,6 +13720,8 @@ const prepareEntryPointBuild = async (
|
|
|
13645
13720
|
});
|
|
13646
13721
|
}
|
|
13647
13722
|
|
|
13723
|
+
endPhase("shape");
|
|
13724
|
+
|
|
13648
13725
|
const buildSideEffectFiles = [];
|
|
13649
13726
|
{
|
|
13650
13727
|
finalKitchen.context.buildStep = "refine";
|
|
@@ -13752,6 +13829,8 @@ const prepareEntryPointBuild = async (
|
|
|
13752
13829
|
}
|
|
13753
13830
|
}
|
|
13754
13831
|
}
|
|
13832
|
+
endPhase("refine");
|
|
13833
|
+
|
|
13755
13834
|
const {
|
|
13756
13835
|
buildFileContents,
|
|
13757
13836
|
buildFileVersions,
|
|
@@ -13771,6 +13850,7 @@ const prepareEntryPointBuild = async (
|
|
|
13771
13850
|
buildInlineContents,
|
|
13772
13851
|
buildManifest,
|
|
13773
13852
|
buildSideEffectFiles,
|
|
13853
|
+
phaseTimings,
|
|
13774
13854
|
};
|
|
13775
13855
|
},
|
|
13776
13856
|
};
|
|
@@ -3,8 +3,8 @@ import { extname } from "node:path";
|
|
|
3
3
|
import { readFileSync as readFileSync$1, existsSync, readdir, chmod, stat, lstat, chmodSync, statSync, lstatSync, promises, readdirSync, openSync, closeSync, unlinkSync, rmdirSync, mkdirSync, writeFileSync as writeFileSync$1, unlink, rmdir, watch, realpathSync } from "node:fs";
|
|
4
4
|
import crypto, { createHash } from "node:crypto";
|
|
5
5
|
import { pathToFileURL, fileURLToPath } from "node:url";
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
6
|
+
import { totalmem, freemem } from "node:os";
|
|
7
|
+
import { memoryUsage } from "node:process";
|
|
8
8
|
import { stripVTControlCharacters } from "node:util";
|
|
9
9
|
|
|
10
10
|
const createCallbackListNotifiedOnce = () => {
|
|
@@ -6548,174 +6548,6 @@ const getExtensionsToTry = (magicExtensions, importer) => {
|
|
|
6548
6548
|
return Array.from(extensionsSet.values());
|
|
6549
6549
|
};
|
|
6550
6550
|
|
|
6551
|
-
const startMeasuringTotalCpuUsage = () => {
|
|
6552
|
-
let previousCpuArray = cpus();
|
|
6553
|
-
let previousMs = Date.now();
|
|
6554
|
-
let previousCpuUsage = cpuUsage();
|
|
6555
|
-
|
|
6556
|
-
const overall = {
|
|
6557
|
-
inactive: 100,
|
|
6558
|
-
active: 0,
|
|
6559
|
-
system: 0,
|
|
6560
|
-
user: 0,
|
|
6561
|
-
};
|
|
6562
|
-
const thisProcess = {
|
|
6563
|
-
active: 0,
|
|
6564
|
-
system: 0,
|
|
6565
|
-
user: 0,
|
|
6566
|
-
};
|
|
6567
|
-
const details = previousCpuArray.map(() => {
|
|
6568
|
-
return {
|
|
6569
|
-
inactive: 100,
|
|
6570
|
-
active: 0,
|
|
6571
|
-
system: 0,
|
|
6572
|
-
user: 0,
|
|
6573
|
-
};
|
|
6574
|
-
});
|
|
6575
|
-
|
|
6576
|
-
const samples = [];
|
|
6577
|
-
const interval = setInterval(() => {
|
|
6578
|
-
let cpuArray = cpus();
|
|
6579
|
-
const ms = Date.now();
|
|
6580
|
-
const ellapsedMs = ms - previousMs;
|
|
6581
|
-
const cpuUsageSampleArray = [];
|
|
6582
|
-
let overallSystemMs = 0;
|
|
6583
|
-
let overallUserMs = 0;
|
|
6584
|
-
let overallInactiveMs = 0;
|
|
6585
|
-
let overallActiveMs = 0;
|
|
6586
|
-
let overallMsEllapsed = 0;
|
|
6587
|
-
let index = 0;
|
|
6588
|
-
for (const cpu of cpuArray) {
|
|
6589
|
-
const previousCpuTimes = previousCpuArray[index].times;
|
|
6590
|
-
const cpuTimes = cpu.times;
|
|
6591
|
-
const systemMs = cpuTimes.sys - previousCpuTimes.sys;
|
|
6592
|
-
const userMs = cpuTimes.user - previousCpuTimes.user;
|
|
6593
|
-
const activeMs = systemMs + userMs;
|
|
6594
|
-
const inactiveMs = ellapsedMs - activeMs;
|
|
6595
|
-
const cpuUsageSample = {
|
|
6596
|
-
inactive: inactiveMs / ellapsedMs,
|
|
6597
|
-
active: activeMs / ellapsedMs,
|
|
6598
|
-
system: systemMs / ellapsedMs,
|
|
6599
|
-
user: userMs / ellapsedMs,
|
|
6600
|
-
};
|
|
6601
|
-
cpuUsageSampleArray.push(cpuUsageSample);
|
|
6602
|
-
|
|
6603
|
-
overallSystemMs += systemMs;
|
|
6604
|
-
overallUserMs += userMs;
|
|
6605
|
-
overallInactiveMs += inactiveMs;
|
|
6606
|
-
overallActiveMs += activeMs;
|
|
6607
|
-
overallMsEllapsed += ellapsedMs;
|
|
6608
|
-
index++;
|
|
6609
|
-
}
|
|
6610
|
-
const overallUsageSample = {
|
|
6611
|
-
inactive: overallInactiveMs / overallMsEllapsed,
|
|
6612
|
-
active: overallActiveMs / overallMsEllapsed,
|
|
6613
|
-
system: overallSystemMs / overallMsEllapsed,
|
|
6614
|
-
user: overallUserMs / overallMsEllapsed,
|
|
6615
|
-
};
|
|
6616
|
-
previousCpuArray = cpuArray;
|
|
6617
|
-
previousMs = ms;
|
|
6618
|
-
|
|
6619
|
-
const processCpuUsage = cpuUsage();
|
|
6620
|
-
const thisProcessSystemMs = Math.round(
|
|
6621
|
-
(processCpuUsage.system - previousCpuUsage.system) / 1000,
|
|
6622
|
-
);
|
|
6623
|
-
const thisProcessUserMs = Math.round(
|
|
6624
|
-
(processCpuUsage.user - previousCpuUsage.user) / 1000,
|
|
6625
|
-
);
|
|
6626
|
-
previousCpuUsage = processCpuUsage;
|
|
6627
|
-
|
|
6628
|
-
const thisProcessActiveMs = thisProcessSystemMs + thisProcessUserMs;
|
|
6629
|
-
const thisProcessInactiveMs = overallMsEllapsed - thisProcessActiveMs;
|
|
6630
|
-
const thisProcessSample = {
|
|
6631
|
-
inactive: thisProcessInactiveMs / overallMsEllapsed,
|
|
6632
|
-
active: thisProcessActiveMs / overallMsEllapsed,
|
|
6633
|
-
system: thisProcessSystemMs / overallMsEllapsed,
|
|
6634
|
-
user: thisProcessUserMs / overallMsEllapsed,
|
|
6635
|
-
};
|
|
6636
|
-
samples.push({
|
|
6637
|
-
cpuUsageSampleArray,
|
|
6638
|
-
overallUsageSample,
|
|
6639
|
-
thisProcessSample,
|
|
6640
|
-
});
|
|
6641
|
-
if (samples.length === 10) {
|
|
6642
|
-
{
|
|
6643
|
-
let index = 0;
|
|
6644
|
-
for (const detail of details) {
|
|
6645
|
-
let systemSum = 0;
|
|
6646
|
-
let userSum = 0;
|
|
6647
|
-
let inactiveSum = 0;
|
|
6648
|
-
let activeSum = 0;
|
|
6649
|
-
for (const sample of samples) {
|
|
6650
|
-
const { cpuUsageSampleArray } = sample;
|
|
6651
|
-
const cpuUsageSample = cpuUsageSampleArray[index];
|
|
6652
|
-
inactiveSum += cpuUsageSample.inactive;
|
|
6653
|
-
activeSum += cpuUsageSample.active;
|
|
6654
|
-
systemSum += cpuUsageSample.system;
|
|
6655
|
-
userSum += cpuUsageSample.user;
|
|
6656
|
-
}
|
|
6657
|
-
Object.assign(detail, {
|
|
6658
|
-
inactive: inactiveSum / samples.length,
|
|
6659
|
-
active: activeSum / samples.length,
|
|
6660
|
-
system: systemSum / samples.length,
|
|
6661
|
-
user: userSum / samples.length,
|
|
6662
|
-
});
|
|
6663
|
-
index++;
|
|
6664
|
-
}
|
|
6665
|
-
}
|
|
6666
|
-
{
|
|
6667
|
-
let overallSystemSum = 0;
|
|
6668
|
-
let overallUserSum = 0;
|
|
6669
|
-
let overallInactiveSum = 0;
|
|
6670
|
-
let overallActiveSum = 0;
|
|
6671
|
-
for (const sample of samples) {
|
|
6672
|
-
const { overallUsageSample } = sample;
|
|
6673
|
-
overallSystemSum += overallUsageSample.system;
|
|
6674
|
-
overallUserSum += overallUsageSample.user;
|
|
6675
|
-
overallInactiveSum += overallUsageSample.inactive;
|
|
6676
|
-
overallActiveSum += overallUsageSample.active;
|
|
6677
|
-
}
|
|
6678
|
-
Object.assign(overall, {
|
|
6679
|
-
inactive: overallInactiveSum / samples.length,
|
|
6680
|
-
active: overallActiveSum / samples.length,
|
|
6681
|
-
system: overallSystemSum / samples.length,
|
|
6682
|
-
user: overallUserSum / samples.length,
|
|
6683
|
-
});
|
|
6684
|
-
}
|
|
6685
|
-
{
|
|
6686
|
-
let thisProcessSystemSum = 0;
|
|
6687
|
-
let thisProcessUserSum = 0;
|
|
6688
|
-
let thisProcessInactiveSum = 0;
|
|
6689
|
-
let thisProcessActiveSum = 0;
|
|
6690
|
-
for (const sample of samples) {
|
|
6691
|
-
const { thisProcessSample } = sample;
|
|
6692
|
-
thisProcessSystemSum += thisProcessSample.system;
|
|
6693
|
-
thisProcessUserSum += thisProcessSample.user;
|
|
6694
|
-
thisProcessInactiveSum += thisProcessSample.inactive;
|
|
6695
|
-
thisProcessActiveSum += thisProcessSample.active;
|
|
6696
|
-
}
|
|
6697
|
-
Object.assign(thisProcess, {
|
|
6698
|
-
inactive: thisProcessInactiveSum / samples.length,
|
|
6699
|
-
active: thisProcessActiveSum / samples.length,
|
|
6700
|
-
system: thisProcessSystemSum / samples.length,
|
|
6701
|
-
user: thisProcessUserSum / samples.length,
|
|
6702
|
-
});
|
|
6703
|
-
}
|
|
6704
|
-
samples.length = 0;
|
|
6705
|
-
}
|
|
6706
|
-
}, 15);
|
|
6707
|
-
interval.unref();
|
|
6708
|
-
|
|
6709
|
-
return {
|
|
6710
|
-
overall,
|
|
6711
|
-
thisProcess,
|
|
6712
|
-
details,
|
|
6713
|
-
stop: () => {
|
|
6714
|
-
clearInterval(interval);
|
|
6715
|
-
},
|
|
6716
|
-
};
|
|
6717
|
-
};
|
|
6718
|
-
|
|
6719
6551
|
const startMonitoringMetric = (measure) => {
|
|
6720
6552
|
const metrics = [];
|
|
6721
6553
|
const takeMeasure = () => {
|
|
@@ -6761,22 +6593,6 @@ const medianFromSortedArray = (array) => {
|
|
|
6761
6593
|
return medianNumber;
|
|
6762
6594
|
};
|
|
6763
6595
|
|
|
6764
|
-
// https://gist.github.com/GaetanoPiazzolla/c40e1ebb9f709d091208e89baf9f4e00
|
|
6765
|
-
|
|
6766
|
-
|
|
6767
|
-
const startMonitoringCpuUsage = () => {
|
|
6768
|
-
const cpuUsage = startMeasuringTotalCpuUsage();
|
|
6769
|
-
const processCpuUsageMonitoring = startMonitoringMetric(() => {
|
|
6770
|
-
return cpuUsage.thisProcess.active;
|
|
6771
|
-
});
|
|
6772
|
-
const osCpuUsageMonitoring = startMonitoringMetric(() => {
|
|
6773
|
-
return cpuUsage.overall.active;
|
|
6774
|
-
});
|
|
6775
|
-
const result = [processCpuUsageMonitoring, osCpuUsageMonitoring];
|
|
6776
|
-
result.stop = cpuUsage.stop;
|
|
6777
|
-
return result;
|
|
6778
|
-
};
|
|
6779
|
-
|
|
6780
6596
|
const startMonitoringMemoryUsage = () => {
|
|
6781
6597
|
const processMemoryUsageMonitoring = startMonitoringMetric(() => {
|
|
6782
6598
|
return memoryUsage().rss;
|
|
@@ -11231,4 +11047,4 @@ const escapeRegexpSpecialChars = (string) => {
|
|
|
11231
11047
|
});
|
|
11232
11048
|
};
|
|
11233
11049
|
|
|
11234
|
-
export { ANSI, Abort, CONTENT_TYPE, DATA_URL, JS_QUOTES, RUNTIME_COMPAT, UNICODE, URL_META, applyFileSystemMagicResolution, applyNodeEsmResolution, asSpecifierWithoutSearch, asUrlWithoutSearch, assertAndNormalizeDirectoryUrl, browserDefaultRuntimeCompat, bufferToEtag, clearDirectorySync, collectFiles, compareFileUrls, comparePathnames, composeTwoImportMaps, createDetailedMessage$1 as createDetailedMessage, createDynamicLog, createLogger, createLookupPackageDirectory, createTaskLog, distributePercentages, ensureEmptyDirectory, ensurePathnameTrailingSlash, ensureWindowsDriveLetter, errorToHTML, escapeRegexpSpecialChars, generateContentFrame, getCallerPosition, getExtensionsToTry, humanizeDuration, humanizeFileSize, humanizeMemory, inferRuntimeCompatFromClosestPackage, injectQueryParamIntoSpecifierWithoutEncoding, injectQueryParams, injectQueryParamsIntoSpecifier, isFileSystemPath, isSpecifierForNodeBuiltin, lookupPackageDirectory, moveUrl, nodeDefaultRuntimeCompat, normalizeImportMap, normalizeUrl, raceProcessTeardownEvents, readCustomConditionsFromProcessArgs, readEntryStatSync, readPackageAtOrNull, registerDirectoryLifecycle, renderBigSection, renderDetails, renderTable, renderUrlOrRelativeUrlFilename, resolveImport, setUrlBasename, setUrlExtension, setUrlFilename,
|
|
11050
|
+
export { ANSI, Abort, CONTENT_TYPE, DATA_URL, JS_QUOTES, RUNTIME_COMPAT, UNICODE, URL_META, applyFileSystemMagicResolution, applyNodeEsmResolution, asSpecifierWithoutSearch, asUrlWithoutSearch, assertAndNormalizeDirectoryUrl, browserDefaultRuntimeCompat, bufferToEtag, clearDirectorySync, collectFiles, compareFileUrls, comparePathnames, composeTwoImportMaps, createDetailedMessage$1 as createDetailedMessage, createDynamicLog, createLogger, createLookupPackageDirectory, createTaskLog, distributePercentages, ensureEmptyDirectory, ensurePathnameTrailingSlash, ensureWindowsDriveLetter, errorToHTML, escapeRegexpSpecialChars, generateContentFrame, getCallerPosition, getExtensionsToTry, humanizeDuration, humanizeFileSize, humanizeMemory, inferRuntimeCompatFromClosestPackage, injectQueryParamIntoSpecifierWithoutEncoding, injectQueryParams, injectQueryParamsIntoSpecifier, isFileSystemPath, isSpecifierForNodeBuiltin, lookupPackageDirectory, moveUrl, nodeDefaultRuntimeCompat, normalizeImportMap, normalizeUrl, raceProcessTeardownEvents, readCustomConditionsFromProcessArgs, readEntryStatSync, readPackageAtOrNull, registerDirectoryLifecycle, renderBigSection, renderDetails, renderTable, renderUrlOrRelativeUrlFilename, resolveImport, setUrlBasename, setUrlExtension, setUrlFilename, startMonitoringMemoryUsage, stringifyUrlSite, updateJsonFileSync, urlIsOrIsInsideOf, urlToBasename, urlToExtension$1 as urlToExtension, urlToFileSystemPath, urlToFilename$1 as urlToFilename, urlToPathname$1 as urlToPathname, urlToRelativeUrl, validateResponseIntegrity, writeFileSync };
|
|
@@ -178,11 +178,19 @@ const setup = () => {
|
|
|
178
178
|
// only carries the id, tab, activities and log entries.
|
|
179
179
|
let pendingLogs = [];
|
|
180
180
|
let pendingActivities = [];
|
|
181
|
+
// The server answering that the endpoint does not exist means there is no
|
|
182
|
+
// monitoring behind this origin anymore (the dev server was restarted
|
|
183
|
+
// without it, a test server took the port): reporting stops for the rest of
|
|
184
|
+
// this page's life rather than knocking at every heartbeat.
|
|
185
|
+
let endpointGone = false;
|
|
181
186
|
const post = async ({ beacon = false, closing = false } = {}) => {
|
|
182
187
|
const logs = pendingLogs;
|
|
183
188
|
const activities = pendingActivities;
|
|
184
189
|
pendingLogs = [];
|
|
185
190
|
pendingActivities = [];
|
|
191
|
+
if (endpointGone) {
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
186
194
|
const payload = JSON.stringify({
|
|
187
195
|
clientId,
|
|
188
196
|
// The server reads browser/OS from the request headers, but a headless
|
|
@@ -201,12 +209,15 @@ const setup = () => {
|
|
|
201
209
|
return;
|
|
202
210
|
}
|
|
203
211
|
try {
|
|
204
|
-
await nativeFetch(REPORT_ENDPOINT, {
|
|
212
|
+
const response = await nativeFetch(REPORT_ENDPOINT, {
|
|
205
213
|
method: "POST",
|
|
206
214
|
headers: { "content-type": "application/json" },
|
|
207
215
|
body: payload,
|
|
208
216
|
keepalive: true,
|
|
209
217
|
});
|
|
218
|
+
if (response.status === 404 || response.status === 405) {
|
|
219
|
+
endpointGone = true;
|
|
220
|
+
}
|
|
210
221
|
} catch {
|
|
211
222
|
// dev server gone or offline — dropping the report is acceptable.
|
|
212
223
|
}
|
|
@@ -2467,8 +2467,7 @@ const parseAndTransformJsReferences = async (
|
|
|
2467
2467
|
for (const sequentialAction of sequentialActions) {
|
|
2468
2468
|
await sequentialAction();
|
|
2469
2469
|
}
|
|
2470
|
-
|
|
2471
|
-
return { content, sourcemap };
|
|
2470
|
+
return magicSource.toContentAndSourcemap();
|
|
2472
2471
|
};
|
|
2473
2472
|
|
|
2474
2473
|
const jsenvPluginReferenceExpectedTypes = () => {
|
|
@@ -6161,6 +6160,8 @@ const jsenvPluginImportMetaCss = () => {
|
|
|
6161
6160
|
inputIsJsModule: true,
|
|
6162
6161
|
inputUrl: urlInfo.originalUrl,
|
|
6163
6162
|
outputUrl: urlInfo.generatedUrl,
|
|
6163
|
+
// the map would be dropped: the content sent back carries none
|
|
6164
|
+
options: { sourceMaps: false },
|
|
6164
6165
|
});
|
|
6165
6166
|
if (code === urlInfo.content) {
|
|
6166
6167
|
// all assignments were already in array form (pre-built file) — nothing to do
|
|
@@ -8241,7 +8242,10 @@ const devServerPluginOmegaErrorHandler = () => {
|
|
|
8241
8242
|
status: 403,
|
|
8242
8243
|
};
|
|
8243
8244
|
}
|
|
8244
|
-
|
|
8245
|
+
// the dev server runs with canExposeSensitiveData: file paths are welcome
|
|
8246
|
+
return convertFileSystemErrorToResponseProperties(error, {
|
|
8247
|
+
canExposeSensitiveData: true,
|
|
8248
|
+
});
|
|
8245
8249
|
};
|
|
8246
8250
|
const response = getResponseForError();
|
|
8247
8251
|
if (!response) {
|
|
@@ -8427,10 +8431,9 @@ const prependJsClassicInJsClassic = (jsUrlInfo, urlInfoToPrepend) => {
|
|
|
8427
8431
|
const magicSource = createMagicSource(jsUrlInfo.content);
|
|
8428
8432
|
magicSource.prepend(`${urlInfoToPrepend.content}\n\n`);
|
|
8429
8433
|
const magicResult = magicSource.toContentAndSourcemap();
|
|
8430
|
-
const sourcemap =
|
|
8431
|
-
jsUrlInfo.sourcemap,
|
|
8432
|
-
|
|
8433
|
-
);
|
|
8434
|
+
const sourcemap = jsUrlInfo.context.sourcemapsEnabled
|
|
8435
|
+
? composeTwoSourcemaps(jsUrlInfo.sourcemap, magicResult.sourcemap)
|
|
8436
|
+
: null;
|
|
8434
8437
|
jsUrlInfo.mutateContent({
|
|
8435
8438
|
content: magicResult.content,
|
|
8436
8439
|
sourcemap,
|
|
@@ -8448,6 +8451,7 @@ const prependJsClassicInJsModule = async (jsUrlInfo, urlInfoToPrepend) => {
|
|
|
8448
8451
|
input: jsUrlInfo.content,
|
|
8449
8452
|
inputIsJsModule: true,
|
|
8450
8453
|
inputUrl: jsUrlInfo.originalUrl,
|
|
8454
|
+
options: { sourceMaps: jsUrlInfo.context.sourcemapsEnabled },
|
|
8451
8455
|
});
|
|
8452
8456
|
jsUrlInfo.mutateContent({
|
|
8453
8457
|
content: code,
|
|
@@ -10172,7 +10176,6 @@ const createUrlInfoTransformer = ({
|
|
|
10172
10176
|
contentAst, // undefined most of the time
|
|
10173
10177
|
contentEtag, // in practice always undefined
|
|
10174
10178
|
contentLength,
|
|
10175
|
-
sourcemap,
|
|
10176
10179
|
sourcemapIsWrong,
|
|
10177
10180
|
contentInjections,
|
|
10178
10181
|
} = transformations;
|
|
@@ -10199,11 +10202,14 @@ const createUrlInfoTransformer = ({
|
|
|
10199
10202
|
contentLength,
|
|
10200
10203
|
});
|
|
10201
10204
|
}
|
|
10202
|
-
|
|
10203
|
-
|
|
10204
|
-
|
|
10205
|
-
|
|
10206
|
-
|
|
10205
|
+
// "sourcemap" is read last, and only when it will be used: a plugin can
|
|
10206
|
+
// hand it back as a getter that generates the map on first read, so that
|
|
10207
|
+
// nothing is generated for a kitchen that throws sourcemaps away
|
|
10208
|
+
const sourcemap =
|
|
10209
|
+
mayHaveSourcemap(urlInfo) && shouldHandleSourcemap(urlInfo)
|
|
10210
|
+
? transformations.sourcemap
|
|
10211
|
+
: null;
|
|
10212
|
+
if (sourcemap) {
|
|
10207
10213
|
const sourcemapNormalized = normalizeSourcemap(urlInfo, sourcemap);
|
|
10208
10214
|
let currentSourcemap = urlInfo.sourcemap;
|
|
10209
10215
|
const finalSourcemap = composeTwoSourcemaps(
|
|
@@ -10236,6 +10242,14 @@ const createUrlInfoTransformer = ({
|
|
|
10236
10242
|
writeInsideOutDirectory(urlInfo);
|
|
10237
10243
|
};
|
|
10238
10244
|
|
|
10245
|
+
// Written synchronously on purpose, and measured: async is the tempting
|
|
10246
|
+
// choice, but here it loses. A cold load cooks hundreds of files; their
|
|
10247
|
+
// synchronous writes block the event loop ~160ms in total, while
|
|
10248
|
+
// asynchronous writes queue in the threadpool behind tens of MB of content
|
|
10249
|
+
// and sourcemaps, and a response that waits for its own write then waits
|
|
10250
|
+
// ~36ms on average (18s summed over 500 responses). Not waiting is not an
|
|
10251
|
+
// option either: the last write lands after the test that cooked it has
|
|
10252
|
+
// ended, and the side-effect snapshots lose it.
|
|
10239
10253
|
const writeInsideOutDirectory = (urlInfo) => {
|
|
10240
10254
|
// writing result inside ".jsenv" directory (debug purposes)
|
|
10241
10255
|
if (!outDirectoryUrl) {
|
|
@@ -10555,6 +10569,12 @@ const createKitchen = ({
|
|
|
10555
10569
|
INJECTIONS,
|
|
10556
10570
|
getPluginMeta: null,
|
|
10557
10571
|
sourcemaps,
|
|
10572
|
+
// a plugin producing a sourcemap can skip the work when it would be
|
|
10573
|
+
// thrown away (see shouldHandleSourcemap in url_info_transformations.js)
|
|
10574
|
+
sourcemapsEnabled:
|
|
10575
|
+
sourcemaps === "inline" ||
|
|
10576
|
+
sourcemaps === "file" ||
|
|
10577
|
+
sourcemaps === "programmatic",
|
|
10558
10578
|
outDirectoryUrl,
|
|
10559
10579
|
},
|
|
10560
10580
|
resolve: (specifier, importer = rootDirectoryUrl) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jsenv/core",
|
|
3
|
-
"version": "41.4.
|
|
3
|
+
"version": "41.4.20",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Tool to develop, test and build js projects",
|
|
6
6
|
"repository": {
|
|
@@ -74,11 +74,11 @@
|
|
|
74
74
|
"dependencies": {
|
|
75
75
|
"@jsenv/ast": "6.9.2",
|
|
76
76
|
"@jsenv/js-module-fallback": "1.5.1",
|
|
77
|
-
"@jsenv/plugin-bundling": "2.10.
|
|
78
|
-
"@jsenv/plugin-minification": "1.7.
|
|
77
|
+
"@jsenv/plugin-bundling": "2.10.18",
|
|
78
|
+
"@jsenv/plugin-minification": "1.7.10",
|
|
79
79
|
"@jsenv/plugin-supervisor": "1.8.13",
|
|
80
80
|
"@jsenv/plugin-transpilation": "1.6.1",
|
|
81
|
-
"@jsenv/server": "17.6.
|
|
81
|
+
"@jsenv/server": "17.6.3",
|
|
82
82
|
"@jsenv/sourcemap": "1.4.2",
|
|
83
83
|
"react-table": "7.8.0"
|
|
84
84
|
},
|
package/src/build/build.js
CHANGED
|
@@ -38,10 +38,7 @@ import {
|
|
|
38
38
|
UNICODE,
|
|
39
39
|
} from "@jsenv/humanize";
|
|
40
40
|
import { applyNodeEsmResolution } from "@jsenv/node-esm-resolution";
|
|
41
|
-
import {
|
|
42
|
-
startMonitoringCpuUsage,
|
|
43
|
-
startMonitoringMemoryUsage,
|
|
44
|
-
} from "@jsenv/os-metrics";
|
|
41
|
+
import { startMonitoringMemoryUsage } from "@jsenv/os-metrics";
|
|
45
42
|
import { jsenvPluginBundling } from "@jsenv/plugin-bundling";
|
|
46
43
|
import { jsenvPluginMinification } from "@jsenv/plugin-minification";
|
|
47
44
|
import { jsenvPluginJsModuleFallback } from "@jsenv/plugin-transpilation";
|
|
@@ -395,13 +392,12 @@ entryPoints: {
|
|
|
395
392
|
});
|
|
396
393
|
}
|
|
397
394
|
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
395
|
+
// cpu is not sampled: cooking, rollup and terser hold the event loop for
|
|
396
|
+
// seconds at a time, a sampler only runs in the gaps and would report the
|
|
397
|
+
// idle time. What the build cost is process.cpuUsage() over its duration.
|
|
401
398
|
const memoryMonitoring = startMonitoringMemoryUsage();
|
|
402
399
|
const [processMemoryUsageMonitoring] = memoryMonitoring;
|
|
403
400
|
const interval = setInterval(() => {
|
|
404
|
-
processCpuUsageMonitoring.measure();
|
|
405
401
|
processMemoryUsageMonitoring.measure();
|
|
406
402
|
}, 500).unref();
|
|
407
403
|
operation.addEndCallback(() => {
|
|
@@ -471,19 +467,24 @@ entryPoints: {
|
|
|
471
467
|
content += "\n";
|
|
472
468
|
return content;
|
|
473
469
|
};
|
|
474
|
-
const renderBuildEndLog = ({
|
|
470
|
+
const renderBuildEndLog = ({
|
|
471
|
+
duration,
|
|
472
|
+
buildFileContents,
|
|
473
|
+
cpuUsage,
|
|
474
|
+
phaseTimings,
|
|
475
|
+
}) => {
|
|
475
476
|
// tell how many files are generated in build directory
|
|
476
477
|
// tell the repartition?
|
|
477
478
|
// this is not really useful for single build right?
|
|
478
479
|
|
|
479
|
-
processCpuUsageMonitoring.end();
|
|
480
480
|
processMemoryUsageMonitoring.end();
|
|
481
481
|
|
|
482
482
|
return renderBuildDoneLog({
|
|
483
483
|
entryPointArray,
|
|
484
484
|
duration,
|
|
485
485
|
buildFileContents,
|
|
486
|
-
|
|
486
|
+
cpuUsage,
|
|
487
|
+
phaseTimings,
|
|
487
488
|
processMemoryUsage: processMemoryUsageMonitoring.info,
|
|
488
489
|
});
|
|
489
490
|
};
|
|
@@ -558,13 +559,25 @@ entryPoints: {
|
|
|
558
559
|
}, renderDynamicLog());
|
|
559
560
|
};
|
|
560
561
|
},
|
|
561
|
-
onBuildEnd: ({
|
|
562
|
+
onBuildEnd: ({
|
|
563
|
+
buildFileContents,
|
|
564
|
+
duration,
|
|
565
|
+
cpuUsage,
|
|
566
|
+
phaseTimings,
|
|
567
|
+
}) => {
|
|
562
568
|
clearInterval(interval);
|
|
563
569
|
dynamicLog.update("");
|
|
564
570
|
dynamicLog.destroy();
|
|
565
571
|
dynamicLog = null;
|
|
566
572
|
logger.info("");
|
|
567
|
-
logger.info(
|
|
573
|
+
logger.info(
|
|
574
|
+
renderBuildEndLog({
|
|
575
|
+
duration,
|
|
576
|
+
buildFileContents,
|
|
577
|
+
cpuUsage,
|
|
578
|
+
phaseTimings,
|
|
579
|
+
}),
|
|
580
|
+
);
|
|
568
581
|
},
|
|
569
582
|
};
|
|
570
583
|
};
|
|
@@ -591,8 +604,20 @@ entryPoints: {
|
|
|
591
604
|
);
|
|
592
605
|
};
|
|
593
606
|
},
|
|
594
|
-
onBuildEnd: ({
|
|
595
|
-
|
|
607
|
+
onBuildEnd: ({
|
|
608
|
+
buildFileContents,
|
|
609
|
+
duration,
|
|
610
|
+
cpuUsage,
|
|
611
|
+
phaseTimings,
|
|
612
|
+
}) => {
|
|
613
|
+
logger.info(
|
|
614
|
+
renderBuildEndLog({
|
|
615
|
+
duration,
|
|
616
|
+
buildFileContents,
|
|
617
|
+
cpuUsage,
|
|
618
|
+
phaseTimings,
|
|
619
|
+
}),
|
|
620
|
+
);
|
|
596
621
|
},
|
|
597
622
|
};
|
|
598
623
|
};
|
|
@@ -642,6 +667,7 @@ entryPoints: {
|
|
|
642
667
|
|
|
643
668
|
const runBuild = async ({ signal }) => {
|
|
644
669
|
const startDate = Date.now();
|
|
670
|
+
const cpuUsageAtStart = process.cpuUsage();
|
|
645
671
|
const { onBuildEnd, onEntryPointBuildStart } = startBuildLogs();
|
|
646
672
|
|
|
647
673
|
const buildUrlsGenerator = createBuildUrlsGenerator({
|
|
@@ -750,6 +776,7 @@ entryPoints: {
|
|
|
750
776
|
entryBuildInfo.buildInlineContents = result.buildInlineContents;
|
|
751
777
|
entryBuildInfo.buildManifest = result.buildManifest;
|
|
752
778
|
entryBuildInfo.buildSideEffectFiles = result.buildSideEffectFiles;
|
|
779
|
+
entryBuildInfo.phaseTimings = result.phaseTimings;
|
|
753
780
|
entryBuildInfo.duration = Date.now() - entryPointBuildStartMs;
|
|
754
781
|
onEntryPointBuildEnd();
|
|
755
782
|
})();
|
|
@@ -854,11 +881,19 @@ entryPoints: {
|
|
|
854
881
|
}
|
|
855
882
|
}
|
|
856
883
|
}
|
|
884
|
+
// entry points are built concurrently, interleaved on the same thread:
|
|
885
|
+
// their phases overlap and only a single one can be told apart
|
|
886
|
+
const phaseTimings =
|
|
887
|
+
entryBuildInfoMap.size === 1
|
|
888
|
+
? entryBuildInfoMap.values().next().value.phaseTimings
|
|
889
|
+
: null;
|
|
857
890
|
onBuildEnd({
|
|
858
891
|
buildFileContents,
|
|
859
892
|
buildInlineContents,
|
|
860
893
|
buildManifest,
|
|
861
894
|
duration: Date.now() - startDate,
|
|
895
|
+
cpuUsage: process.cpuUsage(cpuUsageAtStart),
|
|
896
|
+
phaseTimings,
|
|
862
897
|
});
|
|
863
898
|
return {
|
|
864
899
|
...(returnBuildInlineContents ? { buildInlineContents } : {}),
|
|
@@ -1222,6 +1257,14 @@ const prepareEntryPointBuild = async (
|
|
|
1222
1257
|
return {
|
|
1223
1258
|
entryReference,
|
|
1224
1259
|
buildEntryPoint: async ({ getOtherEntryBuildInfo }) => {
|
|
1260
|
+
const phaseTimings = {};
|
|
1261
|
+
let phaseStartMs = Date.now();
|
|
1262
|
+
const endPhase = (name) => {
|
|
1263
|
+
const nowMs = Date.now();
|
|
1264
|
+
phaseTimings[name] = nowMs - phaseStartMs;
|
|
1265
|
+
phaseStartMs = nowMs;
|
|
1266
|
+
};
|
|
1267
|
+
|
|
1225
1268
|
craft: {
|
|
1226
1269
|
_getOtherEntryBuildInfo = getOtherEntryBuildInfo;
|
|
1227
1270
|
if (outDirectoryUrl) {
|
|
@@ -1229,6 +1272,7 @@ const prepareEntryPointBuild = async (
|
|
|
1229
1272
|
}
|
|
1230
1273
|
await rawRootUrlInfo.cookDependencies({ operation: buildOperation });
|
|
1231
1274
|
}
|
|
1275
|
+
endPhase("craft");
|
|
1232
1276
|
|
|
1233
1277
|
const finalKitchen = createKitchen({
|
|
1234
1278
|
name: "shape",
|
|
@@ -1443,6 +1487,8 @@ const prepareEntryPointBuild = async (
|
|
|
1443
1487
|
}
|
|
1444
1488
|
}
|
|
1445
1489
|
|
|
1490
|
+
endPhase("bundle");
|
|
1491
|
+
|
|
1446
1492
|
shape: {
|
|
1447
1493
|
finalKitchen.context.buildStep = "shape";
|
|
1448
1494
|
if (outDirectoryUrl) {
|
|
@@ -1462,6 +1508,8 @@ const prepareEntryPointBuild = async (
|
|
|
1462
1508
|
});
|
|
1463
1509
|
}
|
|
1464
1510
|
|
|
1511
|
+
endPhase("shape");
|
|
1512
|
+
|
|
1465
1513
|
const buildSideEffectFiles = [];
|
|
1466
1514
|
refine: {
|
|
1467
1515
|
finalKitchen.context.buildStep = "refine";
|
|
@@ -1569,6 +1617,8 @@ const prepareEntryPointBuild = async (
|
|
|
1569
1617
|
}
|
|
1570
1618
|
}
|
|
1571
1619
|
}
|
|
1620
|
+
endPhase("refine");
|
|
1621
|
+
|
|
1572
1622
|
const {
|
|
1573
1623
|
buildFileContents,
|
|
1574
1624
|
buildFileVersions,
|
|
@@ -1588,6 +1638,7 @@ const prepareEntryPointBuild = async (
|
|
|
1588
1638
|
buildInlineContents,
|
|
1589
1639
|
buildManifest,
|
|
1590
1640
|
buildSideEffectFiles,
|
|
1641
|
+
phaseTimings,
|
|
1591
1642
|
};
|
|
1592
1643
|
},
|
|
1593
1644
|
};
|
|
@@ -19,11 +19,12 @@ ${createRepartitionMessage(buildContentReport, { indent })}
|
|
|
19
19
|
--------------------`;
|
|
20
20
|
};
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
22
|
+
// a phase can be a few milliseconds long (refine, mostly): shown as such
|
|
23
|
+
const humanizePhaseDuration = (ms) => {
|
|
24
|
+
if (ms < 1000) {
|
|
25
|
+
return `${Math.round(ms)}ms`;
|
|
26
|
+
}
|
|
27
|
+
return humanizeDuration(ms, { short: true });
|
|
27
28
|
};
|
|
28
29
|
const humanizeProcessMemoryUsage = (value) => {
|
|
29
30
|
return humanizeMemory(value, { short: true, decimals: 0 });
|
|
@@ -32,7 +33,8 @@ export const renderBuildDoneLog = ({
|
|
|
32
33
|
entryPointArray,
|
|
33
34
|
duration,
|
|
34
35
|
buildFileContents,
|
|
35
|
-
|
|
36
|
+
cpuUsage,
|
|
37
|
+
phaseTimings,
|
|
36
38
|
processMemoryUsage,
|
|
37
39
|
}) => {
|
|
38
40
|
const buildContentReport = createBuildContentReport(buildFileContents);
|
|
@@ -47,15 +49,10 @@ export const renderBuildDoneLog = ({
|
|
|
47
49
|
title = `build done (${entryPointCount} entry points)`;
|
|
48
50
|
}
|
|
49
51
|
|
|
50
|
-
// cpu
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
med: humanizeProcessCpuUsage(processCpuUsage.median),
|
|
55
|
-
min: humanizeProcessCpuUsage(processCpuUsage.min),
|
|
56
|
-
max: humanizeProcessCpuUsage(processCpuUsage.max),
|
|
57
|
-
});
|
|
58
|
-
lines.push(cpuUsageLine);
|
|
52
|
+
// cpu: the process cpu time over the build duration, 100% being one core
|
|
53
|
+
// busy the whole time (more when a native module works on other threads)
|
|
54
|
+
const cpuMs = (cpuUsage.user + cpuUsage.system) / 1000;
|
|
55
|
+
lines.push(`cpu: ${Math.round((cpuMs / duration) * 100)}%`);
|
|
59
56
|
|
|
60
57
|
// memory usage
|
|
61
58
|
let memoryUsageLine = "memory: ";
|
|
@@ -70,6 +67,16 @@ export const renderBuildDoneLog = ({
|
|
|
70
67
|
// duration
|
|
71
68
|
let durationLine = `duration: `;
|
|
72
69
|
durationLine += humanizeDuration(duration, { short: true });
|
|
70
|
+
if (phaseTimings) {
|
|
71
|
+
durationLine += renderDetails(
|
|
72
|
+
Object.fromEntries(
|
|
73
|
+
Object.keys(phaseTimings).map((phaseName) => [
|
|
74
|
+
phaseName,
|
|
75
|
+
humanizePhaseDuration(phaseTimings[phaseName]),
|
|
76
|
+
]),
|
|
77
|
+
),
|
|
78
|
+
);
|
|
79
|
+
}
|
|
73
80
|
lines.push(durationLine);
|
|
74
81
|
|
|
75
82
|
// content
|
|
@@ -269,6 +276,8 @@ const createBuildContentReport = (buildFileContents) => {
|
|
|
269
276
|
};
|
|
270
277
|
|
|
271
278
|
const determineCategory = (buildRelativeUrl) => {
|
|
279
|
+
// a versioned url ("main.js?v=abc") is categorized by its file
|
|
280
|
+
buildRelativeUrl = buildRelativeUrl.replace(/[?#].*$/, "");
|
|
272
281
|
if (buildRelativeUrl.endsWith(".map")) {
|
|
273
282
|
return "sourcemap";
|
|
274
283
|
}
|
|
@@ -801,7 +801,7 @@ export const createBuildSpecifierManager = ({
|
|
|
801
801
|
}
|
|
802
802
|
if (mayUsePlaceholder(urlInfo)) {
|
|
803
803
|
const contentBeforeReplace = urlInfo.content;
|
|
804
|
-
const
|
|
804
|
+
const replaceResult = placeholderAPI.replaceAll(
|
|
805
805
|
contentBeforeReplace,
|
|
806
806
|
(placeholder) => {
|
|
807
807
|
const reference = placeholderToReferenceMap.get(placeholder);
|
|
@@ -809,7 +809,7 @@ export const createBuildSpecifierManager = ({
|
|
|
809
809
|
return value;
|
|
810
810
|
},
|
|
811
811
|
);
|
|
812
|
-
urlInfo.mutateContent(
|
|
812
|
+
urlInfo.mutateContent(replaceResult);
|
|
813
813
|
}
|
|
814
814
|
},
|
|
815
815
|
);
|
|
@@ -15,7 +15,10 @@ export const devServerPluginOmegaErrorHandler = () => {
|
|
|
15
15
|
status: 403,
|
|
16
16
|
};
|
|
17
17
|
}
|
|
18
|
-
|
|
18
|
+
// the dev server runs with canExposeSensitiveData: file paths are welcome
|
|
19
|
+
return convertFileSystemErrorToResponseProperties(error, {
|
|
20
|
+
canExposeSensitiveData: true,
|
|
21
|
+
});
|
|
19
22
|
};
|
|
20
23
|
const response = getResponseForError();
|
|
21
24
|
if (!response) {
|
package/src/kitchen/kitchen.js
CHANGED
|
@@ -118,6 +118,12 @@ export const createKitchen = ({
|
|
|
118
118
|
INJECTIONS,
|
|
119
119
|
getPluginMeta: null,
|
|
120
120
|
sourcemaps,
|
|
121
|
+
// a plugin producing a sourcemap can skip the work when it would be
|
|
122
|
+
// thrown away (see shouldHandleSourcemap in url_info_transformations.js)
|
|
123
|
+
sourcemapsEnabled:
|
|
124
|
+
sourcemaps === "inline" ||
|
|
125
|
+
sourcemaps === "file" ||
|
|
126
|
+
sourcemaps === "programmatic",
|
|
121
127
|
outDirectoryUrl,
|
|
122
128
|
},
|
|
123
129
|
resolve: (specifier, importer = rootDirectoryUrl) => {
|
|
@@ -67,10 +67,9 @@ const prependJsClassicInJsClassic = (jsUrlInfo, urlInfoToPrepend) => {
|
|
|
67
67
|
const magicSource = createMagicSource(jsUrlInfo.content);
|
|
68
68
|
magicSource.prepend(`${urlInfoToPrepend.content}\n\n`);
|
|
69
69
|
const magicResult = magicSource.toContentAndSourcemap();
|
|
70
|
-
const sourcemap =
|
|
71
|
-
jsUrlInfo.sourcemap,
|
|
72
|
-
|
|
73
|
-
);
|
|
70
|
+
const sourcemap = jsUrlInfo.context.sourcemapsEnabled
|
|
71
|
+
? composeTwoSourcemaps(jsUrlInfo.sourcemap, magicResult.sourcemap)
|
|
72
|
+
: null;
|
|
74
73
|
jsUrlInfo.mutateContent({
|
|
75
74
|
content: magicResult.content,
|
|
76
75
|
sourcemap,
|
|
@@ -88,6 +87,7 @@ const prependJsClassicInJsModule = async (jsUrlInfo, urlInfoToPrepend) => {
|
|
|
88
87
|
input: jsUrlInfo.content,
|
|
89
88
|
inputIsJsModule: true,
|
|
90
89
|
inputUrl: jsUrlInfo.originalUrl,
|
|
90
|
+
options: { sourceMaps: jsUrlInfo.context.sourcemapsEnabled },
|
|
91
91
|
});
|
|
92
92
|
jsUrlInfo.mutateContent({
|
|
93
93
|
content: code,
|
|
@@ -199,7 +199,6 @@ export const createUrlInfoTransformer = ({
|
|
|
199
199
|
contentAst, // undefined most of the time
|
|
200
200
|
contentEtag, // in practice always undefined
|
|
201
201
|
contentLength,
|
|
202
|
-
sourcemap,
|
|
203
202
|
sourcemapIsWrong,
|
|
204
203
|
contentInjections,
|
|
205
204
|
} = transformations;
|
|
@@ -226,11 +225,14 @@ export const createUrlInfoTransformer = ({
|
|
|
226
225
|
contentLength,
|
|
227
226
|
});
|
|
228
227
|
}
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
228
|
+
// "sourcemap" is read last, and only when it will be used: a plugin can
|
|
229
|
+
// hand it back as a getter that generates the map on first read, so that
|
|
230
|
+
// nothing is generated for a kitchen that throws sourcemaps away
|
|
231
|
+
const sourcemap =
|
|
232
|
+
mayHaveSourcemap(urlInfo) && shouldHandleSourcemap(urlInfo)
|
|
233
|
+
? transformations.sourcemap
|
|
234
|
+
: null;
|
|
235
|
+
if (sourcemap) {
|
|
234
236
|
const sourcemapNormalized = normalizeSourcemap(urlInfo, sourcemap);
|
|
235
237
|
let currentSourcemap = urlInfo.sourcemap;
|
|
236
238
|
const finalSourcemap = composeTwoSourcemaps(
|
|
@@ -263,6 +265,14 @@ export const createUrlInfoTransformer = ({
|
|
|
263
265
|
writeInsideOutDirectory(urlInfo);
|
|
264
266
|
};
|
|
265
267
|
|
|
268
|
+
// Written synchronously on purpose, and measured: async is the tempting
|
|
269
|
+
// choice, but here it loses. A cold load cooks hundreds of files; their
|
|
270
|
+
// synchronous writes block the event loop ~160ms in total, while
|
|
271
|
+
// asynchronous writes queue in the threadpool behind tens of MB of content
|
|
272
|
+
// and sourcemaps, and a response that waits for its own write then waits
|
|
273
|
+
// ~36ms on average (18s summed over 500 responses). Not waiting is not an
|
|
274
|
+
// option either: the last write lands after the test that cooked it has
|
|
275
|
+
// ended, and the side-effect snapshots lose it.
|
|
266
276
|
const writeInsideOutDirectory = (urlInfo) => {
|
|
267
277
|
// writing result inside ".jsenv" directory (debug purposes)
|
|
268
278
|
if (!outDirectoryUrl) {
|
|
@@ -178,11 +178,19 @@ const setup = () => {
|
|
|
178
178
|
// only carries the id, tab, activities and log entries.
|
|
179
179
|
let pendingLogs = [];
|
|
180
180
|
let pendingActivities = [];
|
|
181
|
+
// The server answering that the endpoint does not exist means there is no
|
|
182
|
+
// monitoring behind this origin anymore (the dev server was restarted
|
|
183
|
+
// without it, a test server took the port): reporting stops for the rest of
|
|
184
|
+
// this page's life rather than knocking at every heartbeat.
|
|
185
|
+
let endpointGone = false;
|
|
181
186
|
const post = async ({ beacon = false, closing = false } = {}) => {
|
|
182
187
|
const logs = pendingLogs;
|
|
183
188
|
const activities = pendingActivities;
|
|
184
189
|
pendingLogs = [];
|
|
185
190
|
pendingActivities = [];
|
|
191
|
+
if (endpointGone) {
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
186
194
|
const payload = JSON.stringify({
|
|
187
195
|
clientId,
|
|
188
196
|
// The server reads browser/OS from the request headers, but a headless
|
|
@@ -201,12 +209,15 @@ const setup = () => {
|
|
|
201
209
|
return;
|
|
202
210
|
}
|
|
203
211
|
try {
|
|
204
|
-
await nativeFetch(REPORT_ENDPOINT, {
|
|
212
|
+
const response = await nativeFetch(REPORT_ENDPOINT, {
|
|
205
213
|
method: "POST",
|
|
206
214
|
headers: { "content-type": "application/json" },
|
|
207
215
|
body: payload,
|
|
208
216
|
keepalive: true,
|
|
209
217
|
});
|
|
218
|
+
if (response.status === 404 || response.status === 405) {
|
|
219
|
+
endpointGone = true;
|
|
220
|
+
}
|
|
210
221
|
} catch {
|
|
211
222
|
// dev server gone or offline — dropping the report is acceptable.
|
|
212
223
|
}
|
|
@@ -75,6 +75,8 @@ export const jsenvPluginImportMetaCss = () => {
|
|
|
75
75
|
inputIsJsModule: true,
|
|
76
76
|
inputUrl: urlInfo.originalUrl,
|
|
77
77
|
outputUrl: urlInfo.generatedUrl,
|
|
78
|
+
// the map would be dropped: the content sent back carries none
|
|
79
|
+
options: { sourceMaps: false },
|
|
78
80
|
});
|
|
79
81
|
if (code === urlInfo.content) {
|
|
80
82
|
// all assignments were already in array form (pre-built file) — nothing to do
|
|
@@ -190,6 +190,5 @@ const parseAndTransformJsReferences = async (
|
|
|
190
190
|
for (const sequentialAction of sequentialActions) {
|
|
191
191
|
await sequentialAction();
|
|
192
192
|
}
|
|
193
|
-
|
|
194
|
-
return { content, sourcemap };
|
|
193
|
+
return magicSource.toContentAndSourcemap();
|
|
195
194
|
};
|