Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions e2e/tests/issue-339-static-build.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ describe('issue #339: static devtools build', () => {
errors.find(e => /No dump match for "devtoolskit:internal:messages:list"/.test(e)),
'RPC dump regression — messages:list dump missing for args [null]',
).toBeUndefined()
expect(
errors.find(e => /No dump match for "devframe:rpc:server-state:get".+devframe:services/.test(e)),
'RPC dump regression — devframe:services server-state missing (services barrier not fired at build)',
).toBeUndefined()
expect(errors, `unexpected errors:\n${errors.join('\n')}`).toHaveLength(0)
expect(ready, 'DevTools SPA did not render').toBe(true)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import type { ViteDevToolsNodeContext } from '@vitejs/devtools-kit'
import type { ViteDevServer } from 'vite'
import { beforeEach, describe, expect, it, vi } from 'vitest'
import { createDevToolsHub } from '../server'

const initHub = vi.hoisted(() => vi.fn())

vi.mock('@devframes/hub/initiate', () => ({
initHub,
}))

vi.mock('@devframes/json-render-ui/hub', () => ({
jsonRenderUiRenderer: () => ({}),
}))

vi.mock('../ui', () => ({
createViteDevToolsUi: () => ({}),
}))

vi.mock('../auth-handler', () => ({
getAuthHandler: () => ({ rpcFunctions: [] }),
}))

function fakeContext(opts: { viteServer?: boolean } = {}): ViteDevToolsNodeContext {
return {
mode: 'dev',
viteConfig: { devtools: undefined },
viteServer: opts.viteServer ? ({} as ViteDevServer) : undefined,
host: { provideConnectionMeta: vi.fn() },
} as unknown as ViteDevToolsNodeContext
}

describe('createDevToolsHub client module resolution', () => {
beforeEach(() => {
vi.clearAllMocks()
initHub.mockReturnValue({
ready: Promise.resolve(),
connectionMeta: () => ({}),
nodeMiddleware: vi.fn(),
close: vi.fn(),
})
})

it('advertises the Vite `/@id/` resolver when a live dev server backs the requests', async () => {
await createDevToolsHub({ context: fakeContext({ viteServer: true }) })

expect(initHub).toHaveBeenCalledOnce()
expect(initHub.mock.calls[0]![0]).toMatchObject({
clientModuleResolution: '/@id/{specifier}',
})
})

it('leaves the resolver undeclared without a dev server (standalone / build)', async () => {
await createDevToolsHub({ context: fakeContext({ viteServer: false }) })

expect(initHub).toHaveBeenCalledOnce()
expect(initHub.mock.calls[0]![0]).not.toHaveProperty('clientModuleResolution')
})
})
8 changes: 8 additions & 0 deletions packages/core/src/node/build-static.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,14 @@ export async function buildStaticDevTools(options: BuildStaticOptions): Promise<
}
;(await context.rpc.sharedState.get(DOCK_RENDERERS_STATE_KEY, { initialValue: {} })).mutate(() => rendererManifest)

// Fire the services collect-then-setup barrier `initHub` runs in dev. The
// live hub isn't stood up for a static snapshot, so nothing else seeds the
// `devframe:services` shared state the client reads on load — without this,
// the RPC dump has no match for `server-state:get(["devframe:services"])`
// and the client logs a hard error. `ready()` always publishes the state
// (empty when no services are installed) and is idempotent.
await context.services.ready()

await fs.mkdir(resolve(devToolsRoot, DEVTOOLS_RPC_DUMP_DIRNAME), { recursive: true })
await fs.writeFile(resolve(devToolsRoot, DEVTOOLS_CONNECTION_META_FILENAME), JSON.stringify({ backend: 'static' }, null, 2), 'utf-8')
await fs.writeFile(resolve(devToolsRoot, DEVTOOLS_DOCK_IMPORTS_FILENAME), renderDockImportsMap(context.docks.values()), 'utf-8')
Expand Down
9 changes: 9 additions & 0 deletions packages/core/src/node/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,15 @@ export async function createDevToolsHub(options: CreateDevToolsHubOptions): Prom
// docks (kit's `createJsonRenderer`, the git/data-inspector devframes)
// render instead of hub-ui's missing-renderer fallback.
renderers: [jsonRenderUiRenderer()],
// With a live Vite dev server, route bare-specifier dock client scripts
// (`ClientScriptEntry.importFrom` naming an npm module, e.g.
// vue-tracer's `vite-plugin-vue-tracer/client/vite-devtools`) through
// Vite's own `/@id/` resolution — so they load through the inspected
// app's module graph now that v0.9's middleware serves hub assets ahead
// of Vite's transform pipeline. Standalone (CLI) and build snapshots have
// no module graph to resolve against, so the template stays undeclared
// there and such scripts must ship a self-contained bundle URL instead.
...(context.viteServer ? { clientModuleResolution: '/@id/{specifier}' } : {}),
auth: authDisabled ? false : getAuthHandler(context),
...(allowedOrigins ? { allowedOrigins } : {}),
...(options.server
Expand Down
Loading
Loading