gemspecに含まれる依存関係がRailsエンジンのアセットパイプラインに追加されない 質問する

gemspecに含まれる依存関係がRailsエンジンのアセットパイプラインに追加されない 質問する

私はいくつかの依存関係を持つ Rails エンジンを作成しています。 gemspec で依存関係を指定し、エンジンは実行時にそれらを見つけます(つまり、Gemfile.lock は正しいように見えます)。 Ruby ファイルでプラグインを使用する場合は、ファイルの先頭でbundle install明示的に指定する必要があります。require dependency-name

しかし、依存関係のアセット パイプラインを使用したい場合、Sprockets はそれを見つけることができません。

私が (今のところ) 使用しているアプリは、Rails プラグインのテスト フォルダーにあるダミー アプリです。Sprockets は、エンジンの Gemfile (実際にはダミー アプリの Gemfile) でアセットを指定した場合、アセットを見つけることができますが、gemspec で指定した場合は見つけることができません。Gemfile に依存したくないのは、そうすると、私のプラグインを使用するすべてのアプリが、すべての依存関係を手動で Gemfile に追加する必要があるからです。同じ理由で、アプリの構成ファイルの更新を伴うソリューションも望んでいません。

これは、依存関係が gemspec から組み込まれている場合に機能します (Ruby ファイル内)。

require 'dependency-name'

しかし、依存関係が gemspec から含まれている場合は、これ (JS ファイル内) は機能しません。

//= require 'dependency-name'

依存関係が Gemfile から組み込まれている場合は、どちらもrequire必要ありません。かなり明確だと思いますが、さらに詳細が必要な場合はお知らせください。

ベストアンサー1

アセットがアセット パイプラインに取り込まれるようにするには、依存関係を engine.rb に明示的に含める必要がありました。Alastor の回答は正しいように思えたので、なぜこれが必要なのかはわかりません。依存関係は、bundler を使用して作成した gem であることは注目に値しますが、それがなぜ違いを生むのかはわかりません。

module MyRailsPluginFull
  class Engine < ::Rails::Engine
    require 'dependency1'
    require 'dependency2'
  end
end

2012年11月23日追加

Engines での作業にもう少し時間を費やした結果、今ではこれをより完全に理解していると思います。Gemspecs は必要な依存関係のリストにすぎませんが、起動時にアプリケーションにそれらの依存関係からファイルをロードするように指示するものではありません。一方、Gemfiles は起動時にすべてのファイルをロードします。

2015年3月20日追加

2年以上前に私が述べた「Gemfilesは、起動時にすべてのファイルをロードする」という主張は、完全に正しいわけではありません。これは、Bundler.requireジェネレータファイルに示されているように、デフォルトでGemfileにリストされているすべての依存関係を要求するRailsではほぼ当てはまります。ここ-- 前述のように、Railsのデフォルトの動作はRails3からRails4に変更されましたが、ここでは、どちらも を使用します。ただし、 を使用し、実際に に依存するファイルで明示的Bundler.requireに を使用することが強く推奨されます。 を参照してください。Bundler.setuprequire "dependency1"depedency1この議論Bundler.require対のBundler.setup

また、@nruth がコメントで指摘しているように、これにより不要なクラスがロードされる可能性があります。ただし、依存関係が適切に設計されている場合、そのクラスのほとんどは自動ロードされるため、依存関係全体を要求するためのオーバーヘッドは最小限に抑えられます。または、独立して要求できるファイルでエンジンを定義している場合は、エンジン ファイルをインクルードするだけで、必要なファイルがアセット パスに追加され、CSS および JS マニフェストでアセットを要求できるようになります。このbootstrap-sassの例ここで、gem はすべてのアセットを に追加しconfig.assets.paths、その一部を に追加しますconfig.assets.precompile

この質問は数年前のものであり、当時どのような Rails エンジンを書いていたかさえ覚えていませんが、正しい方法は次のようになるのではないかと思います。

module MyRailsPluginFull
  class Engine < ::Rails::Engine
    initializer 'bootstrap-sass.assets.precompile' do |app|
      require 'dependency1'

      # add dependency1's assets to the list of paths
      app.config.assets.paths << ...
    end
  end
end

ただし、これは必須ではないことに注意してください。依存関係自体がこの初期化子を定義して、上記のブートストラップの例のように、単にそれを要求するだけで十分であるはずです。

おすすめ記事