VSCode: Vue 2 or Vue 3 extensions per project

Up until Vue 2, Vetur has been the recommended VScode extension for Vue support.

Since the release of Vue 3 (which introduces first-class TypeScript support), the official recommendation is to use Volar/Vue Language Tools instead.

I'm currently working on multiple Vue.js projects (some Vue 2, some Vue 3), using the same VSCode installation.

As recommend, tried uninstalling Vetur and using Volar instead in some of the Vue 2 projects, but faced some (apparently) minor issues, such as this one, for example.

Since fixes to such issues required updates in the code (which could impact my colleagues' dev environments), and having nothing to complain about Vetur, I've decided to keep using Vetur for Vue 2 projects.

To do so, I have both extensions installed globally, and disabled on a project-by-project basis accordingly:

Credit goes to this Stack Overflow answer.

Update: also noticed that for ESLint to work properly, Vue 2 projects needed the VSCode ESLint extension pinned to version 2.4.2, while Vue 3 projects work fine with the up-to-date 3.0.10. Since a single VSCode installation can't have two versions of the same extension active at once, I achieved this using separate VSCode profiles, one per Vue version, each with its own pinned ESLint version.

Vetur itself is also pinned, at 0.37.3, since it's the legacy Vue 2 language-tooling extension and hasn't seen further releases.

Also, for Vetur to actually handle formatting in Vue 2 projects, I had to set it as the default formatter for .vue files in my settings.json:

"[vue]": {
  "editor.defaultFormatter": "octref.vetur",
},

On the Vue 3 projects, formatting was instead handled by Prettier, configured in each project's .vscode/settings.json:

{
  "editor.codeActionsOnSave": {
    "source.fixAll": "explicit"
  },
  "editor.formatOnSave": true,
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "[vue]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  }
}

There are probably better ways to handle this, with a more intentional separation of VSCode profiles and extensions per Vue version, but this is how I was able to get it working. I'm happy I no longer need to support Vue 2 projects, and I'm writing this down mostly so I can come back to it in case another Vue 2 project lands on my lap.