Rails 3.1 资产管道和手动订购的 Javascript 需要

Posted

技术标签:

【中文标题】Rails 3.1 资产管道和手动订购的 Javascript 需要【英文标题】:Rails 3.1 asset pipeline and manually ordered Javascript requires 【发布时间】:2011-09-03 05:53:29 【问题描述】:

我正在尝试将现有应用程序转换为新的 3.1 资产管道布局,并希望包含许多必须按特定顺序排列的供应商文件(underscore.js 和主干是一对)。因此,我不能只使用= require_tree . 来拉入我的供应商文件(而不用前缀重命名每个文件。呸)。

以下内容在我的app/assets/javascripts/application.js 文件中:

//= 需要modernizr-1.7 //= 需要 jquery-1.6.1 //= 需要下划线 1.1.5 //= 需要骨干网-0.3.3 //= 要求树。

我已经尝试了每一种有/无扩展、有/无require_tree和有/无相对路径的组合,但没有任何效果。我所有的供应商文件都在/vendor/assets/javascripts/

我觉得我很愚蠢,因为这似乎是一个如此明显的用例,(包括按名称排列的特定文件在 JS 中很常见,不是吗?)我一定是在做一些愚蠢的事情?

【问题讨论】:

Romain Tribes 有正确的答案,只是想补充一点,而不是 'require jquery-1.6.1' 你可以做 'require jquery' 并且它会从 gem 中提取它,它是默认随 3.1 一起安装 【参考方案1】:

require_tree 完全按照你说的做。如果你给它

//= require_tree .

它将文件加载到调用 require_tree 的当前目录中。如果你给它

//=require_tree ../../../vendor/assets/javascripts

然后你会得到 vendor 下的 javascript。

我不喜欢 ../../.. 符号,所以我创建了一个名为 vendor/assets/javascripts/vendor_application.js 的文件,其中包含:

//= require_tree .

这会加载供应商目录下的 javascript。

注意,require 会在 3 个管道位置(app、lib、vendor)中搜索需要的文件。 require_tree 是字面的,应该是这样的。

关于这方面的 railscast 非常有帮助:http://railscasts.com/episodes/279-understanding-the-asset-pipeline

【讨论】:

【参考方案2】:

您可以按特定顺序要求每个文件,然后添加:

//= require_self

代替:

//= require_tree .

【讨论】:

我最近开始使用 RoR,但很快注意到 require_tree 。由于您最终加载了许多未使用的 JS/CSS,因此正在为一个大项目开枪自尽……手动要求每个文件,如果需要,将它们分组到带有自己的索引文件的“库文件夹”中…… 【参考方案3】:

我相信您可以在您的vendor/assets/javascripts 中添加一个library.js,然后只需

//= require library.js

来自您的application.js,不是吗?

【讨论】:

对不起,应该是vendor/assets/javascripts 是的,目前我使用两个文件(主要用于错误跟踪),一个 vendor.js 和一个 application.js。我从来没有解决过能够在没有另一个清单文件的情况下直接将所有内容包含到 application.js 清单中的问题。【参考方案4】:

我的回答适用于Rails 3.1rc4,不知道其他版本的功能是否一样。

无论 .js 文件是在 app/assets/javascripts/ 还是 vendor/assets/javascripts/ 中,您实际上都可以将所有 require 语句放在 app/assets/javascripts/application.js 中

像这样:

// this is in app/assets/javascripts/application.js

//= require modernizr-2.0
//= require jquery
//= require jquery_ujs
//= require jqueryui-1.8.12
//= require jquery.easing-1.3
//= require jquery.noisy
//= require jquery.jslide-1.0
//= require respond
//= require smoke
//= require_tree

我在此处包含了 require_tree,因为我有其他 javascript 文件用于我的个人控制器(pages.js.coffee、users.js.coffee)和一个用于站点范围内容的通用文件(site.js.coffee)

同时这里是文件结构。

app/
├── assets
│   ├── javascripts
│   │   ├── application.js
│   │   ├── pages.js.coffee
│   │   ├── users.js.coffee
│   │   └── site.js.coffee
│   └── stylesheets
└── plugins

