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

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

随便举个例子, 假如是 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?

不合在一起…… 或者 //= 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

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