加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

一次搞懂 Assets Pipeline

发布时间:2020-12-13 22:44:37 所属栏目:百科 来源:网络整理
导读:Assets Pipeline 是 Rails 3.1 一?重要的功能,一直??有很去了解其特性,但因?最近都在?前端的?西在 assets pipeline 的?西上跌跌撞撞了不少次(尤其在 deploy 上 production 後常爆炸,爆到我??自容),?篇就是好好研究後的心得以及??。 Assets Pipeline 有什

Assets Pipeline 是 Rails 3.1 一?重要的功能,一直??有很去了解其特性,但因?最近都在?前端的?西在 assets pipeline 的?西上跌跌撞撞了不少次(尤其在 deploy 上 production 後常爆炸,爆到我??自容),?篇就是好好研究後的心得以及??。


Assets Pipeline 有什?好?,不用?怎??


不用?然不?怎?,你可以在 confing/application.rb 中把他?掉:


1

config.assets.enabled = false

但是 Assets Pipeline 有著?多?良的好?,?助你?理的?去一些需要由第三方元件??理的事情,像是:


?所有的 js 或是 css ??打包成?一?案,?少 http request 的大小??量,增加你?站的效能及速度。

支援像是 SCSS 及 CoffeeScript ??的 high-lever ?言,你可以用更??更棒的方式?? css 及 js。

取代原先不可靠的 query string 改用 MD5 的 fingerprint,query string 的用意在於??案?容更?的?候也?一?更??案的 query string,??可以分辨?案是否有更??,因此客?端可以保留快取?比?自己?有的版本以及伺服器上的版本是否一致,?少每次的 request,?奈 query string 的作法?是有些??,像是在部分 CDN 上根本不?快取、在多伺服器的?境中?案名?可能???、以及?多?效的 cache ??,因此在 Rails 3.1 改使用 MD5 的 Fingerprinting ?解?了????。

Assets Pipeline 的功能主要由??重要的元件提供:Sprockets 以及 Tilt。Sprockets 用??你的 assets 路?中打包??你所有的 assets 後包?成一??案,然後放到你目的地路?(public/assets),而 Tilt 主要是一??板引擎,用?? Sprockets 可以去解析像是 SCSS、CoffeeScript 或是 ERB 等各??板,你可以?考 Tilt 的 Readme ?了解支援哪些?板。


Assets 的??


首先必?了解 Assets 的??,在 Rails 的目???中有三?地方:


app/assets(通常放置我?自己?了自己的程式所?的 js、css 或是 images)

lib/assets(通常是我?所使用的套件中去用到的 assets)

vendor/assets(通常是放一些我???的地方借用的 assets,例如?一些 jQuery 的套件)

?三?目?,在??情?下?三??料?的?西是共通的(因?都?被打包成一??案),你可以把你的 rails app 跑起?後在 http://localhost:3000/assets/application.js 中看到你所有的 js 都在?支?案中,css 同理亦然,你可以在 terminal 中?入 Rails.application.config.assets.paths ?查看所有的 assets 路?。你可以??,除了原本我????的三? assets 目?之外,?出?了包含在我? GemFile 中的 jquery,?代表你的 assets ?在也可以包成 gem ?用,如果你有很多? projects 常重?使用一些共通的 assets,不妨考?包成 gem ?使用,方便又愉快。


Assets 的?入


再?是 assets 目?下的?案 import 方式,以 app/asset/javascripts/application.js ?支?案?例,?是一支 manifest ?案,主要用?告? Sprockets ?哪些?案是要被?入最後要被包起???的,最後?支?案?面所有的?西就?被包成 application.js ?支?案,也是我? layout/application.html.erb 中的 javascript_include_tag 'application' 中的?案,打??支?案除了上面的?明外只有?三行:


//= require jquery

//= require jquery_ujs

//= require_tree .

