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
5 changes: 1 addition & 4 deletions packages/vite/src/client/bundledDevClient.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { nanoid } from 'nanoid/non-secure'
import type { DevRuntime as DevRuntimeType } from 'rolldown/experimental/runtime-types'
import { DevRuntime } from 'rolldown/experimental/runtime'
import {
BundledDevHMRClient,
BundledDevHMRContext,
Expand All @@ -22,9 +22,6 @@ export {
ErrorOverlay,
} from './client'

// injected by rolldown's hmr plugin into the bundle prelude, ahead of this client
declare const DevRuntime: typeof DevRuntimeType

if (typeof DevRuntime !== 'undefined') {
class ViteDevRuntime extends DevRuntime {
override createModuleHotContext(moduleId: string) {
Expand Down
39 changes: 33 additions & 6 deletions packages/vite/src/node/server/bundledDev.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import path from 'node:path'
import { setTimeout } from 'node:timers/promises'
import {
type BindingClientHmrUpdate,
Expand All @@ -19,6 +20,7 @@ import { type NormalizedHotChannelClient, debugHmr, getShortName } from './hmr'
import { prepareError } from './middlewares/error'

const debug = createDebugger('vite:full-bundle-mode')
const BUNDLED_DEV_CLIENT_FILENAME = 'bundledDevClient.mjs'

type HmrOutput = BindingClientHmrUpdate['update']

Expand Down Expand Up @@ -62,6 +64,7 @@ export class MemoryFiles {

export class BundledDev {
private _devEngine!: DevEngine
private viteRuntime?: string
private initialBuildCompleted = false
private _closed = false
private clients = new Clients()
Expand Down Expand Up @@ -107,6 +110,14 @@ export class BundledDev {

private pendingPayloadFilenames = new Set<string>()

get hasBuildOutput(): boolean {
return (
this.memoryFiles.size > 1 ||
(this.memoryFiles.size === 1 &&
!this.memoryFiles.has(BUNDLED_DEV_CLIENT_FILENAME))
)
}

async listen(): Promise<void> {
this._closed = false
debug?.('INITIAL: setup bundle options')
Expand Down Expand Up @@ -251,6 +262,10 @@ export class BundledDev {
debug?.('INITIAL: run error', e)
},
)
this.viteRuntime = await getHmrImplementation(
this.environment.getTopLevelConfig(),
)
this.storeOutputFiles([])
this.waitForInitialBuildFinish().then(() => {
if (this._closed) return
debug?.('INITIAL: build done')
Expand All @@ -271,7 +286,7 @@ export class BundledDev {
if (this._closed) return

let state = await this.devEngine.getBundleState()
while (this.memoryFiles.size === 0 && !state.lastBuildErrored) {
while (!this.hasBuildOutput && !state.lastBuildErrored) {
await setTimeout(10)
if (this._closed) return
await this.devEngine.ensureCurrentBuildFinish()
Expand Down Expand Up @@ -354,12 +369,25 @@ export class BundledDev {
this.initialBuildCompleted = false
}

private storeOutputFiles(output: RolldownOutput['output']): void {
private storeOutputFiles(output: RolldownOutput['output'][number][]): void {
// NOTE: don't clear memoryFiles here as incremental build reuses the files
if (this.viteRuntime) {
this.memoryFiles.set(BUNDLED_DEV_CLIENT_FILENAME, {
source: this.viteRuntime,
etag: getEtag(Buffer.from(this.viteRuntime), { weak: true }),
})
}
for (const outputFile of output) {
this.memoryFiles.set(outputFile.fileName, () => {
const source =
let source =
outputFile.type === 'chunk' ? outputFile.code : outputFile.source
if (outputFile.type === 'chunk' && outputFile.isEntry) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sapphi-red With this issue #23160, maybe we need to prepend this runtime file as its own first script tag in the HTML?

const runtimePath = path.posix.join(
this.environment.config.base,
BUNDLED_DEV_CLIENT_FILENAME,
)
source = `import ${JSON.stringify(runtimePath)}\n${source}`
}
return {
source,
etag: getEtag(Buffer.from(source), { weak: true }),
Expand All @@ -380,9 +408,8 @@ export class BundledDev {
...(typeof rolldownOptions.experimental.devMode === 'object'
? rolldownOptions.experimental.devMode
: {}),
implement: await getHmrImplementation(
this.environment.getTopLevelConfig(),
),
implement: '',
skipCommonRuntimeInjection: true,
}

// disable inlineConst optimization due to a bug in Rolldown
Expand Down
2 changes: 1 addition & 1 deletion packages/vite/src/node/server/middlewares/indexHtml.ts
Original file line number Diff line number Diff line change
Expand Up @@ -475,7 +475,7 @@ export function indexHtmlMiddleware(
const filePath = pathname.slice(1) // remove first /

let file = fullBundle.memoryFiles.get(filePath)
if (!file && fullBundle.memoryFiles.size !== 0) {
if (!file && fullBundle.hasBuildOutput) {
return next()
}
const secFetchDest = req.headers['sec-fetch-dest']
Expand Down