はじめに
フロントエンドプロジェクトのパッケージマネージャーを Yarn(v1)から npm に移行した際の具体的な手順と注意点をまとめました。
依存関係が変わってしまうリスクを最小限にしつつ、synp を用いて既存の yarn.lock の内容を引き継いだ移行方法について共有いたします。
1. 移行背景と選択理由
プロジェクトで利用している Storybook v8以降で Yarn v1 のサポートが非推奨となったことを契機に、依存管理方法の見直しが必要になりました。
検討した選択肢は次の2つ:
- Yarn v1 → v4 への大規模アップグレード
- npm へ移行
有識者の方への相談の結果、以下の理由から npm への移行を採用しました。
- Yarn v4 への更新はリスクと工数が大きい
- Node.js に同梱される npm のほうが運用上のリスクが小さい
- npm の機能改善が進み、Yarn を使う優位性が縮まった
一方で、次の懸念がありました。
- 現行の yarn.lock の依存関係を変えたくない
- npm による依存再解決を最小限に抑え、yarn.lockの解決済み依存関係を可能な限り維持したい
そのため、synp による lockfile 変換方式を採用しました。
2. 前提環境
今回の手順は次の環境で実施しました。
OS: Windows
Node.js: v22.21.1
npm: 10.9.4
Yarn: 1.22.22
synp: 1.9.14
3. synp のメリットと仕組み
synp は、以下を目的としたツールです。
- yarn.lock に記載された 解決済み依存関係をそのまま package-lock.json に落とし込む
- npm による依存再解決を最小限に抑え、yarn.lockの解決済み依存関係を可能な限り維持する
※出典:npm公式
https://www.npmjs.com/package/synp
ただし、100% 完全な変換を保証するものではないため、最終的な動作確認は必須です。
4. 移行手順(詳細)
① synp で yarn.lock → package-lock.json に変換
synp をインストール:
npm install -g synp
変換を実行:
npx synp --source-file yarn.lock
② yarn.lock とnode_modules を削除
rm yarn.lock
rm -rf node_modules
ここで npm install を実行すると
npm WARN old lockfile が表示されました。
synp が古い形式の lockfile を生成するために発生するようです。
③ package-lock.json の形式のみを最新仕様へ更新
依存再解決を最小限に抑え、lockfile の形式だけ更新:
npm install --package-lock-only
- node_modules を変更しない
- package-lock.json の形式のみを最新仕様に更新する
- 依存関係の解決結果は維持される
④ npm install を実行
npm install
npm ベースの node_modules が構築されます。
⑤ Yarn scripts を npm scripts に置き換え
以下修正例です。
yarn dev→ npm run dev
yarn build → npm run build
5. 移行後のヒューマンエラー対策
Yarn を誤って実行しないために以下の対応を行いました。
対策①:yarn.lock を .gitignore に追加
yarn.lock
意図しない lockfile 生成・コミットを防止できます。
対策②:preinstall で Yarn の実行を検出してブロック
"scripts": {
"preinstall": "node -e \"const ua=process.env.npm_config_user_agent||''; if(ua.includes('yarn')){console.error('Error: このプロジェクトは npm を使用します。Yarn は利用できません。'); process.exit(1);}\""
}
preinstallに設定した内容は、npm install やyarn installの前に実行されます。
誤って Yarn を使おうとすると、次のように停止します。
Error: このプロジェクトは npm を使用します。Yarn は利用できません。
移行完了
これでパッケージマネージャーをYarnからnpmへ移行することができました!
あとはビルドやテスト、動作確認で問題ないことが確認できたら移行完了です。

