@timber-js/app 0.1.27 → 0.1.29
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/cli.d.ts +9 -3
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +6 -9
- package/dist/cli.js.map +1 -1
- package/dist/client/index.js +11 -34
- package/dist/client/index.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -21
- package/dist/index.js.map +1 -1
- package/dist/plugins/entries.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/cli.ts +13 -6
- package/src/index.ts +24 -1
- package/src/plugins/entries.ts +6 -34
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entries.d.ts","sourceRoot":"","sources":["../../src/plugins/entries.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAInC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAqGhD;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"entries.d.ts","sourceRoot":"","sources":["../../src/plugins/entries.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAInC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAqGhD;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CA+DxD"}
|
package/package.json
CHANGED
package/src/cli.ts
CHANGED
|
@@ -54,12 +54,19 @@ export function parseArgs(args: string[]): ParsedArgs {
|
|
|
54
54
|
|
|
55
55
|
// ─── Command Implementations ─────────────────────────────────────────────────
|
|
56
56
|
|
|
57
|
+
/** @internal Dependency injection for testing. */
|
|
58
|
+
export interface ViteDeps {
|
|
59
|
+
createServer?: typeof import('vite').createServer;
|
|
60
|
+
createBuilder?: typeof import('vite').createBuilder;
|
|
61
|
+
preview?: typeof import('vite').preview;
|
|
62
|
+
}
|
|
63
|
+
|
|
57
64
|
/**
|
|
58
65
|
* Start the Vite dev server.
|
|
59
66
|
* Middleware re-runs on file change via HMR wiring in timber-routing.
|
|
60
67
|
*/
|
|
61
|
-
export async function runDev(options: CommandOptions): Promise<void> {
|
|
62
|
-
const
|
|
68
|
+
export async function runDev(options: CommandOptions, _deps?: ViteDeps): Promise<void> {
|
|
69
|
+
const createServer = _deps?.createServer ?? (await import('vite')).createServer;
|
|
63
70
|
const server = await createServer({
|
|
64
71
|
configFile: options.config,
|
|
65
72
|
});
|
|
@@ -72,8 +79,8 @@ export async function runDev(options: CommandOptions): Promise<void> {
|
|
|
72
79
|
* Direct build() calls do NOT trigger the RSC plugin's multi-environment
|
|
73
80
|
* pipeline — createBuilder/buildApp is required.
|
|
74
81
|
*/
|
|
75
|
-
export async function runBuild(options: CommandOptions): Promise<void> {
|
|
76
|
-
const
|
|
82
|
+
export async function runBuild(options: CommandOptions, _deps?: ViteDeps): Promise<void> {
|
|
83
|
+
const createBuilder = _deps?.createBuilder ?? (await import('vite')).createBuilder;
|
|
77
84
|
const builder = await createBuilder({
|
|
78
85
|
configFile: options.config,
|
|
79
86
|
});
|
|
@@ -123,7 +130,7 @@ async function loadTimberConfig(
|
|
|
123
130
|
* If the adapter provides a preview() method, it takes priority.
|
|
124
131
|
* Otherwise falls back to Vite's built-in preview server.
|
|
125
132
|
*/
|
|
126
|
-
export async function runPreview(options: CommandOptions): Promise<void> {
|
|
133
|
+
export async function runPreview(options: CommandOptions, _deps?: ViteDeps): Promise<void> {
|
|
127
134
|
const { join } = await import('node:path');
|
|
128
135
|
|
|
129
136
|
// Try to load timber config for adapter-specific preview
|
|
@@ -139,7 +146,7 @@ export async function runPreview(options: CommandOptions): Promise<void> {
|
|
|
139
146
|
}
|
|
140
147
|
|
|
141
148
|
// Fallback: Vite's built-in preview server
|
|
142
|
-
const
|
|
149
|
+
const preview = _deps?.preview ?? (await import('vite')).preview;
|
|
143
150
|
const server = await preview({
|
|
144
151
|
configFile: options.config,
|
|
145
152
|
});
|
package/src/index.ts
CHANGED
|
@@ -303,7 +303,7 @@ export function timber(config?: TimberUserConfig): PluginOption[] {
|
|
|
303
303
|
// Also loads timber.config.ts and merges it into ctx.config (inline config wins).
|
|
304
304
|
const rootSync: Plugin = {
|
|
305
305
|
name: 'timber-root-sync',
|
|
306
|
-
async config(userConfig) {
|
|
306
|
+
async config(userConfig, { command }) {
|
|
307
307
|
// Load timber.config.ts early — before configResolved/buildStart — so
|
|
308
308
|
// all plugins (including timber-mdx) see the merged config in their
|
|
309
309
|
// buildStart hooks. The config hook runs once and supports async.
|
|
@@ -315,6 +315,29 @@ export function timber(config?: TimberUserConfig): PluginOption[] {
|
|
|
315
315
|
ctx.clientJavascript = resolveClientJavascript(ctx.config);
|
|
316
316
|
}
|
|
317
317
|
ctx.timer.end('config-load');
|
|
318
|
+
|
|
319
|
+
// Force production JSX transform for builds.
|
|
320
|
+
//
|
|
321
|
+
// Vite determines dev vs prod JSX via `isProduction`, which checks
|
|
322
|
+
// `process.env.NODE_ENV === 'production'`. If the shell has
|
|
323
|
+
// NODE_ENV=development (common in dev toolchains), `vite build`
|
|
324
|
+
// respects that and emits jsxDEV calls with fileName/lineNumber
|
|
325
|
+
// args. This causes runtime crashes because the production React
|
|
326
|
+
// jsx-runtime doesn't export jsxDEV, and also leaks file paths
|
|
327
|
+
// into production bundles (security concern).
|
|
328
|
+
//
|
|
329
|
+
// We explicitly set `oxc.jsx.development: false` for builds so
|
|
330
|
+
// the client bundle always uses jsx/jsxs from react/jsx-runtime,
|
|
331
|
+
// regardless of the ambient NODE_ENV value.
|
|
332
|
+
if (command === 'build') {
|
|
333
|
+
return {
|
|
334
|
+
oxc: {
|
|
335
|
+
jsx: {
|
|
336
|
+
development: false,
|
|
337
|
+
},
|
|
338
|
+
},
|
|
339
|
+
};
|
|
340
|
+
}
|
|
318
341
|
},
|
|
319
342
|
configResolved(resolved) {
|
|
320
343
|
ctx.root = resolved.root;
|
package/src/plugins/entries.ts
CHANGED
|
@@ -177,39 +177,11 @@ export function timberEntries(ctx: PluginContext): Plugin {
|
|
|
177
177
|
* in the client output. This is confusing since those chunks contain client
|
|
178
178
|
* components, not server code. Renaming clarifies their purpose.
|
|
179
179
|
*/
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
const newFileName = fileName.replace('rsc-entry', 'rsc-client-entry');
|
|
188
|
-
// Extract just the basename for matching code references like "./rsc-entry-XYZ.js"
|
|
189
|
-
const oldBase = fileName.split('/').pop()!;
|
|
190
|
-
const newBase = newFileName.split('/').pop()!;
|
|
191
|
-
|
|
192
|
-
chunk.fileName = newFileName;
|
|
193
|
-
chunk.name = chunk.name.replace('rsc-entry', 'rsc-client-entry');
|
|
194
|
-
bundle[newFileName] = chunk;
|
|
195
|
-
delete bundle[fileName];
|
|
196
|
-
|
|
197
|
-
// Update import references in other chunks
|
|
198
|
-
for (const other of Object.values(bundle)) {
|
|
199
|
-
if (other.type !== 'chunk') continue;
|
|
200
|
-
if (other.code.includes(oldBase)) {
|
|
201
|
-
other.code = other.code.replaceAll(oldBase, newBase);
|
|
202
|
-
}
|
|
203
|
-
if (other.imports) {
|
|
204
|
-
other.imports = other.imports.map((i) => (i === fileName ? newFileName : i));
|
|
205
|
-
}
|
|
206
|
-
if (other.dynamicImports) {
|
|
207
|
-
other.dynamicImports = other.dynamicImports.map((i) =>
|
|
208
|
-
i === fileName ? newFileName : i
|
|
209
|
-
);
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
},
|
|
180
|
+
// Note: chunk renaming (rsc-entry → rsc-client-entry) was previously done
|
|
181
|
+
// in generateBundle by mutating the bundle object. Rolldown does not support
|
|
182
|
+
// bundle mutation in generateBundle — assignments are silently ignored, which
|
|
183
|
+
// causes the renamed file to never be emitted while code references are
|
|
184
|
+
// updated, breaking client hydration. The rename is purely cosmetic and has
|
|
185
|
+
// been removed. The chunks keep their original "rsc-entry" names.
|
|
214
186
|
};
|
|
215
187
|
}
|