20

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

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

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

これは、gemspecから依存関係が含まれている場合に(rubyファイルで)機能します。

require 'dependency-name'

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

//= require 'dependency-name'

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

4

2 に答える 2

27

そのアセットが最終的にアセット パイプラインに到達するようにするには、engine.rb に依存関係を明示的に含める必要がありました。アラスターの答えが私には正しいように聞こえたので、なぜこれが必要なのかわかりません。依存関係がバンドラーを使用して作成した gem であることは注目に値しますが、それが違いを生む理由はわかりません。

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

2012 年 11 月 23 日追加

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

2015/03/20 追記

「一方、Gemfiles は起動時にすべてのファイルをロードする」という 2 年以上前の私の声明は、完全に真実ではありません。これは Rails にほぼ当てはまりますBundler.require。Rails は、Gemfile にリストされているすべての依存関係を必要とするようにデフォルトで実行されます (こちらのジェネレーター ファイルを参照)。Rails のデフォルトの動作は、こちらで説明されているように Rails3 から Rails 4 に変更されましたが、どちらもBundler.require. ただし、実際に依存しているファイルにBundler.setup明示的に使用してから明示的に使用することには、強いケースがあります。対のこの議論を参照してください。require "dependency1"depedency1Bundler.requireBundler.setup

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

この質問は数年前のもので、当時どの Rails Engine を書いていたかさえ覚えていませんが、これを行う正しい方法は次のようなものだったと思います。

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

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

于 2012-09-04T15:08:25.687 に答える
0

http://edgeguides.rubyonrails.org/engines.htmlに従ってエンジンを設計しましたか? エンジン クラスが Rails::Engine を継承している場合、実際にはすべてのアセットを単独で検出する必要があります。

于 2012-09-04T10:05:17.230 に答える