allt du bör veta om Rails Asset Pipeline

Vad är asset pipeline?

om du bygger en Rails-applikation har du förmodligen hört talas om tillgångsrörledningen. Tillgångsrörledningen kan betraktas som de verktyg och mekanismer genom vilka Javascript-filer, formatmallar och bilder bearbetas och förbereds för användning av webbläsaren. Dessa processer kan minifiera och komprimera tillgångar, samt förbehandla tillgångar som är skrivna på andra språk som Coffeescript eller Sass.

tillgångsrörledningen skapades för att lösa en rad problem relaterade till statiska tillgångar. En sådan fråga är att varje tillgång som anges separat i HTML-markeringen måste hämtas separat, vilket resulterar i ett högre antal HTTP-förfrågningar och i slutändan en längre laddningstid. Raw Javascript-och CSS-filer kan också slösa mycket bandbredd med kommentarer, extra vitt utrymme och långa variabelnamn. En annan fråga som kommer upp handlar om caching. När du till exempel serverar en Javascript-fil från din server cachar webbläsaren automatiskt den filen under en tidsperiod. Det förbättrar sidladdningstiden, men vad händer om den tillgången ändras vid en senare tidpunkt? Webbläsaren vet inte om den, så den fortsätter att använda den cachade tillgången tills dess cache-livslängd har löpt ut. Slutligen har språk som Coffeescript, Sass, Less och Erb gjort det lättare att organisera och skriva Javascript och CSS, men webbläsaren kan inte tolka dem direkt, så en förprocessor behövs för att konvertera dessa filer till sina lämpliga motsvarigheter innan de skickas till webbläsaren.

tillgångsrörledningen kan i sin välvilja lösa alla ovanstående problem när de används korrekt. Det kan kompilera flera tillgångar till en, minifiera och komprimera tillgångar, ge uppslutning av tillgångar för att undvika cachningsproblem och kan förbehandla alternativa språk och göra dem till Javascript och CSS.

det här inlägget täcker en rad olika ämnen relaterade till tillgångsrörledningen:

  • grunderna för hur du använder tillgångsrörledningen
  • bästa praxis för att strukturera var du ska placera dina tillgångar
  • så här använder du förkompileringsmatrisen för att ange vilka filer som behandlas av tillgångsrörledningen
  • hur Sass och Coffeescript kan utnyttjas
  • hur man använder Rails asset helper-metoder och
  • vissa gotchas

grundläggande användning

det finns två grundläggande sätt att tillgångsrörledningen används:

  1. när du kör en server i utvecklingsläge förbehandlar den automatiskt och förbereder dina tillgångar direkt.
  2. i produktionsläge kommer du förmodligen att använda den för att förbehandla, versionera och komprimera och kompilera dina tillgångar. Du kan göra det genom att köra följande kommando:

1
bundle exec rake assets:precompile

detta skapar (som standard) EN assets katalog i mappen public/. Den lägger sedan till alla komprimerade och kompilerade filer i den katalogen, i lämpliga format och med de nya smälta versionerna. Du kan sedan ställa in Nginx eller Apache till server dessa filer direkt så att Rails inte behöver leverera dem (och köra on-the-fly förbehandling, etc.) själv.

kom ihåg att standardinställningar kan ändras, så om saker inte fungerar som förväntat, kontrollera din programinställningsfil i config/application.rb. I Rails 4 är tillgångshantering vanligtvis konfigurerad i config/initializers/assets.rb.

filstruktur

det är viktigt att organisera dina tillgångar på ett sätt som är förståeligt för dig och underlättar den befintliga funktionaliteten i tillgångsrörledningen. Det första du bör veta är att alla dina anpassade Javascript, stilmallar och bilder ska gå i katalogen app/assets/. Som standard finns det en mapp vardera för javascripts, stylesheetsoch images. Du kan också lägga till fonts, audios och videos i katalogen app/assets/ för dessa typer av tillgångar. All kod från tredje part som du använder (t.ex. jQuery, backbone.js, etc.) ska placeras i katalogen vendor/assets/ :

1234567891011
rails-app/ app/ assets/ images/ # Image assets javascripts/ # Custom Javascript/coffeescript stylesheets/ # Custom CSS/Sass ... vendor/ assets/ javascripts/ # Javascript libraries, etc. stylesheets/ # Vendor themes, javascript library themes, etc.

