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)) {