fv17の日記

Webエンジニアの備忘用ブログです。主にWeb界隈の技術に関して書いています。

bundle install と bundle update の違い

概要

bundle install

Gemfile.lockを元にgemをinstall。

Gemfile.lockが存在しない場合、Gemfileを元にgemをinstallした後、Gemfile.lockを作成。

bundle update

Gemfile.lockを無視し、Gemfileを元にgemをinstall後、Gemfile.lockを更新する。 

Gemfile.lockを無視するため、bundle installと異なり、gem同士の依存関係が刷新される。

豆知識

基本的に実開発中はbundle installのみ。

bundle updateを行うのは、gem間の依存関係(バージョン等)が適切でない場合

 

詳細その1 - まずはGemfileとGemfile.lockの理解が必要

Gemfile

Gemfileは必要なgemとそれらのバージョンの一覧。

x.x.x以上のバージョンなど、曖昧なバージョン指定をすることができる。

 

Gemfile.lock

Gemfile.lockはGemfileを元に実際に取得してきた各gemとそれらのバージョン。

特定のバージョンが記載されている。

 

Gemfile.lockが存在する理由

異なるマシンで同一のgemのバージョン、依存関係を再現したいため。gemのバージョンや依存関係が違うだけで不具合出たりするので、それらを揃えたい、揃えなければならない場面は多い。

 

Gemfileではバージョンに関して、x.x.x以上のバージョンなど幅を持たせた記述ができる。そのため、Gemfileだけだと、gemのバージョンが進んだ場合や依存関係が変わった場合に、全く同一の環境を作成できなくなる。

 

Gemfile.lockでは特定のバージョンを明記しているため、全く同一の環境を複製することが可能。bundle installをした場合、基本的に各gemはGemfileではなくGemfile.lockを元にインストールされる。

 

なお、全く同一環境(同一のgemバージョンと依存関係)を揃えたいのは下記のような場合

  • チームメンバーと同一の開発環境を用意したい
  • 自宅と会社で異なるマシンで開発してる時に同一環境を用意したい
  • テスト環境と本番環境で同一環境を用意したい

 

Gemfile.lockだけで良いのでは?

もしくはGemfileに、特定のバージョンを指定すれば良いのではと思うが、

  • 全てのgemのバージョンを開発者が調べ、個別に指定するのは面倒
  • gemのバージョンや依存関係は少しでもズレているとエラーになるが、互いに参照し合うなどしており非常に複雑
  • 開発中はどんどんバージョンアップさせたい

などがあるため、幅のあるバージョン指定を行うことで、Railsが裏でヨロシク管理してくれる方がはるかに楽で、開発効率が良い。 

 

詳細その2 - bundle install と bundle update の違い

いよいよ本題に。

 

bundle install

Gemfile.lockが存在しない場合、Gemfileを元にgemをinstallする。

この時、各gemが依存しているgemも自動的にインストールする。

 

Gemfile.lockが存在し、Gemfileに更新がなければ、Gemfile.lockを元にgemのバージョンと依存しているgemをインストールする。

 

Gemfile.lockが存在し、Gemfileに更新があれば、更新されていないgemに関してはGemfile.lockを元に、更新されているgemに関してはGemfileを元にgemをインストールする。

 

チームに新規配属者が入り環境構築する時、テスト環境や本番環境を作成する時などはすでにGemfile.lockが存在するため、bundle installを行うとGemfile.lockを元にgemのバージョンと依存関係が構築される。

 

Gemfile.lockのバージョンと依存関係を優先するため、仮にGemfile.lockの作成後にgemの新しいバージョンがリリースされていても、最新バージョンにはならず、Gemfile.lockに記載されているバージョンとなる。

 

bundle update

Gemfile.lockを無視し、Gemfileを元にgemをinstallする。

各gemのバージョンと依存関係、依存しているgemのバージョンも最新のものになる。

その後、Gemfile.lockを更新する。

 

基本的には、bundle installを行い、依存関係等でエラーが出た場合にはbundle updateを行うなどの対処が必要。bundle installまわりの依存関係エラーがなぜ発生するのか?については、公式ドキュメントの「Conservative Updating」に記載がある。

 

また、本番環境で気軽にbundle updateすると、開発環境やテスト環境とgemの構成が変わり、思わぬ不具合が発生することがあるので注意。

 

参照

https://bundler.io/v1.16/man/bundle-install.1.html

https://bundler.io/v1.16/man/bundle-update.1.html

https://bundler.io/v1.16/man/bundle-install.1.html#CONSERVATIVE-UPDATING