2012-04-10 12 views
28

Desidero precompilare tutti i file CSS e JS nella cartella app/assets del mio progetto. NON voglio precompilare tutto in vendor/assets o lib/assets, ma solo le dipendenze dei miei file secondo necessità.Impostazioni Rails config.assets.precompile per elaborare tutti i file CSS e JS in app/risorse

Ho provato la seguente impostazione di caratteri jolly, ma precompila in modo errato tutto. Ciò si traduce in un sacco di lavoro extra e causa anche un errore di compilazione quando si utilizza bootstrap-sass.

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

Qual è la mia soluzione migliore per elaborare solo i miei file in app/assets? Grazie!

+0

possibile duplicato di [Come utilizzare config.assets.precompile per le directory anziché singoli file?] (Http://stackoverflow.com/questions/12613980/how-do-i-use-config-assets-precompile -per-directories-piuttosto-than-files) – Jason

risposta

18

Questo compito è reso più difficile dal fatto che le ruote dentate funziona con percorsi logici che non lo fanno includere dove si trova il sottostante, non compilato risorse.

Supponiamo che il mio progetto abbia il file JS "/app/assets/javascripts/foo/bar.js.coffee".

Il compilatore per prima cosa determina l'estensione del file di output, in questo caso ".js", quindi valuta se compilare o meno il percorso logico "foo/bar.js". La risorsa non compilata potrebbe essere in "app/assets/javascripts", "vendor/assets/javascripts", "lib/assets/javascripts" o una gemma, quindi non c'è modo di includere/escludere un particolare file basato sul percorso logico solo.

Per determinare dove si trova la risorsa sottostante, credo sia necessario chiedere all'ambiente di trascinamento (disponibile tramite l'oggetto Rails.application.assets) per risolvere il percorso reale della risorsa dato il percorso logico.

Ecco la soluzione che sto utilizzando. Sono abbastanza nuovo a Ruby, quindi questo non è il codice più elegante:

# 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 
} 

Con ruote dentate> 3.0, questo non funzionerà in produzione, perché Rails.application.assets sarà nullo (supponendo di default: config .assets.compile = false).

Per soluzione alternativa si sostituisce la percorso_completo incarico con:

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

Vedi anche: https://github.com/rails/sprockets-rails/issues/237

+0

Qualcuno ha copiato la tua risposta: http://stackoverflow.com/a/15553781/601607 –

+0

se sei interessato alla lista nera delle risorse di Regex, vedi qui: http://stackoverflow.com/a/34801799/770670 –

7

ho trovato questo nel codice rotaie:

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

che è sostenuta con la guida rotaie:

Il matcher predefinita per la compilazione dei file include application.js, application.css e tutti i file non JS/CSS

Questo valore predefinito non viene ripristinato se si utilizza +=, quindi è necessario sostituirlo con th a = invece di +=. Si noti che, a quanto pare, è possibile passare un proc o una regex a precompile e un'estensione. Credo che, se si vuole preompile solo i file nella directory di livello superiore, si dovrà creare una regex come:

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

Michael Apprezzo la tua risposta, che mi ha portato alla risposta corretta. Voglio precompilare ogni file css/js all'interno dell'albero app/assets, non solo nella directory di primo livello. Sfortunatamente il percorso passato al proc è un percorso logico che non distingue tra app/asset, vendor/assets, lib/assets, ecc., Quindi è necessario più scavo. Vedi la mia risposta per la soluzione utilizzata. – keithgaputis

+0

Ora capisco come usare REGEX nella riga 'Rails.application.config.assets.precompile'. Ho appena cercato in rete per un'ora per capire questo. Non documentato altrove. Grazie. –

23

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

che compilerà qualsiasi JavaScript o CSS nel vostro percorso di asset, indipendentemente dalla directory profondità. Trovato via this answer.

+2

No, è non entrerai in una cartella profonda. Devi utilizzare ['your_inner_directory_name/*. Js'] per compilare i file interni –

2

Desidero compilare tutte le risorse da/app e/vendor, eccetto partial (il cui nome inizia con underscore _). Quindi, ecco la mia versione di una voce in 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 
} 

Inoltre emette elenco dei file che vengono compilati a fini di debug ...

+0

Questo è l'unico che ha funzionato per me, dopo aver trascorso un paio di giorni a provare tutte le possibili soluzioni possibili. Funziona anche con le gemme 'datejs-rails' e' bootstrap-sass' (che causerebbero ogni sorta di problema con altre soluzioni). –

13

Un leggero tweak per la risposta di techpeace:

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

Avrei aggiunto un commento alla sua risposta ma non ho ancora abbastanza reputazione. Dammi un preventivo e io sarò lì!

NOTA: questo precompilerà anche tutti i CSS/JavaScript inclusi tramite rubygems.

+1

è solo '=' o '+ ='? –

+1

Siamo spiacenti, non l'ho visto prima. Puoi usare entrambi. Se vuoi aggiungere alle opzioni attuali, userai + =. Se vuoi sostituire le opzioni, usa solo =. – eltiare

+1

non lo si desidera sempre, perché se si utilizza scss vengono solitamente importate le sottocartelle. Solitamente il livello base è di solito sufficiente. – Pencilcheck

0

Questo frammento include tutti i file CSS/JS, esclusi gemme, sotto: app/Attività, vendor/attività, lib/Attività, a meno che non si tratta di file parziali (ad esempio "_file.sass"). Ha anche una strategia per includere risorse da Gemme che non sono incluse in ogni pagina.

# 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 
    } 

Anche se, probabilmente non vuole fare questo in quanto si sarebbe probabilmente essere precompilazione beni gemma due volte (in pratica tutto ciò che è già \ = require'd nei vostri application.js o CSS). Questo frammento comprende tutti i js/file CSS, tra cui gemme, sotto: app/attività, venditore/attività, lib/attività, a meno che non sono file parziali (ad esempio "_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 
} 
3

Otterrà tutto .css.scss e .js inclusi tutti i file nelle sottodirectory.

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) 
+0

questo è stato il più elegante anche se ho usato + = invece di just = –

2

che sto rivisitando questo post al 2017.

Il nostro prodotto è ancora fortemente utilizza RoR, siamo stati continuamente modificare le nostre configurazioni di precompilazione aggiungendo Rails.application.config.assets.precompile come stiamo aggiungendo nuovi moduli. Recentemente stavo cercando di ottimizzare questo con l'aggiunta di un modello di espressione regolare, ho trovato che il seguente modello di glob funziona:

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

Comunque ho ancora bisogno di escludere alcuni moduli, così ho provato difficile da usare regex invece di glob.

Fino a quando ho guardato in pignoni codice sorgente: https://github.com/rails/sprockets-rails/blob/master/lib/sprockets/railtie.rb#L108, ho trovato che stanno già utilizzando espressioni regolari:

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

Così ho cambiare il mio codice in:

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

che funziona bene.

Problemi correlati