yarn pnp 環境化で VSCode 拡張機能の prettier を動かす
yarn pnp で作成したプロジェクトで VSCode 拡張機能の prettier が動かなかったので対応方法を紹介します。
やりたいこと
yarn pnp で作成したプロジェクトでプロジェクトの prettier とフォーマットルールを使って VSCode 拡張機能の prettier (prettier-vscode) を動かしたかったのですが、ハマったので事象と対応方法をメモしておきます。
環境
- OS
- Microsoft Windows 22H2
- Node.js
- v22.12.0
- yarn
- v4.5.3
- prettier
- v3.4.2
- prettier-vscode
- v11.0.0
事象
以下の手順でセットアップしたのですが prettier-vscode が動きませんでした。
yarn プロジェクト作成と prettier インストール
-
yarn プロジェクト作成
-
prettier インストール
-
フォーマットルール作成
-
この時点で
yarn prettier . --write
はワークしている
VSCode 拡張機能 prettier-vscode
のインストールとセットアップ
-
VSCode 拡張機能 Prettier - Code formatter - Visual Studio Marketplace をインストールする
-
前節で作成した yarn プロジェクトルートに
.vscode
フォルダを作成し、settings.json
ファイルを作成し以下内容で保存する時々プロジェクトの
.prettierrc
を prettier-vscode に認識させるために"prettier.configPath": ".prettierrc"
のような設定が必要と記載されているサイトがあったりしますが、prettier-vscode はデフォルトでプロジェクトにある prettier が許容しているルールファイル (Configuration File · Prettier)を参照してくれるので不要です。 -
npm プロジェクトではこれで動くはずですが、
.js
ファイルを作成して適当なスクリプトを書いて保存してみても全くフォーマットされません
原因
VSCode で prettier-vscode のログを見てみると以下のエラーが出ていました。
prettier-vscode の仕様はプロジェクトの package.json
に prettier
があれば、プロジェクトの node_modules
内の prettier を使用し、VSCode の設定で prettier.resolveGlobalModules
が true
になっていればユーザーグローバルにインストール (npm install -g) された prettier を使用し、何れにも当てはまらなければ prettier-vscode にバンドルされている prettier が使用されるようです。
This extension will use prettier from your project’s local dependencies (recommended). When the
prettier.resolveGlobalModules
is set totrue
the extension can also attempt to resolve global modules. Should prettier not be installed locally with your project’s dependencies or globally on the machine, the version of prettier that is bundled with the extension will be used.
- GitHub - prettier/prettier-vscode: Visual Studio Code extension for Prettier
上記エラーは package.json
に prettier
があるのに node_modules
内の prettier が見つからなかったので発生しているようです。
yarn pnp (Plug’n’Play: プラグアンドプレイ)では npm の node_modules
のようにインストールしたパッケージをプロジェクト毎に展開しません。インストールしたパッケージはユーザーグローバル (%LOCALAPPDATA\Yarn\Berry\cache%
) で保有し、各プロジェクト内の .pnp.cjs
を通じて必要なパッケージがロードされます。
ちょっと長いですが、公式ドキュメントの説明を引用しておきます。
If you look into the files in your project, you may notice the absence of a
node_modules
folder. This is unusual! We regularly get asked on Discord where the folder is, by people thinkingyarn install
silently failed.
The thing is, this is actually expected! The way Yarn PnP works, it tells Yarn to generate a single Node.js loader file in place of the typicalnode_modules
folder. This loader file, named.pnp.cjs
, contains all information about your project’s dependency tree, informing your tools as to the location of the packages on the disk and letting them know how to resolve require and import calls.
- Plug’n’Play | Yarn
さて yarn pnp では各プロジェクトにパッケージを展開せず、.pnp.cjs
を通じてパッケージがロードされるという部分を何とかしないと prettier-vscode は動きそうにないですね。
対応
プロジェクトの .yarnrc.yml
に nodeLinker: node-modules
を設定すれば node_modules
に展開されるようになりますが、これは pnp の恩恵 (Plug’n’Play | Yarn) が失われ本質的ではありません。
Define how Node packages should be installed.
Yarn supports three ways to install your project’s dependencies, based on thenodeLinker
setting. Possible values are:
- If
pnp
, a single Node.js loader file will be generated.- If
pnpm
, anode-modules
will be created using symlinks and hardlinks to a global content-addressable store.- If
node-modules
, a regularnode_modules
folder just like in Yarn Classic or npm will be created.
どうしたものかと色々調べていたところ公式ドキュメントにこんなページが。
Why are SDKs needed with Yarn PnP?
Yarn PnP works by generating a Node.js loader, which has to be injected within the Node.js runtime. Many IDE extensions execute the packages they wrap (Prettier, TypeScript, …) without consideration for loaders. The SDKs workaround that by generating indirection packages. When required, these indirection automatically setup the loader before forwarding therequire
calls to the real packages.
- Editor SDKs | Yarn
Editor SDK なるものが用意されており、まさに「yarn pnp では各プロジェクトにパッケージを展開せず、.pnp.cjs
を通じてパッケージがロードされる」という部分を何とかしてくれると書かれています。
早速上記ページに沿って Editor SDK をインストールします。
適当な JavaScript を保存してみると、無事にフォーマットされました!
prettier-vscode のログを見てみると prettier がプロジェクトの .yarn/sdks/prettier
に解決されるようになっていることが確認できます。
あとがき
yarn pnp のプロジェクトで VSCode 拡張機能の prettier-vscode をプロジェクトの prettier を使って動かす方法を紹介しました。Editor SDK は yarn dlx
でインストールするのでプロジェクトのパッケージ依存関係に影響を与えませんが、その分各開発者のプロジェクトインストール作業がひと手間増えます。プロジェクトでエディタが固定されている場合はひょっとするとプロジェクトの依存に入れちゃってもよいのかもしれませんが、yarn add
でインストールした場合も、問題なく動くかは検証できていません。