链接:https://www.cnblogs.com/zs-note/p/7049288.html

在 Rails 的早期版本中,所有静态资源文件都放在 public 文件夹的子文件夹中,例如 imagesjavascripts 和 stylesheets 子文件夹。当 Rails 开始使用 Asset Pipeline 后,就推荐把静态资源文件放在 app/assets 文件夹中,并使用 Sprockets 中间件处理这些文件。

当然,静态资源文件仍然可以放在 public 文件夹及其子文件夹中。只要把 config.public_file_server.enabled 选项设置为 true,Rails 应用或 Web 服务器就会处理 public 文件夹及其子文件夹中的所有静态资源文件。但对于需要预处理的文件,都应该放在 app/assets 文件夹中。

在生产环境中,Rails 默认会对 public/assets 文件夹中的文件进行预处理,经过预处理的静态资源文件将由 Web 服务器直接处理,app/assets 文件夹中的文件不会直接交由 Web 服务器处理。

1 针对控制器的静态资源文件

使用生成器生成控制器时,Rails 会同时为控制器生成以下文件:

  • JavaScript 文件,如果 Gemfile 中包含了 coffee-rails gem,那么生成的是 CoffeeScript 文件
  • CSS 文件,如果 Gemfile 中包含了 sass-rails gem,那么生成的是 SCSS 文件

在生成脚手架时,Rails 还会生成

  • scaffolds.css 文件,如果 Gemfile 中包含了 sass-rails gem,那么生成的是 scaffolds.scss 文件

针对控制器的 JavaScript 文件和 CSS 文件也可以只在相应的控制器中引入:

<%= javascript_include_tag params[:controller] %> 或 <%= stylesheet_link_tag params[:controller] %>

此时,千万不要使用 require_tree 指令,否则就会重复包含这些静态资源文件。

在进行静态资源文件预编译时,请确保针对控制器的静态文件是在按页加载时进行预编译的。默认情况下,Rails 不会自动对 .coffee 和 .scss 文件进行预编译。

要使用 CoffeeScript,就必须安装支持 ExecJS 的运行时。macOS 和 Windows 已经预装了此类运行时。

通过在 config/application.rb 配置文件中添加下述代码,可以禁止生成针对控制器的静态资源文件:

config.generators do |g|g.assets false
end

2 静态资源文件的组织方式

应用的 Asset Pipeline 静态资源文件可以储存在三个位置:app/assetslib/assets 和 vendor/assets

  • app/assets 用于储存应用自有的静态资源文件,例如自定义图像、JavaScript 文件和 CSS 文件。
  • lib/assets 用于储存自有代码库的静态资源文件,这些代码库或者不适合放在当前应用中,或者需要在多个应用间共享。
  • vendor/assets 用于储存第三方代码库的静态资源文件,例如 JavaScript 插件和 CSS 框架。如果第三方代码库中引用了同样由 Asset Pipeline 处理的静态资源文件(图像、CSS 文件等),就必须使用 asset_path 这样的辅助方法重新编写相关代码。
从 Rails 3 升级而来的用户需要注意,通过设置应用的清单文件, 我们可以包含 lib/assets 和 vendor/assets 文件夹中的静态资源文件,但是这两个文件夹不再是预编译数组的一部分。

2.1 搜索路径

当清单文件或辅助方法引用了静态资源文件时,Sprockets 会在静态资源文件的三个默认存储位置中进行查找。

这三个默认存储位置分别是 app/assets 文件夹的 imagesjavascripts 和 stylesheets 子文件夹,实际上这三个文件夹并没有什么特别之处,所有的 app/assets/* 文件夹及其子文件夹都会被搜索。

例如,下列文件:

app/assets/javascripts/home.js
lib/assets/javascripts/moovinator.js
vendor/assets/javascripts/slider.js
vendor/assets/somepackage/phonebox.js

在清单文件中可以像下面这样进行引用:

//= require home
//= require moovinator
//= require slider
//= require phonebox

这些文件夹的子文件夹中的静态资源文件:

app/assets/javascripts/sub/something.js

可以像下面这样进行引用:

//= require sub/something

通过在 Rails 控制台中检查 Rails.application.config.assets.paths 变量,我们可以查看搜索路径。

除了标准的 app/assets/* 路径,还可以在 config/application.rb 配置文件中为 Asset Pipeline 添加其他路径。例如:

config.assets.paths << Rails.root.join("lib", "videoplayer", "flash")

Rails 会按照路径在搜索路径中出现的先后顺序,对路径进行遍历。因此,在默认情况下,app/assets 中的文件优先级最高,将会遮盖 lib 和 vendor 文件夹中的同名文件。

千万注意,在清单文件之外引用的静态资源文件必须添加到预编译数组中,否则无法在生产环境中使用。

2.2 使用索引文件

对于 Sprockets,名为 index(带有相关扩展名)的文件具有特殊用途。

例如,假设应用中使用的 jQuery 库及多个模块储存在 lib/assets/javascripts/library_name 文件夹中,那么 lib/assets/javascripts/library_name/index.js 文件将作为这个库的清单文件。在这个库的清单文件中,应该按顺序列出所有需要加载的文件,或者干脆使用require_tree 指令。

在应用的清单文件中,可以把这个库作为一个整体加载:

//= require library_name

这样,相关代码总是作为整体在应用中使用,降低了维护成本,并使代码保持简洁。

3 创建指向静态资源文件的链接

Sprockets 没有为访问静态资源文件添加任何新方法,而是继续使用我们熟悉的 javascript_include_tag 和 stylesheet_link_tag 辅助方法:

<%= stylesheet_link_tag "application", media: "all" %>
<%= javascript_include_tag "application" %>

如果使用了 Rails 默认包含的 turbolinks gem,并使用了 data-turbolinks-track 选项,Turbolinks 就会检查静态资源文件是否有更新,如果有更新就加载到页面中:

<%= stylesheet_link_tag "application", media: "all", "data-turbolinks-track" => "reload" %>
<%= javascript_include_tag "application", "data-turbolinks-track" => "reload" %>

在常规视图中,我们可以像下面这样访问 app/assets/images 文件夹中的图像:

<%= image_tag "rails.png" %>

如果在应用中启用了 Asset Pipeline,并且未在当前环境中禁用 Asset Pipeline,那么这个图像文件将由 Sprockets 处理。如果图像的位置是 public/assets/rails.png,那么将由 Web 服务器处理。

如果文件请求包含 SHA256 哈希值,例如 public/assets/rails-f90d8a84c707a8dc923fca1ca1895ae8ed0a09237f6992015fef1e11be77c023.png,处理的方式也是一样的。

Sprockets 还会检查 config.assets.paths 中指定的路径,其中包括 Rails 应用的标准路径和 Rails 引擎添加的路径。

也可以把图像放在子文件夹中,访问时只需加上子文件夹的名称即可:

<%= image_tag "icons/rails.png" %>

如果对静态资源文件进行了预编译,那么在页面中链接到并不存在的静态资源文件或空字符串将导致该页面抛出异常。因此,在使用 image_tag 等辅助方法处理用户提供的数据时一定要小心。

3.1 CSS 和 ERB

Asset Pipeline 会自动计算 ERB 的值。也就是说,只要给 CSS 文件添加 .erb 扩展名(例如 application.css.erb),就可以在 CSS 规则中使用 asset_path 等辅助方法。

.class { background-image: url(<%= asset_path 'image.png' %>) }

上述代码中的 asset_path 辅助方法会返回指向图像真实路径的链接。图像必须位于静态文件加载路径中,例如 app/assets/images/image.png,以便在这里引用。如果在 public/assets 文件夹中已经存在此图像的带指纹的版本,那么将引用这个带指纹的版本。

要想使用 data URI(用于把图像数据直接嵌入 CSS 文件中),可以使用 asset_data_uri 辅助方法:

#logo { background: url(<%= asset_data_uri 'logo.png' %>) }

asset_data_uri 辅助方法会把正确格式化后的 data URI 插入 CSS 源代码中。

注意,关闭标签不能使用 -%> 形式。

3.2 CSS 和 Sass

在使用 Asset Pipeline 时,静态资源文件的路径都必须重写,为此 sass-rails gem 提供了 -url 和 -path 系列辅助方法(在 Sass 中使用连字符,在 Ruby 中使用下划线),用于处理图像、字体、视频、音频、JavaScript 和 CSS 等类型的静态资源文件。

  • image-url("rails.png") 会返回 url(/assets/rails.png)
  • image-path("rails.png") 会返回 "/assets/rails.png"

或使用更通用的形式:

  • asset-url("rails.png") 返回 url(/assets/rails.png)
  • asset-path("rails.png") 返回 "/assets/rails.png"

3.3 JavaScript/CoffeeScript 和 ERB

只要给 JavaScript 文件添加 .erb 扩展名(例如 application.js.erb),就可以在 JavaScript 源代码中使用 asset_path 辅助方法:

$('#logo').attr({ src: "<%= asset_path('logo.png') %>" });

上述代码中的 asset_path 辅助方法会返回指向图像真实路径的链接。

同样,只要给 CoffeeScript 文件添加 .erb 扩展名(例如 application.coffee.erb),就可以在 CoffeeScript 源代码中使用 asset_path 辅助方法:

$('#logo').attr src: "<%= asset_path('logo.png') %>"

4 清单文件和指令

Sprockets 使用清单文件来确定需要包含和处理哪些静态资源文件。这些清单文件中的指令会告诉 Sprockets,要想创建 CSS 或 JavaScript 文件需要加载哪些文件。通过这些指令,可以让 Sprockets 加载指定文件,对这些文件进行必要的处理,然后把它们连接为单个文件,最后进行压缩(压缩方式取决于 Rails.application.config.assets.js_compressor 选项的值)。这样在页面中只需处理一个文件而非多个文件,减少了浏览器的请求次数,大大缩短了页面的加载时间。通过压缩还能使文件变小,使浏览器可以更快地下载。

4.1 javascript

在默认情况下,新建 Rails 应用的 app/assets/javascripts/application.js 文件包含下面几行代码:

// ...
//= require jquery
//= require jquery_ujs
//= require_tree .

在 JavaScript 文件中,Sprockets 指令以 //=. 开头。上述代码中使用了 require 和 require_tree 指令。require 指令用于告知 Sprockets 哪些文件需要加载。这里加载的是 Sprockets 搜索路径中的 jquery.js 和 jquery_ujs.js 文件。我们不必显式提供文件的扩展名,因为 Sprockets 假定在 .js 文件中加载的总是 .js 文件。

require_tree 指令告知 Sprockets 以递归方式包含指定文件夹中的所有 JavaScript 文件。在指定文件夹路径时,必须使用相对于清单文件的相对路径。也可以通过 require_directory 指令包含指定文件夹中的所有 JavaScript 文件,此时将不会采取递归方式。

清单文件中的指令是按照从上到下的顺序处理的,但我们无法确定 require_tree 指令包含文件的顺序,因此不应该依赖于这些文件的顺序。如果想要确保连接文件时某些 JavaScript 文件出现在其他 JavaScript 文件之前,可以在清单文件中先行加载这些文件。注意,require 系列指令不会重复加载文件。

4.2 css

在默认情况下,新建 Rails 应用的 app/assets/stylesheets/application.css 文件包含下面几行代码:

/* ...
*= require_self
*= require_tree .
*/

