阅读更多
Assets Pipeline 有什么好处,不用会怎样
怎样禁止Assets Pipeline:
不用当然可以,你可以在config/application.rb中将它干掉:
config.assets.enabled = false
Assets Pipeline 好处:
1、将所有的js或css压缩打包成单一的文件,减少http request的大小与数量,增加你网站的速度
2、支持香scss及coffeescript这样的语言,让你可以用更简单更棒的方式来写css及javascript
Assets Pipeline 组成元件
主要有两个元件组成:Sprockets以及Tilt. Sprockets用来从你的assets路径中打包你所有的assets后,包装成一个文件,然后放到你的目的路径(public/assets),而Tilt主要是一个模板引擎,用来让Sprockets可以去解析Scss,coffeescript或是erb等各种各样的模板。
Assets结构:
在rails目录结构中,有三个地方:
app/assets(通常放置我们自己为了自己的程序所写的js,css,或者是images)
lib/assets(通常是放置我们使用的插件中用到的assets)
vender/assets(通常是放置一些我们从别的地方借用的assets,比如说一些jquery插件)
在默认情况下,这三个文件夹内是共通的(因为都会被打包成一个文件),你可以把你的rails app跑起来,然后在localhost:3000/assets/applications.js中看到你所有的js都在这个文件中,同理,css也一样,你可一在console里面输入Rails.application.config.assets.paths来查看所有的assets路径,你可以发现,除了我们刚刚说的三个目录,还有Gemfile中初夏的jquery,这就是说,将来我们的assets也可以打包成gem来用,如果你有多个projects常重复使用一些共同的assets,不妨我们可以考虑将我们的assets打包成gem,方便以后使用。
Assets目录内文件的导入方式:
以app/assets/javascripts/application.js为例,这是一个manifest文件,主要用来告诉Spockets说,哪些文件是要被载入后打包起来压缩的,最后这些文档里面的所有内容都会被打包成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文件或者子目录内的所有文件都包进来。这时候你一定会问,如果有些js或是css我只想在某西特定页面中使用的话该怎么办,例如:假如说我们今天有个admin_function.js的文件,我只想在我的后台使用,其他页面不使用,那么你有两种方法可以实现:
1、你可以将require_tree的目录改成其他的目录,例如在app/assets/javascript目录下创建一个叫做common的文件夹,然后把require_tree . 改成require_tree ./common,这样的话,所产生的application.js就不会用到admin_function.js这个文件了。
2、你可以建立一个新的文件见,用来盛放那些你不想被application.js载入的文件,例如我们在app/assets/javascript下建立了一个admin的文件夹,并吧刚刚的admin_function.js文件放进去,然后把applicaiton.js文件中的require_tree . 改为require_directory . 这样子,程序只会载入与application.js文件统一级目录中的所有文件,而不会去加载子目录中的文件。
如果你想在某个页面加载admin下的所有的js,那么你需要在这个admin目录下新建一个manifest,用来引入该目录下的文件,比如我们在admin目录下建立了一个叫做admin.js的文件,然后在里面我们可以一样使用require_tree 或者require_directory的方式来载入,然后你需要在你的这个特定的页面中使用javascript_include_tag 'admin/admin'这样来进行引用。
千万要记住,当你使用application.js之外的manifest文件时,一定要在你的环境设置文件中加入precompile的清单,否则伤了production时,你会收到一堆500error xxxx isn't precompiled ,加入的位置在production.rb中加入:config.assets.precompile += %w( 'admin/admin.js' )
除了require_tree 及 require_directory 之外,还有其他的方法,你都可以使用绝对或者相对路径来制定文件的位置,文件的后缀名可有可无:
require[路径]载入某特定的文件,如果该文件被多次载入的话,Sprockets会很聪明的帮你载入一次。
include[路径] 与require一样,差别在于,每次都会重新加载一次文件。
require_directory [路径] 将路径下,不包含子目录的文件按照字母顺序依次载入。
require_tree [路径] 将路径下的文件,包含子文件夹中的文件全部载入
require_self [路径] 告诉Sprockets在载入其他文件之前,先将自己的内容插入
Preprocessing:
Sprockets在Itlt的协助下,有preprocessing的功能,例如你可以使用像是someting.js.coffee.erb这样的文件名,Tilt会一次根据不同的代码调用不同的模板解析器,所以,你可以在js中使用CoffeeScript的写法来写js,并在里面使用ruby的代码来产生你所需要的东西例如:
jQuery ->
number = <%= 1 + 1 %>
Helper:
Assets 提供了很多路径helper,来让你指向你的assets:
audio_path("horse.wav") # => /audios/horse.wav
audio_tag("sound") # =>
font_path("font.ttf") # => /fonts/font.ttf
image_path("edit.png") # => "/images/edit.png"
image_tag("icon.png") # =>
video_path("hd.avi") # => /videos/hd.avi
video_tag("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运行时的情形,如果你直接在terminal中打rails s -e production 来启动production环境时,你会发现马上就报错了,类似application.css isn't precompiled这样的错误,这是因为子啊production的环境下,我们的assets是必须呗compile过后存在public/assets目录下的,你可以在terminal中输入rake assets:precompile,rails会帮你把所有的assets文件按照你manifests以及环境设置打包压缩成单一的文件后放在public/assets目录下,并且所有的文件名会加入md5字符串用来标识其内容的快照(版本)。在你precompile后,你再打开localhost;3000会发现这时候已经没有报错了,但是感觉网站看起来像是没有引入css一样乱,这时候查看log你会发现rails找不到assets,这是因为在production环境是不处理静态文件的,所以你必须在production.rb中将config.serve_static_assets = false 改成 true,这时候你重启服务,再次访问,会发现一切正常了。
本文参考了http://gogojimmy.net/2012/07/03/understand-assets-pipline/,如有任何疑问请详细查看该链接