メインコンテンツまでスキップ

第10章 依存管理①:^ ~ 固定 の違いを体感する🎚️🧨

10.0 この章でできるようになること🎯✨

この章のゴールはこれ👇

  • ^ / ~ / 固定(ピン留め)って 何がどこまで上がるのか 説明できるようになる🔍✨
  • 「勝手に上がって壊れた😭」の原因が “バージョン範囲” だと分かる
  • 自分のプロジェクトに合う 安全寄りルール を選べる🛡️💕

10.1 依存も「約束」だよ🤝📦

第9章で「自分のライブラリは Node >= 22 とか、ESM とか、環境も約束に書こうね」ってやったよね🌍✨ でもね…それに加えて、

依存関係(npmで入れるライブラリ)も、勝手に更新されると壊れる 💥

ってことがあるの🥺

どうして起きるの?😵‍💫

package.jsondependencies にこう書かれてると👇

  • ^~ は「この範囲なら上がってOKだよ〜」って意味になる
  • だから再インストールやアップデートのときに 新しい版が入ることがある 🔄

しかも npm は、デフォルトで ^ を付けて保存しがちなの💡(設定で変えられるよ)(npm ドキュメント)


10.2 まずは超ざっくり!3つの性格👶✨

イメージはこれだけ覚えればOK🥰

  • 固定(例:1.2.3:その1個だけ📌(いちばん固い)
  • ~1.2.31.2.x の範囲だけOK🐛(パッチだけ動く)
  • ^1.2.31.x の範囲までOK✨(マイナー&パッチが動く)

※このルールは「1以上」だと分かりやすいよ🙆‍♀️ ちゃんとした定義は npm の SemVer説明が参考になるよ📘(npm ドキュメント)


10.3 どこまで上がるの?早見表🔢👀✨

例として 1.2.3 を入れたとき👇

  • 固定 1.2.31.2.3 だけ(それ以外は入らない)
  • ~1.2.3>=1.2.3 かつ <1.3.0(パッチ更新だけ)
  • ^1.2.3>=1.2.3 かつ <2.0.0(マイナー&パッチ更新)

この挙動は npm の仕様で(SemVerレンジ)として定義されてるよ📌(npm ドキュメント)


10.4 ⚠️超重要:0.x の世界は別ルールが混ざる🚧💥

ここ、初心者がいちばん事故るポイント😭

0.x は「まだ契約が弱い(未成熟)」になりやすいって第3章でやったよね🚧 だから npm の SemVerでも 0.x を特別扱い してるの💡(npm ドキュメント)

例👇(超大事!)

  • ^0.2.3>=0.2.3 かつ <0.3.0(0の間は “マイナー” が MAJOR っぽい)
  • ^0.0.3>=0.0.3 かつ <0.0.4(さらに狭い)

つまり…

0.x で ^ を付けても、思ったより上がらない / 逆に予想と違う動きをする 😵‍💫

ってなりがち💦(議論も多い…!)(GitHub)


10.5 “事故る”パターンあるある集😇🧨

事故①:相手が SemVer を守ってない🙃

本来 PATCH は「バグ修正」って約束なのに、 実際には 挙動が変わっちゃう 修正が入ってたりするのね…🥺

^~「相手がSemVer守る前提」 だから、ここが崩れると壊れる💥


事故②:自分の直接依存じゃなく、孫依存が更新される👶➡️👶➡️👶

Aを入れたら、中でBを使ってて、さらにBがCを…みたいなやつ🌀 これが更新されて壊れると「え、私なにも変えてないのに😭」ってなる!


事故③:再インストールしたら別バージョンが入った🔄

node_modules 消して入れ直すと、^ / ~ が効いて より新しい版 が入って壊れることがある💥

(この“再現性”の話は次の第11章 lockfile で救えるよ🔒🛡️)


10.6 ハンズオン🧪:^ / ~ / 固定 を同じ手順で体感しよ🎮✨

準備(Windows + VS Code)🪟🧑‍💻

  1. 適当なフォルダ作る(例:svbc-ch10)📁
  2. VS Codeで開いて、ターミナル(PowerShell)を開く✨
mkdir svbc-ch10
cd svbc-ch10
npm init -y

ここから、同じ依存を「3パターン」で入れて比べるよ🎚️✨ (例として lodash を使うね。何でもいいけど、バージョンがよく更新されるやつが体感しやすい😊)


パターンA:^(デフォルトになりやすい)🧨✨

npm i lodash@^4.17.21

package.json を見ると、たぶんこんな感じ👇

"dependencies": {
"lodash": "^4.17.21"
}

パターンB:~(パッチだけ上げたい)🐛🛡️

いったん入れ直しのために消す👇

rmdir /s /q node_modules
del package-lock.json

そして ~ で入れる👇

npm i lodash@~4.17.21

パターンC:固定(ピン留め)📌🔒

また消して👇

rmdir /s /q node_modules
del package-lock.json

固定で入れる👇(バージョン番号だけ指定)

npm i lodash@4.17.21

観察ポイント👀✨(ここが学びの芯!)

同じライブラリでも、package.json の書き方で

  • 「どこまでアップデートを許すか」
  • 「再インストールで別バージョンが入りうるか」

が変わるよ🎚️

✅ 今日の体感:^ は便利だけど、勝手に上がる余地が大きい ✅ ~ は “小さく安全に” 上がる ✅ 固定は “絶対ズレない” けど更新が全部手動になる


10.7 初心者向け:どれを使えばいいの?決め方テンプレ🧠🧭💕

ここ、迷ったらこのルールでOKだよ🙆‍♀️

① 自分が作ってるのは「アプリ」?「ライブラリ」?🎮📦

  • アプリ(自分のサービス/ツール) → 基本は ^ でもOK(ただし lockfile 運用が前提!次章ね🔒)
  • ライブラリ(他人に使われる前提) → 依存の選び方が少し慎重になる(peerDependencies も絡む。第12章でやる🤝)

② その依存、どれくらい信用できる?🧐

  • 信用できる(大手・運用が安定) → ^ OK寄り✨
  • ちょい不安(更新が荒い/破壊が混ざる) → ~ 寄り🛡️
  • 絶対に変えたくない(本番直結、事故が痛い) → 固定📌

③ セキュリティ修正は受け取りたい?🛡️🚑

  • ~ でも ^ でも パッチは入る(前提:SemVer守ってる)
  • 固定だと 自分で上げない限り入らない から、運用でカバーが必要になるよ📌

10.8 npmのデフォルト挙動も知っておこう🧾✨

npm は設定で「保存するときの記号」を変えられるよ🎚️ 公式の設定項目に save-prefix(デフォルト ^)と save-exact(固定保存)があるよ📌(npm ドキュメント)

~ をデフォルトにしたい(安全寄り)🛡️

npm config set save-prefix "~"

固定をデフォルトにしたい(超固め)📌

npm config set save-exact true

※チームでやるなら「全員のPCで揃える」か「プロジェクトのルールとして明記」がおすすめだよ👥✨


10.9 ミニ演習📝🎯(ここで定着!)

演習A:範囲クイズ(10問)🎯✨

次の指定は、どこまで上がるでしょう?(答えは自分で書いてOK!)

  1. ^1.2.3
  2. ~1.2.3
  3. 1.2.3
  4. ^0.2.3
  5. ^0.0.3
  6. ~0.2.3
  7. ^2.0.0
  8. ~2.0.0
  9. ^1.0.0
  10. 固定の弱点を1つ(なぜ怖い?)

演習B:自分のプロジェクト方針を1行で決める📜✨

例👇

  • 「基本 ^、ただし不安な依存は ~、超重要は固定📌」
  • 「学習中なので ~ で安全寄りにする🛡️」

10.10 AI活用🤖✨(VS Codeでそのまま使える)

🪄 ① 範囲の説明を“やさしく”してもらう

^1.2.3~1.2.31.2.3 の違いを、女子大生に説明する感じで、たとえ話も入れて🙏」

🪄 ② 自分の依存一覧の“危険度”チェック

「この package.json の dependencies を見て、^/~/固定の選び方の改善案を出して。理由は1行ずつで!」

🪄 ③ クイズの自動採点

「この10問の答えを採点して、間違いは“なぜそうなるか”を1〜2行で教えて!」


まとめ🎀✨

  • ^ / ~ / 固定は「更新をどこまで許すか」の 安全レバー 🎚️🛡️
  • ^ は便利だけど、上がる余地が大きい(特に再インストール時にびっくりしがち)
  • ~ は “パッチだけ” で 安全寄り 🐛✨
  • 固定は “ズレない” けど 自分で更新しないと一生古い 📌
  • そして 0.x は特別ルールがある から要注意🚧💥(npm ドキュメント)

次の第11章では、今日の「勝手に上がる」問題を lockfile(盾)🔒🛡️ でどう止めるかやるよ〜😊✨