vite-plugin-vue
vite-plugin-vue copied to clipboard
when use <script lang="tsx" setup> with template. HMR can not resolve import component using in template
Describe the bug
after project run. replace App.vue
<script setup lang="tsx">
import { Search } from '@element-plus/icons-vue'
// import { Apple } from '@element-plus/icons-vue'
import RenderComp from './components/RenderComp'
const label = () => (<div>test</div>)
</script>
<template>
<RenderComp :label="label" />
<Search />
<!-- <Apple /> -->
</template>
warning only after the project running, import new component using in template. the problem appears.
Reproduction
https://stackblitz.com/edit/vitejs-vite-qrc4zw?file=src/App.vue
System Info
System:
OS: macOS 11.6.5
CPU: (8) x64 Apple M1
Memory: 31.31 MB / 16.00 GB
Shell: 5.8 - /bin/zsh
Binaries:
Node: 14.17.6 - /usr/local/bin/node
Yarn: 1.22.11 - /usr/local/bin/yarn
npm: 6.14.15 - /usr/local/bin/npm
Browsers:
Chrome: 103.0.5060.53
Firefox: 95.0
Safari: 15.4
npmPackages:
@vitejs/plugin-vue: ^2.3.3 => 2.3.3
@vitejs/plugin-vue-jsx: ^1.3.10 => 1.3.10
vite: ^2.9.12 => 2.9.12
Used Package Manager
pnpm
Logs
No response
Validations
- [X] Follow our Code of Conduct
- [X] Read the Contributing Guidelines.
- [X] Read the docs.
- [X] Check that there isn't already an issue that reports the same bug to avoid creating a duplicate.
- [X] Make sure this is a Vite issue and not a framework-specific issue. For example, if it's a Vue SFC related bug, it should likely be reported to vuejs/core instead.
- [X] Check that this is a concrete bug. For Q&A open a GitHub Discussion or join our Discord Chat Server.
- [X] The provided reproduction is a minimal reproducible example of the bug.
video can see in issue https://github.com/vuejs/core/issues/6171#issuecomment-1165543687
I found that the bug was caused by the Vite cache. I've tried if remove them and that can fixes the issue.
So i think that when it using <script setup>
and the templates and scripts both has changed, it needs to re-cache.
If that solution is okay, I can try to pr it. :smile:
@glitchboyl the issue is only show while using
@we125182 Yeah, thank you for your complement. While using <script setup>
, it didn't generate the cache but generate resolved
everytime, I need to dig in and figure it out why.
这个问题目前有解决方案吗?
@sapphi-red @patak-dev
it is similar with issue vitejs/vite#6568 and PR vitejs/vite#4563. the bug was caused by this line.
using <script setup lang="tsx">
in sfc file, while template code changed and affectedModules.has(mainModule) === false
it will use prevDescriptor. because of this, script code changing was ignored.
// packages/plugin-vue/src/handleHotUpdate.ts
export async function handleHotUpdate(
{ file, modules, read, server }: HmrContext,
options: ResolvedOptions
): Promise<ModuleNode[] | void> {
...
const affectedModules = new Set<ModuleNode | undefined>()
const mainModule = modules.find(
(m) => !/type=/.test(m.url) || /type=script/.test(m.url)
)
const templateModule = modules.find((m) => /type=template/.test(m.url))
if (hasScriptChanged(prevDescriptor, descriptor)) {
let scriptModule: ModuleNode | undefined // TODO: this line should move out of block
if (
(descriptor.scriptSetup?.lang && !descriptor.scriptSetup.src) ||
(descriptor.script?.lang && !descriptor.script.src)
) {
const scriptModuleRE = new RegExp(
`type=script.*&lang\.${
descriptor.scriptSetup?.lang || descriptor.script?.lang
}$`
)
scriptModule = modules.find((m) => scriptModuleRE.test(m.url))
}
affectedModules.add(scriptModule || mainModule)
}
if (!isEqualBlock(descriptor.template, prevDescriptor.template)) {
// when a <script setup> component's template changes, it will need correct
// binding metadata. However, when reloading the template alone the binding
// metadata will not be available since the script part isn't loaded.
// in this case, reuse the compiled script from previous descriptor.
if (mainModule && !affectedModules.has(mainModule)) { // TODO: here should add condition: !affectedModules.has(scriptModule)
setResolvedScript(
descriptor,
getResolvedScript(prevDescriptor, false)!,
false
)
}
affectedModules.add(templateModule)
needRerender = true
}
@sapphi-red @patak-dev it is similar with issue vitejs/vite#6568 and PR vitejs/vite#4563. the bug was caused by this line. using
<script setup lang="tsx">
in sfc file, while template code changed andaffectedModules.has(mainModule) === false
it will use prevDescriptor. because of this, script code changing was ignored.// packages/plugin-vue/src/handleHotUpdate.ts export async function handleHotUpdate( { file, modules, read, server }: HmrContext, options: ResolvedOptions ): Promise<ModuleNode[] | void> { ... const affectedModules = new Set<ModuleNode | undefined>() const mainModule = modules.find( (m) => !/type=/.test(m.url) || /type=script/.test(m.url) ) const templateModule = modules.find((m) => /type=template/.test(m.url)) if (hasScriptChanged(prevDescriptor, descriptor)) { let scriptModule: ModuleNode | undefined // TODO: this line should move out of block if ( (descriptor.scriptSetup?.lang && !descriptor.scriptSetup.src) || (descriptor.script?.lang && !descriptor.script.src) ) { const scriptModuleRE = new RegExp( `type=script.*&lang\.${ descriptor.scriptSetup?.lang || descriptor.script?.lang }$` ) scriptModule = modules.find((m) => scriptModuleRE.test(m.url)) } affectedModules.add(scriptModule || mainModule) } if (!isEqualBlock(descriptor.template, prevDescriptor.template)) { // when a <script setup> component's template changes, it will need correct // binding metadata. However, when reloading the template alone the binding // metadata will not be available since the script part isn't loaded. // in this case, reuse the compiled script from previous descriptor. if (mainModule && !affectedModules.has(mainModule)) { // TODO: here should add condition: !affectedModules.has(scriptModule) setResolvedScript( descriptor, getResolvedScript(prevDescriptor, false)!, false ) } affectedModules.add(templateModule) needRerender = true }
Has it been resolved? Currently, there is still this problem.
Closing as it can't reproduce with:
"dependencies": {
"vue": "3.5.8"
},
"devDependencies": {
"@vitejs/plugin-vue": "5.1.4",
"@vitejs/plugin-vue-jsx": " 4.0.1",
"vite": "5.4.7",
}