Skip to content

Commit 9230d05

Browse files
authored
feat: upgrade devframe to v0.9.1 and adopt bare-specifier dock client script resolution (#534)
1 parent e7366fa commit 9230d05

6 files changed

Lines changed: 255 additions & 179 deletions

File tree

e2e/tests/issue-339-static-build.test.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ describe('issue #339: static devtools build', () => {
4545
errors.find(e => /No dump match for "devtoolskit:internal:messages:list"/.test(e)),
4646
'RPC dump regression — messages:list dump missing for args [null]',
4747
).toBeUndefined()
48+
expect(
49+
errors.find(e => /No dump match for "devframe:rpc:server-state:get".+devframe:services/.test(e)),
50+
'RPC dump regression — devframe:services server-state missing (services barrier not fired at build)',
51+
).toBeUndefined()
4852
expect(errors, `unexpected errors:\n${errors.join('\n')}`).toHaveLength(0)
4953
expect(ready, 'DevTools SPA did not render').toBe(true)
5054
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import type { ViteDevToolsNodeContext } from '@vitejs/devtools-kit'
2+
import type { ViteDevServer } from 'vite'
3+
import { beforeEach, describe, expect, it, vi } from 'vitest'
4+
import { createDevToolsHub } from '../server'
5+
6+
const initHub = vi.hoisted(() => vi.fn())
7+
8+
vi.mock('@devframes/hub/initiate', () => ({
9+
initHub,
10+
}))
11+
12+
vi.mock('@devframes/json-render-ui/hub', () => ({
13+
jsonRenderUiRenderer: () => ({}),
14+
}))
15+
16+
vi.mock('../ui', () => ({
17+
createViteDevToolsUi: () => ({}),
18+
}))
19+
20+
vi.mock('../auth-handler', () => ({
21+
getAuthHandler: () => ({ rpcFunctions: [] }),
22+
}))
23+
24+
function fakeContext(opts: { viteServer?: boolean } = {}): ViteDevToolsNodeContext {
25+
return {
26+
mode: 'dev',
27+
viteConfig: { devtools: undefined },
28+
viteServer: opts.viteServer ? ({} as ViteDevServer) : undefined,
29+
host: { provideConnectionMeta: vi.fn() },
30+
} as unknown as ViteDevToolsNodeContext
31+
}
32+
33+
describe('createDevToolsHub client module resolution', () => {
34+
beforeEach(() => {
35+
vi.clearAllMocks()
36+
initHub.mockReturnValue({
37+
ready: Promise.resolve(),
38+
connectionMeta: () => ({}),
39+
nodeMiddleware: vi.fn(),
40+
close: vi.fn(),
41+
})
42+
})
43+
44+
it('advertises the Vite `/@id/` resolver when a live dev server backs the requests', async () => {
45+
await createDevToolsHub({ context: fakeContext({ viteServer: true }) })
46+
47+
expect(initHub).toHaveBeenCalledOnce()
48+
expect(initHub.mock.calls[0]![0]).toMatchObject({
49+
clientModuleResolution: '/@id/{specifier}',
50+
})
51+
})
52+
53+
it('leaves the resolver undeclared without a dev server (standalone / build)', async () => {
54+
await createDevToolsHub({ context: fakeContext({ viteServer: false }) })
55+
56+
expect(initHub).toHaveBeenCalledOnce()
57+
expect(initHub.mock.calls[0]![0]).not.toHaveProperty('clientModuleResolution')
58+
})
59+
})

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,14 @@ export async function buildStaticDevTools(options: BuildStaticOptions): Promise<
8585
}
8686
;(await context.rpc.sharedState.get(DOCK_RENDERERS_STATE_KEY, { initialValue: {} })).mutate(() => rendererManifest)
8787

88+
// Fire the services collect-then-setup barrier `initHub` runs in dev. The
89+
// live hub isn't stood up for a static snapshot, so nothing else seeds the
90+
// `devframe:services` shared state the client reads on load — without this,
91+
// the RPC dump has no match for `server-state:get(["devframe:services"])`
92+
// and the client logs a hard error. `ready()` always publishes the state
93+
// (empty when no services are installed) and is idempotent.
94+
await context.services.ready()
95+
8896
await fs.mkdir(resolve(devToolsRoot, DEVTOOLS_RPC_DUMP_DIRNAME), { recursive: true })
8997
await fs.writeFile(resolve(devToolsRoot, DEVTOOLS_CONNECTION_META_FILENAME), JSON.stringify({ backend: 'static' }, null, 2), 'utf-8')
9098
await fs.writeFile(resolve(devToolsRoot, DEVTOOLS_DOCK_IMPORTS_FILENAME), renderDockImportsMap(context.docks.values()), 'utf-8')

packages/core/src/node/server.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,15 @@ export async function createDevToolsHub(options: CreateDevToolsHubOptions): Prom
6969
// docks (kit's `createJsonRenderer`, the git/data-inspector devframes)
7070
// render instead of hub-ui's missing-renderer fallback.
7171
renderers: [jsonRenderUiRenderer()],
72+
// With a live Vite dev server, route bare-specifier dock client scripts
73+
// (`ClientScriptEntry.importFrom` naming an npm module, e.g.
74+
// vue-tracer's `vite-plugin-vue-tracer/client/vite-devtools`) through
75+
// Vite's own `/@id/` resolution — so they load through the inspected
76+
// app's module graph now that v0.9's middleware serves hub assets ahead
77+
// of Vite's transform pipeline. Standalone (CLI) and build snapshots have
78+
// no module graph to resolve against, so the template stays undeclared
79+
// there and such scripts must ship a self-contained bundle URL instead.
80+
...(context.viteServer ? { clientModuleResolution: '/@id/{specifier}' } : {}),
7281
auth: authDisabled ? false : getAuthHandler(context),
7382
...(allowedOrigins ? { allowedOrigins } : {}),
7483
...(options.server

0 commit comments

Comments
 (0)