`
aegoose
  • 浏览: 40126 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

Asset Pipeline in rails 3.1.0

 
阅读更多

原英文版为:http://guides.rubyonrails.org/asset_pipeline.html

本文: http://blog.csdn.net/aegoose/article/details/7029307

0. Pipeline的概念:

 

输入 ===pipeline1处理==> 输出 ===pipeline2处理==> 输出 ... ... ===pipelineN处理==> 输出

 

1. 什么是Asset Pipeline

Asset pipline提供一个框架,整合并压缩所有的js和css等资源,资源文件可以用coffeeScript,sass或erb扩展编写.

在rails3.1以前,一般要通过第三方库比如jammitsprockets来实现assets机制,而rails3.1默认的actionpack已支持, 主要通过sprockets插件实现.

开发人员可以只要通过sprokets库便可以对assets资源进行预处理,压缩.这种方式 与DHH在2011的RailsConf所提出的”fastby default”策略相吻合.

Rails3.1中,assetpipeline默认开启, 可以修改config/application.rb来禁用:
#也可以在新建工程时禁用sprockets,不推荐.

1.1 主要特点

个特点是为页面整合所有assets资源.在生产环境此特点极为重要,可以简少浏览器加载页面时对资源的请求次数.

Rails本身也可以通过helper来引用资源文件,如”javascipt_include_tag”或”stylesheet_link_tag”加上”:cache=> true”, 实现资源缓存到浏览器上.不过存在局限性,比如,它不能提前缓存资源,不能隐式包含一些第三方库的资源.(隐式包含是指将第三方库代码如js直接合并到当前引用的js代码中)

Rails3.1默认把所有的js和css文件整合到一个文件中.当然,你也可以按实际需要差分成多个文件.在生产环境,每个生成的资源文件会追加一个MD5的数字摘要串.浏览器会直接缓存这个文件,而当MD5串在后台环境修改了,浏览器会重新请求缓存.

个特点是压缩资源文件.比如css文件会移除所有的无用空白和注释,js则可以进行更复杂的压缩(如变量名可以优化等).可以选择不同的压缩机制或者自己进行定制.

个特点是用其他语言扩展资源文件内容.可以使用sass编写css,coffeeScript编写js,以及erb编写css或js,这样更好的集成rails的helper.

1.2 Fingerprinting有什么好的?

Fingerprinting是一种文件签名技术.Rails 3.1使用它分析文件内容生成带签名的文件名,标识出文件的最后一次变更,可以确保文件内容与文件名的唯一对应.

由于文件名与文件内容的唯一对应关系,这样浏览器缓存的文件就是某个时期修改了的文件.而当文件内容更新了,fingerprint生成新的文件名,浏览器也会重新缓存新文件.这便是cachebusting技术.
通常的做法是在文件名后追加一个哈希序列.比如对global.css加上一个数据签名的哈希序列,变成:
Railsasset pipeline 主要使用以上方式.
Rails以前版本主要是通过为请求加上一个时间撮,主要是通过helper来动态,生成如下:

这种方式存在局限性:

1)并非所有的缓存机制支持带参的查询串.

SteveSouders曾说到”要避免通过查询串来缓存资源文件”,他研究发现浏览器有5-20%机率不能带参数缓存资源.许多CDN(ContentDelivery Network,内容分发网络)环境不能缓存查询串的资源.


2)针对分布式服务器环境,文件名随时会改变

查询串主要是基于时间撮的,而资源同服务器一同部署,不同的服务器会产生不一样的时间撮,这样就无法保证请求时附加的查询串能对应到产生该串的服务器上了.比如A,B服务器分别产生的查询串为a,b,客户端第一次得到查询串a,第二次用a去请求,该请求可能分配B上,不是B期望的查询串b,这样B会重新传给客户端相同的资源.

另一个问题是当服务器新版本部署后,即使新版本没有改动资源文件,那也会强制客户端重新缓存资源文件.

Fingerprinting根据文件内容生成文件名避开使用查询串的问题,只要内容是相同的,文件名也是相同的.

Fingerprinting在生产环境默认是开启,而其他环境不开启.可以在config/application.rb设置 config.assets.digest 选择开启动.更多参数

Optimizecaching
RevvingFilenames: don’t use query string

2. 如何使用assets pipeline

Rails以前的版本,所有的assets资源文件都放在public的子目录中,如imaegs/,javascript/, 及stylesheets.而当使用assetpipeline, 这些资源文件可以放在app/assets目录下.所以文件被srockets插件进行管理.

这并不是说”public”目录不再放资源文件,一些静态的资源文件仍然可以放在public下,而另一些文件可以放在app/assets文件下,以便可以通过预编译处理再被调用到.

Rails生产环境默认会预编译这些资源文件到public/assets目录下,这样可以直接在发布到服务器下被使用.

但使用scaffold或者controller生成应用代码,rails会为每个controller生成一个js文件(如果安装了coffeescript插件则会生成对应的js文件)和css文件.

比如,当生成ProjectsController,会同生成app/assets/javascripts/prjects.js.coffee及app/assets/stylesheets/projects.css.scss文件.每一个controller对应一个相同命名的js和css文件.这些文件可以通过如下helper进行自动加载到每个controller的应用:
可以使用ExecJS 支持coffeeScript.更多参考ExecJS相关的文件.

2.1 Asset的组成

Assets可以出现在三处地方,app/assets, lib/assets及vendor/assets.

App/assets存的是当前应用程序的各种资源,如自定义的图片,js和样式;
Lib/assets存的是当前自定义库对应的资源;
vendor/assets则存第三方插件库对应的资源文件(有些插件支持自定义资源)

这三处地方会被加入到sprockets会搜索路径(可以通过Rails.application.config.assets.paths定义Sprockets的搜索路径).当sprockets请求一个资源文件,会检索所有路径直至资源文件匹配,然后将文件编译并应用到服务器上.
可以通过以下配置定义更多的资源文件位置:

2.2 在程序中引用assets资源

通过helper手工添加资源文件到应用程序中,这点sprockets没有直接支持,

在view中可能添加以下helper引用图片文件:
假设你已在程序中启动pipeline,那么以上helper会搜索public/assets/rails.png这个图片.
同样的,当请求的是一个带MD5哈希的图片(如请求public/assets/rails-af27b6a414e6da00003503148be9b409.png)时,helper会搜索对应的位置(哈希算法将在InProduction章节中介绍).
也可以将图片放在assets的子目录:

2.2.1 css整合erb

css可以扩展成css.erb(如application.css.erb),这样可以使用rails的helper,如使用asset_path为css来定义图片资源:

其中<%%>是ruby语法,调用了asset_path helper,指定对image.png文件的引用,些文件会自动关联到app/assets/image-<MD5hash>.png.也可以用data URI方法引用资源路径:

这个helper会加载带上data_URI标准的图片路径,详细参考data URI.

2.2.2 css整合sass

css可以扩展成css.sass,sass-rails将通过url或path两种形式重写css的路径,主要在使用在image,font,video, audio, javascript, stylesheet各种具体helper上进行应用.

也可以通用形式的helper,同时指定路径的文件类型:

2.2.3 js整合ERB

Js文件可以使用js.erb进行扩展(如application.js.erb),这样可以引用rails的helper,用asset_path来定义资源路径:

asset_path将请求的路径引用到对应的assets路径上.

同样的,coffeeScript也可以使用asset_path引用资源.

2.3 manifest文件及其引用规则

Sprockets定义了一些manifest文件集,决策哪些资源被使用.这些文件会使用一些规则来告诉sprockets哪些文件可以被引入,并指导sprockets整合生成单一的js或css文件(当Rails.application.config.assets.compress=true才整合资源).单一资源文件可以减少更多的请求时间.

比如在Rails应用程序中的app/assets/javascripts/application.js文件包含以行内容:

引用规则以”//=”作为开始标记.上述实例使用require和require_tree规则.

其中require指加载某些指定文件,上述实例的”require jquery”通知sprockets加载jquery.js文件,这些文件的位置是sprockets path定义的位置.

Rails3.1默认使用jquery-rails插件,jquery.js和jquery_ujs.js都存在插件的assetpipeline位置上,在当前工程的assets上看不到的.

而require_tree指加载所有路径上的资源文件.上述实例的”require_tree .”通知sprockets加载当前路径下的所有js资源.

其他的规则如require_directory则指加载指定路径下的资源文件(js)文件.

引用规则是从上到下顺序解释的,不过require_tree规则没有指定tree目录的翻译顺序,所以tree目录下的js文件最好没有顺序要求.如果是第三方的js插件需要其他js依赖某些js库文件,最好把依赖的js文件放到最上面.注意不要多次引入相用的文件.

同样的,css也会在app/assets/stylesheets/application.css定义引用规则,如下实例:

规则与css的引用规则是相同的.在以上实例中,用到了require_self规则,它会去寻找调用它的页面的路径,并把同名的css包含进来(每个controller会有对应的css和js文件).require_self多次被调用,只有最后一次调用有效.

可以使用sass的@import规则来引入多个sass文件.

srpockets的引用规则可以定义多个manifest文件,比如定义admin.css和admin.js文件用于包含后台应用需要引用的资源文件,使用规则跟上面所描述的一致.

2.4 资源文件预编译机制

不同资源文件的(如.erb,.sass,.coffee)在生成时将会由不同的解析机制进行预编译(这里的编译是指对文件进行解析和转换,得到新输入格式).

controller和scaffold自动生成时会产生一个coffeescript文件和scss文件,替代传统的js和css文件.

如”projects”controller会产生app/assets/javascripts/projects.js.coffee和app/assets/stylesheets/projects.css.scss文件.当客户请求使用这两个文件时,会分别由coffeescript插件和sass-rails插件编译后再传给客户端.其他形式的文件也是相同的.

文件名按从左到右的格式进行命名,从右到左进行预编译,比如projects.css.scss.erb首先由erb进行编译处理一次,再由scss进行编译处理,最后生成css文件,project.js.coffee.erb则先由erb处理,再由coffeescript处理,最后生成js文件.

3. 开发模式下的设置

开发模式下,manifest文件定义的资源文件会生成独立的文件被网页的头引用:

其中body参数是sprockets定义的.

3.1 禁用debug模式

设置config/environments/development.rb的debug参数:

一旦debug禁用,sprockets会调用所有编译器解析所有连接所的文件.Manifest文件会生成一个引用文件:
服务器启动后,同时在首次请求资源时,assets资源会被编译并缓存.Sprokets会在http的响应header设置cache-control为must-revalidate,以减少客户端浏览器再次请求资源,下一次请求资源时一般就会返回304响应,表示请求资源无变化.

如果manifest文件变化了,服务器会响应新编译的资源文件.

可以手工设置资源的属性来启动debug模式:

The :debug optionis redundant if debug mode is on.

Youcould potentially also enable compression in development mode as asanity check, and disable it on-demand as required for debugging.

4.生产环境下的设置

生产环境下rails使用figerprinting策略引用资源.资源默认情况是预编译好的,并可以作为静态资源被服务器引用.

而在编译的时候,每个文件都生成一个MD5串,追加到文件名后面,存放在特定位置上.

通过helper来引用文件,helper中文件是普通文件名,而在页面上会是figerprinting文件名.例如:会在页面生成为:

可以通过config.assets.digest 设置是否通过figerprinting编译文件名.

4.1 编译资源

可以使用rails所绑定的rake命令来编译资源文件,主要将manifests及其他文件通过pipeline输出到指定位置.可以设置config.assets.prefix来指定资源输出的路径,默认是public/assets.可以使用以下命令进行编译:

可以在config/application.rb设置config.assets.initialize_on_precompile=false, 加速资源文件的编译.不过这样会生成的模板不能辨识出程序的对象及函数.Heroku就要求将些选项设置为false.

注意:假如设置nitialize_on_precompile=false,最好在部署前设置一下rakeassets:precompile的结果是否正确. Itmayexpose bugs where your assets reference application objectsormethods, since those are still in scope in developmentmoderegardless of the value of this flag.

Capistrano(v2.8.0以上)已支持自动预编译,只要在Capfile加下以下语句:

此语句会将config.assets.prefix的路径连接到shared/assets目录.如shared路径已被使用,则要重新设计部署策略.

最好保证shared路径被所有部署工所共享,这样远程服务器已存在的一些缓存资源仍然可以被引用(比如一些文件是客户上传的,可以保证不被新文件覆盖删除掉).

如果是本地编译资源文件,可以使用”bundleinstall–without assets”运行服务器,这样就不同在服务器上加载assets插件了.

默认进行编译的文件主要包括application.js,application.css以及一些满足以下规则的文件集:

如果需要包含其他manifest文件,或者内部孤css,js文件,可以自定义以下属性进行包含:
Rake会生成一个manifest.xml文件,包含了所有引用资源及其对应的fingerprint文件名.Rails的helper就是通过查询此关系将资源引用串输出到页面上的.以下是manifest.xml的例子:

Manifest默认的根目录由config.assets.prefix定义的,默认是”/assets”.

可以通过以下选项的设置改变manifest的根目录:

注意:在生产环境编译时一旦找不到资源文件会报错:


4.1.1 web服务器的资源配置

可以直接通过web服务器定义资源文件,这样这些文件可以由web服务器直接进行响应.

Apache下的定义:

Nginx下的定义:

当编译资源文件时,sprockets会同时创建一个gz版的assets文件压缩包.Web服务器通常使用的是适中的压缩比压缩文件,而sprockets使用的是高压缩比压缩资源文件,可以减少文件传输带宽.另一个方面,web服务器直接从磁盘加载压缩好的资源文件,而不需要使用deflating机制再次压缩文件(每次请求压缩一次并不实际).

Nginx可以自动启动gzip_static:不过需要在编译web服务器手工加入的编译选项以加载gzip_static模块,Ubuntu及nginx-light默认是加载了此模块,其他要手工.If you’re compiling nginx with Phusion Passenger you’ll need to passthat option when prompted.

Unfortunately, a robust configuration for Apache is possible but tricky, please Google around.

4.2 在线编译

某些环境可能需要用在线编译模式(即无预编译过程).所有的资源请求直接由sprockets调用对应的pipeline进行解析编译,可以通过以下选项启动在线编译:

第一次请求时资源会被编译并缓存,同开发模式相同原理,同时manifest文件的资源会解析成带MD5的资源文件被页面引用.

Sprockets同时在http的header设置了cache-control为max-age=3153600.表示资源文件可以在服务器及客户端缓存1年.这样可以减少从服务器请求相同的资源,客户端直接从本地取得资源,速度更快.

这种模式将会耗费更多的内存资源,性能会比默认方式差.

在生产模式下,如果没有javascript运行时环境,可以用以下作为默认运行时环境:

5. 自定义pipeline解释器

5.1 css 压缩器

可以用YUI来压缩css文件.YUI扩展css语法,支持语法缩小.可以设置以下选项提供支持:

必须设置config.assets.compress= true以支持css压缩.

5.2 js压缩器

有三个选项支持js压缩,:closur, :uglifier, :yui, 分别需要closure-compiler,uglifier及yui-compressor插件的支持.

Rails3.1默认使用uglifier,些插件封装了UglifierJS (NodeJS)的ruby实现.压缩主要是去空格及魔术代码串,尽可能取代if和else语法峦三目操作符.可以定义如下选项:

必须设置config.assets.compress=true来启动js压缩.

注意:uglifier需要ExecJS运行时环境的支持.如果os环境是Mac或windows,则需要安装js的运行时环境.可以参考ExecJS官方相关的文档.

5.3 自定义压缩类

可以自定义一个类来支持css和js的压缩.此类必须实现compress方法,输入为一个串,输出为压缩后的串:

可以在application.rb中启动自定义的压缩类:


5.4 切换资源文件根路径

默认是/assets路径,可以配置换成其他路径:

主要是考虑到rails3.1以前的资源文件使用的路径不是assets,方便扩展.

5.5 X-Sendfile Headers

X-Sendfileheader为web服务定义一些请求参数,以便web服务器忽略应用服务器的响应,而用请求头所指定的文件进行替代.这个选项默认是禁用的,如果web服务器支持,则可以启动些选项.一旦启动,web服务器可以直接从响应头中分析取出输入的资源文件,使响应更快.

apache和nginx运载X-Sendfileheader,可以在config/environments/production.rb设置:

注意:可以将这个选项设置在production.rb下,用于生产环境下才有效,而开发和测试环境忽略X-Sendfileheader,对开发有利(比如错误提示信息在开发环境可见,在生产环境不可见).

6. How Caching Works

Sprocketsuses the default Rails cachestore to cache assets in development andproduction.

TODO:Addmore about changing the default store.

(Sprockets默认在开发和生产环境使用rails缓存机制来缓存assets资源.)

7.为你的Gem加入assets支持

Assets资源可以从gem中获得.

比如jquery-rails插件提供了rails标准js库的支持.插件包含了rails引擎,继承自Rails::Engine,这样它里面的app/assets,lib/assets, vendor/assets目录便可以直接被rails辨识出来,sprockets可以直接读到到相关路径的资源文件.

8. Making Your Library or Gem a Pre-Processor

TODO:Registering gems on Tilt enablingSprockets to find them.

9. 更新到新版本的rails

更新过程需要注意两个问题:

首先要将更变资源文件集的路径.不同类型的文件js,css等移动到不同的位置;其次要重新设置一系列的系统选项,以下是rails3.1.0会添加以下选项:

config/application.rb:

Config/environments/development.rb:

Config/environments/production.rb:

config/environment/test.rb:

 

Gemfile:

 

要求bundler使用assets group, config/application.rb:

rails 3.0则为:

10. Feedback




分享到:
评论

相关推荐

    css_splitter:Gem,用于使用Asset Pipeline为Rails 3.1+应用程序拆分超出IE限制4095选择器的IE限制的样式表

    用于使用Asset Pipeline分割Rails 3.1+应用程序的样式表的样式表,这些样式表超出IE选择器的IE限制。 您可以阅读此,以了解有关该gem的背景故事的说明。 发展状况 由于此gem的原始开发人员目前未在任何项目中积极...

    asset-pipeline

    import { AssetPipeline } from "asset-pipeline" ; const pipeline = new AssetPipeline ( ) pipeline . rules . saltKey = "saltKey" pipeline . rules . cacheBreak = true // Set origin (Rendered: ...

    Rails 3 in Action

    - **Asset Pipeline**:Rails 3.1引入了Asset Pipeline,将CSS、JavaScript、图片等静态资源管理整合到一个统一的流程中,提高了页面加载速度。 - **CoffeeScript**:默认使用CoffeeScript作为JavaScript的预...

    AssetPipeline:元和编译资源!

    AssetPipeline是Unity引擎中一个非常重要的概念,它主要用于管理和优化游戏开发中的资源流程。在Unity中,AssetPipeline处理资源的加载、预处理、打包和序列化等操作,以提高游戏性能并降低内存占用。元数据...

    关于rails 3.1 cucumber-rails 1.2.0

    结合Rails 3.1的Asset Pipeline和Cucumber-Rails 1.2.0,开发者能够构建出一个既高效又健壮的Web应用程序。Asset Pipeline优化了前端资源的处理,Cucumber-Rails则提供了强大的测试工具,确保代码的质量和功能符合...

    Rails 4 in Action, Second Edition.pdf

    - **Asset Pipeline的优化**:Rails 4对Asset Pipeline进行了改进,使得前端资源的管理更加简便。 - **Webpacker支持**:虽然Webpacker不是Rails 4的核心特性,但本书可能会提及Rails 4如何与Webpacker集成,以更好...

    ratpack-asset-pipeline:用于Ratpack的Asset-Pipeline适配器

    Ratpack资产管道感动:该项目已移动到主资产管道仓库的一个子项目 该模块为Ratpack框架提供了开发和生产的运行时,以渲染由Asset-Pipeline编译的文件。 这应该与asset-pipeline-gradle插件适当地配对注意: 2.3.0版...

    gakubuchi:使用Asset Pipeline进行静态页面管理

    学渊 Gakubuchi提供了一种使用Asset Pipeline管理静态页面(例如错误页面)的简单方法。安装将其放在您的Gemfile中: gem 'gakubuchi' 使用以下命令运行安装生成器: rails g gakubuchi:install 或指定静态页面的...

    jquery-ui+jquery-ui-rails

    这个gem负责将jQuery UI的库文件打包并整合到Rails的asset pipeline中,使得在Rails项目中使用jQuery UI变得简单。 要使用`jquery-ui-rails` gem,开发者需要在Gemfile中添加依赖,并执行`bundle install`命令安装...

    Unity-AssetPipeline-Presentation:在Develop上展示了“对Unity资产管道进行技术深入研究”的Unity项目

    深入了解Unity资产管道的技术 此仓库包含在Develop Conference:2018上展示的Unity项目。 涵盖的主题 资产,对象和Unity的导入管道 什么是.meta文件以及它们如何工作 资产参考和依赖关系如何表示 ...

    sinatra-asset-pipeline:基于Sprockets的Sinatra的资产管道

    sinatra-asset-pipeline支持即时编译资产以进行开发以及预编译资产以进行生产。 sinatra-asset-pipeline的设计目标是为将Sinatra应用程序与Sprockets集成提供良好的默认设置。 安装 从RubyGems安装Sinatra Asset ...

    在Rails和S3之间同步资产-Ruby开发

    Asset Sync构建为与Rails 3.1中引入的新的Rails Asset Pipeline功能一起运行。 运行bundle exec rake asset:后,将对资产进行预编译。Asset Sync在Rails和S3之间同步资产。 Asset Sync构建为与Rails 3.1中引入的新...

    asset-pipeline:NodeJS 的资产管道

    Asset Pipeline 是一个专为 Express.js 设计的 NodeJS 模块。 它的工作方式类似于 Rails 资产管道,并提供特殊的帮助程序将 JS 和 CSS 包含到您的页面中。 要开始使用npm安装 Asset Pipeline: npm install ...

    external_asset_pipeline:轻松将外部管理的资产管道与Rails集成

    external_asset_pipeline gem在rails和可以生成资产清单的任何独立资产处理器之间提供了轻便灵活的集成。 它可以与结合使用,也可以作为管理所有资产的完​​整替代品使用。 也许最好通过示例来说明,所以请不要...

    rails向导打包

    6. **Asset Pipeline**: Rails 的 Asset Pipeline 提供了一种管理应用程序静态资源(如 CSS、JavaScript 和图片)的方式。它会讨论预处理(如 SASS 和 CoffeeScript)、组合和压缩资产,以及如何配置 pipeline。 7....

    Rails进行敏捷Web开发(所有版本的源码rails3.0-4.0)

    2. Rails 3.1: 这个版本引入了Asset Pipeline,它管理应用程序的CSS、JavaScript和其他静态资源,提高了加载速度并支持压缩和合并。另外,它还引入了CoffeeScript和Sass作为默认的JavaScript和CSS预处理器,提升了...

    前端开源库-hpd-asset-pipeline

    **前端开源库-hpd-asset-pipeline** "前端开源库-hpd-asset-pipeline"是一个专为前端开发者设计的开源工具,旨在优化和管理前端项目的静态资源,如JavaScript、CSS、图片和其他媒体文件。这个库被称为HPD资产管道,...

    rails4.0.0

    Rails 4中的Asset Pipeline进行了优化,提升了静态资源如CSS、JavaScript的处理速度。这个功能允许开发者合并、压缩和版本化静态资源,以减少HTTP请求并提高页面加载速度。 6. **Strong Parameters** 为了解决...

    react-asset-pipeline:React资产管道

    React Asset Pipeline 是一个针对React应用的构建工具,它主要用于优化和管理React项目中的资源,特别是JavaScript文件,包括jsx语法的转换。在React开发中,jsx是一种用于描述React组件的语法扩展,它允许开发者以...

    org.jresearch.commons.gwt.utils.shared-1.0.45.zip

    《org.jresearch.commons.gwt.utils.shared-1.0.45.zip》是一个开源项目的压缩包,主要包含的是asset-pipeline库的资源。这个库是专为处理和服务静态Web资产而设计的,尤其适用于Java虚拟机(JVM)环境。在本文中,...

Global site tag (gtag.js) - Google Analytics