1- import { existsSync } from 'node:fs'
2- import { dirname , join } from 'node:path'
3- import { fileURLToPath } from 'node:url'
4- import { defineConfig , type Plugin } from 'vite'
1+ import { defineConfig } from 'vite'
52import { tanstackStart } from '@tanstack/react-start/plugin/vite'
63import { nitro } from 'nitro/vite'
74import viteReact from '@vitejs/plugin-react'
85import tailwindcss from '@tailwindcss/vite'
96import { devtools } from '@tanstack/devtools-vite'
107
118// Native / wasm / binary server-only modules that can't be bundled by esbuild
12- // or rolldown (isolated-vm is a `.node` addon, the quickjs engines ship wasm,
13- // esbuild/puppeteer carry platform binaries). They stay external in every pass.
14- // nitro 3's server build (rolldown) externalizes node_modules but must *resolve*
15- // each external at build time; under pnpm these live under the isolate adapters'
16- // nested store dirs, so they're declared as direct dependencies of this example
17- // (see package.json) so the resolve succeeds. The pure-JS server deps that the
18- // old nitro-v2 externals list also named (google-auth-library, gaxios, jws,
19- // gcp-metadata, google-logging-utils, ws, node-fetch, openai) are left to be
20- // bundled normally — nitro 3 handles them without an explicit external entry.
9+ // or rolldown. They stay external so the host runtime loads them.
10+ // Under pnpm, declare them as direct deps of this example so nitro can resolve
11+ // them (see package.json).
2112const SERVER_ONLY_NATIVE = [
2213 'isolated-vm' ,
2314 'esbuild' ,
@@ -28,80 +19,30 @@ const SERVER_ONLY_NATIVE = [
2819 '@jitl/quickjs-wasmfile-release-sync' ,
2920 '@jitl/quickjs-wasmfile-debug-asyncify' ,
3021 '@jitl/quickjs-wasmfile-debug-sync' ,
22+ // Bun-native QuickJS (exports.bun only) — host Bun loads it, not Vite.
3123 'quickjs-bun' ,
24+ '@tanstack/ai-isolate-quickjs-bun' ,
25+ 'bun:ffi' ,
3226]
3327
34- /**
35- * quickjs-bun only publishes `exports["."].bun` (no import/default). Vite/Node
36- * package resolution always fails on that map — even with `conditions: ['bun']`
37- * under Nitro's module runner (which still hits resolvePackageEntry). Point at
38- * the package's `index.ts` on disk and mark it external so the Bun runtime
39- * loads it natively (bun:ffi + TypeScript).
40- */
41- function resolveQuickjsBunIndex ( ) : string {
42- const starts = [
43- dirname ( fileURLToPath ( import . meta. url ) ) ,
44- process . cwd ( ) ,
45- ]
46- for ( const start of starts ) {
47- let dir = start
48- for ( let i = 0 ; i < 14 ; i ++ ) {
49- const candidates = [
50- join ( dir , 'node_modules' , 'quickjs-bun' , 'index.ts' ) ,
51- join (
52- dir ,
53- 'packages' ,
54- 'ai-isolate-quickjs-bun' ,
55- 'node_modules' ,
56- 'quickjs-bun' ,
57- 'index.ts' ,
58- ) ,
59- ]
60- for ( const candidate of candidates ) {
61- if ( existsSync ( candidate ) ) return candidate
62- }
63- const parent = dirname ( dir )
64- if ( parent === dir ) break
65- dir = parent
66- }
67- }
68- throw new Error (
69- 'Could not locate quickjs-bun/index.ts. Run pnpm install from the monorepo root.' ,
70- )
71- }
72-
73- const quickjsBunIndex = resolveQuickjsBunIndex ( )
74-
75- function quickjsBunResolvePlugin ( ) : Plugin {
76- return {
77- name : 'resolve-quickjs-bun-entry' ,
78- enforce : 'pre' ,
79- resolveId ( id ) {
80- // Bare package or deep imports → absolute entry, always external so the
81- // Vite module runner never runInlinedModule()'s quickjs-bun (that path
82- // throws strict-mode SyntaxError on Bun-oriented source).
83- if (
84- id === 'quickjs-bun' ||
85- id . startsWith ( 'quickjs-bun/' ) ||
86- id === quickjsBunIndex ||
87- id . endsWith ( '/quickjs-bun/index.ts' ) ||
88- id . includes ( '/quickjs-bun/src/' )
89- ) {
90- return { id : quickjsBunIndex , external : true }
91- }
92- return null
93- } ,
94- }
95- }
96-
9728/** `CODE_MODE_BUN=1` or running the Vite CLI under Bun enables Bun isolate defaults. */
9829const codeModeBun =
9930 process . env . CODE_MODE_BUN === '1' ||
10031 typeof ( process . versions as { bun ?: string } ) . bun === 'string'
10132
102- const config = defineConfig ( {
33+ /**
34+ * Same lessons as the Bun Code Mode path:
35+ *
36+ * - Do **not** put `bun` in top-level `resolve.conditions`. router-core's
37+ * `isServer` maps `bun` → server build; the browser would get isServer=true,
38+ * createRouter never builds a store, hydrateStart crashes on `router.state`.
39+ * - Put `bun` only on `ssr.resolve.conditions` so `quickjs-bun` resolves under Bun.
40+ * - Externalize quickjs-bun + the isolate driver so Vite never inlines them.
41+ *
42+ * `pnpm dev:bun` → CODE_MODE_BUN=1 bun --bun vite dev
43+ */
44+ export default defineConfig ( {
10345 define : {
104- // Client UI defaults (selected isolate VM) follow the same flag.
10546 'import.meta.env.VITE_CODE_MODE_BUN' : JSON . stringify (
10647 codeModeBun ? '1' : '' ,
10748 ) ,
@@ -111,19 +52,11 @@ const config = defineConfig({
11152 } ,
11253 resolve : {
11354 tsconfigPaths : true ,
114- // Client must prefer `browser` over `bun`. router-core's isServer maps
115- // `bun` → server build (isServer=true); if the browser gets that, hydrate
116- // crashes on router.state. quickjs-bun is handled by the plugin + ssr.conditions.
55+ // Client: browser/import only — never prefer `bun` here.
11756 conditions : [ 'import' , 'module' , 'browser' , 'default' ] ,
118- alias : {
119- // Belt-and-suspenders for static analysis / tools that don't use resolveId
120- 'quickjs-bun' : quickjsBunIndex ,
121- } ,
12257 } ,
12358 plugins : [
124- quickjsBunResolvePlugin ( ) ,
12559 devtools ( ) ,
126- // Bun-optimized server only when in Bun mode — default Node Nitro for `pnpm dev`.
12760 // https://bun.com/docs/guides/ecosystem/tanstack-start
12861 nitro ( codeModeBun ? { preset : 'bun' } : { } ) ,
12962 tailwindcss ( ) ,
@@ -133,14 +66,16 @@ const config = defineConfig({
13366 ssr : {
13467 external : SERVER_ONLY_NATIVE ,
13568 resolve : {
136- // Always allow `bun` on the server so quickjs-bun resolves when the
137- // process is actually Bun (even without CODE_MODE_BUN).
69+ // Server under Bun: need `bun` for quickjs-bun's export map.
13870 conditions : [ 'bun' , 'node' , 'import' , 'module' , 'default' ] ,
13971 } ,
14072 } ,
14173 optimizeDeps : {
142- exclude : [ 'isolated-vm' , 'quickjs-emscripten' , 'quickjs-bun' ] ,
74+ exclude : [
75+ 'isolated-vm' ,
76+ 'quickjs-emscripten' ,
77+ 'quickjs-bun' ,
78+ '@tanstack/ai-isolate-quickjs-bun' ,
79+ ] ,
14380 } ,
14481} )
145-
146- export default config
0 commit comments