web-dev-qa-db-ja.com

Rails app / assetsのすべてのCSSおよびJSファイルを処理するためのconfig.assets.precompile設定

プロジェクトのapp/assetsフォルダー内のすべてのCSSおよびJSファイルをプリコンパイルしたいです。 vendor/assetsまたはlib/assetsのすべてをプリコンパイルするのではなく、必要に応じてファイルの依存関係のみをプリコンパイルします。

次のワイルドカード設定を試しましたが、すべてが誤ってプリコンパイルされます。これにより、多くの余分な作業が必要になり、bootstrap-sassを使用するときにコンパイルエラーが発生します。

config.assets.precompile += ['*.js', '*.css']

app/assetsのファイルのみを処理する場合の最善の方法は何ですか?ありがとう!

30
keithgaputis

このタスクは、スプロケットが、基礎となる未コンパイルのリソースが配置されている場所を含まない論理パスで機能するため、より困難になります。

私のプロジェクトにJSファイル「/app/assets/javascripts/foo/bar.js.coffee」があるとします。

スプロケットコンパイラは、最初に出力ファイル拡張子(この場合は「.js」)を決定し、次に論理パス「foo/bar.js」をコンパイルするかどうかを評価します。未コンパイルのリソースは、「app/assets/javascripts」、「vendor/assets/javascripts」、「lib/assets/javascripts」またはgemにある可能性があるため、論理パスに基づいて特定のファイルを含める/除外する方法はありません。一人で。

基礎となるリソースがどこにあるかを判断するには、スプロケット環境(オブジェクトRails.application.assetsを介して利用可能)に、論理パスが指定されたリソースの実際のパスを解決するように依頼する必要があると思います。

ここに私が使用しているソリューションがあります。 Rubyが初めてなので、これは最もエレガントなコードではありません。

# In production.rb
config.assets.precompile << Proc.new { |path|
  if path =~ /\.(css|js)\z/
    full_path = Rails.application.assets.resolve(path).to_path
    app_assets_path = Rails.root.join('app', 'assets').to_path
    if full_path.starts_with? app_assets_path
      puts "including asset: " + full_path
      true
    else
      puts "excluding asset: " + full_path
      false
    end
  else
    false
  end
}

スプロケット> 3.0では、Rails.application.assetsがnilになるため、本番環境では機能しません(デフォルト:config.assets.compile = falseと仮定)。

回避するには、full_path割り当てを次のように置き換えます。

@assets ||= Rails.application.assets || Sprockets::Railtie.build_environment(Rails.application)
full_path = @assets.resolve(path)

参照: https://github.com/Rails/sprockets-Rails/issues/237

20
keithgaputis

config.assets.precompile = ['*.js', '*.css']

これにより、ディレクトリの深さに関係なく、アセットパス内のJavaScriptまたはCSSがコンパイルされます。 この回答 で見つかりました。

23
techpeace

Techpeaceの答えの微調整:

config.assets.precompile = ['*.js', '*.css', '**/*.js', '**/*.css']

私は彼の答えにコメントを付けたでしょうが、まだ十分な評判はありません。賛成票をください、私はそこにいます!

注:これにより、rubygemsを介して含まれるすべてのCSS/JavaScriptもプリコンパイルされます。

17
eltiare

Railsコードでこれを見つけました:

@assets.precompile               = [ Proc.new{ |path| !File.extname(path).in?(['.js', '.css']) },
                                     /(?:\/|\\|\A)application\.(css|js)$/ ]

Railsガイドでバックアップされています:

ファイルをコンパイルするためのデフォルトのマッチャーには、application.js、application.css、およびすべての非JS/CSSファイルが含まれます

+=を使用する場合、このデフォルトはリセットされないため、=の代わりに+=でオーバーライドする必要があります。明らかに、Procまたは正規表現をprecompileおよび拡張機能に渡すことができることに注意してください。最上位ディレクトリのファイルのみを圧縮する場合は、次のような正規表現を作成する必要があります。

config.assets.precompile = [ /\A[^\/\\]+\.(ccs|js)$/i ]
7
Michael Slade

これにより、すべての.css.scssおよび.jsサブディレクトリ内のすべてのファイルを含みます。

js_prefix    = 'app/assets/javascripts/'
style_prefix = 'app/assets/stylesheets/'