无论新建 Rails 应用时是否使用了 --skip-sprockets 选项,Rails 都会创建 app/assets/javascripts/application.js 和 app/assets/stylesheets/application.css 文件。因此,之后想要使用 Asset Pipeline 非常容易。

我们在 JavaScript 文件中使用的指令同样可以在 CSS 文件中使用,此时加载的是 CSS 文件而不是 JavaScript 文件。在 CSS 清单文件中,require_tree 指令的工作原理和在 JavaScript 清单文件中相同,会加载指定文件夹中的所有 CSS 文件。

上述代码中使用了 require_self 指令,用于把当前文件中的 CSS 代码(如果存在)插入调用这个指令的位置。

要想使用多个 Sass 文件,通常应该使用 Sass @import 规则,而不是 Sprockets 指令。如果使用 Sprockets 指令,这些 Sass 文件将拥有各自的作用域,这样变量和混入只能在定义它们的文件中使用。

和使用 require_tree 指令相比,使用 @import "*" 和 @import "**/*" 的效果完全相同,都能加载指定文件夹中的所有文件。

我们可以根据需要使用多个清单文件。例如,可以用 admin.js 和 admin.css 清单文件分别包含应用管理后台的 JS 和 CSS 文件。

CSS 清单文件中指令的执行顺序类似于前文介绍的 JavaScript 清单文件,尤其是加载的文件都会按照指定顺序依次编译。例如,我们可以像下面这样把 3 个 CSS 文件连接在一起:

