@timber-js/app 0.2.0-alpha.151 → 0.2.0-alpha.153
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/_chunks/actions-8lJZYYGq.js +298 -0
- package/dist/_chunks/actions-8lJZYYGq.js.map +1 -0
- package/dist/_chunks/{cache-api-Co-yI-gP.js → cache-api-e1E4i3Vy.js} +3 -26
- package/dist/_chunks/cache-api-e1E4i3Vy.js.map +1 -0
- package/dist/_chunks/{cli-schema-sync-DJDdyEae.js → cli-schema-sync-ChsRzw8o.js} +2 -2
- package/dist/_chunks/{cli-schema-sync-DJDdyEae.js.map → cli-schema-sync-ChsRzw8o.js.map} +1 -1
- package/dist/_chunks/{cli-schema-sync-D_IhHEUW.js → cli-schema-sync-D4urWkeV.js} +1 -1
- package/dist/_chunks/{actions-a0RczDnB.js → logger-DvmCWhN9.js} +665 -274
- package/dist/_chunks/logger-DvmCWhN9.js.map +1 -0
- package/dist/_chunks/plugin-context-GfDWsdd2.js.map +1 -1
- package/dist/_chunks/{walkers-DvWDj453.js → walkers-DZuFKqFX.js} +2 -2
- package/dist/_chunks/{walkers-DvWDj453.js.map → walkers-DZuFKqFX.js.map} +1 -1
- package/dist/cache/index.js +1 -1
- package/dist/cli.js +1 -1
- package/dist/client/browser-dev.d.ts +3 -0
- package/dist/client/browser-dev.d.ts.map +1 -1
- package/dist/config-types.d.ts +8 -0
- package/dist/config-types.d.ts.map +1 -1
- package/dist/config-validation.d.ts.map +1 -1
- package/dist/index.js +193 -48
- package/dist/index.js.map +1 -1
- package/dist/plugin-context.d.ts +9 -0
- package/dist/plugin-context.d.ts.map +1 -1
- package/dist/plugins/build-report.d.ts +13 -0
- package/dist/plugins/build-report.d.ts.map +1 -1
- package/dist/plugins/chunks.d.ts +11 -4
- package/dist/plugins/chunks.d.ts.map +1 -1
- package/dist/plugins/client-chunks.d.ts +23 -22
- package/dist/plugins/client-chunks.d.ts.map +1 -1
- package/dist/routing/index.js +2 -2
- package/dist/server/index.js +2 -2
- package/dist/server/internal.js +65 -2
- package/dist/server/internal.js.map +1 -1
- package/dist/server/logger.d.ts.map +1 -1
- package/dist/server/pipeline.d.ts.map +1 -1
- package/dist/server/primitives.d.ts +8 -0
- package/dist/server/primitives.d.ts.map +1 -1
- package/dist/server/route-element-builder.d.ts.map +1 -1
- package/dist/server/stream-utils.d.ts +11 -0
- package/dist/server/stream-utils.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/client/browser-dev.ts +3 -0
- package/src/config-types.ts +8 -0
- package/src/config-validation.ts +16 -0
- package/src/index.ts +2 -2
- package/src/plugin-context.ts +9 -0
- package/src/plugins/build-report.ts +105 -10
- package/src/plugins/chunks.ts +74 -5
- package/src/plugins/client-chunks.ts +73 -42
- package/src/server/logger.ts +5 -0
- package/src/server/pipeline.ts +13 -0
- package/src/server/primitives.ts +29 -0
- package/src/server/route-element-builder.ts +4 -1
- package/src/server/stream-utils.ts +73 -0
- package/dist/_chunks/actions-a0RczDnB.js.map +0 -1
- package/dist/_chunks/cache-api-Co-yI-gP.js.map +0 -1
- package/dist/_chunks/logger-CM0clugc.js +0 -645
- package/dist/_chunks/logger-CM0clugc.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { c as isDynamicMetadataExtension, l as isMetadataRouteServePath, r as canonicalize } from "./_chunks/canonicalize-P41GR6tY.js";
|
|
2
2
|
import { t as matchUrlParts } from "./_chunks/tree-match-D2l830j2.js";
|
|
3
|
-
import { h as swallow } from "./_chunks/logger-
|
|
4
|
-
import { s as scanRoutes } from "./_chunks/cli-schema-sync-
|
|
5
|
-
import { a as generateRouteMap, i as validateSchemaAgainstRoutes, n as collectInterceptionRewrites, o as readFileCached, t as collectLeafRoutes } from "./_chunks/walkers-
|
|
3
|
+
import { h as swallow } from "./_chunks/logger-DvmCWhN9.js";
|
|
4
|
+
import { s as scanRoutes } from "./_chunks/cli-schema-sync-ChsRzw8o.js";
|
|
5
|
+
import { a as generateRouteMap, i as validateSchemaAgainstRoutes, n as collectInterceptionRewrites, o as readFileCached, t as collectLeafRoutes } from "./_chunks/walkers-DZuFKqFX.js";
|
|
6
6
|
import { a as mergeFileConfig, c as resolveClientJavascript, i as loadTimberConfigFile, o as resolveAppDir, r as createPluginContext, s as resolveBuildDir, u as createNoopTimer } from "./_chunks/plugin-context-GfDWsdd2.js";
|
|
7
7
|
import { t as fnv1aHash } from "./_chunks/fast-hash-D6hIVt1Y.js";
|
|
8
8
|
import { t as formatSize } from "./_chunks/format-CfwjgPz9.js";
|
|
@@ -1153,6 +1153,14 @@ function validateConfig(config) {
|
|
|
1153
1153
|
value: config.sitemap.defaultPriority
|
|
1154
1154
|
});
|
|
1155
1155
|
}
|
|
1156
|
+
if (config.budget != null && typeof config.budget === "object") {
|
|
1157
|
+
if (config.budget.firstLoadJs !== void 0 && (typeof config.budget.firstLoadJs !== "number" || config.budget.firstLoadJs <= 0)) errors.push({
|
|
1158
|
+
field: "budget.firstLoadJs",
|
|
1159
|
+
message: `budget.firstLoadJs must be a positive number in bytes (got ${JSON.stringify(config.budget.firstLoadJs)}).`,
|
|
1160
|
+
value: config.budget.firstLoadJs,
|
|
1161
|
+
suggestion: "Example: budget: { firstLoadJs: 150_000 } for a ~150 kB limit."
|
|
1162
|
+
});
|
|
1163
|
+
}
|
|
1156
1164
|
for (const key of Object.keys(config)) if (!knownKeys.has(key)) errors.push({
|
|
1157
1165
|
field: key,
|
|
1158
1166
|
message: `Unknown config option: "${key}".`,
|
|
@@ -1248,7 +1256,8 @@ var init_config_validation = __esmMin((() => {
|
|
|
1248
1256
|
reactCompiler: true,
|
|
1249
1257
|
sitemap: true,
|
|
1250
1258
|
buildDir: true,
|
|
1251
|
-
topLoader: true
|
|
1259
|
+
topLoader: true,
|
|
1260
|
+
budget: true
|
|
1252
1261
|
}));
|
|
1253
1262
|
RED$1 = "\x1B[31m";
|
|
1254
1263
|
BOLD$1 = "\x1B[1m";
|
|
@@ -6734,11 +6743,52 @@ function timberReactProd() {
|
|
|
6734
6743
|
//#endregion
|
|
6735
6744
|
//#region src/plugins/chunks.ts
|
|
6736
6745
|
/**
|
|
6746
|
+
* Build a map from absolute module IDs in non-facade RSC chunks to the
|
|
6747
|
+
* absolute facade module paths that transitively import them.
|
|
6748
|
+
*
|
|
6749
|
+
* Used by `clientChunkGroup` to reclassify `shared:` client references
|
|
6750
|
+
* that are only consumed by a single route boundary (TIM-1107).
|
|
6751
|
+
*/
|
|
6752
|
+
function buildFacadeAncestryMap(bundle) {
|
|
6753
|
+
const chunks = /* @__PURE__ */ new Map();
|
|
6754
|
+
for (const [file, asset] of Object.entries(bundle)) if (asset.type === "chunk") chunks.set(file, asset);
|
|
6755
|
+
const importedBy = /* @__PURE__ */ new Map();
|
|
6756
|
+
for (const [file, chunk] of chunks) for (const imp of chunk.imports) {
|
|
6757
|
+
let parents = importedBy.get(imp);
|
|
6758
|
+
if (!parents) {
|
|
6759
|
+
parents = [];
|
|
6760
|
+
importedBy.set(imp, parents);
|
|
6761
|
+
}
|
|
6762
|
+
parents.push(file);
|
|
6763
|
+
}
|
|
6764
|
+
function facadeAncestors(file, visited) {
|
|
6765
|
+
if (visited.has(file)) return [];
|
|
6766
|
+
visited.add(file);
|
|
6767
|
+
const chunk = chunks.get(file);
|
|
6768
|
+
if (!chunk) return [];
|
|
6769
|
+
if (chunk.facadeModuleId) return [chunk.facadeModuleId];
|
|
6770
|
+
const parents = importedBy.get(file) ?? [];
|
|
6771
|
+
const result = [];
|
|
6772
|
+
for (const p of parents) for (const f of facadeAncestors(p, visited)) result.push(f);
|
|
6773
|
+
return result;
|
|
6774
|
+
}
|
|
6775
|
+
const moduleToFacades = /* @__PURE__ */ new Map();
|
|
6776
|
+
for (const [file, chunk] of chunks) {
|
|
6777
|
+
if (chunk.facadeModuleId) continue;
|
|
6778
|
+
const facades = facadeAncestors(file, /* @__PURE__ */ new Set());
|
|
6779
|
+
if (facades.length === 0) continue;
|
|
6780
|
+
const unique = [...new Set(facades)];
|
|
6781
|
+
for (const modId of chunk.moduleIds) moduleToFacades.set(modId, unique);
|
|
6782
|
+
}
|
|
6783
|
+
return moduleToFacades;
|
|
6784
|
+
}
|
|
6785
|
+
/**
|
|
6737
6786
|
* Create the timber-chunks Vite plugin.
|
|
6738
6787
|
*
|
|
6739
|
-
*
|
|
6740
|
-
*
|
|
6741
|
-
*
|
|
6788
|
+
* Rolldown's default splitting produces the desired output (one main
|
|
6789
|
+
* bundle + per-route chunks). This plugin's main job is building the
|
|
6790
|
+
* facade ancestry map during the RSC build so `clientChunkGroup` can
|
|
6791
|
+
* reclassify shared client references to their correct route boundary.
|
|
6742
6792
|
*
|
|
6743
6793
|
* NOTE: Ideally we'd use Rolldown's `format: 'app'` (module registry format)
|
|
6744
6794
|
* which guarantees single-copy module semantics like webpack/Turbopack.
|
|
@@ -6748,21 +6798,31 @@ function timberReactProd() {
|
|
|
6748
6798
|
*
|
|
6749
6799
|
* Design docs: 27-chunking-strategy.md
|
|
6750
6800
|
*/
|
|
6751
|
-
function timberChunks() {
|
|
6752
|
-
return {
|
|
6801
|
+
function timberChunks(ctx) {
|
|
6802
|
+
return {
|
|
6803
|
+
name: "timber-chunks",
|
|
6804
|
+
generateBundle(_options, bundle) {
|
|
6805
|
+
if (this.environment?.name !== "rsc") return;
|
|
6806
|
+
ctx.sharedModuleFacades = buildFacadeAncestryMap(bundle);
|
|
6807
|
+
}
|
|
6808
|
+
};
|
|
6753
6809
|
}
|
|
6754
6810
|
//#endregion
|
|
6755
6811
|
//#region src/plugins/client-chunks.ts
|
|
6756
6812
|
/**
|
|
6757
6813
|
* Client chunk grouping strategy for @vitejs/plugin-rsc.
|
|
6758
6814
|
*
|
|
6759
|
-
* Groups client reference modules by
|
|
6760
|
-
*
|
|
6761
|
-
*
|
|
6762
|
-
*
|
|
6763
|
-
*
|
|
6815
|
+
* Groups client reference modules by the **consuming route's** layout boundary
|
|
6816
|
+
* (derived from `meta.serverChunk`), not by the module's own file location.
|
|
6817
|
+
* This ensures components in shared directories (e.g. `components/`) land in
|
|
6818
|
+
* the chunk of the route that uses them, not in a single catch-all chunk.
|
|
6819
|
+
*
|
|
6820
|
+
* For `shared:` modules (client references in non-facade RSC chunks), the
|
|
6821
|
+
* function consults a facade ancestry map built during the RSC build. If all
|
|
6822
|
+
* consuming facades belong to the same route boundary, the module is
|
|
6823
|
+
* reclassified to that boundary instead of falling through to `client-shared`.
|
|
6764
6824
|
*
|
|
6765
|
-
* See design/27-chunking-strategy.md, TIM-440, TIM-499.
|
|
6825
|
+
* See design/27-chunking-strategy.md, TIM-440, TIM-499, TIM-1104, TIM-1107.
|
|
6766
6826
|
*/
|
|
6767
6827
|
/**
|
|
6768
6828
|
* Check whether a root-relative path lives under the app directory,
|
|
@@ -6795,34 +6855,53 @@ function findAppBoundary(path, appPrefix) {
|
|
|
6795
6855
|
};
|
|
6796
6856
|
}
|
|
6797
6857
|
/**
|
|
6858
|
+
* For a `shared:` client reference, check the facade ancestry map to
|
|
6859
|
+
* see if all consuming facades belong to the same route boundary.
|
|
6860
|
+
* Returns the boundary segment name, or null if the module is
|
|
6861
|
+
* genuinely shared across multiple boundaries.
|
|
6862
|
+
*/
|
|
6863
|
+
function reclassifySharedModule(meta, appPrefix, root, sharedModuleFacades) {
|
|
6864
|
+
const facades = sharedModuleFacades.get(meta.id);
|
|
6865
|
+
if (!facades || facades.length === 0) return null;
|
|
6866
|
+
const boundaries = /* @__PURE__ */ new Set();
|
|
6867
|
+
for (const facade of facades) {
|
|
6868
|
+
const result = findAppBoundary(relative(root, facade).replace(/\\/g, "/"), appPrefix);
|
|
6869
|
+
if (result.inApp && result.segment) boundaries.add(result.segment);
|
|
6870
|
+
else if (result.inApp) return null;
|
|
6871
|
+
else return null;
|
|
6872
|
+
}
|
|
6873
|
+
if (boundaries.size === 1) return [...boundaries][0];
|
|
6874
|
+
return null;
|
|
6875
|
+
}
|
|
6876
|
+
/**
|
|
6798
6877
|
* Derive a chunk group name for a client reference module.
|
|
6799
6878
|
*
|
|
6800
|
-
*
|
|
6801
|
-
*
|
|
6802
|
-
*
|
|
6879
|
+
* Always derives the group from the **consuming route** (`serverChunk`'s
|
|
6880
|
+
* facade path), not from the module's own file location. This prevents
|
|
6881
|
+
* components in shared directories (e.g. `app/components/`, `src/lib/`)
|
|
6882
|
+
* from collapsing into a single chunk when they're only used by one route.
|
|
6883
|
+
*
|
|
6884
|
+
* For `shared:` modules (non-facade RSC chunks), consults the facade
|
|
6885
|
+
* ancestry map to reclassify modules that are only consumed by a single
|
|
6886
|
+
* route boundary. This prevents large dependencies from polluting
|
|
6887
|
+
* `client-shared` when they're route-scoped (TIM-1107).
|
|
6888
|
+
*
|
|
6889
|
+
* Examples:
|
|
6803
6890
|
* - `facade:app/dashboard/settings/page.tsx` → `"client-dashboard"`
|
|
6804
6891
|
* - `facade:app/(group-a)/group-page-a/page.tsx` → `"client-group-page-a"`
|
|
6805
6892
|
* - `facade:app/layout.tsx` (root layout) → `"client-shared"`
|
|
6806
|
-
* - `shared:...` (shared across chunks) → `"client-shared"`
|
|
6807
|
-
|
|
6808
|
-
|
|
6809
|
-
|
|
6810
|
-
* the layout boundary from the serverChunk's facade path. This prevents
|
|
6811
|
-
* lazily-loaded client dependencies (e.g. via import.meta.glob) from
|
|
6812
|
-
* being hoisted into the shared chunk when they're only used by a
|
|
6813
|
-
* specific route.
|
|
6814
|
-
*
|
|
6815
|
-
* This balances route-scoped code splitting with HTTP request count:
|
|
6816
|
-
* fewer chunks than per-serverChunk, but still avoids downloading every
|
|
6817
|
-
* client component on every page.
|
|
6818
|
-
*/
|
|
6819
|
-
function clientChunkGroup(meta, appDir, root) {
|
|
6820
|
-
const { normalizedId, serverChunk } = meta;
|
|
6821
|
-
if (serverChunk.startsWith("shared:")) return "client-shared";
|
|
6893
|
+
* - `shared:...` (shared across chunks) → reclassified or `"client-shared"`
|
|
6894
|
+
*/
|
|
6895
|
+
function clientChunkGroup(meta, appDir, root, sharedModuleFacades) {
|
|
6896
|
+
const { serverChunk } = meta;
|
|
6822
6897
|
const appPrefix = relative(root, appDir).replace(/\\/g, "/") + "/";
|
|
6823
|
-
|
|
6824
|
-
|
|
6825
|
-
|
|
6898
|
+
if (serverChunk.startsWith("shared:")) {
|
|
6899
|
+
if (sharedModuleFacades) {
|
|
6900
|
+
const boundary = reclassifySharedModule(meta, appPrefix, root, sharedModuleFacades);
|
|
6901
|
+
if (boundary) return `client-${boundary}`;
|
|
6902
|
+
}
|
|
6903
|
+
return "client-shared";
|
|
6904
|
+
}
|
|
6826
6905
|
if (serverChunk.startsWith("facade:")) {
|
|
6827
6906
|
const facadePath = serverChunk.slice(7).replace(/\\/g, "/");
|
|
6828
6907
|
const facadeResult = findAppBoundary(facadePath, appPrefix);
|
|
@@ -7397,6 +7476,14 @@ function buildRouteReport(entries, sharedSize) {
|
|
|
7397
7476
|
lines.push("○ (Static) λ (Dynamic) ƒ (Function)");
|
|
7398
7477
|
return lines;
|
|
7399
7478
|
}
|
|
7479
|
+
/** Check route entries against a First-Load-JS budget and return warning lines. */
|
|
7480
|
+
function buildWarnings(entries, budget) {
|
|
7481
|
+
if (!budget?.firstLoadJs) return [];
|
|
7482
|
+
const limit = budget.firstLoadJs;
|
|
7483
|
+
const warnings = [];
|
|
7484
|
+
for (const entry of entries) if (entry.firstLoadSize > limit) warnings.push(`⚠ ${entry.path} first-load JS (${formatSize(entry.firstLoadSize)}) exceeds budget (${formatSize(limit)})`);
|
|
7485
|
+
return warnings;
|
|
7486
|
+
}
|
|
7400
7487
|
function pad(str, width, align = "right") {
|
|
7401
7488
|
const gap = Math.max(0, width - stripAnsi(str).length);
|
|
7402
7489
|
return align === "left" ? " ".repeat(gap) + str : str + " ".repeat(gap);
|
|
@@ -7430,7 +7517,42 @@ function findChunkForFile(filePath, bundle) {
|
|
|
7430
7517
|
}
|
|
7431
7518
|
return null;
|
|
7432
7519
|
}
|
|
7433
|
-
|
|
7520
|
+
/**
|
|
7521
|
+
* Derive the expected client chunk group prefix for a route.
|
|
7522
|
+
*
|
|
7523
|
+
* Mirrors the `clientChunkGroup` logic: extract the first non-group segment
|
|
7524
|
+
* from the route's file path under appDir. Routes at the root level or
|
|
7525
|
+
* without a matching segment return null (their JS is in client-shared).
|
|
7526
|
+
*/
|
|
7527
|
+
function routeChunkGroupPrefix(entryFilePath, appDir, root) {
|
|
7528
|
+
const appPrefix = relative(root, appDir).replace(/\\/g, "/") + "/";
|
|
7529
|
+
const relPath = relative(root, entryFilePath).replace(/\\/g, "/");
|
|
7530
|
+
if (!relPath.startsWith(appPrefix)) return null;
|
|
7531
|
+
const segments = relPath.slice(appPrefix.length).split("/");
|
|
7532
|
+
for (const seg of segments) {
|
|
7533
|
+
if (seg.includes(".")) break;
|
|
7534
|
+
if (seg.startsWith("(") && seg.endsWith(")")) continue;
|
|
7535
|
+
return `client-${seg}`;
|
|
7536
|
+
}
|
|
7537
|
+
return null;
|
|
7538
|
+
}
|
|
7539
|
+
/**
|
|
7540
|
+
* Find all client bundle chunks belonging to a chunk group.
|
|
7541
|
+
*
|
|
7542
|
+
* Uses the chunk's `name` property (set by Rolldown from the `clientChunks`
|
|
7543
|
+
* callback's return value) for exact matching. The `name` is the group name
|
|
7544
|
+
* itself (e.g. `client-docs`), not the hashed filename.
|
|
7545
|
+
*/
|
|
7546
|
+
function findChunksForGroup(groupName, chunkSizes, bundle) {
|
|
7547
|
+
if (!bundle) return [];
|
|
7548
|
+
const matched = [];
|
|
7549
|
+
for (const [fileName, item] of Object.entries(bundle)) {
|
|
7550
|
+
if (item.type !== "chunk") continue;
|
|
7551
|
+
if (item.name === groupName && chunkSizes.has(fileName)) matched.push(fileName);
|
|
7552
|
+
}
|
|
7553
|
+
return matched;
|
|
7554
|
+
}
|
|
7555
|
+
function buildEntries(routeTree, chunkSizes, bundle, outputMode, appDir, root) {
|
|
7434
7556
|
const routeInfos = collectRoutes(routeTree);
|
|
7435
7557
|
let totalGzip = 0;
|
|
7436
7558
|
for (const s of chunkSizes.values()) totalGzip += s.gzip;
|
|
@@ -7440,14 +7562,32 @@ function buildEntries(routeTree, chunkSizes, bundle, outputMode) {
|
|
|
7440
7562
|
let raw = 0;
|
|
7441
7563
|
let gzip = 0;
|
|
7442
7564
|
if (info.entryFilePath) {
|
|
7443
|
-
|
|
7444
|
-
if (
|
|
7445
|
-
const
|
|
7446
|
-
if (
|
|
7447
|
-
|
|
7448
|
-
|
|
7565
|
+
let matched = false;
|
|
7566
|
+
if (appDir && root) {
|
|
7567
|
+
const groupPrefix = routeChunkGroupPrefix(info.entryFilePath, appDir, root);
|
|
7568
|
+
if (groupPrefix) {
|
|
7569
|
+
const chunks = findChunksForGroup(groupPrefix, chunkSizes, bundle);
|
|
7570
|
+
for (const chunk of chunks) {
|
|
7571
|
+
const s = chunkSizes.get(chunk);
|
|
7572
|
+
if (s) {
|
|
7573
|
+
raw += s.raw;
|
|
7574
|
+
gzip += s.gzip;
|
|
7575
|
+
}
|
|
7576
|
+
routeChunkFiles.add(chunk);
|
|
7577
|
+
}
|
|
7578
|
+
if (chunks.length > 0) matched = true;
|
|
7579
|
+
}
|
|
7580
|
+
}
|
|
7581
|
+
if (!matched) {
|
|
7582
|
+
const chunk = findChunkForFile(info.entryFilePath, bundle);
|
|
7583
|
+
if (chunk) {
|
|
7584
|
+
const s = chunkSizes.get(chunk);
|
|
7585
|
+
if (s) {
|
|
7586
|
+
raw = s.raw;
|
|
7587
|
+
gzip = s.gzip;
|
|
7588
|
+
}
|
|
7589
|
+
routeChunkFiles.add(chunk);
|
|
7449
7590
|
}
|
|
7450
|
-
routeChunkFiles.add(chunk);
|
|
7451
7591
|
}
|
|
7452
7592
|
}
|
|
7453
7593
|
entries.push({
|
|
@@ -7525,11 +7665,16 @@ function timberBuildReport(ctx) {
|
|
|
7525
7665
|
firstLoadSize: 0
|
|
7526
7666
|
})),
|
|
7527
7667
|
sharedGzip: 0
|
|
7528
|
-
} : buildEntries(ctx.routeTree, chunkSizes, clientBundle, outputMode);
|
|
7668
|
+
} : buildEntries(ctx.routeTree, chunkSizes, clientBundle, outputMode, ctx.appDir, ctx.root);
|
|
7529
7669
|
const elapsed = ((performance.now() - buildStart) / 1e3).toFixed(2);
|
|
7530
7670
|
const lines = buildRouteReport(entries, sharedGzip);
|
|
7531
7671
|
logger.info("");
|
|
7532
7672
|
for (const line of lines) logger.info(line);
|
|
7673
|
+
const warnings = buildWarnings(entries, ctx.config.budget);
|
|
7674
|
+
if (warnings.length > 0) {
|
|
7675
|
+
logger.info("");
|
|
7676
|
+
for (const w of warnings) logger.warn(w);
|
|
7677
|
+
}
|
|
7533
7678
|
logger.info("");
|
|
7534
7679
|
logger.info(`✓ built ${entries.length} routes for all three environments (rsc, ssr, client) in ${elapsed}s`);
|
|
7535
7680
|
logger.info("");
|
|
@@ -7931,7 +8076,7 @@ function createRscOptions(ctx, encryptionKeyExpr) {
|
|
|
7931
8076
|
ssr: "virtual:timber-ssr-entry",
|
|
7932
8077
|
client: "virtual:timber-browser-entry"
|
|
7933
8078
|
},
|
|
7934
|
-
clientChunks: (meta) => clientChunkGroup(meta, ctx.appDir, ctx.root)
|
|
8079
|
+
clientChunks: (meta) => clientChunkGroup(meta, ctx.appDir, ctx.root, ctx.sharedModuleFacades)
|
|
7935
8080
|
};
|
|
7936
8081
|
Object.defineProperty(options, "enableActionEncryption", {
|
|
7937
8082
|
get() {
|
|
@@ -8092,7 +8237,7 @@ function timber(config) {
|
|
|
8092
8237
|
timberContent(ctx),
|
|
8093
8238
|
timberServerBundle(),
|
|
8094
8239
|
timberCloudflareWasm(ctx),
|
|
8095
|
-
timberChunks(),
|
|
8240
|
+
timberChunks(ctx),
|
|
8096
8241
|
timberBuildReport(ctx),
|
|
8097
8242
|
timberAdapterBuild(ctx),
|
|
8098
8243
|
timberDevLogs(ctx),
|