Skip to content

Commit b47c62a

Browse files
committed
refactor(ts-code-mode-web): simplify Bun Vite config
Drop the quickjs-bun path walker/plugin/alias. Keep the working pattern: browser-only client resolve conditions, bun on SSR only, externalize quickjs-bun + the isolate driver, and CODE_MODE_BUN/Nitro bun preset.
1 parent d6b9fbf commit b47c62a

2 files changed

Lines changed: 72 additions & 320 deletions

File tree

Lines changed: 27 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,14 @@
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'
52
import { tanstackStart } from '@tanstack/react-start/plugin/vite'
63
import { nitro } from 'nitro/vite'
74
import viteReact from '@vitejs/plugin-react'
85
import tailwindcss from '@tailwindcss/vite'
96
import { 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).
2112
const 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. */
9829
const 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

Comments
 (0)