Skip to content

Commit 4ccd96f

Browse files
committed
fix: improve HMR reliability
1 parent 67a0782 commit 4ccd96f

File tree

3 files changed

+18
-30
lines changed

3 files changed

+18
-30
lines changed

lib/codegen/hotReload.js

+13-18
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,30 @@
11
const hotReloadAPIPath = JSON.stringify(require.resolve('vue-hot-reload-api'))
22

3-
exports.genHotReloadCode = (id, functional) => {
4-
return wrap(`
5-
if (!module.hot.data) {
6-
api.createRecord('${id}', component.options)
7-
} else {
8-
api.${functional ? `rerender` : `reload`}('${id}', component.options)
9-
}
10-
`)
11-
}
12-
13-
exports.genTemplateHotReloadCode = id => {
14-
return wrap(`
15-
if (module.hot.data) {
16-
require(${hotReloadAPIPath}).rerender('${id}', {
3+
const genTemplateHotReloadCode = (id, request) => {
4+
return `
5+
module.hot.accept(${request}, function () {
6+
api.rerender('${id}', {
177
render: render,
188
staticRenderFns: staticRenderFns
199
})
20-
}
21-
`)
10+
})
11+
`.trim()
2212
}
2313

24-
function wrap (inner) {
14+
exports.genHotReloadCode = (id, functional, templateRequest) => {
2515
return `
2616
/* hot reload */
2717
if (module.hot) {
2818
var api = require(${hotReloadAPIPath})
2919
api.install(require('vue'))
3020
if (api.compatible) {
3121
module.hot.accept()
32-
${inner.trim()}
22+
if (!module.hot.data) {
23+
api.createRecord('${id}', component.options)
24+
} else {
25+
api.${functional ? `rerender` : `reload`}('${id}', component.options)
26+
}
27+
${templateRequest ? genTemplateHotReloadCode(id, templateRequest) : ``}
3328
}
3429
}
3530
`.trim()

lib/index.js

+3-2
Original file line numberDiff line numberDiff line change
@@ -80,13 +80,14 @@ module.exports = function (source) {
8080

8181
// template
8282
let templateImport = `var render, staticRenderFns`
83+
let templateRequest
8384
if (descriptor.template) {
8485
const src = descriptor.template.src || resourcePath
8586
const idQuery = `&id=${id}`
8687
const scopedQuery = hasScoped ? `&scoped=true` : ``
8788
const attrsQuery = attrsToQuery(descriptor.template.attrs)
8889
const query = `?vue&type=template${idQuery}${scopedQuery}${attrsQuery}`
89-
const request = stringifyRequest(src + query)
90+
const request = templateRequest = stringifyRequest(src + query)
9091
templateImport = `import { render, staticRenderFns } from ${request}`
9192
}
9293

@@ -145,7 +146,7 @@ var component = normalizer(
145146
}
146147

147148
if (needsHotReload) {
148-
code += `\n` + genHotReloadCode(id, hasFunctional)
149+
code += `\n` + genHotReloadCode(id, hasFunctional, templateRequest)
149150
}
150151

151152
// Expose filename. This is used by the devtools and vue runtime warnings.

lib/loaders/templateLoader.js

+2-10
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
const qs = require('querystring')
22
const loaderUtils = require('loader-utils')
33
const { compileTemplate } = require('@vue/component-compiler-utils')
4-
const { genTemplateHotReloadCode } = require('../codegen/hotReload')
54

65
// Loader that compiles raw template into JavaScript functions.
76
// This is injected by the global pitcher (../pitch) for template
@@ -18,7 +17,6 @@ module.exports = function (source) {
1817
const isServer = loaderContext.target === 'node'
1918
const isProduction = loaderContext.minimize || process.env.NODE_ENV === 'production'
2019
const isFunctional = query.functional
21-
const needsHotReload = !isServer && !isProduction && options.hotReload !== false
2220

2321
// allow using custom compiler via options
2422
const compiler = options.compiler || require('vue-template-compiler')
@@ -59,16 +57,10 @@ module.exports = function (source) {
5957
)
6058
}
6159

62-
let { code } = compiled
63-
64-
// hot-reload
65-
if (needsHotReload) {
66-
code += genTemplateHotReloadCode(id)
67-
}
60+
const { code } = compiled
6861

6962
// finish with ESM exports
70-
code += `export { render, staticRenderFns }`
71-
return code
63+
return code + `\nexport { render, staticRenderFns }`
7264
}
7365

7466
function pad (source) {

0 commit comments

Comments
 (0)