🌳

モノレポ向けのVSCode Prettier拡張機能の設定

に公開

小ネタ。以下のような、一方がNode.jsでない構成のモノレポにおいてMarkdownをPrettier拡張でフォーマットしたい。

$ tree -L 2 .
.
├── backend
│   ├── pyproject.toml
│   ├── README.md
│   ├── src
│   └── tests
├── foxtail.code-workspace
├── frontend
│   ├── node_modules
│   ├── package.json
│   ├── package-lock.json
│   ├── README.md
│   └── src
└── README.md

7 directories, 7 files

https://code.visualstudio.com/docs/editing/workspaces/workspaces

単一ウィンドウで済ませたい & 各種拡張機能に依存関係も解決してもらいたいので、以下のようなワークスペース設定を書いてVSCodeを使うと思う。

foxtail.code-workspace
{
  "folders": [
    {
      "name": "app",
      "path": "."
    },
    {
      "name": "backend",
      "path": "./backend"
    },
    {
      "name": "frontend",
      "path": "./frontend"
    }
  ],
  "settings": {
    "[markdown]": {
      "editor.defaultFormatter": "esbenp.prettier-vscode",
      "editor.formatOnSave": true
    },
    // ...
  },
  "extensions": {
    "recommendations": [
      "esbenp.prettier-vscode"
    ]
  }
}

問題点

Prettier拡張は開いているディレクトリのnode_modulesにPrettierがインストールされていれば、そのPrettierを利用してくれる。なければ拡張機能に同梱のPrettierが動作するわけだが、同梱のPrettierにはちょっと問題があり、期待通りのフォーマット結果にならない。

v3に対応していないだけと理解していたが、他にも内部に設定ファイルを持ってしまっているという問題があるよう(以下の記事より)で、その影響か、私の環境では例のアルファベットと日本語の間にスペースを挿入する挙動になっていた。

- Pythonのインストール
+ Python のインストール

https://zenn.dev/teppeis/scraps/c093e386614fb8

このためだけにbackendディレクトリにPrettierをインストールするのは嫌だし、Markdownファイルのフォーマットにしか利用していないとはいえ、そもそもモノレポ内部でファイルによってバージョンの異なるツールによってフォーマットされるのも気持ちが悪い

対策

Prettier拡張では使用するPrettierのパスを指定することができるので、以下のような設定を書いてやれば他方でもfrontendディレクトリで管理しているPrettierを流用できる。

  "settings": {
+   "prettier.prettierPath": "../frontend/node_modules/prettier",
    "[markdown]": {

ただしcode-workspaceファイルでは、foldersで設定したパスをルートとしてパスが解決されるので、これでは今回のワークスペース設定でいうapp(プロジェクトルート直下)のファイルがフォーマットできない。

Prettier拡張のエラー
["INFO" - 10:08:45 PM] Attempted to load Prettier module from /home/username/workspace/frontend/node_modules/prettier
["ERROR" - 10:08:45 PM] Failed to load module. If you have prettier or plugins referenced in package.json, ensure you have run `npm install`

folders内にそれぞれの相対パス設定を書けないかと思ったが、サポートされていないようなので、これは.vscode/settings.jsonを対象のワークスペースに配置してパスを上書きする。

.vscode/settings.json
{
  "prettier.prettierPath": "./frontend/node_modules/prettier",
}

これですべてのファイルがfrontendで管理のPrettierでフォーマットできるようになる。

雑感

  • appfrontendのみを対象としたnpm workspaceを設定して、それを参照させてもよかったかも
  • code-workspaceでも変数を使わせてほしい

Discussion