Docs header transparent bg

よくある質問

なぜ=依存関係のみを指定できないのですか?

Q: 特定のバージョンにgemを固定することの価値は理解していますが、Gemfile内のすべての依存関係に=バージョンを指定して、Gemfile.lockについて忘れることはできないのでしょうか?

A: 多くのgemには独自の依存関係があり、それらは=依存関係を指定する可能性は低いでしょう。さらに、gemが自身の依存関係をすべて厳密に固定することは、おそらく賢明ではありません。Gemfile.lockを使用すると、アプリケーションがGemfileで必要な依存関係のバージョンを指定できるだけでなく、アプリケーションが最後に正しく動作したときに使用したサードパーティコードの正確なバージョンをすべて記憶できます。

Gemfileでより緩い依存関係(例:nokogiri ~> 1.4.2)を指定することで、bundle update nokogiriを実行して、bundlerにnokogiriとその依存関係を、~> 1.4.2のバージョン要件を満たす最新バージョンにのみ更新させることができます。これにより、「nokogiriの現在のバージョンを使用したい」(Gemfile内のgem 'nokogiri')と指定することもでき、正確なバージョン番号を調べる必要がなくなり、アプリケーションが常にまったく同じバージョンのサードパーティコードで実行されるという利点も得られます。

なぜすべてをサブモジュール化できないのですか?

Q: このようにgemを管理するためにbundlerが必要な理由がわかりません。必要なgemを取得してサブモジュールに入れ、各サブモジュールをロードパスに入れるだけではいけないのでしょうか?

A: 残念ながら、その解決策では、依存関係の依存関係を含め、アプリケーション内のすべての依存関係を手動で解決する必要があります。そして、一度それを正常に行ったとしても、特定のgemを更新したい場合は、その作業をやり直す必要があります。たとえば、rails gemを更新したい場合、Railsの依存関係(rackerubisi18ntzinfoなど)に依存しているすべてのgemを見つけ、新しいバージョンのRailsの要件を満たす新しいバージョンを見つける必要があります。

率直に言って、これはコンピュータが得意とする種類の問題であり、開発者であるあなたは時間を費やすべきではありません。

さらに重要なことに、手動の依存関係解決プロセスで間違いを犯した場合、異なる依存関係間の競合に関するフィードバックが得られず、微妙なランタイムエラーが発生します。たとえば、誤って間違ったバージョンのrackをサブモジュールに入れた場合、Railsまたは別の依存関係が存在しないメソッドに依存しようとしたときに、実行時にエラーが発生する可能性があります。

結論: 一見シンプルに見えるかもしれませんが、実際には非常に複雑です。

なぜBundlerは--withoutグループからgemをダウンロードしているのですか?

Q: bundle install --without productionを実行しましたが、bundlerは依然として:productionグループのgemをダウンロードしています。なぜですか?

A: BundlerのGemfile.lockには、渡すオプションに関係なく、Gemfile内のすべての依存関係の正確なバージョンが含まれている必要があります。そうでない場合、アプリケーションを本番環境にデプロイすると、すべての依存関係が変更される可能性があり、Bundlerの利点が失われます。開発およびテストで使用したのと同じgemを本番環境でアプリケーションが使用しているかどうかを確信できなくなります。さらに、本番環境で依存関係を追加すると、デプロイ不可能なアプリケーションになる可能性があります。

たとえば、rack =1.1に依存する本番環境専用のgem(rack-debuggingと呼びましょう)があると想像してください。bundle install --without productionを実行したときにproductionグループを評価しなかった場合、アプリケーションをデプロイしたときに、rack-debuggingrailsrack ~> 1.2.1に依存するactionpackに依存)と競合するというエラーが表示されるでしょう。

別の例:Gemfilegem 'rack'があるシンプルなRackアプリケーションを想像してください。繰り返しますが、rack-debugging:productionグループに入れると想像してください。bundle install --without productionでインストールしたときに:productionグループを評価しなかった場合、アプリは開発環境でrack 1.2.1を使用し、デプロイ時にrack-debuggingがテストしたRackのバージョンと競合することを知ることになります。

対照的に、環境で実際に使用したいグループに関係なく、bundle installを呼び出すときにすべてのグループのgemを評価することで、rack-debuggerの要件を発見し、Gemfile内のgem 'rack'の要件とも互換性のあるrack 1.1をインストールします。

