JavaScript 单个页面才需要的 js 你们一般怎么安排?

ywencn · 2012年11月22日 · 最后由 MaFai 回复于 2012年11月28日 · 4787 次阅读

随便举个例子, 假如是 app/assets/javascripts/aaa.js 然后只有aaa.html.erb需要 最重要的是,里面有一段类似

$(document).ready(function() {
    update_something();
});

这种ready后就要执行的东西。 而rails会把所有的js合在一起,那么别的页面上运行这个update_something()的时候就会报错。 大家一般怎么处理?

  1. 把这个js拿出去不合并?
  2. update_something之前加个判断如果这个页面上有什么东西再执行update_something?
共收到 25 条回复

不合在一起…… 或者 //= require_directory .

问个问题,js 如何区分当前的运行环境是development 还是 production 呢?大家都是怎么做的?

我是拿出去,结果就是很多页面都需要单独引入,也很纠结

#2楼 @fresh_fish 拿楼主的 app/assets/javascripts/aaa.js 做例子,文件名改成 aaa.js.erb,然后就可以在文件里面 <%= Rails.env.production? ? 'serious' : 'crazy' %> 了

另一种方式就是页面提供一个全局变量,在 View 里头用 <%= javascript_tag %> 输出出来,然后在 js 代码中判断就行

#3楼 @suupic 可以在application.js中用 require_directory . 代替 require_tree. 这样就只引用javascript目录下的js文件,而不引用子目录中的文件,然后把个别页面需要用到的js放到一个新建子目录中

#5楼 @keating 那岂不是precompile里要加一堆东西?

#6楼 @ywencn 之前的项目一直没有precompile……

我们是这样做的: 每个单独的界面 (不是页面)都给一个独立 ID。为这个界面创一个独立文件。

  1. 侦测 DOM ID 是否存在
  2. 如果存在,执行初始界面的函数
  3. 函数应该是只有文件闭包可见

CoffeeScript 大概是这个架构

# my-widget.js.coffee
id = "my-widget"
if $(id).length > 0
  init($(id))

init = ($e) ->
 # your code here

asset-pipeline 我们分成两个档案,一个叫 libs.coffee, 一个叫 apps.coffee

libs 包含 jquery, jquery-ui, underscore, backbone 等等不常变动的文件。

app 包含所有应用的文件。

这样可以帮助缓存。libs 几乎不会变, app 每次变动需要用户更新。目前我们的 libs 大概有 70~80kb gzipped-compressed, app 大概只有 5~6kb

#9楼 @hayeah 你的Libs和apps分开的方法看起来不错。 但是前面那个判断如果比较多的话,会不会影响游览器性能?还是我想多了?

#10楼 @ywencn 多是什么概念? 我们大概 10 个上下吧?

@hayeah 我们也是这么做的

$(document).ready ->
    return true if $("#id").length == 0

    ......

以 Controller 为主,一个 Controller 一个 JS 文件,就算某些独立页面需要的,也统一放到 Controller 的 JS 里面

分开目录,不要加载tree,在layout上留个<%= yield :js %>

layout上加<%= yield :js %> aaa.html.erb上加這個

<%= content_for :js do %>
  <%= javascript_include_tag "aaa" %>
<% end %>

我一直是分开的,目录类似

├── site
│   └── works.js
└── modules
    └── avatar.js

modules 下放公共的 js 模块 site 下放实际页面中引用的 js ,并且通常是 per action 的,例如我的项目里有个 work 类型,则在它的列表页会有 works.js, 在详情页有 work.js,表单页则是 work_form.js (因为 new 和 edit 页面都会要)

然后,在 config/application.rb 里,记得告诉 sprocket 压缩 site 下的文件:

config.assets.precompile += [/site\/\w+\.js/]

土办法: 把页面专用的 js 写成一个 partial ...

#10楼 @ywencn js虽说速度是慢了点,不过简单判断一万次都用不了一秒。 我也是比较喜欢function跟调用function的分开,这样感觉rails既可以整合在一个文件里面,另外调用function在同个js文件中,只需要加上简单的注释,就可以知道这个界面调用到那些函数,debug起来也是比较方便。

谢谢楼上各位!

大家都是自己写 css, js 的吗? 我们公司有 UED 组,都没有用到 assets

我和@huacnlee 的做法是类似,基本上也是按照controller分类,我会更细一点,基本上保证上服务器以后,application.js编译一个文件,然后再有针对当前页面的独立的js编译成另一个文件

#21楼 @pzgz #16楼 @dotnil #9楼 @hayeah #15楼 @fizzwu #12楼 @jonny 谢谢各位,要是这里也有v2ex那种感谢的按钮我就挨个点一下

#20楼 @tumayun 我在鄙公司担任的主要职务就是 UED,不过我可以放到 assets,自然也会用 Asset Pipeline 哈哈

@dotnil 跨部门沟通起来就比较麻烦了,我们这边很难实现

我的方法,另外开了张贴 http://ruby-china.org/topics/7145

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