Skip to content

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

@Robbe95

Description

@Robbe95

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>

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workinggood reproduction ✨This issue provides a good reproduction, we will be able to investigate it firstupstream

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions