Rails Asset Pipeline 会存在资源冲突和效率问题么

xautjzd · 2014年05月02日 · 最后由 cassiuschen 回复于 2014年05月10日 · 2656 次阅读

刚了解了 Asset Pipeline 的机制,发现会自动将 app/assets 下所有的 js 和 css 分别整合到一个 application.js 和 application.css,那么这样会不会 js 间产生冲突问题?如果某些页面只需要单纯的几个 js 文件,而采用 asset pipeline 将一个大的 application 加载,会不会有效率的问题?

所以你写的时候就要考虑好啊,如果一点要针对某个页面就在那个页面单独引用,或者用一些 gem

所以这就是为什么 Rails 要加入 turbolink。你会发现这些决定都是一环套一环的:

  1. 简单容易的集成前端功能?默认全部 js 和 css 打包成一个。
  2. 打包成一个文件导致页面切换时反复加载?使用 turbolink 只更新 title 和 body。这点本身不见得对,如有错误请指正。

require_tree . 可以删掉

默认的 app/assets/javascripts/application.js 里面有这么一句

//= require_tree . 它的意思是引用 app/assets/javascripts 文件夹下的所有 js 文件,全部打包成一个,这是 Rails 框架认为合适的默认行为。

但是很多人在这里栽跟头,没有理解 pipeline 工作原理的人会发现 js 工作不正常(重复载入);了解 pipeline 原理的人通常也会删掉这句,用自己的目录结构来组织 js 文件。

所以,如果无法接受将所有 js 文件都打包成一个,那么就去掉这行代码,用自己理解的形式组织代码。

#3 楼 @shinefine 那您的意思是不使用 pipeline? 自己根据需要组织 js 在 assets/javascripts 目录下,然后根据需要分别引用么?

不是不使用 pipeline(如果想不使用 pipeline,需要到配置文件里面去关闭这个特性。),而是你可以在使用 pipeline 的情况下去掉/application.js 里面的//= require_tree . 这句。注意 application.js 同时是一个清单列表文件因为它内部有 require**** 这种语句。实际上,你可以根据自己的需要定义多个清单文件,在不同的清单文件中引用对应的 js,然后在页面中引用不同的清单文件。比如:

清单 A.js 的内容 //= require 1.js //= require 2.js 清单 B.js 的内容 //= require 1.js //= require 3.js

然后在你的页面 a.HTML 中: <%= javascript_include_tag "清单 A" %>

页面 B.HTML 中: <%= javascript_include_tag "清单 B" %>

打包逻辑一点也不坑爹,坑爹的是写 js 被打包压缩的时候比较蛋疼…有个别特殊的写法… 不过这和 pipeline 没关系

#6 楼 @cassiuschen 可以详细说说吗?

#7 楼 @alsotang 其实很简单,主要是 uglifier 压缩的时候会把 Angular 的函数名改掉,导致代码找不到目标函数,所以常规写法:

window.MobileController = angular.module 'mobile.controllers', []
window.MobileController
    .controller 'DashCtrl', ($scope, $http, FeedList, UserInfo) -> 
        $scope.feeds = FeedList.getList()

要写成

window.MobileController
    .controller 'DashCtrl', ['$scope', '$http', 'FeedList', 'UserInfo', ($scope, $http, FeedList, UserInfo) -> 
        $scope.feeds = FeedList.getList()
    ]

不光 controller,包括 server 之类的绑定都需要写成这样。

需要 登录 后方可回复, 如果你还没有账号请 注册新账号