上面?行很明?的就是要?入 jquery 以及 jquery_ujs ??支?案,??支?案??有提到他其?是被包含在我?所使用的 Gem 中,而下面那行 require_tree . 表示是把三? assets/javascript 目?下的?案或是子目??的?案全部都包??,??候你一定?想?如果有些 js 或是 css 我只想在某些特定?面中使用的??怎??,例如?假?我?今天有? admin_functions.js 的?案只想在我?的後台使用,有??方法可以使用:


你可以? require_tree 的目?改成其他目?,例如在 app/assets/javascript 目?下建? common ?料?,把 require_tree . 改成 require_tree ./common,??子所?生的 application.js ?支?案就不?用到 admin_functions.js ?支?案。

你可以建立一?新的?料??放你不想要被 application.js ?入的?案,例如我?在 app/assets/javascript 下建立一? admin ?料?把??的 admin_functions.js ?案放?去,然後把原先 application.js 中的 require_tree . 改? require_directory . ??子只?抓? apllication.js ?案同目?底下的所有?案而不?去?入子目?中的?案。

最後再建立另外一支 manifest 用? import 那些我?要?立出?的 assets,例如我?建立一支 admin.js 的?案用??入其他功能,一?使用 require_tree 或是 require_directory 的方式??入,然後在你需要用到的?面中使用 javascript_include_tag 'admin' ?存取。


千千??要?得,?你使用 application.js 以外的 manifest ?案?,一定要在你?境?定?中??支?案加入 precompile 的清?,否?上了 staging 或是 production ?你就?收到一堆 500 Error XXXX isn’t precompiled,加入的位置在?境?定?像是 production.rb 中的 config.assets.precompile += %w( search.js ) 中。


除了 require_tree 及 require_directory 之外,?有其他的用法,你都可以使用??或是相?路??指定?案位置,副?名可有可?:


require [路?] ?入某支特定?案,如果?支?案被?入多次,Sprockets 也?很?明的只?你?入一次。

include [路?] ? require 一?,差?在即使是被?入?的?案也?再被?入。

require_directory [路?] ?路?下不包含子目?的?案按照字母?序依次?入。

require_tree [路?] ??路?下包含子目?的?案全部?入。

require_self [路?] 告? Sprockets 再?入其他的?案前,先?自己的?容插入。

depend_on [路?] 宣告依?於某支 js,在需要通知某支快取的 assets ?期?非常?用。

stub [路?] ?路?中的 assets 加入黑名?,所有其他的 require 都不??他?入。

你可以看 Sprockets 的 Readme ??得更多的??。


Preprocessing


另外就是 Sprockets 在 Tilt 的?助下有 preprocessing 的功能,例如你可以使用像是 something.js.coffee.erb ??的?名,Sprockets ???名的最後面一直解析回去成最後的?案,因此你可以在 js 中使用 CoffeeScript 的?法?? js,?在?面? ruby code ??生你想要的?西,例如:


jQuery ->

number = <%= 1 + 1 %>

不用我?我想你也知道?有什??果。


Helper


Assets 提供了很多路? helper ??你指向你的 assets:


audio_path("horse.wav") # => /audios/horse.wav

audio_tag("sound") # => <audio src="/audios/sound" />

font_path("font.ttf") # => /fonts/font.ttf

image_path("edit.png") # => "/images/edit.png"

image_tag("icon.png") # => <img src="/images/icon.png" alt="Icon" />

video_path("hd.avi") # => /videos/hd.avi

video_tag("trailer.ogg") # => <video src="/videos/trailer.ogg" />

Sass ?提供了像是 -url 和 -path ??的 helper ??助你,因此你也可以??使用:



image-url("rails.png") # => url(/assets/rails.png)

image-path("rails.png") # => "/assets/rails.png".

asset-url("rails.png",image) # => url(/assets/rails.png)

asset-path("rails.png",image) # => "/assets/rails.png"

Production


