Skip to content

Commit e640296

Browse files
authored
feat(core): honor deploy base in static build (#555)
1 parent f5abefb commit e640296

4 files changed

Lines changed: 43 additions & 4 deletions

File tree

packages/core/src/node/__tests__/build-static-renderers.test.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,4 +66,24 @@ describe('buildStaticDevTools renderers', () => {
6666
'custom-render': { importFrom: '/__devtools/__renderers/custom-render.mjs' },
6767
})
6868
})
69+
70+
it('prefixes the deploy base onto renderer imports and the root redirect', async () => {
71+
const temporaryDirectory = await mkdtemp(join(tmpdir(), 'vite-devtools-renderers-base-'))
72+
const replacementFile = join(temporaryDirectory, 'replacement.mjs')
73+
const outputDirectory = join(temporaryDirectory, 'output')
74+
await writeFile(replacementFile, 'export const replacement = true')
75+
76+
await buildStaticDevTools({
77+
context: fakeContext(),
78+
outDir: outputDirectory,
79+
base: '/ci-build-123456/',
80+
renderers: [{ type: 'json-render', file: replacementFile }],
81+
})
82+
83+
expect(mutateRendererManifest.mock.calls[0]![0]({})).toEqual({
84+
'json-render': { importFrom: '/ci-build-123456/__devtools/__renderers/json-render.mjs' },
85+
})
86+
expect(await readFile(join(outputDirectory, 'index.html'), 'utf8'))
87+
.toContain('location.replace("/ci-build-123456/__devtools/")')
88+
})
6989
})

packages/core/src/node/build-static.ts

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,33 @@ import { createViteDevToolsUi } from './ui'
2323
export interface BuildStaticOptions {
2424
context: ViteDevToolsNodeContext
2525
outDir: string
26+
/**
27+
* Absolute path the snapshot is deployed under (e.g. `/ci-build-123456/`).
28+
* Prefixes the root-relative URLs baked into the output — the root redirect
29+
* and the dock-renderer import specifiers — so the snapshot works when hosted
30+
* below the domain root. Defaults to `/`.
31+
*/
32+
base?: string
2633
/** Dock renderer modules copied into the static output, replacing built-ins by matching type. */
2734
renderers?: readonly DockRendererRegistration[]
2835
withApp?: boolean
2936
/** Reference-UI options forwarded to `createUi`. */
3037
ui?: ViteDevToolsUiOptions
3138
}
3239

40+
/**
41+
* Join the deploy `base` with the kit-pinned `/__devtools/` mount so absolute
42+
* URLs in the snapshot point at the right place when hosted below the domain
43+
* root. `/` (the default) collapses to the bare mount path.
44+
*/
45+
function resolveMountPath(base: string): string {
46+
const prefix = base.replace(/\/+$/, '')
47+
return prefix ? `${prefix}${DEVTOOLS_MOUNT_PATH}` : DEVTOOLS_MOUNT_PATH
48+
}
49+
3350
export async function buildStaticDevTools(options: BuildStaticOptions): Promise<void> {
3451
const { context, outDir, withApp } = options
52+
const mountPath = resolveMountPath(options.base ?? '/')
3553

3654
if (!withApp && existsSync(outDir))
3755
await fs.rm(outDir, { recursive: true })
@@ -82,7 +100,7 @@ export async function buildStaticDevTools(options: BuildStaticOptions): Promise<
82100
for (const registration of resolveDockRendererRegistrations(options.renderers)) {
83101
await fs.cp(registration.file, resolve(renderersRoot, `${registration.type}.mjs`))
84102
rendererManifest[registration.type] = {
85-
importFrom: `${DEVTOOLS_MOUNT_PATH}__renderers/${registration.type}.mjs`,
103+
importFrom: `${mountPath}__renderers/${registration.type}.mjs`,
86104
}
87105
}
88106
;(await context.rpc.sharedState.get(DOCK_RENDERERS_STATE_KEY, { initialValue: {} })).mutate(() => rendererManifest)
@@ -121,10 +139,10 @@ export async function buildStaticDevTools(options: BuildStaticOptions): Promise<
121139
' <meta charset="UTF-8">',
122140
' <meta name="viewport" content="width=device-width, initial-scale=1.0">',
123141
' <title>Vite DevTools</title>',
124-
` <meta http-equiv="refresh" content="0; url=${DEVTOOLS_MOUNT_PATH}">`,
142+
` <meta http-equiv="refresh" content="0; url=${mountPath}">`,
125143
'</head>',
126144
'<body>',
127-
` <script>location.replace(${JSON.stringify(DEVTOOLS_MOUNT_PATH)})</script>`,
145+
` <script>location.replace(${JSON.stringify(mountPath)})</script>`,
128146
'</body>',
129147
'</html>',
130148
].join('\n'),

packages/core/src/node/cli-commands.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ export async function build(options: BuildOptions) {
4040
await buildStaticDevTools({
4141
context: devtools.context,
4242
outDir,
43+
base: options.base,
4344
})
4445

4546
diagnostics.DTK0010()

packages/core/src/node/plugins/build.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ export function DevToolsBuild(options: DevToolsBuildOptions = {}): Plugin {
4545
: resolve(resolvedConfig.root, resolvedConfig.build.outDir)
4646

4747
const { buildStaticDevTools } = await import('../build-static')
48-
await buildStaticDevTools({ context, outDir, withApp: true, ui: options.ui, renderers: options.renderers })
48+
await buildStaticDevTools({ context, outDir, base: resolvedConfig.base, withApp: true, ui: options.ui, renderers: options.renderers })
4949
},
5050
}
5151
}

0 commit comments

Comments
 (0)