javascripts = Dir["#{js_prefix}**/*.js"].map      { |x| x.gsub(js_prefix,    '') }
css         = Dir["#{style_prefix}**/*.css"].map  { |x| x.gsub(style_prefix, '') }
scss        = Dir["#{style_prefix}**/*.scss"].map { |x| x.gsub(style_prefix, '') }

Rails.application.config.assets.precompile = (javascripts + css + scss)
3
TJ Biddle

私は2017年にこの投稿を再検討しています。

私たちの製品はまだRoRを頻繁に使用しています。新しいモジュールを追加するときにRails.application.config.assets.precompileを追加することで、プリコンパイル構成を継続的に変更しています。最近、正規表現パターンを追加してこれを最適化しようとしていましたが、次のグロブパターンが機能することがわかりました。

Rails.application.config.assets.precompile += %w(**/bundle/*.js)

ただし、特定のモジュールを除外する必要があるため、globの代わりに正規表現を使用するように努めました。

スプロケットのソースコードを確認するまで: https://github.com/Rails/sprockets-Rails/blob/master/lib/sprockets/railtie.rb#L108 正規表現を使用:

app.config.assets.precompile +=
  [LOOSE_APP_ASSETS, /(?:\/|\\|\A)application\.(css|js)$/]

そこで、コードを次のように変更します。

Rails.application.config.assets.precompile +=
  [/^((?!my_excluded_module)\w)*\/bundle\/\w*\.js$/]

それはうまく機能します。

3
Evi Song

パーシャル(名前はアンダースコア_で始まる)を除く、/ appと/ vendorの両方のすべてのアセットをコンパイルしたかった。したがって、application.rbのエントリの私のバージョンは次のとおりです。

config.assets.precompile << Proc.new { |path|
  if path =~ /\.(css|js)\z/
    full_path = Rails.application.assets.resolve(path).to_path
    app_assets_path = Rails.root.join('app', 'assets').to_path
    vendor_assets_path = Rails.root.join('vendor', 'assets').to_path

    if ((full_path.starts_with? app_assets_path) || (full_path.starts_with? vendor_assets_path)) && (!path.starts_with? '_')
      puts "\t" + full_path.slice(Rails.root.to_path.size..-1)
      true
    else
      false
    end
  else
    false
  end
}

さらに、デバッグ目的でコンパイルされているファイルのリストを出力します...

2
Piotr Kuczynski

このスニペットには、すべてのjs/cssファイル、gemを除く、以下のapp/assets、vendor/assetslib/assetsが含まれます。部分ファイル(「_file.sass」など)。また、すべてのページに含まれていないGemsのアセットを含めるための戦略もあります。

    # These assets are from Gems which aren't included in every page.
    # So they must be included here
    # instead of in the application.js and css manifests.
    config.assets.precompile += %w(a-gem.css a-gem.js b-gem.js)

    # This block includes all js/css files, excluding gems,
    # under: app/assets, vendor/assets, lib/assets
    # unless they are partial files (e.g. "_file.sass")
    config.assets.precompile << Proc.new { |path|
      if path =~ /\.(css|js)\z/
        full_path = Rails.application.assets.resolve(path).to_path
        aps = %w( /app/assets /vendor/assets /lib/assets )
        if aps.any? {|ap| full_path.starts_with?("#{Rails.root}#{ap}")} &&
            !path.starts_with?('_')
          puts "\tIncluding: " + full_path.slice(Rails.root.to_path.size..-1)
          true
        else
          puts "\tExcluding: " + full_path
          false
        end
      else
        false
      end
    }

ただし、gemアセットを2回プリコンパイルする可能性が高いため(基本的にはapplication.jsまたはcssで既に\ = require'dされているもの)、おそらくこれはしたくないでしょう。このスニペットには、すべてのjs/cssファイル、gemを含む、以下のapp/assets、vendor/assetslib/assetsが含まれます。部分ファイル(例: "_file.sass")

# This block includes all js/css files, including gems, 
# under: app/assets, vendor/assets, lib/assets
# and excluding partial files (e.g. "_file.sass")
config.assets.precompile << Proc.new { |path|
  if path =~ /\.(css|js)\z/
    full_path = Rails.application.assets.resolve(path).to_path
    asset_paths = %w( app/assets vendor/assets lib/assets)
    if (asset_paths.any? {|ap| full_path.include? ap}) && 
        !path.starts_with?('_')
      puts "\tIncluding: " + full_path
      true
    else
      puts "\tExcluding: " + full_path
      false
    end
  else
    false
  end
}
0
proteantech