eftersom din webbserver automatiskt serverar statiska filer från katalogen public/, varför ska inte alla Javascript -, bild-och formatmallar placeras där? För det första kommer ingenting i mappen public att förbehandlas, kompileras eller komprimeras automatiskt, så genom att sätta tillgångar där, kringgår du helt tillgångsrörledningen och förlorar alla dess fördelar. När du lägger tillgångar där, förlorar du också möjligheten att enkelt referera till dem i din Rails-kod. Du kan till exempel ha en vy som har följande kod:

12345678910
# app/assets/images/logo.png= image_tag('logo')# Outputs something like <img src="/assets/logo-.png" /># public/images/logo.png= image_tag('/images/logo.png')# Outputs something like# <img src="/images/logo.png" />

i det andra scenariot (public/images/logo.png) fungerar webbplatsen bara om den levereras från baskatalogen. Det kan inte heller dra nytta av tillgångsrörledningens versionshantering av filen.

Förkompilering

du kanske nu undrar om allt du lägger i mappen app/assets/javascripts/ automatiskt förkompileras för din app. Lyckligtvis ger tillgångsrörledningen ett sätt att ange vilka filer som sammanställs och i vilken ordning. Som standard, ansökan.css och applikation.js (eller deras Sass/coffeescript-ekvivalenter), tillsammans med alla icke-Javascript, ingår icke-CSS-tillgångar. Att inkludera en annan CSS-eller Javascript-fil än applikation.css och applikation.js, du måste kräva det på ett av två sätt:

  1. Lägg till den i förkompileringsmatrisen i config/initializers/assets.rb (Rails 4) eller din programinställningsfil (t.ex. config/application.rb) eller
  2. inkludera filen i tillgångens manifest eller en av dess underfils manifest.

det första alternativet ser ut så här:

12
# In config/initializers/assets.rbRails.application.config.assets.precompile += %w( some-other-file.js even-another.css )

det här alternativet är bäst för filer som det är vettigt att bara inkludera på vissa sidor och bör inte inkluderas på andra. Om du till exempel har en del av din webbplats som kommer att användas som en inbäddad Iframe-widget kanske du bara vill att widget.js och widget.css eller liknande ska användas på den sidan. Dessa filer måste läggas till i förkompilmatrisen som visas ovan.

det andra alternativet är vad som ska användas för det mesta och gör att dina Javascript-och CSS-filer kan kompileras till ett program.js och en ansökan.css-fil. Manifestet är skrivet högst upp i den tillämpliga tillgången.

i coffeescript ser det ut så här:

12345
# In application.coffee##= require jquery#= require jquery_ujs#= require_tree .

