1+ import type {
2+ DevRuntime as DevRuntimeType ,
3+ Messenger ,
4+ } from 'rolldown/experimental/runtime-types'
15import type { ErrorPayload , HotPayload } from '#types/hmrPayload'
26import type { ViteHotContext } from '#types/hot'
37import { HMRClient , HMRContext } from '../shared/hmr'
@@ -20,6 +24,7 @@ declare const __HMR_BASE__: string
2024declare const __HMR_TIMEOUT__ : number
2125declare const __HMR_ENABLE_OVERLAY__ : boolean
2226declare const __WS_TOKEN__ : string
27+ declare const __BUNDLED_DEV__ : boolean
2328
2429console . debug ( '[vite] connecting...' )
2530
@@ -37,6 +42,7 @@ const directSocketHost = __HMR_DIRECT_TARGET__
3742const base = __BASE__ || '/'
3843const hmrTimeout = __HMR_TIMEOUT__
3944const wsToken = __WS_TOKEN__
45+ const isBundleMode = __BUNDLED_DEV__
4046
4147const transport = normalizeModuleRunnerTransport (
4248 ( ( ) => {
@@ -140,32 +146,53 @@ const hmrClient = new HMRClient(
140146 debug : ( ...msg ) => console . debug ( '[vite]' , ...msg ) ,
141147 } ,
142148 transport ,
143- async function importUpdatedModule ( {
144- acceptedPath,
145- timestamp,
146- explicitImportRequired,
147- isWithinCircularImport,
148- } ) {
149- const [ acceptedPathWithoutQuery , query ] = acceptedPath . split ( `?` )
150- const importPromise = import (
151- /* @vite -ignore */
152- base +
153- acceptedPathWithoutQuery . slice ( 1 ) +
154- `?${ explicitImportRequired ? 'import&' : '' } t=${ timestamp } ${
155- query ? `&${ query } ` : ''
156- } `
157- )
158- if ( isWithinCircularImport ) {
159- importPromise . catch ( ( ) => {
160- console . info (
161- `[hmr] ${ acceptedPath } failed to apply HMR as it's within a circular import. Reloading page to reset the execution order. ` +
162- `To debug and break the circular import, you can run \`vite --debug hmr\` to log the circular dependency path if a file change triggered it.` ,
149+ isBundleMode
150+ ? async function importUpdatedModule ( {
151+ url,
152+ acceptedPath,
153+ isWithinCircularImport,
154+ } ) {
155+ const importPromise = import ( base + url ! ) . then ( ( ) =>
156+ // @ts -expect-error globalThis.__rolldown_runtime__
157+ globalThis . __rolldown_runtime__ . loadExports ( acceptedPath ) ,
163158 )
164- pageReload ( )
165- } )
166- }
167- return await importPromise
168- } ,
159+ if ( isWithinCircularImport ) {
160+ importPromise . catch ( ( ) => {
161+ console . info (
162+ `[hmr] ${ acceptedPath } failed to apply HMR as it's within a circular import. Reloading page to reset the execution order. ` +
163+ `To debug and break the circular import, you can run \`vite --debug hmr\` to log the circular dependency path if a file change triggered it.` ,
164+ )
165+ pageReload ( )
166+ } )
167+ }
168+ return await importPromise
169+ }
170+ : async function importUpdatedModule ( {
171+ acceptedPath,
172+ timestamp,
173+ explicitImportRequired,
174+ isWithinCircularImport,
175+ } ) {
176+ const [ acceptedPathWithoutQuery , query ] = acceptedPath . split ( `?` )
177+ const importPromise = import (
178+ /* @vite -ignore */
179+ base +
180+ acceptedPathWithoutQuery . slice ( 1 ) +
181+ `?${ explicitImportRequired ? 'import&' : '' } t=${ timestamp } ${
182+ query ? `&${ query } ` : ''
183+ } `
184+ )
185+ if ( isWithinCircularImport ) {
186+ importPromise . catch ( ( ) => {
187+ console . info (
188+ `[hmr] ${ acceptedPath } failed to apply HMR as it's within a circular import. Reloading page to reset the execution order. ` +
189+ `To debug and break the circular import, you can run \`vite --debug hmr\` to log the circular dependency path if a file change triggered it.` ,
190+ )
191+ pageReload ( )
192+ } )
193+ }
194+ return await importPromise
195+ } ,
169196)
170197transport . connect ! ( createHMRHandler ( handleMessage ) )
171198
@@ -593,3 +620,41 @@ export function injectQuery(url: string, queryToInject: string): string {
593620}
594621
595622export { ErrorOverlay }
623+
624+ declare const DevRuntime : typeof DevRuntimeType
625+
626+ if ( isBundleMode && typeof DevRuntime !== 'undefined' ) {
627+ class ViteDevRuntime extends DevRuntime {
628+ override createModuleHotContext ( moduleId : string ) {
629+ const ctx = createHotContext ( moduleId )
630+ // @ts -expect-error TODO: support CSS properly
631+ ctx . _internal = { updateStyle, removeStyle }
632+ return ctx
633+ }
634+
635+ override applyUpdates ( _boundaries : [ string , string ] [ ] ) : void {
636+ // noop, handled in the HMR client
637+ }
638+ }
639+
640+ const wrappedSocket : Messenger = {
641+ send ( message ) {
642+ switch ( message . type ) {
643+ case 'hmr:module-registered' : {
644+ transport . send ( {
645+ type : 'custom' ,
646+ event : 'vite:module-loaded' ,
647+ // clone array as the runtime reuses the array instance
648+ data : { modules : message . modules . slice ( ) } ,
649+ } )
650+ break
651+ }
652+ default :
653+ throw new Error ( `Unknown message type: ${ JSON . stringify ( message ) } ` )
654+ }
655+ } ,
656+ }
657+ ; ( globalThis as any ) . __rolldown_runtime__ ??= new ViteDevRuntime (
658+ wrappedSocket ,
659+ )
660+ }
0 commit comments