vuejs / language-tools

⚡ High-performance Vue language tooling based-on Volar.js
https://marketplace.visualstudio.com/items?itemName=Vue.volar
MIT License
5.79k stars 390 forks source link

VSCode `addMissingImports` on save adds imports to bottom of file instead of the script block #4586

Closed Robbe95 closed 2 months ago

Robbe95 commented 2 months ago

Vue - Official extension or vue-tsc version

2.0.26

VSCode version

1.91.0

Vue version

3.4.30

TypeScript version

5.5.2

System Info

System:
    OS: macOS 13.3
    CPU: (10) arm64 Apple M2 Pro
    Memory: 71.95 MB / 32.00 GB
    Shell: 3.6.1 - /opt/homebrew/bin/fish
  Binaries:
    Node: 20.4.0 - ~/Library/Caches/fnm_multishells/13963_1721037540438/bin/node
    npm: 9.8.0 - ~/Library/Caches/fnm_multishells/13963_1721037540438/bin/npm
    pnpm: 9.1.1 - ~/Library/pnpm/pnpm
  Browsers:
    Chrome: 126.0.6478.127
    Safari: 16.4

Steps to reproduce

Enable imports on save in VSCode settings

  "editor.codeActionsOnSave": {
    "source.addMissingImports": "always"
  },

Export a string test

export const TEST = 'test'

In a Vue file, use it in both a computed and a normal const

<script setup lang="ts">
const testConst = TEST
const testComputed = computed<string>(() => TEST)
</script>

<template>
  <div>
    {{ testConst }}
    {{ testComputed }}
  </div>
</template>

Save the file and imports get added to bottom

What is expected?

Import is added to top of script block

<script setup lang="ts">
import { TEST } from '~/test'

const testConst = TEST
const testComputed = computed<string>(() => TEST)
</script>

<template>
  <div>
    {{ testConst }}
    {{ testComputed }}
  </div>
</template>

What is actually happening?

Import is added at the bottom of the file

<script setup lang="ts">
const testConst = TEST
const testComputed = computed<string>(() => TEST)
</script>

<template>
  <div>
    {{ testConst }}
    {{ testComputed }}
  </div>
</template>
import { TEST } from '~/test';

Link to minimal reproduction

No response

Any additional comments?

I've also had this happen when moving files, that imports are added to the bottom of the file instead of the top of the script block.

It does work correctly if you remove either the constant or the computed. Saving this

<script setup lang="ts">
const testConst = TEST
</script>

<template>
  <div>
    {{ testConst }}
  </div>
</template>

or

<script setup lang="ts">
const testComputed = computed<string>(() => TEST)
</script>

<template>
  <div>
    {{ testComputed }}
  </div>
</template>

Produces the correct result, for example:

<script setup lang="ts">
import { TEST } from '~/test';

const testComputed = computed<string>(() => TEST)
</script>

<template>
  <div>
    {{ testComputed }}
  </div>
</template>