From aa87995b91ee854b85e2af4c3c09511dbbf15d42 Mon Sep 17 00:00:00 2001 From: OneNail <31649110+OneNail@users.noreply.github.com> Date: Wed, 1 Sep 2021 20:25:57 +0800 Subject: [PATCH] fix: hmr doesn't work when modifying the code of jsx in sfc (#4563) --- packages/playground/vue-jsx/Script.vue | 14 ++++++++++ packages/playground/vue-jsx/SrcImport.jsx | 12 ++++++++ packages/playground/vue-jsx/SrcImport.vue | 1 + .../vue-jsx/__tests__/vue-jsx.spec.ts | 28 +++++++++++++++++++ packages/playground/vue-jsx/main.jsx | 4 +++ packages/playground/vue-jsx/package.json | 3 +- packages/playground/vue-jsx/vite.config.js | 4 ++- packages/plugin-vue-jsx/index.js | 2 +- packages/plugin-vue/src/handleHotUpdate.ts | 9 +++++- 9 files changed, 73 insertions(+), 4 deletions(-) create mode 100644 packages/playground/vue-jsx/Script.vue create mode 100644 packages/playground/vue-jsx/SrcImport.jsx create mode 100644 packages/playground/vue-jsx/SrcImport.vue diff --git a/packages/playground/vue-jsx/Script.vue b/packages/playground/vue-jsx/Script.vue new file mode 100644 index 00000000000000..2689ed2dfe6ffb --- /dev/null +++ b/packages/playground/vue-jsx/Script.vue @@ -0,0 +1,14 @@ + diff --git a/packages/playground/vue-jsx/SrcImport.jsx b/packages/playground/vue-jsx/SrcImport.jsx new file mode 100644 index 00000000000000..dc775be205af73 --- /dev/null +++ b/packages/playground/vue-jsx/SrcImport.jsx @@ -0,0 +1,12 @@ +import { defineComponent, ref } from 'vue' + +export default defineComponent(() => { + const count = ref(5) + const inc = () => count.value++ + + return () => ( + + ) +}) diff --git a/packages/playground/vue-jsx/SrcImport.vue b/packages/playground/vue-jsx/SrcImport.vue new file mode 100644 index 00000000000000..89f6fb3eb77e2b --- /dev/null +++ b/packages/playground/vue-jsx/SrcImport.vue @@ -0,0 +1 @@ + diff --git a/packages/playground/vue-jsx/__tests__/vue-jsx.spec.ts b/packages/playground/vue-jsx/__tests__/vue-jsx.spec.ts index b17ba40ce772be..b929f61fe965c3 100644 --- a/packages/playground/vue-jsx/__tests__/vue-jsx.spec.ts +++ b/packages/playground/vue-jsx/__tests__/vue-jsx.spec.ts @@ -5,6 +5,8 @@ test('should render', async () => { expect(await page.textContent('.named-specifier')).toMatch('1') expect(await page.textContent('.default')).toMatch('2') expect(await page.textContent('.default-tsx')).toMatch('3') + expect(await page.textContent('.script')).toMatch('4') + expect(await page.textContent('.src-import')).toMatch('5') expect(await page.textContent('.other-ext')).toMatch('Other Ext') }) @@ -17,6 +19,10 @@ test('should update', async () => { expect(await page.textContent('.default')).toMatch('3') await page.click('.default-tsx') expect(await page.textContent('.default-tsx')).toMatch('4') + await page.click('.script') + expect(await page.textContent('.script')).toMatch('5') + await page.click('.src-import') + expect(await page.textContent('.src-import')).toMatch('6') }) if (!isBuild) { @@ -74,4 +80,26 @@ if (!isBuild) { // should not affect other components on the page expect(await page.textContent('.named')).toMatch('1') }) + + test('hmr: script in .vue', async () => { + editFile('Script.vue', (code) => + code.replace('script {count', 'script updated {count') + ) + await untilUpdated(() => page.textContent('.script'), 'script updated 4') + + expect(await page.textContent('.src-import')).toMatch('6') + }) + + test('hmr: src import in .vue', async () => { + await page.click('.script') + editFile('SrcImport.jsx', (code) => + code.replace('src import {count', 'src import updated {count') + ) + await untilUpdated( + () => page.textContent('.src-import'), + 'src import updated 5' + ) + + expect(await page.textContent('.script')).toMatch('5') + }) } diff --git a/packages/playground/vue-jsx/main.jsx b/packages/playground/vue-jsx/main.jsx index f9de952320d709..200702c2cc69a1 100644 --- a/packages/playground/vue-jsx/main.jsx +++ b/packages/playground/vue-jsx/main.jsx @@ -2,6 +2,8 @@ import { createApp } from 'vue' import { Named, NamedSpec, default as Default } from './Comps' import { default as TsxDefault } from './Comp' import OtherExt from './OtherExt.tesx' +import JsxScript from './Script.vue' +import JsxSrcImport from './SrcImport.vue' function App() { return ( @@ -11,6 +13,8 @@ function App() { + + ) } diff --git a/packages/playground/vue-jsx/package.json b/packages/playground/vue-jsx/package.json index ac4f309ffb58d3..84cd946f2d070b 100644 --- a/packages/playground/vue-jsx/package.json +++ b/packages/playground/vue-jsx/package.json @@ -9,6 +9,7 @@ "serve": "vite preview" }, "devDependencies": { - "@vitejs/plugin-vue-jsx": "^1.0.0" + "@vitejs/plugin-vue-jsx": "^1.0.0", + "@vitejs/plugin-vue": "^1.3.0" } } diff --git a/packages/playground/vue-jsx/vite.config.js b/packages/playground/vue-jsx/vite.config.js index 05d1ce17aabbe2..3ec89a003d79f4 100644 --- a/packages/playground/vue-jsx/vite.config.js +++ b/packages/playground/vue-jsx/vite.config.js @@ -1,4 +1,5 @@ const vueJsxPlugin = require('@vitejs/plugin-vue-jsx') +const vuePlugin = require('@vitejs/plugin-vue') /** * @type {import('vite').UserConfig} @@ -7,7 +8,8 @@ module.exports = { plugins: [ vueJsxPlugin({ include: [/\.tesx$/, /\.[jt]sx$/] - }) + }), + vuePlugin() ], build: { // to make tests faster diff --git a/packages/plugin-vue-jsx/index.js b/packages/plugin-vue-jsx/index.js index 8b739a4f84a20a..86b011702578b2 100644 --- a/packages/plugin-vue-jsx/index.js +++ b/packages/plugin-vue-jsx/index.js @@ -207,7 +207,7 @@ function vueJsxPlugin(options = {}) { ) + `\nexport default __default__` } - if (needHmr && !ssr) { + if (needHmr && !ssr && !/\?vue&type=script/.test(id)) { let code = result.code let callbackCode = `` for (const { local, exported, id } of hotComponents) { diff --git a/packages/plugin-vue/src/handleHotUpdate.ts b/packages/plugin-vue/src/handleHotUpdate.ts index bed495a2878711..94d1fb4ee7830e 100644 --- a/packages/plugin-vue/src/handleHotUpdate.ts +++ b/packages/plugin-vue/src/handleHotUpdate.ts @@ -46,7 +46,14 @@ export async function handleHotUpdate({ !isEqualBlock(descriptor.script, prevDescriptor.script) || !isEqualBlock(descriptor.scriptSetup, prevDescriptor.scriptSetup) ) { - affectedModules.add(mainModule) + let scriptModule: ModuleNode | undefined + if (descriptor.script?.lang && !descriptor.script.src) { + const scriptModuleRE = new RegExp( + `type=script.*&lang\.${descriptor.script.lang}$` + ) + scriptModule = modules.find((m) => scriptModuleRE.test(m.url)) + } + affectedModules.add(scriptModule || mainModule) } if (!isEqualBlock(descriptor.template, prevDescriptor.template)) {