Skip to content

Commit b27d962

Browse files
committed
fix(hmr): should reload if relies file changed after re-render
1 parent 9ba0234 commit b27d962

File tree

5 files changed

+35
-3
lines changed

5 files changed

+35
-3
lines changed

playground/hmr/TestHmr.vue

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
<script>
2+
import { test } from './lib.js'
23
export default {
34
data() {
45
return {
56
count: 0,
7+
number: test()
68
}
79
},
810
}
@@ -20,5 +22,6 @@ export default {
2022
&gt;&gt;&gt; {{ count }} &lt;&lt;&lt;
2123
</button>
2224
</p>
25+
<span class="hmr-number">{{ number }}</span>
2326
</div>
2427
</template>

playground/hmr/lib.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export function test() {
2+
return 100
3+
}

src/index.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import fs from 'node:fs'
2-
import { createFilter } from 'vite'
2+
import { createFilter, normalizePath } from 'vite'
33
import type { Plugin, ViteDevServer } from 'vite'
44
import type {
55
SFCBlock,
@@ -85,6 +85,12 @@ export default function vuePlugin(rawOptions: Options = {}): Plugin {
8585
name: 'vite:vue2',
8686

8787
handleHotUpdate(ctx) {
88+
ctx.server.ws.send({
89+
type: 'custom',
90+
event: 'file-changed',
91+
data: { file: normalizePath(ctx.file) },
92+
})
93+
8894
if (!filter(ctx.file)) {
8995
return
9096
}

src/main.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import path from 'node:path'
22
import type { SFCBlock, SFCDescriptor } from 'vue/compiler-sfc'
33
import type { PluginContext, TransformPluginContext } from 'rollup'
44
import type { RawSourceMap } from 'source-map'
5-
import { transformWithEsbuild } from 'vite'
5+
import { transformWithEsbuild, normalizePath } from 'vite'
66
import {
77
createDescriptor,
88
getPrevDescriptor,
@@ -110,12 +110,24 @@ var __component__ = /*#__PURE__*/__normalizer(
110110
` __VUE_HMR_RUNTIME__.createRecord(${id}, __component__.options)`,
111111
`}`
112112
)
113+
output.push(
114+
`import.meta.hot.on('file-changed', ({ file }) => {`,
115+
` __VUE_HMR_RUNTIME__.CHANGED_FILE = file`,
116+
`})`,
117+
)
113118
// check if the template is the only thing that changed
114119
if (
115120
hasFunctional ||
116121
(prevDescriptor && isOnlyTemplateChanged(prevDescriptor, descriptor))
117122
) {
118-
output.push(`export const _rerender_only = true`)
123+
// https://github.com/vitejs/vite-plugin-vue/issues/7
124+
// #7 only consider re-render if the HMR is triggered by the current component,
125+
// otherwise reload. Due to vite will cache the transform result. If the HMR
126+
// is triggered by other files that the current component relies on, a reload
127+
// is required.
128+
output.push(
129+
`export const _rerender_only = __VUE_HMR_RUNTIME__.CHANGED_FILE === ${JSON.stringify(normalizePath(filename))}`,
130+
)
119131
}
120132
output.push(
121133
`import.meta.hot.accept(mod => {`,

test/test.spec.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,14 @@ export function declareTests(isBuild: boolean) {
8080
)
8181
await expectByPolling(() => getText('.hmr-increment'), 'count is 1337')
8282
})
83+
84+
test('should reload when relies file changed', async () => {
85+
await expectByPolling(() => getText('.hmr-number'), '100')
86+
await updateFile('hmr/lib.js', content =>
87+
content.replace('100', '200')
88+
)
89+
await expectByPolling(() => getText('.hmr-number'), '200')
90+
})
8391
}
8492

8593
test('SFC <style scoped>', async () => {

0 commit comments

Comments
 (0)