Je souhaite précompiler tous les fichiers CSS et JS du dossier app/assets
de mon projet. Je ne veux PAS pré-compiler tout ce qui se trouve dans vendeur/assets ou lib/assets, uniquement les dépendances de mes fichiers selon les besoins.
J'ai essayé le paramètre générique suivant, mais il précompile incorrectement tout. Cela entraîne beaucoup de travail supplémentaire et provoque même un échec de compilation lors de l'utilisation de bootstrap-sass.
config.assets.precompile += ['*.js', '*.css']
Quel est mon meilleur choix pour traiter mes fichiers uniquement dans app/assets
? Merci!
Cette tâche est rendue plus difficile par le fait que les pignons fonctionnent avec des chemins logiques qui n'incluent pas l'emplacement des ressources sous-jacentes non compilées.
Supposons que mon projet contienne le fichier JS "/app/assets/javascripts/foo/bar.js.coffee".
Le compilateur de sprockets déterminera d’abord l’extension du fichier de sortie, dans ce cas ".js", puis il évaluera si le chemin logique "foo/bar.js" doit être compilé. La ressource non compilée peut se trouver dans "app/assets/javascripts", "vendor/assets/javascripts", "lib/assets/javascripts" ou une gem, il n'y a donc aucun moyen d'inclure/exclure un fichier particulier basé sur le chemin logique seul.
Pour déterminer où se trouve la ressource sous-jacente, je pense qu’il est nécessaire de demander à l’environnement sprockets (disponible via l’objet Rails.application.assets) de résoudre le chemin réel de la ressource en fonction du chemin logique.
Voici la solution que j'utilise. Je suis assez nouveau pour Ruby, ce n'est donc pas le code le plus élégant:
# 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
}
Avec des pignons> 3.0, cela ne fonctionnera pas en production car Rails.application.assets sera nul (en supposant que par défaut: config.assets.compile = false).
Pour contourner le problème, vous remplacez l'affectation chemin_complet par:
@assets ||= Rails.application.assets || Sprockets::Railtie.build_environment(Rails.application)
full_path = @assets.resolve(path)
Voir aussi: https://github.com/Rails/sprockets-Rails/issues/237
config.assets.precompile = ['*.js', '*.css']
Cela compilera tout code JavaScript ou CSS dans votre chemin d’actif, quelle que soit la profondeur du répertoire. Trouvé via cette réponse .
Un léger tweak à la réponse de techpeace:
config.assets.precompile = ['*.js', '*.css', '**/*.js', '**/*.css']
J'aurais ajouté un commentaire à sa réponse mais je n'ai pas encore assez de réputation. Donnez-moi un vote positif et je serai là!
NOTE: ceci précalculera également tous les CSS/JavaScript inclus via rubygems.
J'ai trouvé ceci dans le code Rails:
@assets.precompile = [ Proc.new{ |path| !File.extname(path).in?(['.js', '.css']) },
/(?:\/|\\|\A)application\.(css|js)$/ ]
Qui est sauvegardé avec le guide Rails:
Le matcher par défaut pour la compilation de fichiers comprend application.js, application.css et tous les fichiers autres que JS/CSS
Cette valeur par défaut n'est pas réinitialisée si vous utilisez +=
. Vous devez donc la remplacer par un =
au lieu de +=
. Notez que, apparemment, vous pouvez passer un proc ou une expression rationnelle à precompile
ainsi qu’une extension. Je pense que si vous voulez pré-compiler uniquement les fichiers du répertoire de niveau supérieur, vous devrez créer une regex du type:
config.assets.precompile = [ /\A[^\/\\]+\.(ccs|js)$/i ]
Tous les .css
.scss
et .js
seront inclus, y compris tous les fichiers des sous-répertoires.
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)
Je revisite ce post à l'année 2017.
Notre produit utilise toujours beaucoup RoR, nous avons constamment modifié nos configurations de précompilation en ajoutant Rails.application.config.assets.precompile
à mesure que nous ajoutons de nouveaux modules. Récemment, j'essayais d'optimiser cela en ajoutant un motif regex. J'ai constaté que le motif glob suivant fonctionnait:
Rails.application.config.assets.precompile += %w(**/bundle/*.js)
Cependant, il me faut toujours exclure certains modules, j'ai donc essayé d'utiliser regex au lieu de glob.
Jusqu'à ce que j'examine le code source de Sprockets: https://github.com/Rails/sprockets-Rails/blob/master/lib/sprockets/railtie.rb#L108 , j'ai constaté qu'ils utilisent déjà regex
app.config.assets.precompile +=
[LOOSE_APP_ASSETS, /(?:\/|\\|\A)application\.(css|js)$/]
Alors je change mon code en:
Rails.application.config.assets.precompile +=
[/^((?!my_excluded_module)\w)*\/bundle\/\w*\.js$/]
Ce qui fonctionne bien
Je voulais que tous les actifs de/app et/vendor soient compilés, sauf les partiels (dont le nom commence par le caractère de soulignement _). Alors voici ma version d'une entrée dans 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
}
De plus, il affiche la liste des fichiers en cours de compilation à des fins de débogage ...
Ce fragment de code inclut tous les fichiers js/css, à l’exclusion de gems , sous: app/assets, vendor/assets , lib/assets , sauf s’il s’agit de fichiers partiels (par exemple, "_file.sass" ). Il a également une stratégie pour inclure les actifs de Gems qui ne sont pas inclus dans chaque page.
# 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
}
Cependant, vous ne voudriez probablement pas faire cela car vous pré-compileriez probablement deux fois plus d’actifs gem (en gros tout ce qui est déjà requis dans votre application.js ou css). Cet extrait inclut tous les fichiers js/css, y compris les gems , sous: app/assets, vendor/assets , lib/assets , sauf s’il s’agit de fichiers partiels (par exemple, "_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
}