Search code examples
visual-studio-codeprettier

How do I specify a specific prettier version in a VSCode .devcontainer?


Background

In a repo, we have a pre-commit configuration that requires version 2.2.1 of prettier:

  - repo: https://github.com/pre-commit/mirrors-prettier
    rev: "v2.2.1"
    hooks:
      - id: prettier

And in my .devcontainer I specify use of prettier, so that my code gets formatted on save:

{
  // ...
  "settings": {
    "editor.formatOnSave": true,
    "editor.defaultFormatter": "esbenp.prettier-vscode"
    // ...
  }
}

Prettier is installed by the vscode extension, not globally, so doing:

npm list -g | grep prettier

in my dev container doesn't list anything installed.

The problem

A different version of prettier is being used, and I get a conflict in how it formats arrays in json files. Every time I open up a particular json file, it gets reformatted by my editor.

Also, if I rebuild my devcontainer, I'm then liable to unknowingly switch the version of code formatter I use, leading to git hell.

The question

How can I specify that my devcontainer use an exact prettier version so I can enforce the same behaviour in my dev environment as in our code quality tools?

I have already tried this:

You can set up the prettier extension to use a resolved version of prettier, according to the instructions under "Prettier Resolution" here.

So I added to the Dockerfile:

# Ensure prettier is installed globally so the esbenp.prettier-vscode can find a specific version
# as discussed here:
#   https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode
# NB You can remove the -g flag if you have a node project. I install globally because I use prettier on all projects, whether they have a node_modules folder or not.
RUN npm install [email protected] -g -D --save-exact

And in the .devcontainer.json settings, told the extension to resolve the prettier module instead of using its own:

{
  // ...
  "settings": {
    "editor.formatOnSave": true,
    "editor.defaultFormatter": "esbenp.prettier-vscode",
    "prettier.resolveGlobalModules": true,
    // ...
  }
}

That didn't work so I also tried adding:

    "prettier.prettierPath": "$(npm root -g)/prettier",

Which also didn't work; the prettier extension is still using it's own version.


Solution

  • You can set the version in the .devcontainer like this:

    "extensions": ["[email protected]"],
    

    The trick is you also have to turn off extension automatic updates:

    "settings": {
        "extensions.autoCheckUpdates": false,
        "extensions.autoUpdate": false
    },
    

    Note: This turns off automatic updates for all extensions.

    Also, RUN npm install [email protected] -g -D --save-exact in the Dockerfile adds the prettier CLI to the environment, not the VS Code extension.