From 41bdd19c153ea87bbd4691f9be8fb66878f89733 Mon Sep 17 00:00:00 2001 From: likui <2218301630@qq.com> Date: Sun, 24 May 2020 14:07:37 +0800 Subject: [PATCH 1/8] refactor: vue update by hmr api --- src/client/client.ts | 26 ++---- src/node/server/serverPluginHmr.ts | 88 +++++++++++--------- src/node/server/serverPluginModuleRewrite.ts | 5 +- src/node/server/serverPluginVue.ts | 50 +++++++---- src/node/utils/cssUtils.ts | 18 ++++ 5 files changed, 109 insertions(+), 78 deletions(-) diff --git a/src/client/client.ts b/src/client/client.ts index 909b676742d594..2d487a749fc47f 100644 --- a/src/client/client.ts +++ b/src/client/client.ts @@ -84,22 +84,6 @@ socket.addEventListener('message', async ({ data }) => { case 'connected': console.log(`[vite] connected.`) break - case 'vue-reload': - import(`${path}?t=${timestamp}`) - .then((m) => { - __VUE_HMR_RUNTIME__.reload(path, m.default) - console.log(`[vite] ${path} reloaded.`) - }) - .catch((err) => warnFailedFetch(err, path)) - break - case 'vue-rerender': - const templatePath = `${path}?type=template` - await bustSwCache(templatePath) - import(`${templatePath}&t=${timestamp}`).then((m) => { - __VUE_HMR_RUNTIME__.rerender(path, m.render) - console.log(`[vite] ${path} template updated.`) - }) - break case 'vue-style-update': const stylePath = `${path}?type=style&index=${index}` await bustSwCache(stylePath) @@ -220,8 +204,14 @@ async function updateModule( Array.from(modulesToUpdate).map(async (dep) => { const disposer = jsDisposeMap.get(dep) if (disposer) await disposer() - const newMod = await import(dep + `?t=${timestamp}`) - moduleMap.set(dep, newMod) + try { + const newMod = await import( + dep + (dep.includes('?') ? '&' : '?') + `t=${timestamp}` + ) + moduleMap.set(dep, newMod) + } catch (e) { + warnFailedFetch(e, dep) + } }) ) diff --git a/src/node/server/serverPluginHmr.ts b/src/node/server/serverPluginHmr.ts index f166f445ef00cd..fa35ad723874d1 100644 --- a/src/node/server/serverPluginHmr.ts +++ b/src/node/server/serverPluginHmr.ts @@ -73,8 +73,6 @@ export const hmrClientPublicPath = `/${hmrClientId}` interface HMRPayload { type: - | 'vue-rerender' - | 'vue-reload' | 'vue-style-update' | 'js-update' | 'style-update' @@ -178,12 +176,21 @@ export const hmrPlugin: ServerPlugin = ({ } // check which part of the file changed - let needReload = false - let needCssModuleReload = false let needRerender = false if (!isEqual(descriptor.script, prevDescriptor.script)) { - needReload = true + // reload + send({ + type: 'js-update', + path: publicPath, + changeSrcPath: publicPath, + timestamp + }) + console.log( + chalk.green(`[vite:hmr] `) + + `${path.relative(root, file)} updated. (reload)` + ) + return } if (!isEqual(descriptor.template, prevDescriptor.template)) { @@ -194,12 +201,6 @@ export const hmrPlugin: ServerPlugin = ({ const styleId = hash_sum(publicPath) const prevStyles = prevDescriptor.styles || [] const nextStyles = descriptor.styles || [] - if ( - !needReload && - prevStyles.some((s) => s.scoped) !== nextStyles.some((s) => s.scoped) - ) { - needReload = true - } // css modules update causes a reload because the $style object is changed // and it may be used in JS. It also needs to trigger a vue-style-update @@ -208,25 +209,40 @@ export const hmrPlugin: ServerPlugin = ({ prevStyles.some((s) => s.module != null) || nextStyles.some((s) => s.module != null) ) { - needCssModuleReload = true + send({ + type: 'js-update', + path: publicPath, + changeSrcPath: publicPath, + timestamp + }) + console.log( + chalk.green(`[vite:hmr] `) + + `${path.relative(root, file)} updated. (reload)` + ) + return + } + + if (prevStyles.some((s) => s.scoped) !== nextStyles.some((s) => s.scoped)) { + needRerender = true } // only need to update styles if not reloading, since reload forces // style updates as well. - if (!needReload) { - nextStyles.forEach((_, i) => { - if (!prevStyles[i] || !isEqual(prevStyles[i], nextStyles[i])) { - didUpdateStyle = true - send({ - type: 'vue-style-update', - path: publicPath, - index: i, - id: `${styleId}-${i}`, - timestamp - }) - } - }) - } + nextStyles.forEach((_, i) => { + if (!prevStyles[i] || !isEqual(prevStyles[i], nextStyles[i])) { + didUpdateStyle = true + send({ + type: 'vue-style-update', + path: publicPath, + changeSrcPath: + `${publicPath}?type=style&index=${i}` + + (nextStyles[i].module ? '&module' : ''), + index: i, + id: `${styleId}-${i}`, + timestamp + }) + } + }) // stale styles always need to be removed prevStyles.slice(nextStyles.length).forEach((_, i) => { @@ -239,22 +255,17 @@ export const hmrPlugin: ServerPlugin = ({ }) }) - if (needReload || needCssModuleReload) { - send({ - type: 'vue-reload', - path: publicPath, - timestamp - }) - } else if (needRerender) { + if (needRerender) { send({ - type: 'vue-rerender', + type: 'js-update', path: publicPath, + changeSrcPath: `${publicPath}?type=template`, timestamp }) } - if (needReload || needRerender || didUpdateStyle) { - let updateType = needReload ? `reload` : needRerender ? `template` : `` + if (needRerender || didUpdateStyle) { + let updateType = needRerender ? `template` : `` if (didUpdateStyle) { updateType += ` & style` } @@ -308,9 +319,9 @@ export const hmrPlugin: ServerPlugin = ({ `${vueBoundary} reloaded due to change in ${relativeFile}.` ) send({ - type: 'vue-reload', + type: 'js-update', path: vueBoundary, - changeSrcPath: publicPath, + changeSrcPath: vueBoundary, timestamp }) }) @@ -385,6 +396,7 @@ function isHmrAccepted(importer: string, dep: string): boolean { function isEqual(a: SFCBlock | null, b: SFCBlock | null) { if (!a && !b) return true if (!a || !b) return false + if (a.content.length !== b.content.length) return false if (a.content !== b.content) return false const keysA = Object.keys(a.attrs) const keysB = Object.keys(b.attrs) diff --git a/src/node/server/serverPluginModuleRewrite.ts b/src/node/server/serverPluginModuleRewrite.ts index db7241d4844f02..538dc2c877aa9f 100644 --- a/src/node/server/serverPluginModuleRewrite.ts +++ b/src/node/server/serverPluginModuleRewrite.ts @@ -150,10 +150,7 @@ export function rewriteImports( let resolved if (id === hmrClientId) { resolved = hmrClientPublicPath - if ( - /\bhot\b/.test(source.substring(ss, se)) && - !/.vue$|.vue\?type=/.test(importer) - ) { + if (/\bhot\b/.test(source.substring(ss, se))) { // the user explicit imports the HMR API in a js file // making the module hot. rewriteFileWithHMR(root, source, importer, resolver, s) diff --git a/src/node/server/serverPluginVue.ts b/src/node/server/serverPluginVue.ts index 635e1330b5d13a..d2787649fa2b22 100644 --- a/src/node/server/serverPluginVue.ts +++ b/src/node/server/serverPluginVue.ts @@ -28,7 +28,7 @@ import { Context } from 'koa' import { transform } from '../esbuildService' import { InternalResolver } from '../resolver' import { seenUrls } from './serverPluginServeStatic' -import { compileCss, rewriteCssUrls } from '../utils/cssUtils' +import { codegenCss, compileCss, rewriteCssUrls } from '../utils/cssUtils' const debug = require('debug')('vite:sfc') const getEtag = require('etag') @@ -114,6 +114,7 @@ export const vuePlugin: ServerPlugin = ({ if (styleBlock.src) { filename = await resolveSrcImport(styleBlock, ctx, resolver) } + const id = hash_sum(publicPath) const result = await compileSFCStyle( root, styleBlock, @@ -121,13 +122,8 @@ export const vuePlugin: ServerPlugin = ({ filename, publicPath ) - if (query.module != null) { - ctx.type = 'js' - ctx.body = `export default ${JSON.stringify(result.modules)}` - } else { - ctx.type = 'js' - ctx.body = `export default ${JSON.stringify(result.code)}` - } + ctx.type = 'js' + ctx.body = codegenCss(`${id}-${index}`, result.code, result.modules) return etagCacheCheck(ctx) } @@ -219,7 +215,8 @@ async function compileSFCMain( return cached.script } - let code = '' + const id = hash_sum(publicPath) + let code = `\nimport { updateStyle, hot } from "${hmrClientId}"\n` if (descriptor.script) { let content = descriptor.script.content if (descriptor.script.lang === 'ts') { @@ -231,11 +228,16 @@ async function compileSFCMain( code += `const __script = {}` } - const id = hash_sum(publicPath) + code += `\n if (hot) { + hot.accept((m) => { + console.log(m) + __VUE_HMR_RUNTIME__.reload("${id}", m.default) + }) +}` + let hasScoped = false let hasCSSModules = false if (descriptor.styles) { - code += `\nimport { updateStyle } from "${hmrClientId}"\n` descriptor.styles.forEach((s, i) => { const styleRequest = publicPath + `?type=style&index=${i}` if (s.scoped) hasScoped = true @@ -246,13 +248,19 @@ async function compileSFCMain( } const styleVar = `__style${i}` const moduleName = typeof s.module === 'string' ? s.module : '$style' - code += `\nimport ${styleVar} from ${JSON.stringify( - styleRequest + '&module' - )}` + const moduleRequest = styleRequest + '&module' + code += `\nimport ${styleVar} from ${JSON.stringify(moduleRequest)}` code += `\n__cssModules[${JSON.stringify(moduleName)}] = ${styleVar}` + code += `\n if (hot) { + hot.accept(${JSON.stringify(moduleRequest)}, (a) => { + __cssModules[${JSON.stringify(moduleName)}] = ${styleVar} + __VUE_HMR_RUNTIME__.rerender("${id}") + }) +}` + } else { + code += `\nimport css_${i} from ${JSON.stringify(styleRequest)}` + code += `\nupdateStyle("${id}-${i}", css_${i})` } - code += `\nimport css_${i} from ${JSON.stringify(styleRequest)}` - code += `\nupdateStyle("${id}-${i}", css_${i})` }) if (hasScoped) { code += `\n__script.__scopeId = "data-v-${id}"` @@ -260,12 +268,18 @@ async function compileSFCMain( } if (descriptor.template) { + const templateRequest = publicPath + `?type=template` code += `\nimport { render as __render } from ${JSON.stringify( - publicPath + `?type=template` + templateRequest )}` code += `\n__script.render = __render` + code += `\n if (hot) { + hot.accept(${JSON.stringify(templateRequest)}, (m) => { + __VUE_HMR_RUNTIME__.rerender("${id}", m.render) + }) +}` } - code += `\n__script.__hmrId = ${JSON.stringify(publicPath)}` + code += `\n__script.__hmrId = ${JSON.stringify(id)}` code += `\n__script.__file = ${JSON.stringify(filePath)}` code += `\nexport default __script` diff --git a/src/node/utils/cssUtils.ts b/src/node/utils/cssUtils.ts index d0610f589e9bb3..20ac409387cc3e 100644 --- a/src/node/utils/cssUtils.ts +++ b/src/node/utils/cssUtils.ts @@ -9,6 +9,7 @@ import { SFCAsyncStyleCompileOptions, SFCStyleCompileResults } from '@vue/compiler-sfc' +import { hmrClientPublicPath } from '../server/serverPluginHmr' export const urlRE = /(url\(\s*['"]?)([^"')]+)(["']?\s*\))/ export const cssPreprocessLangRE = /(.+).(less|sass|scss|styl|stylus)$/ @@ -81,6 +82,23 @@ export async function compileCss( }) } +export function codegenCss( + id: string, + css: string, + modules?: Record +): string { + let code = + `import { hot, updateStyle } from "${hmrClientPublicPath}"\n` + + `const css = ${JSON.stringify(css)}\n` + + `updateStyle("${id}", css)\n` + if (modules) { + code += `export default ${JSON.stringify(modules)}` + } else { + code += `export default css` + } + return code +} + // postcss-load-config doesn't expose Result type type PostCSSConfigResult = ReturnType extends Promise ? T From 241cce29d1b4a9d974e4224e9cc2d5a8a4c56793 Mon Sep 17 00:00:00 2001 From: likui <2218301630@qq.com> Date: Sun, 24 May 2020 14:25:15 +0800 Subject: [PATCH 2/8] fix: add __DEV__ for for vue hmr codegen --- src/node/server/serverPluginVue.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/node/server/serverPluginVue.ts b/src/node/server/serverPluginVue.ts index d2787649fa2b22..fb19117161a7c1 100644 --- a/src/node/server/serverPluginVue.ts +++ b/src/node/server/serverPluginVue.ts @@ -228,9 +228,8 @@ async function compileSFCMain( code += `const __script = {}` } - code += `\n if (hot) { + code += `\n if (__DEV__) { hot.accept((m) => { - console.log(m) __VUE_HMR_RUNTIME__.reload("${id}", m.default) }) }` @@ -251,7 +250,7 @@ async function compileSFCMain( const moduleRequest = styleRequest + '&module' code += `\nimport ${styleVar} from ${JSON.stringify(moduleRequest)}` code += `\n__cssModules[${JSON.stringify(moduleName)}] = ${styleVar}` - code += `\n if (hot) { + code += `\n if (__DEV__) { hot.accept(${JSON.stringify(moduleRequest)}, (a) => { __cssModules[${JSON.stringify(moduleName)}] = ${styleVar} __VUE_HMR_RUNTIME__.rerender("${id}") @@ -273,7 +272,7 @@ async function compileSFCMain( templateRequest )}` code += `\n__script.render = __render` - code += `\n if (hot) { + code += `\n if (__DEV__) { hot.accept(${JSON.stringify(templateRequest)}, (m) => { __VUE_HMR_RUNTIME__.rerender("${id}", m.render) }) From f3e33b8852e97ad82aa3cc1f4acf68d404a38313 Mon Sep 17 00:00:00 2001 From: likui <2218301630@qq.com> Date: Sun, 24 May 2020 14:44:35 +0800 Subject: [PATCH 3/8] chore: remove unnecessary style codegen --- src/client/client.ts | 3 +-- src/node/server/serverPluginVue.ts | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/client/client.ts b/src/client/client.ts index 2d487a749fc47f..a5c86c9a24f085 100644 --- a/src/client/client.ts +++ b/src/client/client.ts @@ -87,8 +87,7 @@ socket.addEventListener('message', async ({ data }) => { case 'vue-style-update': const stylePath = `${path}?type=style&index=${index}` await bustSwCache(stylePath) - const content = await import(stylePath + `&t=${timestamp}`) - updateStyle(id, content.default) + await import(stylePath + `&t=${timestamp}`) console.log( `[vite] ${path} style${index > 0 ? `#${index}` : ``} updated.` ) diff --git a/src/node/server/serverPluginVue.ts b/src/node/server/serverPluginVue.ts index fb19117161a7c1..979853a7f64628 100644 --- a/src/node/server/serverPluginVue.ts +++ b/src/node/server/serverPluginVue.ts @@ -257,8 +257,7 @@ async function compileSFCMain( }) }` } else { - code += `\nimport css_${i} from ${JSON.stringify(styleRequest)}` - code += `\nupdateStyle("${id}-${i}", css_${i})` + code += `\nimport ${JSON.stringify(styleRequest)}` } }) if (hasScoped) { From f0f4e04b8ac22b53e5df44b4bfa34d3c5d58e5c2 Mon Sep 17 00:00:00 2001 From: likui <2218301630@qq.com> Date: Sun, 24 May 2020 16:36:55 +0800 Subject: [PATCH 4/8] chore: remove unnecessary style codegen --- src/node/server/serverPluginHmr.ts | 3 --- src/node/server/serverPluginVue.ts | 11 +++-------- 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/src/node/server/serverPluginHmr.ts b/src/node/server/serverPluginHmr.ts index fa35ad723874d1..93c5a4b9b0e2ee 100644 --- a/src/node/server/serverPluginHmr.ts +++ b/src/node/server/serverPluginHmr.ts @@ -234,9 +234,6 @@ export const hmrPlugin: ServerPlugin = ({ send({ type: 'vue-style-update', path: publicPath, - changeSrcPath: - `${publicPath}?type=style&index=${i}` + - (nextStyles[i].module ? '&module' : ''), index: i, id: `${styleId}-${i}`, timestamp diff --git a/src/node/server/serverPluginVue.ts b/src/node/server/serverPluginVue.ts index 979853a7f64628..b51bdadac12be2 100644 --- a/src/node/server/serverPluginVue.ts +++ b/src/node/server/serverPluginVue.ts @@ -247,15 +247,10 @@ async function compileSFCMain( } const styleVar = `__style${i}` const moduleName = typeof s.module === 'string' ? s.module : '$style' - const moduleRequest = styleRequest + '&module' - code += `\nimport ${styleVar} from ${JSON.stringify(moduleRequest)}` + code += `\nimport ${styleVar} from ${JSON.stringify( + styleRequest + '&module' + )}` code += `\n__cssModules[${JSON.stringify(moduleName)}] = ${styleVar}` - code += `\n if (__DEV__) { - hot.accept(${JSON.stringify(moduleRequest)}, (a) => { - __cssModules[${JSON.stringify(moduleName)}] = ${styleVar} - __VUE_HMR_RUNTIME__.rerender("${id}") - }) -}` } else { code += `\nimport ${JSON.stringify(styleRequest)}` } From ab212450b1f80044d40c3fd7d1059696617026e8 Mon Sep 17 00:00:00 2001 From: likui <2218301630@qq.com> Date: Sun, 24 May 2020 19:18:36 +0800 Subject: [PATCH 5/8] fix: hmr boundaries should not self update when deps is changed --- src/client/client.ts | 8 ++++---- test/test.js | 10 +++++----- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/client/client.ts b/src/client/client.ts index a5c86c9a24f085..b56f4e5032e748 100644 --- a/src/client/client.ts +++ b/src/client/client.ts @@ -180,9 +180,9 @@ async function updateModule( } else { // dep update for (const { deps } of mod.callbacks) { - if (Array.isArray(deps)) { + if (Array.isArray(deps) && deps.includes(changedPath)) { deps.forEach((dep) => modulesToUpdate.add(dep)) - } else { + } else if (deps === changedPath) { modulesToUpdate.add(deps) } } @@ -195,7 +195,7 @@ async function updateModule( : modulesToUpdate.has(deps) }) // reset callbacks on self update since they are going to be registered again - if (isSelfUpdate) { + if (modulesToUpdate.has(id)) { mod.callbacks = [] } @@ -222,7 +222,7 @@ async function updateModule( } } - console.log(`[vite]: js module hot updated: `, id) + console.log(`[vite]: js module hot updated: `, changedPath) } interface HotModule { diff --git a/test/test.js b/test/test.js index b7505ccd934a2f..727e7d477f207d 100644 --- a/test/test.js +++ b/test/test.js @@ -164,17 +164,17 @@ describe('vite', () => { ) await expectByPolling( () => browserLogs[browserLogs.length - 1], - 'js module hot updated: /testHmrManual.js' + 'js module hot updated: /testHmrManualDep.js' ) expect( - browserLogs.slice(browserLogs.length - 7, browserLogs.length - 1) + browserLogs.slice(browserLogs.length - 4, browserLogs.length - 1) ).toEqual([ // dispose for both dep and self - `foo was: 2`, + // `foo was: 2`, `(dep) foo was: 1`, // self callbacks - `(self-accepting)1.foo is now: 2`, - `(self-accepting)2.foo is now: 2`, + // `(self-accepting)1.foo is now: 2`, + // `(self-accepting)2.foo is now: 2`, // dep callbacks `(single dep) foo is now: 2`, `(multiple deps) foo is now: 2` From 7c5085b5e3afdcb068549c8f5013fa5117465f65 Mon Sep 17 00:00:00 2001 From: likui <2218301630@qq.com> Date: Mon, 25 May 2020 10:14:34 +0800 Subject: [PATCH 6/8] refactor: css update refactor --- src/client/client.ts | 26 ++++++-------------------- src/node/server/serverPluginCss.ts | 30 +++++++----------------------- src/node/server/serverPluginHmr.ts | 25 ++++++++----------------- src/node/utils/cssUtils.ts | 4 ++-- 4 files changed, 23 insertions(+), 62 deletions(-) diff --git a/src/client/client.ts b/src/client/client.ts index b56f4e5032e748..97af535e7935d1 100644 --- a/src/client/client.ts +++ b/src/client/client.ts @@ -63,15 +63,9 @@ function warnFailedFetch(err: Error, path: string | string[]) { // Listen for messages socket.addEventListener('message', async ({ data }) => { - const { - type, - path, - changeSrcPath, - id, - index, - timestamp, - customData - } = JSON.parse(data) + const { type, path, changeSrcPath, id, timestamp, customData } = JSON.parse( + data + ) if (changeSrcPath) { await bustSwCache(changeSrcPath) @@ -84,18 +78,10 @@ socket.addEventListener('message', async ({ data }) => { case 'connected': console.log(`[vite] connected.`) break - case 'vue-style-update': - const stylePath = `${path}?type=style&index=${index}` - await bustSwCache(stylePath) - await import(stylePath + `&t=${timestamp}`) - console.log( - `[vite] ${path} style${index > 0 ? `#${index}` : ``} updated.` - ) - break case 'style-update': - await bustSwCache(`${path}?import`) - const style = await import(`${path}?t=${timestamp}`) - updateStyle(id, style.default) + const hasQuery = path.includes('?') ? '&' : '?' + await bustSwCache(`${path}${hasQuery}import`) + await import(`${path}${hasQuery}t=${timestamp}`) console.log(`[vite] ${path} updated.`) break case 'style-remove': diff --git a/src/node/server/serverPluginCss.ts b/src/node/server/serverPluginCss.ts index d78a64d9f05fd2..00bad318fd18f7 100644 --- a/src/node/server/serverPluginCss.ts +++ b/src/node/server/serverPluginCss.ts @@ -1,10 +1,10 @@ import { ServerPlugin } from '.' -import { hmrClientId } from './serverPluginHmr' import hash_sum from 'hash-sum' import { Context } from 'koa' import { cleanUrl, isImportRequest, readBody } from '../utils' import { srcImportMap, vueCache } from './serverPluginVue' import { + codegenCss, compileCss, cssPreprocessLangRE, rewriteCssUrls @@ -34,33 +34,21 @@ export const cssPlugin: ServerPlugin = ({ // note ctx.body could be null if upstream set status to 304 ctx.body ) { + const id = JSON.stringify(hash_sum(ctx.path)) if (isImportRequest(ctx)) { await processCss(root, ctx) // we rewrite css with `?import` to a js module that inserts a style // tag linking to the actual raw url ctx.type = 'js' - const id = JSON.stringify(hash_sum(ctx.path)) - let code = - `import { updateStyle } from "${hmrClientId}"\n` + - `const css = ${JSON.stringify(processedCSS.get(ctx.path)!.css)}\n` + - `updateStyle(${id}, css)\n` - if (ctx.path.endsWith('.module.css')) { - code += `export default ${JSON.stringify( - processedCSS.get(ctx.path)!.modules - )}` - } else { - code += `export default css` - } - ctx.body = code.trim() + const { css, modules } = processedCSS.get(ctx.path)! + ctx.body = codegenCss(id, css, modules) } else { // raw request, return compiled css if (!processedCSS.has(ctx.path)) { await processCss(root, ctx) } ctx.type = 'js' - ctx.body = `export default ${JSON.stringify( - processedCSS.get(ctx.path)!.css - )}` + ctx.body = codegenCss(id, processedCSS.get(ctx.path)!.css) } } }) @@ -78,10 +66,8 @@ export const cssPlugin: ServerPlugin = ({ chalk.green(`[vite:hmr] `) + `${publicPath} updated. (style)` ) watcher.send({ - type: 'vue-style-update', - path: publicPath, - index: Number(index), - id: `${hash_sum(publicPath)}-${index}`, + type: 'style-update', + path: `${publicPath}?type=style&index=${index}`, timestamp: Date.now() }) return @@ -94,14 +80,12 @@ export const cssPlugin: ServerPlugin = ({ } const publicPath = resolver.fileToRequest(file) - const id = hash_sum(publicPath) // bust process cache processedCSS.delete(publicPath) watcher.send({ type: 'style-update', - id, path: publicPath, timestamp: Date.now() }) diff --git a/src/node/server/serverPluginHmr.ts b/src/node/server/serverPluginHmr.ts index 93c5a4b9b0e2ee..091cb3094b5029 100644 --- a/src/node/server/serverPluginHmr.ts +++ b/src/node/server/serverPluginHmr.ts @@ -73,7 +73,6 @@ export const hmrClientPublicPath = `/${hmrClientId}` interface HMRPayload { type: - | 'vue-style-update' | 'js-update' | 'style-update' | 'style-remove' @@ -178,8 +177,7 @@ export const hmrPlugin: ServerPlugin = ({ // check which part of the file changed let needRerender = false - if (!isEqual(descriptor.script, prevDescriptor.script)) { - // reload + const vueReload = () => { send({ type: 'js-update', path: publicPath, @@ -190,6 +188,10 @@ export const hmrPlugin: ServerPlugin = ({ chalk.green(`[vite:hmr] `) + `${path.relative(root, file)} updated. (reload)` ) + } + + if (!isEqual(descriptor.script, prevDescriptor.script)) { + vueReload() return } @@ -209,16 +211,7 @@ export const hmrPlugin: ServerPlugin = ({ prevStyles.some((s) => s.module != null) || nextStyles.some((s) => s.module != null) ) { - send({ - type: 'js-update', - path: publicPath, - changeSrcPath: publicPath, - timestamp - }) - console.log( - chalk.green(`[vite:hmr] `) + - `${path.relative(root, file)} updated. (reload)` - ) + vueReload() return } @@ -232,10 +225,8 @@ export const hmrPlugin: ServerPlugin = ({ if (!prevStyles[i] || !isEqual(prevStyles[i], nextStyles[i])) { didUpdateStyle = true send({ - type: 'vue-style-update', - path: publicPath, - index: i, - id: `${styleId}-${i}`, + type: 'style-update', + path: `${publicPath}?type=style&index=${i}`, timestamp }) } diff --git a/src/node/utils/cssUtils.ts b/src/node/utils/cssUtils.ts index 20ac409387cc3e..657efaeacf31ac 100644 --- a/src/node/utils/cssUtils.ts +++ b/src/node/utils/cssUtils.ts @@ -88,9 +88,9 @@ export function codegenCss( modules?: Record ): string { let code = - `import { hot, updateStyle } from "${hmrClientPublicPath}"\n` + + `import { updateStyle } from "${hmrClientPublicPath}"\n` + `const css = ${JSON.stringify(css)}\n` + - `updateStyle("${id}", css)\n` + `updateStyle(${JSON.stringify(id)}, css)\n` if (modules) { code += `export default ${JSON.stringify(modules)}` } else { From c9742b0d23b720bcabc8c2a6c7921fc2adc99889 Mon Sep 17 00:00:00 2001 From: likui <2218301630@qq.com> Date: Mon, 25 May 2020 23:38:40 +0800 Subject: [PATCH 7/8] revert: revert unrelated changes with hmr --- src/client/client.ts | 8 ++++---- src/node/server/serverPluginHmr.ts | 2 +- test/test.js | 10 +++++----- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/client/client.ts b/src/client/client.ts index 97af535e7935d1..0da7503e696b72 100644 --- a/src/client/client.ts +++ b/src/client/client.ts @@ -166,9 +166,9 @@ async function updateModule( } else { // dep update for (const { deps } of mod.callbacks) { - if (Array.isArray(deps) && deps.includes(changedPath)) { + if (Array.isArray(deps)) { deps.forEach((dep) => modulesToUpdate.add(dep)) - } else if (deps === changedPath) { + } else { modulesToUpdate.add(deps) } } @@ -181,7 +181,7 @@ async function updateModule( : modulesToUpdate.has(deps) }) // reset callbacks on self update since they are going to be registered again - if (modulesToUpdate.has(id)) { + if (isSelfUpdate) { mod.callbacks = [] } @@ -208,7 +208,7 @@ async function updateModule( } } - console.log(`[vite]: js module hot updated: `, changedPath) + console.log(`[vite]: js module hot updated: `, id) } interface HotModule { diff --git a/src/node/server/serverPluginHmr.ts b/src/node/server/serverPluginHmr.ts index 091cb3094b5029..756f392d05f5f6 100644 --- a/src/node/server/serverPluginHmr.ts +++ b/src/node/server/serverPluginHmr.ts @@ -309,7 +309,7 @@ export const hmrPlugin: ServerPlugin = ({ send({ type: 'js-update', path: vueBoundary, - changeSrcPath: vueBoundary, + changeSrcPath: publicPath, timestamp }) }) diff --git a/test/test.js b/test/test.js index 727e7d477f207d..b7505ccd934a2f 100644 --- a/test/test.js +++ b/test/test.js @@ -164,17 +164,17 @@ describe('vite', () => { ) await expectByPolling( () => browserLogs[browserLogs.length - 1], - 'js module hot updated: /testHmrManualDep.js' + 'js module hot updated: /testHmrManual.js' ) expect( - browserLogs.slice(browserLogs.length - 4, browserLogs.length - 1) + browserLogs.slice(browserLogs.length - 7, browserLogs.length - 1) ).toEqual([ // dispose for both dep and self - // `foo was: 2`, + `foo was: 2`, `(dep) foo was: 1`, // self callbacks - // `(self-accepting)1.foo is now: 2`, - // `(self-accepting)2.foo is now: 2`, + `(self-accepting)1.foo is now: 2`, + `(self-accepting)2.foo is now: 2`, // dep callbacks `(single dep) foo is now: 2`, `(multiple deps) foo is now: 2` From 063cf51e41dbb71997cccd8bb5800dece93bdae4 Mon Sep 17 00:00:00 2001 From: likui <2218301630@qq.com> Date: Mon, 25 May 2020 23:45:01 +0800 Subject: [PATCH 8/8] fix: ci