ovanstående manifest kommer att innehålla jQuery, Rails jQuery diskreta skriptadapter (jquery_ujs) och alla filer i det aktuella trädet (dvs app/assets/javascript/*). Observera att require_tree inte kompilerar resurser rekursivt genom kataloger. Om du har en mapp med filer som du vill inkludera måste du också lägga till det i manifestet:

1
#= require_tree ./components

ett annat manifest-direktiv är require_self, som används för att inkludera den aktuella filens Javascript vid den punkten i kedjan. Ovanstående, med en require_self kan skrivas i en .js fil enligt följande:

1234567
// In application.js////= require jquery//= require jquery_ujs//= require_tree .//= require_tree ./components//= require_self

Sass / CSS-manifesten använder samma grundformat, men med lämplig kommentarstil:

123456
/** In application.css * *= require reset *= require global *= require layout */

Observera att när du använder Sass måste du använda dess @import – regel för att dra nytta av variabler och mixins, eftersom varje fil som sammanställts av manifestet har sitt eget omfång.

var försiktig med din användning av require_tree – direktivet. Tillgångar i trädet kommer att inkluderas i alfabetisk ordning, vilket innebär att om en fil som börjar med ”a” beror på en fil som börjar med ”z”, kan du stöta på problem där nödvändiga bitar inte är tillgängliga när Javascript utvärderas av webbläsaren. Det här problemet kan undvikas genom att använda lämpliga jQuery(document).ready() eller window.onload vakter, genom att ange en order manuellt eller prefixa filerna med siffror som 01_, 02_ :

12345
# application.js# Note that the `.js` isn't needed at the end of the filename.##= require subfolder/library#= require subfolder/depends-on-library

kom ihåg att alla förkompilerade Javascript-eller CSS-filer kan innehålla ett manifest högst upp, så att du kan använda undermapparnas filer för att förenkla ditt manifest på toppnivå.

Sass och Coffescript, och Rails Asset Helpers

jag har nämnt Sass och Coffeescript lite i ovanstående avsnitt, men jag har ännu inte gått in i vad de är. Om du redan är bekant med dem, hoppa gärna ner till avsnittet ”Rails Asset Helpers”.

Sass och Coffeescript

Sass och Coffeescript är språk som använder förprocessorer för att omvandla sin syntax till CSS respektive Javascript. Det finns flera andra förbehandlade språk som Typescript och Less, men Sass och Coffeescript ingår som standard med skenor och är förmodligen de mest populära. Jag kommer inte att gå in på omfattande detaljer här på dessa språk, så kolla in länkarna ovan för mer information.

från min erfarenhet, medan Sass och Coffeescript ger mycket syntaktiskt socker (vackra kodfunktioner), är det faktum att undantag kastas för ogiltig kod i förbehandlingsstadiet tillräckligt för att motivera att använda dem. Coffeescript sveper automatiskt din kod per fil och lägger till var nyckelordet till dina lokala variabler, vilket förhindrar en hel del omfattning huvudvärk som kan hända lättare i vanilj Javascript.

till exempel följande Coffeescript-kod:

12345
$ -> $('#element').on 'click', -> state = 'clicked' window.state = 'clicked' console.log 'element clicked'

konverteras till följande Javascript:

1234567891011
(function() { $(function() { return $('#element').on('click', function() { var state; state = 'clicked'; window.state = 'clicked'; return console.log('element clicked'); }); });}).call(this);

när förprocessorn behandlar filen, sveper den automatiskt koden i en anonym funktion ((function() {}).call(this)) och lägger till var nyckelordet till den första användningen av state. Observera att om du vill använda det globala omfånget måste du ange det genom att prefixa window..

det finns mycket mer att Coffeescript, men den automatiska scoping har varit till stor hjälp för mig personligen för att förhindra svåra att hitta buggar.

Rails Asset Helpers

en annan bra funktion som du bara kan få genom att använda Sass i ditt Rails-projekt är asset path helpers. När du refererar till andra tillgångar i din Sass kan du använda följande syntax för att få lämpliga sökvägar:

123
.logo { background-image: image-url("logo.png");}

hjälparna image-path, asset-url och asset-path kan också användas. De -urlhjälpare Linda sökvägen med url().

Erb i tillgångar

tillgångsrörledningen låter dig utvärdera ERB-kod i dina CSS-och Javascript-tillgångar genom att suffixa filnamnet med .erb (t.ex. application.js.erb eller application.scss.erb). Även om detta kan vara användbart för att lägga till tillgångsvägar till Javascript, rekommenderar jag inte att du använder den här funktionen. Det lägger till ytterligare ett förbehandlingssteg i filen, vilket ökar tiden det tar att förkompilera. Det kan också leda till dåliga vanor. Du kan bli frestad att lägga till kod som inte är meningsfull vid kompileringstiden, som att översätta strängar. Dessa strängar skulle bara översättas vid kompileringstiden och därmed förneka hela syftet med att översätta dem. Den enda anledningen till att använda Erb i en Javascript-fil bör vara att använda asset_path – hjälpen som diskuteras i guiden.

Tillgångsrörledning Gotchas

följande är några gotchas och godbitar som kan vara till hjälp för att utveckla din Rails applikations tillgångar.

  • Hur lägger jag till globala data för mitt Javascript att använda?
    • gon gem kan användas för att infoga globalt scoped data till sidan för Javascript att konsumera. Det här är bra för saker som att tillhandahålla den aktuella användarens ID eller Webbplatsinställningar.
  • Var ska jag utöka förkompileringsmatrisen?
    • i Rails 4 bör du öka arrayen i config/initializers/assets.rb, och i Rails 3 bör du göra det i config/application.rb. Använda tillgångar.rb eller ansökan.rb ställer in förkompilmatrisen för alla miljöer så att om du lägger till en miljö (kanske staging) behöver du inte utöka förkompilmatrisen specifikt för den nya miljön.
      • tillgångar.rb: Rails.application.config.assets.precompile += %w( widget.css widget.js )
      • ansökan.rb: config.assets.precompile += %w( widget.js widget.css )
  • När ska jag förkompilera tillgångar separat genom att utöka förkompilmatrisen?
    • detta bör sällan göras. För det mesta är den enda anledningen till att du vill göra detta om tillgången ingår ensam på en speciell sida där du inte vill ha resten av tillgångarna, till exempel en Iframe-inbäddad widget. Använd din ansökan.js och ansökan.css-manifest för att dra in dina tillgångar.
  • ska jag tillåta Rails att tjäna statiska filer?
    • Ja. Detta följer riktlinjerna för Tolvfaktorsappen och förhindrar fel om du glömde att inkludera en fil i förkompilmatrisen eller om du glömde att förkompilera.
    • Ställ in config.serve_static_assets = true i räls 3 och config.serve_static_files = true i räls 4.
  • Hur kan jag se till att mitt Javascript / CSS är välskrivet?
    • att skriva Javascript och CSS av hög kvalitet (eller Coffeescript och Sass) kan ta mycket tid och erfarenhet, men en sak som har hjälpt mig mycket är att använda en linter). Vissa ide, som Sublime Text, har plugins som integrerar linters. Jag använder personligen SublimeLinter-paketet. Om du ska skriva vanligt gammalt Javascript och CSS bör du definitivt använda en linter.
  • Hur ändrar jag katalogen där mina förkompilerade tillgångar placeras?
    • du kan ändra inställningen config.asset.prefix till en annan katalog, till exempel /static.
    • ändra tillgångsprefixet i development.rb om du vill spåra förkompilerade tillgångar i git för produktionsanvändning.
    • ändra tillgångsprefixet globalt om du vill använda sökvägsnamnrymden /assets för dina kontroller.
  • hur serverar jag statiska tillgångar med Nginx?
    • det grundläggande nginx-direktivet ska se ut så här (se avsnittet Förkompilering av tillgångar i Skenguiden för mer information):