/* ...
*= require reset
*= require layout
*= require chrome
*/

5 预处理

静态资源文件的扩展名决定了预处理的方式。在使用默认的 Rails gemset 生成控制器或脚手架时,会生成 CoffeeScript 和 SCSS 文件,而不是普通的 JavaScript 和 CSS 文件。在前文的例子中,生成 projects 控制器时会生成 app/assets/javascripts/projects.coffee和 app/assets/stylesheets/projects.scss 文件。

在开发环境中,或 Asset Pipeline 被禁用时,会使用 coffee-script 和 sass gem 提供的处理器分别处理相应的文件请求,并把生成的 JavaScript 和 CSS 文件发给浏览器。当 Asset Pipeline 可用时,会对这些文件进行预处理,然后储存在 public/assets 文件夹中,由 Rails 应用或 Web 服务器处理。

通过添加其他扩展名,可以对文件进行更多预处理。对扩展名的解析顺序是从右到左,相应的预处理顺序也是从右到左。例如,对于 app/assets/stylesheets/projects.scss.erb 文件,会先处理 ERB,再处理 SCSS,最后作为 CSS 文件处理。同样,对于app/assets/javascripts/projects.coffee.erb 文件,会先处理 ERB,再处理 CoffeeScript,最后作为 JavaScript 文件处理。

记住预处理顺序很重要。例如,如果我们把文件名写为 app/assets/javascripts/projects.erb.coffee,就会先处理 CoffeeScript,这时一旦遇到 ERB 代码就会出错。

转载于:https://www.cnblogs.com/qinyan20/p/7909532.html

