(id: string, newComp: HMRComponent)
| 113 | } |
| 114 | |
| 115 | function reload(id: string, newComp: HMRComponent): void { |
| 116 | const record = map.get(id) |
| 117 | if (!record) return |
| 118 | |
| 119 | newComp = normalizeClassComponent(newComp) |
| 120 | // update initial def (for not-yet-rendered components) |
| 121 | updateComponentDef(record.initialDef, newComp) |
| 122 | |
| 123 | // create a snapshot which avoids the set being mutated during updates |
| 124 | const instances = [...record.instances] |
| 125 | |
| 126 | for (let i = 0; i < instances.length; i++) { |
| 127 | const instance = instances[i] |
| 128 | const oldComp = normalizeClassComponent(instance.type as HMRComponent) |
| 129 | |
| 130 | let dirtyInstances = hmrDirtyComponents.get(oldComp) |
| 131 | if (!dirtyInstances) { |
| 132 | // 1. Update existing comp definition to match new one |
| 133 | if (oldComp !== record.initialDef) { |
| 134 | updateComponentDef(oldComp, newComp) |
| 135 | } |
| 136 | // 2. mark definition dirty. This forces the renderer to replace the |
| 137 | // component on patch. |
| 138 | hmrDirtyComponents.set(oldComp, (dirtyInstances = new Set())) |
| 139 | } |
| 140 | dirtyInstances.add(instance) |
| 141 | |
| 142 | // 3. invalidate options resolution cache |
| 143 | instance.appContext.propsCache.delete(instance.type as any) |
| 144 | instance.appContext.emitsCache.delete(instance.type as any) |
| 145 | instance.appContext.optionsCache.delete(instance.type as any) |
| 146 | |
| 147 | // 4. actually update |
| 148 | if (instance.ceReload) { |
| 149 | // custom element |
| 150 | dirtyInstances.add(instance) |
| 151 | instance.ceReload((newComp as any).styles) |
| 152 | dirtyInstances.delete(instance) |
| 153 | } else if (instance.parent) { |
| 154 | // 4. Force the parent instance to re-render. This will cause all updated |
| 155 | // components to be unmounted and re-mounted. Queue the update so that we |
| 156 | // don't end up forcing the same parent to re-render multiple times. |
| 157 | queueJob(() => { |
| 158 | // vite-plugin-vue/issues/599 |
| 159 | // don't update if the job is already disposed |
| 160 | if (!(instance.job.flags! & SchedulerJobFlags.DISPOSED)) { |
| 161 | isHmrUpdating = true |
| 162 | instance.parent!.update() |
| 163 | isHmrUpdating = false |
| 164 | // #6930, #11248 avoid infinite recursion |
| 165 | dirtyInstances.delete(instance) |
| 166 | } |
| 167 | }) |
| 168 | } else if (instance.appContext.reload) { |
| 169 | // root instance mounted via createApp() has a reload method |
| 170 | instance.appContext.reload() |
| 171 | } else if (typeof window !== 'undefined') { |
| 172 | // root instance inside tree created via raw render(). Force reload. |
no test coverage detected