@markless/bundler 0.8.0 → 0.10.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-worker.d.ts +1 -0
- package/dist/build-worker.js +59 -0
- package/dist/chunk-ast-C8zKZiam.js +1 -0
- package/dist/chunk-ast-pN_P5wIo.js +204 -0
- package/dist/chunk-tasks-BexSGNjx.js +1 -0
- package/dist/compile-store-DxF9Vj4_.js +187 -0
- package/dist/{execution-log-BL-7a77M.d.ts → execution-log-7HH5XDfA.d.ts} +2 -2
- package/dist/lazy-module-facades-qZajWDD8.js +2691 -0
- package/dist/planned-landing-BHy22Yf5.js +2291 -0
- package/dist/preload.d.ts +2 -2
- package/dist/preload.js +2 -2
- package/dist/{rolldown-BMQrr9-Y.js → rolldown-DS8OY1i9.js} +801 -4406
- package/dist/rolldown.d.ts +3 -3
- package/dist/rolldown.js +3 -2
- package/dist/{roster-resume-CpphsFl_.js → roster-resume-DXptD6DG.js} +2 -1
- package/dist/{route-pack-groups-BLS6xeVV.js → route-pack-groups-ByQmKKom.js} +892 -1004
- package/dist/{types-iOUoceJ-.d.ts → types-B8YqEscg.d.ts} +55 -2
- package/dist/vite.d.ts +6 -1
- package/dist/vite.js +798 -26
- package/package.json +6 -5
- package/dist/optimized-deps-BfzxSm6C.js +0 -89
package/dist/vite.js
CHANGED
|
@@ -1,19 +1,25 @@
|
|
|
1
|
+
import { i as persistentCompileCacheAvailable, n as compilerFingerprint, r as createPersistentCompileCache } from "./compile-store-DxF9Vj4_.js";
|
|
1
2
|
import { a as MARKLESS_DEV_RELOADS_ATTRIBUTE, d as renderMarklessDevErrorDocument, i as MARKLESS_DEV_PAGE_EDIT_EVENT, n as MARKLESS_DEV_ERROR_CLIENT_ID, o as MARKLESS_DEV_RELOADS_EVENT, r as MARKLESS_DEV_ERROR_EVENT, t as MARKLESS_DEV_ERROR_CLEAR_EVENT, u as normalizeMarklessDevError } from "./dev-error-BEduK_R3.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import { A as sharedReachedRenderDataRequest, T as pathname, W as usePersistentStrippedCode, i as STRING_EXPORT_QUERY, it as includeOptimizedDeps, m as isCompilerStatefulModuleId, ot as runtimeFunctionSpecifiers, rt as excludeSourceShippedDeps, tt as outputDefaults, z as preflightTsrxModuleDiagnostics } from "./planned-landing-BHy22Yf5.js";
|
|
4
|
+
import { C as MARKLESS_VIRTUAL_PREFIX, Q as PROTOCOL_BLOCK_START_COMMENT, T as STORAGE_FREE_RESUME_ENTRY_SPECIFIER, X as createInlineDeferTriggerSource, Y as INLINE_DEFER_LOADER_SOURCE, Z as inlineDeferSource, f as PACK_COST_MODEL, h as moduleIdFor, rt as executionLogActivationInjection, t as MARKLESS_DEFERRED_PACK, w as RESUME_ENTRY_SPECIFIER } from "./route-pack-groups-ByQmKKom.js";
|
|
5
|
+
import { o as clearChunkFactCaches } from "./chunk-ast-pN_P5wIo.js";
|
|
6
|
+
import { a as collapseInitFacadeImports, b as runtimeModuleIdFromOrigin, c as marklessRuntimeSpecifierId, d as nativePackingPlugins, f as isReExportDoor, g as isPlannedCoLocation, h as dynamicImportersOf, l as DEPRECATED_NATIVE_PACKING_WARNING, m as withUndemandedReExportDoors, p as undemandedRuntimeModules, t as createMarklessRolldownPlugin, u as nativePackingEnabled, v as createPreloadGraphAdder, y as entryReachableModuleIds } from "./rolldown-DS8OY1i9.js";
|
|
7
|
+
import { a as createCompileWorkerPool, i as buildWorkerCount, n as prefetchChunkDynamicImports, u as unwrapAsyncImportWrappers } from "./lazy-module-facades-qZajWDD8.js";
|
|
5
8
|
import { n as marklessRosterPositions, r as marklessRosterRenderContext, t as marklessRosterPositionSeeds } from "./shared-seed-slot-ihIVCD2S.js";
|
|
9
|
+
import { DEBUGGING_PLAYBOOK_HINT, evaluateModuleConstants, parseJavaScriptModule, useCompileRunner, usePersistentCompileStore } from "@markless/compiler";
|
|
10
|
+
import { readFileSync } from "node:fs";
|
|
11
|
+
import { mkdtemp, readFile, rm, writeFile } from "node:fs/promises";
|
|
12
|
+
import { builtinModules } from "node:module";
|
|
13
|
+
import { isAbsolute, join, relative, resolve } from "pathe";
|
|
6
14
|
import { joinURL, parsePath, withQuery } from "ufo";
|
|
7
15
|
import { ASYNC_PROTOCOL_VERSION, PROTOCOL_CONTAINER_HOST_NODE_ID, STORAGE_SLOT_SYMBOL_KEY, escapeScriptJson, serializeRuntimeAsyncSnapshots, serializeRuntimeStateCells, storageAttributeName, storageCookieName, storageSlotEntryKeyFromGraphNodeId } from "@markless/serializer";
|
|
8
|
-
import { isAbsolute, join, resolve } from "pathe";
|
|
9
|
-
import { DEBUGGING_PLAYBOOK_HINT } from "@markless/compiler";
|
|
10
|
-
import { mkdtemp, readFile, rm, writeFile } from "node:fs/promises";
|
|
11
|
-
import { isAbsolute as isAbsolute$1 } from "node:path";
|
|
12
16
|
import { pathToFileURL } from "node:url";
|
|
13
|
-
import { createServerModuleRunner, isRunnableDevEnvironment } from "vite";
|
|
14
17
|
import { tmpdir } from "node:os";
|
|
18
|
+
import { isAbsolute as isAbsolute$1 } from "node:path";
|
|
19
|
+
import { createServerModuleRunner, isCSSRequest, isRunnableDevEnvironment } from "vite";
|
|
15
20
|
import { PROTOCOL_CONTAINER_END_COMMENT, PROTOCOL_CONTAINER_START_COMMENT, PROTOCOL_EVENT_ACTION_KIND as PROTOCOL_EVENT_ACTION_KIND$1, PROTOCOL_EVENT_HOST_ATTRIBUTE, PROTOCOL_EVENT_HOST_DELEGATED_REF, PROTOCOL_IDLE_EVENT_NAME as PROTOCOL_IDLE_EVENT_NAME$1, PROTOCOL_LOCATOR_PATHS_ATTRIBUTE, PROTOCOL_SYNC_POLICY_TABLE_TYPE, PROTOCOL_VISIBLE_EVENT_NAME, constantSyncPolicyCode, formatEventHostEntries, protocolEventDispatchesMarkless, syncPolicyNeverActs } from "@markless/serializer/protocol";
|
|
16
21
|
import "@markless/serializer/resume-record-delta";
|
|
22
|
+
import { analyze } from "yuku/analyzer";
|
|
17
23
|
//#region ../web/src/inline/served-census.ts
|
|
18
24
|
/**
|
|
19
25
|
* Pins the container's elements in DOM order as its census and returns them,
|
|
@@ -39,7 +45,24 @@ function marklessServedCensus(root, attribute) {
|
|
|
39
45
|
return value && (parseInt(value) !== live.length || order && order !== (signature >>> 0).toString(36)) ? (root.__marklessShifted = 1, []) : live;
|
|
40
46
|
}
|
|
41
47
|
//#endregion
|
|
48
|
+
//#region ../serializer/src/protocol-record-keys.ts
|
|
49
|
+
/** The field names each templated record list may spell, in the order its templates index them. */
|
|
50
|
+
const PROTOCOL_RECORD_KEYS = {
|
|
51
|
+
"markless/state": {
|
|
52
|
+
computed: "graphNodeId name async deriveSymbolId value version root $type $ref source flags records id type fields items entries values bytes arrayType buffer byteOffset length byteLength directValue dependencies path snapshot status key error hostScope",
|
|
53
|
+
sharedSeeds: "graphNodeId deriveSymbolId dependencies path reads",
|
|
54
|
+
sharedDefinitions: "id name exportedName scope version graphNodeIds projectionIds dependencies definitionId definitionName returnProperties kind graphNodeId path"
|
|
55
|
+
},
|
|
56
|
+
"markless/view": {
|
|
57
|
+
domUpdates: "hostNodeId source graphNodeId path target kind prefix suffix trueValue falseValue textNode name constantClass leadingClass symbolId",
|
|
58
|
+
behaviors: "hostNodeId source functionSource inputSources inputValues inputGraphReads inputIndex graphNodeId path symbolId usesGraph",
|
|
59
|
+
elementHandles: "hostNodeId handleId name plural"
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
//#endregion
|
|
42
63
|
//#region ../web/src/inline/resumer.ts
|
|
64
|
+
const listKeys = (type, list) => PROTOCOL_RECORD_KEYS[type][list] ?? "";
|
|
65
|
+
listKeys("markless/state", "cells"), listKeys("markless/state", "sharedRecords"), listKeys("markless/view", "events");
|
|
43
66
|
const withPageMarkers = (source) => source.replaceAll("__MARKLESS_PAGE_START__", JSON.stringify(PROTOCOL_CONTAINER_START_COMMENT)).replaceAll("__MARKLESS_PAGE_END__", JSON.stringify(PROTOCOL_CONTAINER_END_COMMENT));
|
|
44
67
|
const servedCensusSource = () => withPageMarkers(marklessServedCensus.toString());
|
|
45
68
|
PROTOCOL_EVENT_ACTION_KIND$1.event, PROTOCOL_EVENT_ACTION_KIND$1.externalDelegate;
|
|
@@ -163,11 +186,13 @@ function runPrerenderInlineResumer(eventNames, fallbackResumeModuleUrl, loadModu
|
|
|
163
186
|
const root = currentScript?.closest("[data-async-container]");
|
|
164
187
|
const resumeModuleUrl = currentScript?.getAttribute?.("data-markless-resume-module") ?? fallbackResumeModuleUrl;
|
|
165
188
|
if (!root || !resumeModuleUrl) return;
|
|
189
|
+
const life = root.__mL ||= {};
|
|
166
190
|
let loaded;
|
|
167
191
|
const dispatch = (event) => {
|
|
192
|
+
if (root.__mL !== life) return root.removeEventListener(event.type, dispatch, true);
|
|
168
193
|
root.__marklessDelegatedDispatch = true;
|
|
169
194
|
if (!root.__marklessCensus) census(root, pathsAttribute);
|
|
170
|
-
return (loaded ||= loadModule(resumeModuleUrl)).then((module) => module.resumeContainerEvent({
|
|
195
|
+
return (loaded ||= loadModule(resumeModuleUrl)).then((module) => root.__mL === life && module.resumeContainerEvent({
|
|
171
196
|
root,
|
|
172
197
|
event,
|
|
173
198
|
element: event.target,
|
|
@@ -181,10 +206,12 @@ function runInlineResumerSelfWake(fallbackResumeModuleUrl, loadModule, defer) {
|
|
|
181
206
|
const root = currentScript?.closest("[data-async-container]");
|
|
182
207
|
const resumeModuleUrl = currentScript?.getAttribute?.("data-markless-resume-module") ?? fallbackResumeModuleUrl;
|
|
183
208
|
if (!root || !resumeModuleUrl) return;
|
|
209
|
+
const life = root.__mL ||= {};
|
|
184
210
|
defer.idle(root, async () => {
|
|
185
|
-
if (root.__asyncResumeRuntimeStarted) return;
|
|
211
|
+
if (root.__asyncResumeRuntimeStarted || root.__mL !== life) return;
|
|
186
212
|
root.__marklessDelegatedDispatch = true;
|
|
187
|
-
|
|
213
|
+
const module = await (root.__mResume ||= loadModule(resumeModuleUrl));
|
|
214
|
+
if (root.__mL === life) await module.resumeContainerEvent({
|
|
188
215
|
root,
|
|
189
216
|
event: 0
|
|
190
217
|
});
|
|
@@ -195,8 +222,9 @@ function runInlineResumerOverlayPrimer(fallbackResumeModuleUrl, loadModule) {
|
|
|
195
222
|
const root = currentScript?.closest("[data-async-container]");
|
|
196
223
|
const resumeModuleUrl = currentScript?.getAttribute?.("data-markless-resume-module") ?? fallbackResumeModuleUrl;
|
|
197
224
|
if (!root || !resumeModuleUrl) return;
|
|
225
|
+
const life = root.__mL ||= {};
|
|
198
226
|
const prime = (event) => {
|
|
199
|
-
if (root.__marklessOverlayInstalled) {
|
|
227
|
+
if (root.__marklessOverlayInstalled || root.__mL !== life) {
|
|
200
228
|
removeEventListener("keydown", prime, true);
|
|
201
229
|
removeEventListener("pointerdown", prime, true);
|
|
202
230
|
return;
|
|
@@ -213,9 +241,9 @@ function runInlineResumerOverlayPrimer(fallbackResumeModuleUrl, loadModule) {
|
|
|
213
241
|
root.__marklessCensus = census;
|
|
214
242
|
}
|
|
215
243
|
setTimeout(() => {
|
|
216
|
-
if (root.__marklessDelegatedDispatch === true) return;
|
|
244
|
+
if (root.__marklessDelegatedDispatch === true || root.__mL !== life) return;
|
|
217
245
|
root.__marklessDelegatedDispatch = true;
|
|
218
|
-
loadModule(resumeModuleUrl).then((module) => module.resumeContainerEvent({
|
|
246
|
+
loadModule(resumeModuleUrl).then((module) => root.__mL === life && module.resumeContainerEvent({
|
|
219
247
|
root,
|
|
220
248
|
event: 0
|
|
221
249
|
}));
|
|
@@ -370,11 +398,24 @@ function servedElementTree(html) {
|
|
|
370
398
|
const elements = [{
|
|
371
399
|
tag: "",
|
|
372
400
|
parent: -1,
|
|
373
|
-
child: 0
|
|
401
|
+
child: 0,
|
|
402
|
+
node: 0
|
|
374
403
|
}];
|
|
375
404
|
const childCounts = [0];
|
|
405
|
+
const nodeCounts = [0];
|
|
406
|
+
const inText = [false];
|
|
407
|
+
const current = () => stack.length ? stack[stack.length - 1].index : 0;
|
|
408
|
+
const node = (parent, text) => {
|
|
409
|
+
if (templateDepth > 0 || text && inText[parent]) return;
|
|
410
|
+
nodeCounts[parent]++;
|
|
411
|
+
inText[parent] = text;
|
|
412
|
+
};
|
|
376
413
|
const commentElementIndexes = [];
|
|
377
414
|
const nameEnds = [0];
|
|
415
|
+
const addressSteps = [[]];
|
|
416
|
+
const blockSteps = /* @__PURE__ */ new Map();
|
|
417
|
+
const openBlocks = [[]];
|
|
418
|
+
const stepsOf = (parent) => openBlocks[parent].at(-1)?.steps ?? addressSteps[parent];
|
|
378
419
|
const stack = [];
|
|
379
420
|
let templateDepth = 0;
|
|
380
421
|
let foreignDepth = 0;
|
|
@@ -383,11 +424,28 @@ function servedElementTree(html) {
|
|
|
383
424
|
while (at < html.length) {
|
|
384
425
|
const open = html.indexOf("<", at);
|
|
385
426
|
if (open < 0) break;
|
|
427
|
+
if (open > at) node(current(), true);
|
|
386
428
|
if (html.startsWith("<!--", open)) {
|
|
429
|
+
node(current(), false);
|
|
387
430
|
const end = html.indexOf("-->", open + 4);
|
|
388
431
|
at = end < 0 ? html.length : end + 3;
|
|
389
432
|
const data = html.slice(open + 4, end < 0 ? html.length : end);
|
|
390
|
-
if (templateDepth
|
|
433
|
+
if (templateDepth > 0) continue;
|
|
434
|
+
const parent = current();
|
|
435
|
+
if (openBlocks[parent].at(-1)?.end === data) openBlocks[parent].pop();
|
|
436
|
+
else if (PROTOCOL_BLOCK_START_COMMENT.test(data)) {
|
|
437
|
+
const steps = [];
|
|
438
|
+
stepsOf(parent).push(-1);
|
|
439
|
+
openBlocks[parent].push({
|
|
440
|
+
end: `/${data}`,
|
|
441
|
+
steps
|
|
442
|
+
});
|
|
443
|
+
if (!isArmBranchAnchorComment({
|
|
444
|
+
nodeType: 8,
|
|
445
|
+
data
|
|
446
|
+
})) blockSteps.set(commentElementIndexes.length, steps);
|
|
447
|
+
}
|
|
448
|
+
if (!isArmBranchAnchorComment({
|
|
391
449
|
nodeType: 8,
|
|
392
450
|
data
|
|
393
451
|
})) commentElementIndexes.push(elements.length);
|
|
@@ -395,6 +453,7 @@ function servedElementTree(html) {
|
|
|
395
453
|
}
|
|
396
454
|
const next = html[open + 1] ?? "";
|
|
397
455
|
if (next === "!" || next === "?") {
|
|
456
|
+
node(current(), false);
|
|
398
457
|
const end = html.indexOf(">", open);
|
|
399
458
|
at = end < 0 ? html.length : end + 1;
|
|
400
459
|
continue;
|
|
@@ -403,6 +462,7 @@ function servedElementTree(html) {
|
|
|
403
462
|
const nameStart = closing ? open + 2 : open + 1;
|
|
404
463
|
const nameMatch = /^[a-zA-Z][^\s/>]*/.exec(html.slice(nameStart, nameStart + 64));
|
|
405
464
|
if (!nameMatch) {
|
|
465
|
+
node(current(), true);
|
|
406
466
|
at = open + 1;
|
|
407
467
|
continue;
|
|
408
468
|
}
|
|
@@ -428,10 +488,17 @@ function servedElementTree(html) {
|
|
|
428
488
|
index = elements.push({
|
|
429
489
|
tag,
|
|
430
490
|
parent,
|
|
431
|
-
child: childCounts[parent]
|
|
491
|
+
child: childCounts[parent]++,
|
|
492
|
+
node: nodeCounts[parent]
|
|
432
493
|
}) - 1;
|
|
494
|
+
node(parent, false);
|
|
495
|
+
stepsOf(parent).push(index);
|
|
433
496
|
childCounts.push(0);
|
|
497
|
+
nodeCounts.push(0);
|
|
498
|
+
inText.push(false);
|
|
434
499
|
nameEnds.push(nameStart + name.length);
|
|
500
|
+
addressSteps.push([]);
|
|
501
|
+
openBlocks.push([]);
|
|
435
502
|
}
|
|
436
503
|
if (VOID_TAGS.has(lower) || selfClosing) continue;
|
|
437
504
|
if (PROTOCOL_RAW_TEXT_TAGS.has(lower)) {
|
|
@@ -450,7 +517,9 @@ function servedElementTree(html) {
|
|
|
450
517
|
elements,
|
|
451
518
|
childCounts,
|
|
452
519
|
commentElementIndexes,
|
|
453
|
-
nameEnds
|
|
520
|
+
nameEnds,
|
|
521
|
+
addressSteps,
|
|
522
|
+
blockSteps
|
|
454
523
|
};
|
|
455
524
|
}
|
|
456
525
|
/** Writes `attribute="value"` on each element the map names by its index in servedElementTree(html). */
|
|
@@ -553,7 +622,7 @@ async function assemblePrerenderPageParts(component, output, options) {
|
|
|
553
622
|
}
|
|
554
623
|
async function renderSsrOutput(component, props, renderContext) {
|
|
555
624
|
assertPageRenderable(component);
|
|
556
|
-
globalThis.__marklessRosterResume ??= () => import("./roster-resume-
|
|
625
|
+
globalThis.__marklessRosterResume ??= () => import("./roster-resume-DXptD6DG.js");
|
|
557
626
|
const context = marklessSsrRosterPositionContext(renderContext);
|
|
558
627
|
if (typeof component === "function") return marklessSsrRosterCounted(context, await marklessSsrDeferredCounted(context, await component(props, context)));
|
|
559
628
|
if (component && typeof component.renderSsr === "function") return marklessSsrRosterCounted(context, await marklessSsrDeferredCounted(context, await component.renderSsr(props, context)));
|
|
@@ -718,8 +787,64 @@ function addEventHostEntry(marks, index, entry) {
|
|
|
718
787
|
const entries = marks.get(index);
|
|
719
788
|
if (!entries) return void marks.set(index, [entry]);
|
|
720
789
|
const same = entries.findIndex((candidate) => candidate.name === entry.name);
|
|
721
|
-
if (same < 0) entries.push(entry);
|
|
722
|
-
|
|
790
|
+
if (same < 0) return void entries.push(entry);
|
|
791
|
+
const held = entries[same];
|
|
792
|
+
entries[same] = {
|
|
793
|
+
...held,
|
|
794
|
+
...held.ref === void 0 && entry.ref !== void 0 ? { ref: entry.ref } : {},
|
|
795
|
+
...held.policy === void 0 && entry.policy !== void 0 ? { policy: entry.policy } : {}
|
|
796
|
+
};
|
|
797
|
+
}
|
|
798
|
+
const childLists = /* @__PURE__ */ new WeakMap();
|
|
799
|
+
function addRowPolicyMarks(marks, tree, parent, repeat, policyTable) {
|
|
800
|
+
if (repeat.rowEndOffset === void 0) return;
|
|
801
|
+
const events = repeat.rowEvents.flatMap((event) => {
|
|
802
|
+
const policy = policyTable.entry(event.syncPolicy);
|
|
803
|
+
return policy === void 0 ? [] : [{
|
|
804
|
+
...event,
|
|
805
|
+
policy
|
|
806
|
+
}];
|
|
807
|
+
});
|
|
808
|
+
if (!events.length) return;
|
|
809
|
+
const rows = servedChildren(tree, parent);
|
|
810
|
+
for (const row of rows.slice(repeat.rowStartOffset ?? 0, rows.length - repeat.rowEndOffset)) for (const event of events) {
|
|
811
|
+
const host = event.hostPath.length ? servedElementAt(tree, tree.addressSteps[row], event.hostPath) : row;
|
|
812
|
+
if (host !== void 0) addEventHostEntry(marks, host, {
|
|
813
|
+
name: event.eventName,
|
|
814
|
+
policy: event.policy
|
|
815
|
+
});
|
|
816
|
+
}
|
|
817
|
+
}
|
|
818
|
+
function servedChildren(tree, of) {
|
|
819
|
+
let lists = childLists.get(tree);
|
|
820
|
+
if (!lists) {
|
|
821
|
+
lists = tree.elements.map(() => []);
|
|
822
|
+
tree.elements.forEach((element, index) => index && lists.at(element.parent).push(index));
|
|
823
|
+
childLists.set(tree, lists);
|
|
824
|
+
}
|
|
825
|
+
return lists[of];
|
|
826
|
+
}
|
|
827
|
+
function servedElementAt(tree, steps, address) {
|
|
828
|
+
let host;
|
|
829
|
+
for (const step of address) {
|
|
830
|
+
host = steps?.at(step);
|
|
831
|
+
steps = host === void 0 || host < 0 ? void 0 : tree.addressSteps[host];
|
|
832
|
+
}
|
|
833
|
+
return host === void 0 || host < 0 ? void 0 : host;
|
|
834
|
+
}
|
|
835
|
+
function addPaintedArmPolicyMarks(marks, tree, branch, policyTable) {
|
|
836
|
+
const taken = branch.takenArm;
|
|
837
|
+
const set = taken === void 0 ? void 0 : branch.armRecords?.[taken];
|
|
838
|
+
const steps = tree.blockSteps.get(branch.startAnchor.index);
|
|
839
|
+
if (!set || !steps) return;
|
|
840
|
+
for (const event of set.events) {
|
|
841
|
+
const policy = policyTable.entry(event.syncPolicy);
|
|
842
|
+
const host = servedElementAt(tree, steps, event.hostPath);
|
|
843
|
+
if (policy !== void 0 && host !== void 0) addEventHostEntry(marks, host, {
|
|
844
|
+
name: event.eventName,
|
|
845
|
+
policy
|
|
846
|
+
});
|
|
847
|
+
}
|
|
723
848
|
}
|
|
724
849
|
function writeEventHostMarks(html, nameEnds, marks) {
|
|
725
850
|
return marks.size ? withElementAttributes(html, nameEnds, PROTOCOL_EVENT_HOST_ATTRIBUTE, new Map([...marks].map(([index, entries]) => [index, formatEventHostEntries(entries)]))) : html;
|
|
@@ -750,6 +875,7 @@ function withEventHostMarks(view, html, policyTable) {
|
|
|
750
875
|
const index = shell.get(repeat.parentHostNodeId);
|
|
751
876
|
if (index === void 0) continue;
|
|
752
877
|
for (const event of repeat.rowEvents) addEventHostEntry(marks, index, { name: event.eventName });
|
|
878
|
+
addRowPolicyMarks(marks, tree, index, repeat, policyTable);
|
|
753
879
|
}
|
|
754
880
|
for (const [anchor, records] of [...view.asyncBoundaries.map((boundary) => [boundary.startAnchor, boundary.armRecords]), ...(view.branches ?? []).map((branch) => [branch.startAnchor, branch.servedArmRecords])]) {
|
|
755
881
|
if (!records || Array.isArray(records)) continue;
|
|
@@ -766,7 +892,12 @@ function withEventHostMarks(view, html, policyTable) {
|
|
|
766
892
|
policy
|
|
767
893
|
});
|
|
768
894
|
}
|
|
895
|
+
for (const repeat of set.keyedRepeats ?? []) {
|
|
896
|
+
const index = arm.get(repeat.parentHostNodeId);
|
|
897
|
+
if (index !== void 0) addRowPolicyMarks(marks, tree, offset + index, repeat, policyTable);
|
|
898
|
+
}
|
|
769
899
|
}
|
|
900
|
+
for (const branch of view.branches ?? []) if (!branch.servedArmRecords) addPaintedArmPolicyMarks(marks, tree, branch, policyTable);
|
|
770
901
|
return writeEventHostMarks(html, tree.nameEnds, marks);
|
|
771
902
|
}
|
|
772
903
|
function renderSyncPolicyTableScript(policies) {
|
|
@@ -1378,6 +1509,7 @@ function deferredRuntimePacks(input) {
|
|
|
1378
1509
|
}
|
|
1379
1510
|
function deferredRuntimePlugin(demandMaps) {
|
|
1380
1511
|
let packs = /* @__PURE__ */ new Map();
|
|
1512
|
+
let dynamicImporters = /* @__PURE__ */ new Map();
|
|
1381
1513
|
return {
|
|
1382
1514
|
name: "markless:deferred-runtime",
|
|
1383
1515
|
options(input) {
|
|
@@ -1388,6 +1520,7 @@ function deferredRuntimePlugin(demandMaps) {
|
|
|
1388
1520
|
},
|
|
1389
1521
|
buildEnd(error) {
|
|
1390
1522
|
packs = /* @__PURE__ */ new Map();
|
|
1523
|
+
dynamicImporters = /* @__PURE__ */ new Map();
|
|
1391
1524
|
if (error) return;
|
|
1392
1525
|
const modules = /* @__PURE__ */ new Map();
|
|
1393
1526
|
for (const id of entryReachableModuleIds(this)) {
|
|
@@ -1406,6 +1539,10 @@ function deferredRuntimePlugin(demandMaps) {
|
|
|
1406
1539
|
moduleIds: modules.keys()
|
|
1407
1540
|
})
|
|
1408
1541
|
});
|
|
1542
|
+
dynamicImporters = dynamicImportersOf(modules);
|
|
1543
|
+
},
|
|
1544
|
+
onLog(_level, log) {
|
|
1545
|
+
if (isPlannedCoLocation(log, (id) => packs.get(id), dynamicImporters)) return false;
|
|
1409
1546
|
},
|
|
1410
1547
|
outputOptions(output) {
|
|
1411
1548
|
if (typeof output.codeSplitting !== "object") return null;
|
|
@@ -1414,6 +1551,7 @@ function deferredRuntimePlugin(demandMaps) {
|
|
|
1414
1551
|
codeSplitting: {
|
|
1415
1552
|
...output.codeSplitting,
|
|
1416
1553
|
groups: [{
|
|
1554
|
+
debugName: "markless-deferred-runtime",
|
|
1417
1555
|
name: (id) => packs.get(id) ?? null,
|
|
1418
1556
|
priority: 1e3,
|
|
1419
1557
|
includeDependenciesRecursively: false
|
|
@@ -2167,6 +2305,590 @@ function installDevRuntimeImportResolution(server, clientEnvironment) {
|
|
|
2167
2305
|
}
|
|
2168
2306
|
}
|
|
2169
2307
|
//#endregion
|
|
2308
|
+
//#region src/vite/browser-node-guard.ts
|
|
2309
|
+
const NODE_IN_BROWSER_ERROR = "MARKLESS_NODE_IN_BROWSER";
|
|
2310
|
+
const VITE_BROWSER_EXTERNAL = "__vite-browser-external";
|
|
2311
|
+
const OPTIMIZER_BROWSER_EXTERNAL = "browser-external:";
|
|
2312
|
+
const builtinNames = builtinModules.filter((name) => !name.includes(":"));
|
|
2313
|
+
const escape = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
2314
|
+
/** Specifiers that name a Node built-in: `node:*`, `bun:*`, or a bare built-in and its subpaths. */
|
|
2315
|
+
const NODE_BUILTIN_SPECIFIER = new RegExp(`^(?:node:|bun:|(?:${builtinNames.map(escape).join("|")})(?:/|$))`);
|
|
2316
|
+
function isNodeBuiltinSpecifier(specifier) {
|
|
2317
|
+
return NODE_BUILTIN_SPECIFIER.test(specifier);
|
|
2318
|
+
}
|
|
2319
|
+
/** Free names that only exist in Node; a browser throws a ReferenceError on any of them. */
|
|
2320
|
+
const NODE_ONLY_GLOBALS = [
|
|
2321
|
+
"process",
|
|
2322
|
+
"Buffer",
|
|
2323
|
+
"global",
|
|
2324
|
+
"__dirname",
|
|
2325
|
+
"__filename",
|
|
2326
|
+
"require"
|
|
2327
|
+
];
|
|
2328
|
+
const NODE_GLOBAL_WORD = new RegExp(`\\b(?:${NODE_ONLY_GLOBALS.join("|")})\\b`);
|
|
2329
|
+
function parsed(code) {
|
|
2330
|
+
for (const options of [
|
|
2331
|
+
{
|
|
2332
|
+
lang: "js",
|
|
2333
|
+
sourceType: "module"
|
|
2334
|
+
},
|
|
2335
|
+
{
|
|
2336
|
+
lang: "js",
|
|
2337
|
+
sourceType: "commonjs"
|
|
2338
|
+
},
|
|
2339
|
+
{
|
|
2340
|
+
lang: "ts",
|
|
2341
|
+
sourceType: "module"
|
|
2342
|
+
}
|
|
2343
|
+
]) {
|
|
2344
|
+
const module = analyze(code, options);
|
|
2345
|
+
if (!module.diagnostics.some((diagnostic) => diagnostic.severity === "error")) return module;
|
|
2346
|
+
}
|
|
2347
|
+
}
|
|
2348
|
+
function contains(outer, inner) {
|
|
2349
|
+
return !!outer && outer.start <= inner.start && inner.end <= outer.end;
|
|
2350
|
+
}
|
|
2351
|
+
function testsTypeof(module, test, name) {
|
|
2352
|
+
if (!test) return false;
|
|
2353
|
+
return module.unresolvedReferences.some((reference) => {
|
|
2354
|
+
const node = reference.node;
|
|
2355
|
+
if (reference.name !== name || !contains(test, node)) return false;
|
|
2356
|
+
const parent = module.parentOf(reference.node);
|
|
2357
|
+
return parent?.type === "UnaryExpression" && parent.operator === "typeof";
|
|
2358
|
+
});
|
|
2359
|
+
}
|
|
2360
|
+
function allowedUse(module, reference) {
|
|
2361
|
+
const node = reference.node;
|
|
2362
|
+
const parent = module.parentOf(reference.node);
|
|
2363
|
+
if (parent?.type === "UnaryExpression" && parent.operator === "typeof") return true;
|
|
2364
|
+
const name = reference.name;
|
|
2365
|
+
if (name === "process" && parent?.type === "MemberExpression" && parent.object === reference.node && !parent.computed && parent.property.name === "env") return true;
|
|
2366
|
+
if (name === "require" && parent?.type === "CallExpression" && parent.callee === reference.node && parent.arguments.length === 1 && parent.arguments[0].type === "Literal" && typeof parent.arguments[0].value === "string") return true;
|
|
2367
|
+
for (const ancestor of module.ancestors(reference.node)) {
|
|
2368
|
+
if (ancestor === node) continue;
|
|
2369
|
+
if ((ancestor.type === "ConditionalExpression" || ancestor.type === "IfStatement") && !contains(ancestor.test, node) && testsTypeof(module, ancestor.test, name)) return true;
|
|
2370
|
+
if (ancestor.type === "LogicalExpression" && contains(ancestor.right, node) && testsTypeof(module, ancestor.left, name)) return true;
|
|
2371
|
+
}
|
|
2372
|
+
return false;
|
|
2373
|
+
}
|
|
2374
|
+
function lineAndColumn(code, offset) {
|
|
2375
|
+
let line = 1;
|
|
2376
|
+
let lineStart = 0;
|
|
2377
|
+
for (let index = code.indexOf("\n"); index !== -1 && index < offset; index = code.indexOf("\n", index + 1)) {
|
|
2378
|
+
line++;
|
|
2379
|
+
lineStart = index + 1;
|
|
2380
|
+
}
|
|
2381
|
+
const lineEnd = code.indexOf("\n", offset);
|
|
2382
|
+
return {
|
|
2383
|
+
line,
|
|
2384
|
+
column: offset - lineStart + 1,
|
|
2385
|
+
code: code.slice(lineStart, lineEnd === -1 ? void 0 : lineEnd).trim().slice(0, 120)
|
|
2386
|
+
};
|
|
2387
|
+
}
|
|
2388
|
+
/**
|
|
2389
|
+
* The places `code` uses a Node-only global a browser does not have. `typeof X`, a branch that runs
|
|
2390
|
+
* only after testing `typeof X`, `process.env` (Vite replaces it, Vitest's browser runner provides
|
|
2391
|
+
* it) and a literal `require("x")` (the bundler resolves it) are allowed.
|
|
2392
|
+
*/
|
|
2393
|
+
function nodeGlobalUses(code) {
|
|
2394
|
+
if (!NODE_GLOBAL_WORD.test(code)) return [];
|
|
2395
|
+
const module = parsed(code);
|
|
2396
|
+
if (!module) return [];
|
|
2397
|
+
const uses = [];
|
|
2398
|
+
for (const reference of module.unresolvedReferences) {
|
|
2399
|
+
if (!NODE_ONLY_GLOBALS.includes(reference.name)) continue;
|
|
2400
|
+
if (reference.inTypePosition) continue;
|
|
2401
|
+
if (allowedUse(module, reference)) continue;
|
|
2402
|
+
const node = reference.node;
|
|
2403
|
+
uses.push({
|
|
2404
|
+
name: reference.name,
|
|
2405
|
+
...lineAndColumn(code, node.start)
|
|
2406
|
+
});
|
|
2407
|
+
}
|
|
2408
|
+
return uses;
|
|
2409
|
+
}
|
|
2410
|
+
/** The shortest import chain from an entry to `id`, entry first; a link is `dynamic` when reached by `import()`. */
|
|
2411
|
+
function importChain(graph, id) {
|
|
2412
|
+
const reachedFrom = /* @__PURE__ */ new Map([[id, null]]);
|
|
2413
|
+
const queue = [id];
|
|
2414
|
+
let root = id;
|
|
2415
|
+
for (let index = 0; index < queue.length; index++) {
|
|
2416
|
+
const current = queue[index];
|
|
2417
|
+
const { static: staticImporters, dynamic } = graph.importers(current);
|
|
2418
|
+
if (graph.isEntry(current) || staticImporters.length === 0 && dynamic.length === 0) {
|
|
2419
|
+
root = current;
|
|
2420
|
+
break;
|
|
2421
|
+
}
|
|
2422
|
+
for (const [importers, isDynamic] of [[staticImporters, false], [dynamic, true]]) for (const importer of importers) {
|
|
2423
|
+
if (reachedFrom.has(importer)) continue;
|
|
2424
|
+
reachedFrom.set(importer, {
|
|
2425
|
+
toward: current,
|
|
2426
|
+
dynamic: isDynamic
|
|
2427
|
+
});
|
|
2428
|
+
queue.push(importer);
|
|
2429
|
+
}
|
|
2430
|
+
}
|
|
2431
|
+
const chain = [{
|
|
2432
|
+
id: root,
|
|
2433
|
+
dynamic: false
|
|
2434
|
+
}];
|
|
2435
|
+
for (let step = reachedFrom.get(root); step; step = reachedFrom.get(step.toward)) chain.push({
|
|
2436
|
+
id: step.toward,
|
|
2437
|
+
dynamic: step.dynamic
|
|
2438
|
+
});
|
|
2439
|
+
return chain;
|
|
2440
|
+
}
|
|
2441
|
+
function displayId(id, root) {
|
|
2442
|
+
const clean = id.replace(/^\0/, "").replace(/\?.*$/, "");
|
|
2443
|
+
const relativeToRoot = (path) => path.startsWith("/") && root ? relative(root, path) : path;
|
|
2444
|
+
if (clean.startsWith("virtual:markless:")) {
|
|
2445
|
+
const [kind = "", ...source] = clean.slice(MARKLESS_VIRTUAL_PREFIX.length).split(":");
|
|
2446
|
+
return `${relativeToRoot(decodeURIComponent(source.join(":")))} (Markless ${kind.replaceAll("-", " ")} module)`;
|
|
2447
|
+
}
|
|
2448
|
+
return relativeToRoot(clean);
|
|
2449
|
+
}
|
|
2450
|
+
const FINDING_ORDER = {
|
|
2451
|
+
builtin: 0,
|
|
2452
|
+
"browser-field": 1,
|
|
2453
|
+
global: 2
|
|
2454
|
+
};
|
|
2455
|
+
function compareFindings(a, b) {
|
|
2456
|
+
if (a.kind !== b.kind) return FINDING_ORDER[a.kind] - FINDING_ORDER[b.kind];
|
|
2457
|
+
if (a.kind === "global" && b.kind === "global") return a.use.line - b.use.line || a.use.column - b.use.column;
|
|
2458
|
+
if (a.kind === "builtin" && b.kind === "builtin") return a.specifier < b.specifier ? -1 : a.specifier > b.specifier ? 1 : 0;
|
|
2459
|
+
return 0;
|
|
2460
|
+
}
|
|
2461
|
+
function describeFinding(violation) {
|
|
2462
|
+
switch (violation.kind) {
|
|
2463
|
+
case "builtin": return `imports "${violation.specifier}", a Node built-in module`;
|
|
2464
|
+
case "browser-field": return "imports a module its package removes from browser builds (its package.json \"browser\" field maps it to false)";
|
|
2465
|
+
case "global": return `uses \`${violation.use.name}\` at ${violation.use.line}:${violation.use.column}, a global only Node has: ${violation.use.code}`;
|
|
2466
|
+
}
|
|
2467
|
+
}
|
|
2468
|
+
/** The error a browser build fails with: each import chain once, what its last module does, then how to fix it. */
|
|
2469
|
+
function nodeInBrowserMessage(environment, violations, chainOf, root) {
|
|
2470
|
+
const byImporter = /* @__PURE__ */ new Map();
|
|
2471
|
+
for (const violation of violations) {
|
|
2472
|
+
const list = byImporter.get(violation.importer) ?? [];
|
|
2473
|
+
list.push(violation);
|
|
2474
|
+
byImporter.set(violation.importer, list);
|
|
2475
|
+
}
|
|
2476
|
+
const sections = [...byImporter].map(([importer, findings]) => {
|
|
2477
|
+
const lines = chainOf(importer).map((link, index) => {
|
|
2478
|
+
return `${index === 0 ? " " : link.dynamic ? " → import() " : " → "}${displayId(link.id, root)}`;
|
|
2479
|
+
});
|
|
2480
|
+
const described = [...new Set(findings.toSorted(compareFindings).map(describeFinding))];
|
|
2481
|
+
return [...lines, ...described.map((finding) => ` ${finding}`)].join("\n");
|
|
2482
|
+
});
|
|
2483
|
+
return [
|
|
2484
|
+
`${NODE_IN_BROWSER_ERROR}: Node-only code is reachable from the browser build ("${environment}").`,
|
|
2485
|
+
"",
|
|
2486
|
+
sections.join("\n\n"),
|
|
2487
|
+
"",
|
|
2488
|
+
"A browser cannot run Node code: Vite would ship an empty stand-in that breaks when it is used.",
|
|
2489
|
+
"Fix: move what the browser side needs (a constant, a type, a pure function) into a module that imports nothing from Node, and import that module instead. Keep Node work in server-only files."
|
|
2490
|
+
].join("\n");
|
|
2491
|
+
}
|
|
2492
|
+
function isBrowserExternal(id) {
|
|
2493
|
+
return id === VITE_BROWSER_EXTERNAL || id.startsWith(`${VITE_BROWSER_EXTERNAL}:`);
|
|
2494
|
+
}
|
|
2495
|
+
function guardsEnvironment(environment) {
|
|
2496
|
+
return environment.config.consumer === "client";
|
|
2497
|
+
}
|
|
2498
|
+
function devChain(environment, id) {
|
|
2499
|
+
const graph = environment.moduleGraph;
|
|
2500
|
+
return importChain({
|
|
2501
|
+
importers: (current) => ({
|
|
2502
|
+
static: [...graph?.getModuleById(current)?.importers ?? []].map((node) => node.id).filter((importer) => !!importer),
|
|
2503
|
+
dynamic: []
|
|
2504
|
+
}),
|
|
2505
|
+
isEntry: () => false
|
|
2506
|
+
}, id);
|
|
2507
|
+
}
|
|
2508
|
+
const ROLLDOWN_RUNTIME = "\0rolldown/runtime.js";
|
|
2509
|
+
/**
|
|
2510
|
+
* Fails every browser build, worker bundle and dev request that reaches a Node built-in, a module
|
|
2511
|
+
* Vite would replace with an empty browser stand-in, or a global only Node has.
|
|
2512
|
+
*/
|
|
2513
|
+
function browserNodeGuard() {
|
|
2514
|
+
const violationsByEnvironment = /* @__PURE__ */ new Map();
|
|
2515
|
+
const record = (environment, violation) => {
|
|
2516
|
+
const list = violationsByEnvironment.get(environment) ?? [];
|
|
2517
|
+
list.push(violation);
|
|
2518
|
+
violationsByEnvironment.set(environment, list);
|
|
2519
|
+
};
|
|
2520
|
+
let root = "";
|
|
2521
|
+
return {
|
|
2522
|
+
name: "markless:browser-node-guard",
|
|
2523
|
+
enforce: "pre",
|
|
2524
|
+
applyToEnvironment(environment) {
|
|
2525
|
+
return guardsEnvironment(environment);
|
|
2526
|
+
},
|
|
2527
|
+
configEnvironment(name, config) {
|
|
2528
|
+
if ((config.consumer ?? (name === "client" ? "client" : "server")) !== "client") return void 0;
|
|
2529
|
+
return { optimizeDeps: { rolldownOptions: { plugins: [optimizedDepsGuard(name, () => root)] } } };
|
|
2530
|
+
},
|
|
2531
|
+
configResolved(config) {
|
|
2532
|
+
root = config.root;
|
|
2533
|
+
},
|
|
2534
|
+
config() {
|
|
2535
|
+
return { worker: { plugins: () => [browserNodeGuard()] } };
|
|
2536
|
+
},
|
|
2537
|
+
buildStart() {
|
|
2538
|
+
violationsByEnvironment.delete(this.environment.name);
|
|
2539
|
+
},
|
|
2540
|
+
resolveId: {
|
|
2541
|
+
order: "pre",
|
|
2542
|
+
filter: { id: NODE_BUILTIN_SPECIFIER },
|
|
2543
|
+
async handler(source, importer, options) {
|
|
2544
|
+
if (!importer) return null;
|
|
2545
|
+
const resolved = await this.resolve(source, importer, {
|
|
2546
|
+
...options,
|
|
2547
|
+
skipSelf: true
|
|
2548
|
+
});
|
|
2549
|
+
if (!resolved) return null;
|
|
2550
|
+
if (!(isBrowserExternal(resolved.id) || resolved.external !== false && resolved.external !== void 0 && isNodeBuiltinSpecifier(resolved.id))) return resolved;
|
|
2551
|
+
const environment = this.environment;
|
|
2552
|
+
const violation = {
|
|
2553
|
+
kind: "builtin",
|
|
2554
|
+
importer,
|
|
2555
|
+
specifier: source
|
|
2556
|
+
};
|
|
2557
|
+
if (environment.mode === "dev") throw new Error(nodeInBrowserMessage(environment.name, [violation], (id) => devChain(environment, id), environment.config.root));
|
|
2558
|
+
record(environment.name, violation);
|
|
2559
|
+
return resolved;
|
|
2560
|
+
}
|
|
2561
|
+
},
|
|
2562
|
+
transform: {
|
|
2563
|
+
order: "post",
|
|
2564
|
+
filter: { code: NODE_GLOBAL_WORD },
|
|
2565
|
+
handler(code, id) {
|
|
2566
|
+
if (id === ROLLDOWN_RUNTIME || isCSSRequest(id) || STRING_EXPORT_QUERY.test(id)) return null;
|
|
2567
|
+
const environment = this.environment;
|
|
2568
|
+
if (environment.depsOptimizer?.isOptimizedDepFile(id)) return null;
|
|
2569
|
+
const uses = nodeGlobalUses(code);
|
|
2570
|
+
if (uses.length === 0) return null;
|
|
2571
|
+
const violations = uses.map((use) => ({
|
|
2572
|
+
kind: "global",
|
|
2573
|
+
importer: id,
|
|
2574
|
+
use
|
|
2575
|
+
}));
|
|
2576
|
+
if (environment.mode === "dev") throw new Error(nodeInBrowserMessage(environment.name, violations, (target) => devChain(environment, target), environment.config.root));
|
|
2577
|
+
for (const violation of violations) record(environment.name, violation);
|
|
2578
|
+
return null;
|
|
2579
|
+
}
|
|
2580
|
+
},
|
|
2581
|
+
buildEnd(error) {
|
|
2582
|
+
if (error) return;
|
|
2583
|
+
const environment = this.environment;
|
|
2584
|
+
const violations = [...violationsByEnvironment.get(environment.name) ?? []];
|
|
2585
|
+
violationsByEnvironment.delete(environment.name);
|
|
2586
|
+
const recorded = new Set(violations.map((violation) => violation.kind === "builtin" ? `${violation.importer}\0${violation.specifier}` : ""));
|
|
2587
|
+
const explained = new Set(violations.filter((violation) => violation.kind === "builtin").map((violation) => violation.importer));
|
|
2588
|
+
for (const importer of this.getModuleIds()) {
|
|
2589
|
+
const info = this.getModuleInfo(importer);
|
|
2590
|
+
for (const id of [...info?.importedIds ?? [], ...info?.dynamicallyImportedIds ?? []]) if (isNodeBuiltinSpecifier(id)) {
|
|
2591
|
+
if (!recorded.has(`${importer}\0${id}`)) violations.push({
|
|
2592
|
+
kind: "builtin",
|
|
2593
|
+
importer,
|
|
2594
|
+
specifier: id
|
|
2595
|
+
});
|
|
2596
|
+
} else if (isBrowserExternal(id) && !explained.has(importer)) violations.push({
|
|
2597
|
+
kind: "browser-field",
|
|
2598
|
+
importer
|
|
2599
|
+
});
|
|
2600
|
+
}
|
|
2601
|
+
if (violations.length === 0) return;
|
|
2602
|
+
const graph = {
|
|
2603
|
+
importers: (id) => {
|
|
2604
|
+
const info = this.getModuleInfo(id);
|
|
2605
|
+
return {
|
|
2606
|
+
static: info?.importers ?? [],
|
|
2607
|
+
dynamic: info?.dynamicImporters ?? []
|
|
2608
|
+
};
|
|
2609
|
+
},
|
|
2610
|
+
isEntry: (id) => this.getModuleInfo(id)?.isEntry === true
|
|
2611
|
+
};
|
|
2612
|
+
this.error(nodeInBrowserMessage(environment.name, violations, (id) => importChain(graph, id), environment.config.root));
|
|
2613
|
+
}
|
|
2614
|
+
};
|
|
2615
|
+
}
|
|
2616
|
+
/** The dev dependency optimizer's half: a pre-bundled package that reaches a Node built-in fails too. */
|
|
2617
|
+
function optimizedDepsGuard(environment, root) {
|
|
2618
|
+
return {
|
|
2619
|
+
name: "markless:browser-node-guard-deps",
|
|
2620
|
+
buildEnd(error) {
|
|
2621
|
+
if (error) return;
|
|
2622
|
+
const violations = [];
|
|
2623
|
+
for (const id of this.getModuleIds()) {
|
|
2624
|
+
const specifier = id.startsWith(OPTIMIZER_BROWSER_EXTERNAL) ? id.slice(17) : void 0;
|
|
2625
|
+
if (specifier === void 0 && id !== VITE_BROWSER_EXTERNAL) continue;
|
|
2626
|
+
for (const importer of this.getModuleInfo(id)?.importers ?? []) violations.push(specifier === void 0 ? {
|
|
2627
|
+
kind: "browser-field",
|
|
2628
|
+
importer
|
|
2629
|
+
} : {
|
|
2630
|
+
kind: "builtin",
|
|
2631
|
+
importer,
|
|
2632
|
+
specifier
|
|
2633
|
+
});
|
|
2634
|
+
}
|
|
2635
|
+
if (violations.length === 0) return;
|
|
2636
|
+
const graph = {
|
|
2637
|
+
importers: (id) => {
|
|
2638
|
+
const info = this.getModuleInfo(id);
|
|
2639
|
+
return {
|
|
2640
|
+
static: info?.importers ?? [],
|
|
2641
|
+
dynamic: info?.dynamicImporters ?? []
|
|
2642
|
+
};
|
|
2643
|
+
},
|
|
2644
|
+
isEntry: (id) => this.getModuleInfo(id)?.isEntry === true
|
|
2645
|
+
};
|
|
2646
|
+
this.error(nodeInBrowserMessage(environment, violations, (id) => importChain(graph, id), root()));
|
|
2647
|
+
}
|
|
2648
|
+
};
|
|
2649
|
+
}
|
|
2650
|
+
//#endregion
|
|
2651
|
+
//#region src/constant-slices.ts
|
|
2652
|
+
const SLICE_PREFIX = `${MARKLESS_VIRTUAL_PREFIX}constant-slice:`;
|
|
2653
|
+
const SLICED_MODULE = /^\0virtual:markless:(?:symbol|symbol-bundle|render-data|render-data-served):|[?&]markless-render-data(?:[&#]|$)/;
|
|
2654
|
+
const AUTHORED_IMPORT = /\bimport\s*\{[^}]*\}\s*from\s*["'](?!@markless\/|virtual:)/;
|
|
2655
|
+
const PLAIN_SCRIPT_FILE = /\.[cm]?[jt]sx?$/;
|
|
2656
|
+
const MUTATING_METHODS = /* @__PURE__ */ new Set([
|
|
2657
|
+
"push",
|
|
2658
|
+
"pop",
|
|
2659
|
+
"shift",
|
|
2660
|
+
"unshift",
|
|
2661
|
+
"splice",
|
|
2662
|
+
"sort",
|
|
2663
|
+
"reverse",
|
|
2664
|
+
"fill",
|
|
2665
|
+
"copyWithin",
|
|
2666
|
+
"set",
|
|
2667
|
+
"add",
|
|
2668
|
+
"delete",
|
|
2669
|
+
"clear"
|
|
2670
|
+
]);
|
|
2671
|
+
const evaluated = /* @__PURE__ */ new Map();
|
|
2672
|
+
function moduleConstants(file) {
|
|
2673
|
+
const source = readFileSync(file, "utf8");
|
|
2674
|
+
const cached = evaluated.get(file);
|
|
2675
|
+
if (cached?.source === source) return cached.constants;
|
|
2676
|
+
const constants = evaluateModuleConstants({
|
|
2677
|
+
filename: file,
|
|
2678
|
+
source
|
|
2679
|
+
});
|
|
2680
|
+
evaluated.set(file, {
|
|
2681
|
+
source,
|
|
2682
|
+
constants
|
|
2683
|
+
});
|
|
2684
|
+
return constants;
|
|
2685
|
+
}
|
|
2686
|
+
function constantSliceId(file, exportName, path) {
|
|
2687
|
+
return `${SLICE_PREFIX}${encodeURIComponent(file)}:${encodeURIComponent(exportName)}:${encodeURIComponent(JSON.stringify(path))}`;
|
|
2688
|
+
}
|
|
2689
|
+
function sliceAt(value, path) {
|
|
2690
|
+
let current = value;
|
|
2691
|
+
for (const segment of path) current = current[segment];
|
|
2692
|
+
return current;
|
|
2693
|
+
}
|
|
2694
|
+
function plainJson(value) {
|
|
2695
|
+
if (value === null || typeof value === "string" || typeof value === "boolean") return true;
|
|
2696
|
+
if (typeof value === "number") return Number.isFinite(value) && !Object.is(value, -0);
|
|
2697
|
+
if (Array.isArray(value)) return value.every(plainJson);
|
|
2698
|
+
if (typeof value === "object") return Object.getPrototypeOf(value) === Object.prototype && Object.values(value).every(plainJson);
|
|
2699
|
+
return false;
|
|
2700
|
+
}
|
|
2701
|
+
function children(node) {
|
|
2702
|
+
const out = [];
|
|
2703
|
+
for (const [key, value] of Object.entries(node)) {
|
|
2704
|
+
if (key === "start" || key === "end" || key === "type") continue;
|
|
2705
|
+
if (Array.isArray(value)) {
|
|
2706
|
+
for (const item of value) if (item && typeof item === "object" && "type" in item) out.push(item);
|
|
2707
|
+
} else if (value && typeof value === "object" && "type" in value) out.push(value);
|
|
2708
|
+
}
|
|
2709
|
+
return out;
|
|
2710
|
+
}
|
|
2711
|
+
function declaredNames(node, into) {
|
|
2712
|
+
if (!node) return;
|
|
2713
|
+
if (node.type === "Identifier") into.add(node.name);
|
|
2714
|
+
else if (node.type === "ObjectPattern") for (const property of node.properties) declaredNames(property.type === "RestElement" ? property.argument : property.value, into);
|
|
2715
|
+
else if (node.type === "ArrayPattern") for (const element of node.elements ?? []) declaredNames(element, into);
|
|
2716
|
+
else if (node.type === "AssignmentPattern") declaredNames(node.left, into);
|
|
2717
|
+
else if (node.type === "RestElement") declaredNames(node.argument, into);
|
|
2718
|
+
}
|
|
2719
|
+
/** Every use of `local` as the root of a member chain, with the chain cut where the value stops having that own property. */
|
|
2720
|
+
function references(program, local, value) {
|
|
2721
|
+
const found = [];
|
|
2722
|
+
const shadowed = /* @__PURE__ */ new Set();
|
|
2723
|
+
let bare = false;
|
|
2724
|
+
const visit = (node, parents) => {
|
|
2725
|
+
if (node.type === "VariableDeclarator") declaredNames(node.id, shadowed);
|
|
2726
|
+
if (/Function/.test(node.type)) {
|
|
2727
|
+
for (const param of node.params ?? []) declaredNames(param, shadowed);
|
|
2728
|
+
if (node.id) declaredNames(node.id, shadowed);
|
|
2729
|
+
}
|
|
2730
|
+
if (node.type === "CatchClause") declaredNames(node.param, shadowed);
|
|
2731
|
+
if (node.type === "Identifier" && node.name === local) {
|
|
2732
|
+
const parent = parents.at(-1);
|
|
2733
|
+
if (!(parent?.type === "MemberExpression" && parent.property === node && !parent.computed || parent?.type === "Property" && parent.key === node && !parent.computed && !parent.shorthand || parent?.type === "ImportSpecifier")) {
|
|
2734
|
+
const chain = [node];
|
|
2735
|
+
const path = [];
|
|
2736
|
+
let current = value;
|
|
2737
|
+
for (let depth = parents.length - 1; depth >= 0; depth--) {
|
|
2738
|
+
const member = parents[depth];
|
|
2739
|
+
if (member.type !== "MemberExpression" || member.object !== chain.at(-1)) break;
|
|
2740
|
+
const property = member.property;
|
|
2741
|
+
const key = member.computed ? property.type === "Literal" && (typeof property.value === "string" || typeof property.value === "number") ? property.value : void 0 : property.name;
|
|
2742
|
+
if (key === void 0 || !current || typeof current !== "object" || !Object.hasOwn(current, key)) break;
|
|
2743
|
+
current = current[key];
|
|
2744
|
+
path.push(key);
|
|
2745
|
+
chain.push(member);
|
|
2746
|
+
}
|
|
2747
|
+
if (path.length === 0) bare = true;
|
|
2748
|
+
const top = chain.at(-1);
|
|
2749
|
+
const above = parents[parents.length - chain.length];
|
|
2750
|
+
const mutates = above?.type === "AssignmentExpression" && above.left === top || above?.type === "UpdateExpression" || above?.type === "UnaryExpression" && above.operator === "delete" || above?.type === "MemberExpression" && above.object === top && !above.computed && MUTATING_METHODS.has(above.property.name);
|
|
2751
|
+
found.push({
|
|
2752
|
+
chain,
|
|
2753
|
+
path,
|
|
2754
|
+
mutates
|
|
2755
|
+
});
|
|
2756
|
+
}
|
|
2757
|
+
}
|
|
2758
|
+
for (const child of children(node)) visit(child, [...parents, node]);
|
|
2759
|
+
};
|
|
2760
|
+
visit(program, []);
|
|
2761
|
+
if (bare || shadowed.has(local) || found.some((reference) => reference.mutates)) return null;
|
|
2762
|
+
return found;
|
|
2763
|
+
}
|
|
2764
|
+
function slicingPays(value, roots, droppedPathBytes, maxModuleBytes) {
|
|
2765
|
+
const sliced = roots.reduce((sum, path) => sum + JSON.stringify(sliceAt(value, path)).length + PACK_COST_MODEL.packedModuleWrapperBytes, 0);
|
|
2766
|
+
const whole = JSON.stringify(value).length * 1.015 + PACK_COST_MODEL.packedModuleWrapperBytes;
|
|
2767
|
+
return sliced - droppedPathBytes < whole || whole > maxModuleBytes;
|
|
2768
|
+
}
|
|
2769
|
+
/** The module with each imported constant it reads only in slices narrowed to those slices, or null when nothing narrows. */
|
|
2770
|
+
async function narrowConstantImports(code, resolve, maxModuleBytes = Infinity) {
|
|
2771
|
+
if (!AUTHORED_IMPORT.test(code)) return null;
|
|
2772
|
+
let program;
|
|
2773
|
+
try {
|
|
2774
|
+
program = parseJavaScriptModule(code);
|
|
2775
|
+
} catch {
|
|
2776
|
+
return null;
|
|
2777
|
+
}
|
|
2778
|
+
const edits = [];
|
|
2779
|
+
const sliceImports = [];
|
|
2780
|
+
const files = [];
|
|
2781
|
+
const sliceLocals = /* @__PURE__ */ new Map();
|
|
2782
|
+
for (const statement of program.body) {
|
|
2783
|
+
if (statement.type !== "ImportDeclaration" || statement.importKind === "type") continue;
|
|
2784
|
+
const specifier = statement.source.value;
|
|
2785
|
+
if (specifier.startsWith("@markless/") || specifier.startsWith("virtual:")) continue;
|
|
2786
|
+
const named = statement.specifiers.filter((entry) => entry.type === "ImportSpecifier");
|
|
2787
|
+
if (named.length === 0) continue;
|
|
2788
|
+
const file = await resolve(specifier);
|
|
2789
|
+
if (!file || !PLAIN_SCRIPT_FILE.test(file)) continue;
|
|
2790
|
+
const constants = moduleConstants(file);
|
|
2791
|
+
const kept = [];
|
|
2792
|
+
for (const entry of statement.specifiers) {
|
|
2793
|
+
const imported = entry.type === "ImportSpecifier" ? entry.imported : void 0;
|
|
2794
|
+
const exportName = imported ? imported.name ?? imported.value : void 0;
|
|
2795
|
+
const local = entry.local.name;
|
|
2796
|
+
const value = exportName !== void 0 ? constants[exportName] : void 0;
|
|
2797
|
+
const uses = exportName !== void 0 && Object.hasOwn(constants, exportName) && value && typeof value === "object" ? references(program, local, value) : null;
|
|
2798
|
+
const paths = uses ? [...new Map(uses.map((use) => [JSON.stringify(use.path), use.path])).values()].sort((left, right) => left.length - right.length) : [];
|
|
2799
|
+
const roots = paths.filter((path, index) => !paths.slice(0, index).some((shorter) => shorter.every((segment, at) => path[at] === segment)));
|
|
2800
|
+
if (!uses || roots.some((path) => !plainJson(sliceAt(value, path))) || !slicingPays(value, roots, uses.reduce((sum, use) => {
|
|
2801
|
+
const root = roots.find((path) => path.every((segment, at) => use.path[at] === segment));
|
|
2802
|
+
return sum + use.chain[root.length].end - use.chain[0].start - local.length;
|
|
2803
|
+
}, 0), maxModuleBytes)) {
|
|
2804
|
+
kept.push(entry);
|
|
2805
|
+
continue;
|
|
2806
|
+
}
|
|
2807
|
+
for (const use of uses) {
|
|
2808
|
+
const root = roots.find((path) => path.every((segment, at) => use.path[at] === segment));
|
|
2809
|
+
const id = constantSliceId(file, exportName, root);
|
|
2810
|
+
let name = sliceLocals.get(id);
|
|
2811
|
+
if (!name) {
|
|
2812
|
+
name = `marklessConstantSlice${sliceLocals.size}`;
|
|
2813
|
+
sliceLocals.set(id, name);
|
|
2814
|
+
sliceImports.push(`import ${name} from ${JSON.stringify(id)};`);
|
|
2815
|
+
}
|
|
2816
|
+
const node = use.chain[root.length];
|
|
2817
|
+
edits.push({
|
|
2818
|
+
start: use.chain[0].start,
|
|
2819
|
+
end: node.end,
|
|
2820
|
+
text: name
|
|
2821
|
+
});
|
|
2822
|
+
}
|
|
2823
|
+
if (!files.includes(file)) files.push(file);
|
|
2824
|
+
}
|
|
2825
|
+
if (kept.length === named.length && kept.length === statement.specifiers.length) continue;
|
|
2826
|
+
const remaining = kept.map((entry) => code.slice(entry.start, entry.end));
|
|
2827
|
+
edits.push({
|
|
2828
|
+
start: statement.start,
|
|
2829
|
+
end: statement.end,
|
|
2830
|
+
text: remaining.length ? `import ${kept.some((entry) => entry.type === "ImportSpecifier") ? `{ ${remaining.join(", ")} }` : remaining.join(", ")} from ${JSON.stringify(specifier)};` : ""
|
|
2831
|
+
});
|
|
2832
|
+
}
|
|
2833
|
+
if (sliceImports.length === 0) return null;
|
|
2834
|
+
let out = code;
|
|
2835
|
+
for (const edit of edits.sort((left, right) => right.start - left.start)) out = out.slice(0, edit.start) + edit.text + out.slice(edit.end);
|
|
2836
|
+
return {
|
|
2837
|
+
code: `${sliceImports.join("\n")}\n${out}`,
|
|
2838
|
+
files
|
|
2839
|
+
};
|
|
2840
|
+
}
|
|
2841
|
+
function constantSlicesPlugin() {
|
|
2842
|
+
return {
|
|
2843
|
+
name: "markless:constant-slices",
|
|
2844
|
+
enforce: "post",
|
|
2845
|
+
applyToEnvironment(environment) {
|
|
2846
|
+
return environment.config.consumer === "client";
|
|
2847
|
+
},
|
|
2848
|
+
buildEnd() {
|
|
2849
|
+
if (this.environment?.mode !== "dev") evaluated.clear();
|
|
2850
|
+
},
|
|
2851
|
+
resolveId: {
|
|
2852
|
+
filter: { id: /^virtual:markless:constant-slice:/ },
|
|
2853
|
+
handler(source) {
|
|
2854
|
+
return `\0${source}`;
|
|
2855
|
+
}
|
|
2856
|
+
},
|
|
2857
|
+
load: {
|
|
2858
|
+
filter: { id: /^\0virtual:markless:constant-slice:/ },
|
|
2859
|
+
handler(id) {
|
|
2860
|
+
const [file, exportName, path] = id.slice(1 + SLICE_PREFIX.length).split(":").map(decodeURIComponent);
|
|
2861
|
+
this.addWatchFile(file);
|
|
2862
|
+
const at = JSON.parse(path);
|
|
2863
|
+
const value = sliceAt(moduleConstants(file)[exportName], at);
|
|
2864
|
+
const json = JSON.stringify(value);
|
|
2865
|
+
const limitKb = this.environment?.config.build.chunkSizeWarningLimit;
|
|
2866
|
+
if (limitKb === void 0 || json.length <= limitKb * 1e3 || !value || typeof value !== "object") return `export default ${json};`;
|
|
2867
|
+
const keys = Array.isArray(value) ? value.map((_, index) => index) : Object.keys(value);
|
|
2868
|
+
const parts = keys.map((key, index) => `import marklessSlicePart${index} from ${JSON.stringify(constantSliceId(file, exportName, [...at, key]))};`);
|
|
2869
|
+
const body = Array.isArray(value) ? `[${keys.map((_, index) => `marklessSlicePart${index}`).join(",")}]` : `{${keys.map((key, index) => `${JSON.stringify(key)}:marklessSlicePart${index}`).join(",")}}`;
|
|
2870
|
+
return `${parts.join("\n")}\nexport default ${body};`;
|
|
2871
|
+
}
|
|
2872
|
+
},
|
|
2873
|
+
transform: {
|
|
2874
|
+
filter: { id: SLICED_MODULE },
|
|
2875
|
+
async handler(code, id) {
|
|
2876
|
+
const limitKb = this.environment?.config.build.chunkSizeWarningLimit;
|
|
2877
|
+
const narrowed = await narrowConstantImports(code, async (specifier) => {
|
|
2878
|
+
const resolved = await this.resolve(specifier, id, { skipSelf: true });
|
|
2879
|
+
return resolved && !resolved.external ? resolved.id.split("?")[0] : null;
|
|
2880
|
+
}, limitKb === void 0 ? Infinity : limitKb * 1e3);
|
|
2881
|
+
if (!narrowed) return null;
|
|
2882
|
+
for (const file of narrowed.files) this.addWatchFile(file);
|
|
2883
|
+
return {
|
|
2884
|
+
code: narrowed.code,
|
|
2885
|
+
map: null
|
|
2886
|
+
};
|
|
2887
|
+
}
|
|
2888
|
+
}
|
|
2889
|
+
};
|
|
2890
|
+
}
|
|
2891
|
+
//#endregion
|
|
2170
2892
|
//#region src/vite/index.ts
|
|
2171
2893
|
const MARKLESS_SKIP_DUPLICATE_BUILDS = Symbol("markless-skip-duplicate-builds");
|
|
2172
2894
|
const TSRX_INPUT_FILE = /\.tsrx(?:[?#].*)?$/;
|
|
@@ -2190,6 +2912,7 @@ function markless(options = {}) {
|
|
|
2190
2912
|
rolldownOptions.productionPrerenderWakeModuleUrls = /* @__PURE__ */ new Map();
|
|
2191
2913
|
let prerenderEntry = null;
|
|
2192
2914
|
let resolvedRoot = "";
|
|
2915
|
+
let chunkSizeWarningBytes;
|
|
2193
2916
|
let clientOutDir = "dist";
|
|
2194
2917
|
rolldownOptions.bundleGraphAdders = bundleGraphAdders;
|
|
2195
2918
|
const hmrOptions = {
|
|
@@ -2202,6 +2925,20 @@ function markless(options = {}) {
|
|
|
2202
2925
|
pageForUrl: void 0
|
|
2203
2926
|
};
|
|
2204
2927
|
let devPrerender;
|
|
2928
|
+
let compileCache;
|
|
2929
|
+
let compileWorkers;
|
|
2930
|
+
const flushCompileCache = async () => {
|
|
2931
|
+
const workers = compileWorkers;
|
|
2932
|
+
compileWorkers = void 0;
|
|
2933
|
+
useCompileRunner(void 0);
|
|
2934
|
+
await workers?.close();
|
|
2935
|
+
const cache = compileCache;
|
|
2936
|
+
if (!cache) return;
|
|
2937
|
+
compileCache = void 0;
|
|
2938
|
+
usePersistentCompileStore(void 0);
|
|
2939
|
+
usePersistentStrippedCode(void 0);
|
|
2940
|
+
await cache.flush();
|
|
2941
|
+
};
|
|
2205
2942
|
const devTags = createDevTags();
|
|
2206
2943
|
rolldownOptions.devInjections = devTags.tags;
|
|
2207
2944
|
const basePlugin = createMarklessRolldownPlugin({
|
|
@@ -2209,6 +2946,9 @@ function markless(options = {}) {
|
|
|
2209
2946
|
options: rolldownOptions,
|
|
2210
2947
|
prerenderRecordsBySource
|
|
2211
2948
|
});
|
|
2949
|
+
const packingPlugins = nativePackingEnabled(options) ? nativePackingPlugins(() => resolvedRoot, () => basePlugin.api.runtimeDemandMaps(), () => basePlugin.api.runtimeDemandSources(), () => basePlugin.api.directCsrOnly(), () => chunkSizeWarningBytes) : void 0;
|
|
2950
|
+
const packOwnership = packingPlugins?.[0]?.api;
|
|
2951
|
+
if (packOwnership) basePlugin.api.declarePackOwnership(packOwnership);
|
|
2212
2952
|
const hmr = createViteHmr(hmrOptions);
|
|
2213
2953
|
const marklessPlugin = {
|
|
2214
2954
|
...basePlugin,
|
|
@@ -2247,7 +2987,11 @@ function markless(options = {}) {
|
|
|
2247
2987
|
};
|
|
2248
2988
|
configDefaults(config, options, rolldownOptions);
|
|
2249
2989
|
if (devEnabled) {
|
|
2250
|
-
includeOptimizedDeps(config, [
|
|
2990
|
+
includeOptimizedDeps(config, [
|
|
2991
|
+
RESUME_ENTRY_SPECIFIER,
|
|
2992
|
+
STORAGE_FREE_RESUME_ENTRY_SPECIFIER,
|
|
2993
|
+
...runtimeFunctionSpecifiers()
|
|
2994
|
+
]);
|
|
2251
2995
|
excludeSourceShippedDeps(config);
|
|
2252
2996
|
}
|
|
2253
2997
|
if (prerender || stagePrerenderWake) {
|
|
@@ -2258,6 +3002,8 @@ function markless(options = {}) {
|
|
|
2258
3002
|
configResolved(resolvedConfig) {
|
|
2259
3003
|
if (options.experimentalNativePacking !== void 0) resolvedConfig.logger.warn(DEPRECATED_NATIVE_PACKING_WARNING);
|
|
2260
3004
|
resolvedRoot = resolvedConfig.root;
|
|
3005
|
+
const warningKb = (resolvedConfig.environments?.client ?? resolvedConfig).build?.chunkSizeWarningLimit;
|
|
3006
|
+
chunkSizeWarningBytes = warningKb === void 0 ? void 0 : warningKb * 1e3;
|
|
2261
3007
|
clientOutDir = resolvedConfig.build?.outDir ?? "dist";
|
|
2262
3008
|
const serve = resolvedConfig.command === "serve";
|
|
2263
3009
|
hmrOptions.base = resolvedConfig.base;
|
|
@@ -2265,6 +3011,25 @@ function markless(options = {}) {
|
|
|
2265
3011
|
rolldownOptions.dev = serve;
|
|
2266
3012
|
rolldownOptions.rootDir = resolvedConfig.root;
|
|
2267
3013
|
rolldownOptions.publicPath = (fileName) => joinURL(resolvedConfig.base, fileName);
|
|
3014
|
+
if (!serve && resolvedConfig.cacheDir && options.compileCache !== false && persistentCompileCacheAvailable()) {
|
|
3015
|
+
const directory = resolve(resolvedConfig.cacheDir, "markless-compile");
|
|
3016
|
+
const fingerprint = compilerFingerprint();
|
|
3017
|
+
compileCache = createPersistentCompileCache({
|
|
3018
|
+
directory,
|
|
3019
|
+
fingerprint
|
|
3020
|
+
});
|
|
3021
|
+
usePersistentCompileStore(compileCache);
|
|
3022
|
+
usePersistentStrippedCode(compileCache.strippedCode);
|
|
3023
|
+
compileWorkers = createCompileWorkerPool({
|
|
3024
|
+
size: buildWorkerCount(),
|
|
3025
|
+
store: {
|
|
3026
|
+
cache: compileCache,
|
|
3027
|
+
directory,
|
|
3028
|
+
fingerprint
|
|
3029
|
+
}
|
|
3030
|
+
});
|
|
3031
|
+
} else if (!serve) compileWorkers = createCompileWorkerPool({ size: buildWorkerCount() });
|
|
3032
|
+
if (compileWorkers) useCompileRunner(compileWorkers.run);
|
|
2268
3033
|
if (serve) {
|
|
2269
3034
|
devTags.registerViteTags(resolvedConfig.base);
|
|
2270
3035
|
if (prerender && prerenderEntry) {
|
|
@@ -2314,6 +3079,7 @@ function markless(options = {}) {
|
|
|
2314
3079
|
}));
|
|
2315
3080
|
}
|
|
2316
3081
|
await buildMarklessEnvironments(builder, options);
|
|
3082
|
+
await flushCompileCache();
|
|
2317
3083
|
if (prerender && prerenderEntry) {
|
|
2318
3084
|
const source = resolve(resolvedRoot, prerenderEntry);
|
|
2319
3085
|
const clientEnvironment = builder.environments[viteEnvironmentName("client", options)];
|
|
@@ -2335,6 +3101,9 @@ function markless(options = {}) {
|
|
|
2335
3101
|
}
|
|
2336
3102
|
}
|
|
2337
3103
|
},
|
|
3104
|
+
configureVitest({ defineCacheKeyGenerator }) {
|
|
3105
|
+
defineCacheKeyGenerator(({ id }) => isCompilerStatefulModuleId(id) ? false : void 0);
|
|
3106
|
+
},
|
|
2338
3107
|
configureServer(server) {
|
|
2339
3108
|
server.config.logger?.info(`markless diagnostics available - window.__MARKLESS_DEBUG__ records containers, lifecycles, and event routing; ${DEBUGGING_PLAYBOOK_HINT}.`);
|
|
2340
3109
|
rolldownOptions.devServer = {
|
|
@@ -2379,7 +3148,7 @@ function markless(options = {}) {
|
|
|
2379
3148
|
return hmr.load(id) ?? runHook(basePlugin.load, this, id, loadOptions);
|
|
2380
3149
|
},
|
|
2381
3150
|
transform: { async handler(code, id, transformOptions) {
|
|
2382
|
-
if (rolldownOptions.dev === true && TSRX_INPUT_FILE.test(id)) transformedTsrxSources.set(parsePath(id).pathname, code);
|
|
3151
|
+
if (rolldownOptions.dev === true && TSRX_INPUT_FILE.test(id) && !STRING_EXPORT_QUERY.test(id)) transformedTsrxSources.set(parsePath(id).pathname, code);
|
|
2383
3152
|
try {
|
|
2384
3153
|
const context = rolldownOptions.dev === true ? withDevServerExternals(this) : this;
|
|
2385
3154
|
return await runHook(basePlugin.transform, context, code, id, transformOptions);
|
|
@@ -2398,6 +3167,8 @@ function markless(options = {}) {
|
|
|
2398
3167
|
};
|
|
2399
3168
|
return [
|
|
2400
3169
|
marklessPlugin,
|
|
3170
|
+
browserNodeGuard(),
|
|
3171
|
+
constantSlicesPlugin(),
|
|
2401
3172
|
{
|
|
2402
3173
|
name: "markless:shared-render-data-reach",
|
|
2403
3174
|
enforce: "pre",
|
|
@@ -2419,13 +3190,14 @@ function markless(options = {}) {
|
|
|
2419
3190
|
generateBundle: {
|
|
2420
3191
|
order: "post",
|
|
2421
3192
|
async handler(_options, bundle) {
|
|
2422
|
-
await
|
|
3193
|
+
await prefetchChunkDynamicImports(Object.values(bundle).filter((output) => output.type === "chunk" && output.code.includes("import(")));
|
|
2423
3194
|
collapseInitFacadeImports(bundle);
|
|
2424
|
-
unwrapAsyncImportWrappers(bundle);
|
|
3195
|
+
await unwrapAsyncImportWrappers(bundle);
|
|
3196
|
+
clearChunkFactCaches();
|
|
2425
3197
|
}
|
|
2426
3198
|
}
|
|
2427
3199
|
},
|
|
2428
|
-
...
|
|
3200
|
+
...packingPlugins ? packingPlugins.map((plugin) => ({
|
|
2429
3201
|
...plugin,
|
|
2430
3202
|
apply: "build",
|
|
2431
3203
|
enforce: "post",
|