1234567
location ~ ^/assets/ { expires 1y; add_header Cache-Control public; add_header ETag ""; break;}
  • vad är uppenbart.yml eller manifest -.json?
    • manifestet.yml (skenor 3) eller manifest-.JSON (Rails 4) filer skapas automatiskt när du förkompilera dina tillgångar med rake assets:precompile. De innehåller information om vilka filer som ska användas av din app.
  • vilka typer av filer ska inte ingå i tillgångsrörledningen?
    • du vill vanligtvis behålla stora filer (Videor, ett stort antal PDF-nedladdningar etc.) i ett separat arkiv eller i en molnfilhanterare, till exempel AWS S3. Filerna kan sedan refereras från din app, men behöver inte mossa ner ditt git-arkiv.
  • Hur kan jag få mina Rails 3-tillgångar att kompilera snabbare?
    • använd turbo-sprockets-rails3 pärla.
  • kan jag använda ett CDN (content delivery network) för mina tillgångar?
    • Ja! Digest, eller fingeravtryck, suffixed på varje tillgång gör att de fungerar bra med CDN. Ställ in din CDN för att betjäna tillgångar från din Rails-app och ställ sedan in config.action_controller.asset_host – konfigurationen till lämplig domän för din CDN (t.ex. config.action_controller.asset_host = 'mycdn.fictional-cdn.com'). Jag rekommenderar att du använder miljövariabler för att ställa in detta: config.action_controller.asset_host = ENV.

om du packar in den

om du använder tillgångsrörledningen korrekt kan du förbättra den övergripande kvaliteten på din applikation när det gäller prestanda, motståndskraft och kodrenlighet. Genom att använda tillgångsrörledningens funktioner kan du automatiskt övervinna några av de största problemen med kodning och leverans av statiska tillgångar.

You might also like

Lämna ett svar

Din e-postadress kommer inte publiceras.