@@ -34,20 +34,17 @@ export async function handleHotUpdate(file: string, modules: any[]) {
34
34
setDescriptor ( file , descriptor )
35
35
36
36
let needRerender = false
37
- const filteredModules = [ ]
38
-
39
- const reload = ( ) => {
40
- debug ( `[vue:reload] ${ file } ` )
41
- return modules . filter (
42
- ( m ) => ! / t y p e = / . test ( m . id ) || / t y p e = s c r i p t / . test ( m . id )
43
- )
44
- }
37
+ const filteredModules = new Set ( )
38
+ const mainModule = modules . find (
39
+ ( m ) => ! / t y p e = / . test ( m . id ) || / t y p e = s c r i p t / . test ( m . id )
40
+ )
41
+ const templateModule = modules . find ( ( m ) => / t y p e = t e m p l a t e / . test ( m . id ) )
45
42
46
43
if (
47
44
! isEqualBlock ( descriptor . script , prevDescriptor . script ) ||
48
45
! isEqualBlock ( descriptor . scriptSetup , prevDescriptor . scriptSetup )
49
46
) {
50
- return reload ( )
47
+ filteredModules . add ( mainModule )
51
48
}
52
49
53
50
if ( ! isEqualBlock ( descriptor . template , prevDescriptor . template ) ) {
@@ -56,7 +53,7 @@ export async function handleHotUpdate(file: string, modules: any[]) {
56
53
// metadata will not be available since the script part isn't loaded.
57
54
// in this case, reuse the compiled script from previous descriptor.
58
55
setResolvedScript ( descriptor , getResolvedScript ( prevDescriptor ) ! )
59
- needRerender = true
56
+ filteredModules . add ( templateModule )
60
57
}
61
58
62
59
let didUpdateStyle = false
@@ -66,13 +63,15 @@ export async function handleHotUpdate(file: string, modules: any[]) {
66
63
// force reload if CSS vars injection changed
67
64
if ( descriptor . cssVars ) {
68
65
if ( prevDescriptor . cssVars . join ( '' ) !== descriptor . cssVars . join ( '' ) ) {
69
- return reload ( )
66
+ filteredModules . add ( mainModule )
70
67
}
71
68
}
72
69
73
70
// force reload if scoped status has changed
74
71
if ( prevStyles . some ( ( s ) => s . scoped ) !== nextStyles . some ( ( s ) => s . scoped ) ) {
75
- return reload ( )
72
+ // template needs to be invalidated as well
73
+ filteredModules . add ( templateModule )
74
+ filteredModules . add ( mainModule )
76
75
}
77
76
78
77
// only need to update styles if not reloading, since reload forces
@@ -82,25 +81,42 @@ export async function handleHotUpdate(file: string, modules: any[]) {
82
81
const next = nextStyles [ i ]
83
82
if ( ! prev || ! isEqualBlock ( prev , next ) ) {
84
83
didUpdateStyle = true
85
- filteredModules . push ( modules . find ( ( m ) => m . id . includes ( `index=${ i } ` ) ) )
84
+ const mod = modules . find ( ( m ) => m . id . includes ( `type=style&index=${ i } ` ) )
85
+ if ( mod ) {
86
+ filteredModules . add ( mod )
87
+ } else {
88
+ // new style block - force reload
89
+ filteredModules . add ( mainModule )
90
+ }
86
91
}
87
92
}
93
+ if ( prevStyles . length > nextStyles . length ) {
94
+ // style block removed - force reload
95
+ filteredModules . add ( mainModule )
96
+ }
88
97
89
98
const prevCustoms = prevDescriptor . customBlocks || [ ]
90
99
const nextCustoms = descriptor . customBlocks || [ ]
91
100
92
101
// custom blocks update causes a reload
93
102
// because the custom block contents is changed and it may be used in JS.
94
- if (
95
- nextCustoms . some (
96
- ( _ , i ) => ! prevCustoms [ i ] || ! isEqualBlock ( prevCustoms [ i ] , nextCustoms [ i ] )
97
- )
98
- ) {
99
- return reload ( )
103
+ for ( let i = 0 ; i < nextCustoms . length ; i ++ ) {
104
+ const prev = prevCustoms [ i ]
105
+ const next = nextCustoms [ i ]
106
+ if ( ! prev || ! isEqualBlock ( prev , next ) ) {
107
+ const mod = modules . find ( ( m ) =>
108
+ m . id . includes ( `type=${ prev . type } &index=${ i } ` )
109
+ )
110
+ if ( mod ) {
111
+ filteredModules . add ( mod )
112
+ } else {
113
+ filteredModules . add ( mainModule )
114
+ }
115
+ }
100
116
}
101
-
102
- if ( needRerender ) {
103
- filteredModules . push ( modules . find ( ( m ) => / t y p e = t e m p l a t e / . test ( m . id ) ) )
117
+ if ( prevCustoms . length > nextCustoms . length ) {
118
+ // block rmeoved, force reload
119
+ filteredModules . add ( mainModule )
104
120
}
105
121
106
122
let updateType = [ ]
@@ -113,7 +129,7 @@ export async function handleHotUpdate(file: string, modules: any[]) {
113
129
if ( updateType . length ) {
114
130
debug ( `[vue:update(${ updateType . join ( '&' ) } )] ${ file } ` )
115
131
}
116
- return filteredModules
132
+ return [ ... filteredModules ] . filter ( Boolean )
117
133
}
118
134
119
135
// vitejs/vite#610 when hot-reloading Vue files, we read immediately on file
0 commit comments