Rails的静态资源管理相关推荐

  1. Rails的静态资源管理(三)—— 开发环境的Asset Pipelin

    官方文档:http://guides.ruby-china.org/asset_pipeline.html http://guides.rubyonrails.org/asset_pipeline.h ...

  2. vue本地项目静态资源管理

    vue本地项目静态资源管理 统一放在src/static里面css,images,js index.html里面使用重置样式 <link rel="stylesheet" h ...

  3. python pipeline框架_介绍Python的Django框架中的静态资源管理器django-pipeline

    django-pipeline 是一个 Django 下非常方便的静态资源管理 app,尤其是 1.2 版本之后,利用 django-staticfiles 的collectstatic 命令,在开发 ...

  4. 我们是如何做好前端工程化和静态资源管理 - 無雄 - 博客园

    我们是如何做好前端工程化和静态资源管理 随着互联网的发展,我们的业务也日益变得更加复杂且多样化起来,前端工程师也不再只是做简单的页面开发这么简单,我们需要面对的十分复杂的系统性问题,例如,业务愈来愈复 ...

  5. 前端“智能”静态资源管理 - Onebox - 博客园

    前端"智能"静态资源管理 模块化/组件化开发,仅仅描述了一种开发理念,也可以认为是一种开发规范,倘若你认可这规范,对它的分治策略产生了共鸣,那我们就可以继续聊聊它的具体实现了. 很 ...

  6. 京东前端工程化和静态资源管理全面总结

    随着互联网的发展,我们的业务也日益变得更加复杂且多样化起来,前端工程师也不再只是做简单的页面开发这么简单,我们需要面对的十分复杂的系统性问题,例如,业务愈来愈复杂,我们要如何清晰地梳理:团队人员愈来愈 ...

  7. 程序员的nginx技能包(3)——静态资源管理,资源井井有条,生活风花雪月

    点此查看全部文字教程.视频教程.源代码 背景 每次新建项目,都要到处找各种静态资源,是不是很烦. 找那些公司logo图片- 找那些前端样式css- 找那些前端框架vue.jquery- 静态资源太多, ...

  8. 机器学习管道模型_使用连续机器学习来运行您的ml管道

    机器学习管道模型 Vaithy NarayananVaithy Narayanan Follow跟随 Jul 15 7月15 使用连续机器学习来运行ML管道 (Using Continuous Mac ...

  9. openresty 页面静态化及多级缓存

    openresty 页面静态化及多级缓存 多级缓存: 数据缓存的好处不用介绍了吧!, 所谓多级缓存,即在整个系统架构的不同系统层级进行数据缓存,以提升访问效率,这也是应用最广的方案之一. 而 ngin ...

  10. 组件化开发与资源管理

    前端,是一种GUI软件 现如今前端可谓包罗万象,产品形态五花八门,涉猎极广,什么高大上的基础库/框架,拽炫酷的宣传页面,还有屌炸天的小游戏--不过这些一两个文件的小项目并非是前端技术的主要应用场景,更 ...

最新文章

  1. 【深度学习】在PyTorch中使用 LSTM 进行新冠病例预测
  2. C++对象模型探索 / 普通类对象占用的空间
  3. maven乱码解决方案---修改maven编码
  4. 前端打包利器webpack里utils.cssLoaders的工作原理调试
  5. Do 32-bit build only with XCode 5.1
  6. 【代码笔记】iOS-performSelectorOnMainThread
  7. Twitter数据抓取的方法(二)
  8. windows 下 nginx 的反向代理学习整理
  9. 一行代码就能写一个日志打印组件,你信吗?为你揭晓RTOS中日志打印组件的核心
  10. 怎样下载最新的SCI/SSCI/EI目录期刊列表?
  11. 小鸟云数据盘如何进行挂载?
  12. 单调队列java_单调队列单调栈
  13. 行业案例 | AR+工业互联网,智慧园区的全新服务模式
  14. 星星城堡童装加盟雾非雾
  15. 4路 HX5+Emulex 8Gb 实现 BOFM 实施 -chenjhh@dc
  16. 大数据入门9:半结构化数据模型(Semi-structured Data Model)
  17. 绿巨能 macbook pro 电池
  18. 《SpringCloud Alibaba 微服务架构》专题(二十一)-Seat简介与安装
  19. 武汉大学数据结构MOOC第1周测验
  20. 嵌入式开发基于linux系统的c语言程序开发调试工具

热门文章

  1. 给定一个正整数,编写程序计算有多少对质数的和等于输入的这个正整数,并输出结果。...
  2. HG8240电信光猫禁用TR069之修改配置法
  3. neo4j安装与示例
  4. jQery动态添加删除类样式
  5. 前后端分离开发,六大方案全揭秘:HTTP API 认证授权术
  6. 写代码千万别用User这个单词!
  7. Android你可能要用到的自定义View分享
  8. c语言指针 r,C语言指针的高级操作
  9. python 服务器_使用 Python 开发 EMQ X MQTT 服务器插件
  10. Python使用datetime来判断近七天