vendor/
├── assets
│   ├── javascripts
│   │   ├── jquery.easing-1.3.js
│   │   ├── jquery.jslide-1.0.js
│   │   ├── jquery.noisy.js
│   │   ├── jqueryui-1.8.12.js
│   │   ├── modernizr-2.0.js
│   │   ├── respond.js
│   │   └── smoke.js
│   └── stylesheets
└── plugins

这让我可以控制供应商库的加载顺序(这通常很重要),而不必担心我的内部 javascript,因为顺序通常不太重要。

更重要的是,我控制了一个常用文件中的所有 require 语句,我发现这样既安全又干净。

【讨论】:

+1 表示这种处理资产依赖关系的方式。根据指南guides.rubyonrails.org/asset_pipeline.html#asset-organization,这是 Rails 的方式。还记得在移动文件后重新启动 Rails 服务器! 但这一次加载了太多的 JS。 //= require 您的依赖项仅在实际需要的地方要好得多。总的来说,我认为 Rails 3.1 组织 JS 的方式对于设计良好的应用程序来说不够细。 @MarnenLaibow-Koser Rails 的想法是一次加载一大堆 js/css 是好的,因为这样浏览器可以缓存它,然后对于任何后续请求都不需要获取资产从服务器。因此初始加载速度较慢,但​​当每个页面都没有自己的 css 样式和 js 文件时,后续请求会很快。这也促进了编写理智和可重用的 css。但是,您当然可以将资产管道调整为您希望的细粒度。 @TimoLehto 我知道这是 Rails 的想法。我非常不同意它,因为它鼓励使用包含大量当前页面范围不需要的代码的大型 JS/CSS 文件(并且可以说,小的、细粒度的文件更易于缓存)。在我自己的应用程序中,我基本上无视 Rails 的建议,使用细粒度的 JS 和 CSS。【参考方案5】:

您有两种可能的结构:第一种和第二种。 通过以下两个示例,您可以在 /assets/externals.js 公开一个包。 你可以javascript_include_tag这个包,但你也可以在你的application.js文件中要求它。

第一个

vendor/
├── assets
│   ├── javascripts
│   │   ├── externals.js
│   │   ├── modernizr-1.7.js
│   │   └── underscore-1.1.6.js
│   └── stylesheets
└── plugins

文件externals.js 包含:

//= require ./underscore-1.1.6.js
//= require ./modernizr-1.7.js

第二个

vendor/
├── assets
│   ├── javascripts
│   │   └── externals
│   │       ├── index.js
│   │       ├── modernizr-1.7.js
│   │       └── underscore-1.1.6.js
│   └── stylesheets
└── plugins

文件index.js 包含:

//= require ./underscore-1.1.6.js
//= require ./modernizr-1.7.js

【讨论】:

要补充一点,这让我很困惑;设置好外部组件后,您可以在 application.js 中使用简单的 //= require externals 或通过视图/布局中的 javascript_include_tag('externals') 引用它 Erf,我只是在我的帖子中添加了这些信息,但无论如何都是好的。比零更好地看到两倍。 :D 我试过这个,但是当我去 /assets/externals.js 我得到No route matches [GET] "/assets/externals.js" 那么有没有办法做到这一点而不必维护两个或多个清单文件?这似乎在很大程度上违背了 Rails 约定优于配置的方式,不是吗? 我不这么认为。无论如何,这里有一个只使用 require_tree 的技巧:您可以使用前缀命名文件:a_underscore-1.1.6.jsb_modernizr-1.7.js 等。

以上是关于Rails 3.1 资产管道和手动订购的 Javascript 需要的主要内容,如果未能解决你的问题,请参考以下文章

rails 3.1资产管道路由错误

用于 JavaScript 的 Rails 3.1 资产管道

Rails 3.1 资产管道供应商/资产文件夹组织

如何将dojo工具包与rails 3.1资产管道和coffeescript一起使用?

开发中的 rails 3.1 资产管道 css 缓存

Rails 3.1 资产管道 - 为啥我的图像没有为生产进行预编译?