在?不熟悉的情?下,很容易上了 production ?境後??原本在本?好好的?西全部炸掉了,因此我?必?了解一下在 production ?作?的情形,如果你直接在 console 中打 rails s -e production ??? production ?境?,你????上就??? application.css isn't precompiled,?是因?在 production 的?境下我?的 assets 是必?被 compile ?後存在 public/assets 底下的,你可以在 console 中打 rake assets:precompile,Rails ??你把所有的 assets ?案依照你 manifests 以及?境?定打包??成?一的?案後放在 public/assets 目?底下,所有的?案名???加入 MD5 的 fingerprinting 用?表示其?容供快取,?些 assets ?被 Rack Cache middleware 自?的被快取,如果你想要使用自己的 server ?取代 middleware 的功能你也可以自己 precompile 後上?。


在你 precompile 後你再打? localhost:3000 ?????已??有??,但是?站看起?就是?有 css 的感?,??候查看 log 你?看到 Rails 找不到 assets ?案的??,?是因?在 production ?境中是不?理???案的,因此你必?先在 production.rb 中? config.serve_static_assets = false 改成 true,??候重?一次就?看到一切正常,我?已??利在本?上跑起 production ?境了,你就可以在本?上??你的 assets pipeline 是否正常,如果你去?? precompile 後的?案你???它?都加上了我?之前提到的 MD5 digest,用?辨?其?案?容是否有所更?,因此你可以?你的 Server ?定中的 expires ???到最?,因?在?案?有更?的情?下他都?保持相同的?名,?使用者可以?到最快的效能。


Deploy 的小技巧


在本? precompile ??省在 server 上 precompile 的???使用量


一般我?都?使用 Capistrano ? Deploy,?得要? Capfile 中的 load 'deploy/assets' 的?解取消,Deploy 的?程中?使用 production server ? compile 你的 assets,如果你很在意 production server 的效能,你可以在本?先 compile 後再上?到 Server,我?只需要覆?原本 Capistrano 所提供的 assets:precompile 功能,在你的 deploy.rb 中加入下面的 Code:


namespace:deploydo
namespace:assetsdo
desc"Precompileassetsonlocalmachineanduploadthemtotheserver."
task:precompile,:roles=>web,:except=>{:no_release=>true}do
run_locally"bundleexecrakeassets:precompile"
find_servers_for_task(current_task).eachdo|server|
run_locally"rsync-vr--exclude='.DS_Store'public/assets#{user}@#{server.host}:#{shared_path}/"
end
end
end
end

???在本? precompile 後使用 rsync ??案上?上去,如果你有使用 Git 的??忘了把 public/assets 加到 .gitignore 中。


如果 assets ?有更新?,就不要跑 precompile


precompile ??是整? deploy ?程中最漫?的一段??,即使你?有更新 assets ?也免不了?你跑一下,你可以一?覆? assets:precompile ?判?是否有更新 assets,如果?有才?行 precompile:



namespace :deploy do

namespace :assets do

task :precompile,:roles => :web,:except => { :no_release => true } do

from = source.next_revision(current_revision)

if capture("cd #{latest_release} && #{source.local.log(from)} vendor/assets/ app/assets/ | wc -l").to_i > 0

run %Q{cd #{latest_release} && #{rake} RAILS_ENV=#{rails_env} #{asset_env} assets:precompile}

else

logger.info "Skipping asset pre-compilation because there were no asset changes"

end

end

end

end

?然你可以?上面?段 Code 合而?一,有更新 assets 的情?就在本? precompile 後才上?到伺服器:


namespace :deploy do

namespace :assets do

task :precompile,:except => { :no_release => true } do

from = source.next_revision(current_revision)

if capture("cd #{latest_release} && #{source.local.log(from)} vendor/assets/ app/assets/ | wc -l").to_i > 0

run_locally "bundle exec rake assets:precompile"

find_servers_for_task(current_task).each do |server|

run_locally "rsync -vr --exclude='.DS_Store' public/assets #{user}@#{server.host}:#{shared_path}/"

end

else

logger.info "Skipping asset pre-compilation because there were no asset changes"

end

end

end

end

?考?料:


RailsGuides Asset Pipeline

Asset Pipeline for Dummies

#279 Understanding the Asset Pipeline

#341 Asset Pipeline in Production

Speed up assets:precompile with Rails 3.1/3.2 Capistrano deployment


转自:http://gogojimmy.net/2012/07/03/understand-assets-pipline/

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读