vite icon indicating copy to clipboard operation
vite copied to clipboard

when use <script lang="tsx" setup> with template. HMR can not resolve import component using in template

Open we125182 opened this issue 2 years ago • 5 comments

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

we125182 avatar Jun 26 '22 03:06 we125182

video can see in issue https://github.com/vuejs/core/issues/6171#issuecomment-1165543687

we125182 avatar Jun 26 '22 03:06 we125182

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 avatar Jun 28 '22 08:06 glitchboyl

@glitchboyl the issue is only show while using

we125182 avatar Jun 29 '22 01:06 we125182

@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.

glitchboyl avatar Jun 29 '22 03:06 glitchboyl

这个问题目前有解决方案吗?

Preyou avatar Sep 07 '22 07:09 Preyou

@sapphi-red @patak-dev it is similar with issue #6568 and PR #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
  }

we125182 avatar Sep 17 '22 11:09 we125182