要するに、特定の環境で使用するつもりの依存関係に関係なく、常にGemfile内のすべての依存関係を評価することで、異なる環境で異なるグループセットに切り替える際の不快な驚きを回避できます。そして、gemをダウンロードするだけで(インストールはしません)、本番環境(または開発環境)でのみ使用するgemの困難なインストールプロセスについて心配する必要はありません。

インストールに特別なフラグが必要なC拡張機能があります

Q: mysqlなどのC拡張機能のgemがあり、コンパイルとインストールには特別なフラグが必要です。これらのフラグをこれらのgemのインストールプロセスに渡すにはどうすればよいですか?

A: まず第一に、この問題はmysql gemのドロップイン代替であるmysql2 gemには存在しません。一般的に、最新のC拡張機能は必要なヘッダーを適切に検出します。

C拡張機能にフラグを渡す必要がある場合は、bundle configコマンドを使用できます。

$ bundle config build.mysql --with-mysql-config=/usr/local/mysql/bin/mysql_config

Bundlerはこの構成を~/.bundle/configに保存し、bundlerは同じユーザーが実行するすべてのbundle installでこの構成を使用します。その結果、gemに必要なビルドフラグを指定すると、必要な回数だけそのgemを正常にインストールできます。

インターネット接続がなく、Bundlerがgemサーバーに接続しようとし続けます

Q: インターネット接続はありませんが、以前にgemをインストールしました。bundlerにリモートのgemサーバーに接続せずにローカルのgemキャッシュを使用させるにはどうすればよいですか?

A: bundle install--localフラグを使用します。--localフラグは、bundlerにリモートのgemサーバーに接続するのではなく、ローカルのgemキャッシュを使用するように指示します。

$ bundle install --local

RubyGemsからのバンドルが非常に遅いです

Q: RubyGems.orgからバンドルすると、非常に遅いです。速くするためにできることはありますか?

A: まず、gem install bundlerを実行してBundlerの最新バージョンに更新してください。gemのインストールを高速化する多くの改善を長年にわたって追加してきました。非常に遅延が大きい接続の場合は、--full-indexフラグを使用すると改善される可能性があります。これにより、多くの小さなHTTPリクエストを行うのではなく、gem情報をすべて一度にダウンロードします。

$ bundle install --full-index

gem内のGemfileの使用

Q: gemにGemfileを入れるとどうなりますか?

A: 誰かがあなたのgemをインストールすると、あなたがrubygems.orgにアップロードする.gemファイルに含めたとしても、GemfileGemfile.lockファイルは完全に無視されます。gem内のGemfileは、開発者(あなたのような人)があなたのgemで開発作業を行うために必要な依存関係を簡単にインストールできるようにするためのものです。Gemfileは、開発専用またはテスト専用のgemを追跡およびインストールする簡単な方法も提供します。gemでのBundlerページおよびBundlerを使用してgemを作成する方法ガイドから、gem内のGemfileについて読んでください。

Q: gemを作成するときにGemfile.lockをコミットする必要がありますか?

A: はい、コミットする必要があります。gemのリポジトリにGemfile.lockが存在することで、リポジトリの新しいチェックアウトが毎回まったく同じ依存関係のセットを使用することが保証されます。これにより、リポジトリが新規および既存のコントリビューターに対してよりフレンドリーになると考えています。理想的には、誰でもリポジトリをクローンし、bundle installを実行して、テストに合格する必要があります。Gemfile.lockをチェックインしないと、新しいコントリビューターが異なるバージョンの依存関係を取得し、修正方法がわからないテストの失敗に遭遇する可能性があります。

Q: しかし、gemはGemfile.lockをチェックインすべきではないと読んだことがあります!

A: Gemfile.lockをチェックインしない主な利点は、依存関係のいずれかが破壊的な方法で変更された場合、新しいチェックアウト(CIを含む)でテストがすぐに失敗することです。すべての新しいチェックアウト(および可能性のある新しいコントリビューター)に壊れたビルドに遭遇させる代わりに、Bundlerチームは、依存関係が新しいバージョンをリリースするたびに、Dependabotのようなツールを使用して自動的にPRを作成し、テストスイートを実行することを推奨しています。依存関係監視ボットを使用したくない場合は、bundle installを実行する前にGemfile.lockを削除する追加の毎日のCIビルドを作成することをお勧めします。そうすることで、あなたやCIステータスを監視している他の人は、依存関係の変更による失敗について最初に知ることができます。

エラーを見つけたり、何かが欠けていることに気づいた場合は、GitHubでこのドキュメントを編集してください