JavaScript dependency management and concatenation

Web项目中都会有很多的JavaScript引用及压缩合并的问题,同事在邮件组里有问及此事。

首先,回顾一下,JavaScript中的一些场景。

  • JavaScript文件合并。
  • 在生产环境下对JavaScript进行压缩。
  • 文件组织方式。
  • JavaScript在不同页面重复引用。
  • 不同环境使用不同策略。
  • 通过HTTP能进行压缩和过期的配置。
  • 很好的缓存支持。
  • 页面嵌入标签。
  • 支持Web Farm。
  • 命令行支持。

####SPROCKETS

先来介绍下Sprockets,这是基于Ruby语言的JavaScript依赖管理的库,并在Rials 3.1中成为官方使用类库。本篇也会基于该库中所使用的方式来讨论有关JavaScript/CSS的压缩、合并管理。
关于Sprockets,点击这里,Ryan也有一篇关于Rails3 中Asset Pipeline的流程介绍,这里查看

####文件合并

MSN时使用的是一种很通用的手法,通过concatenation的文件来配置js/css的合并策略,支持单文件和目录,以及非选项,并设有默认配置。对MSBuild的target进行改写,添加Concatenation的功能。当然FCity也在使用文件配置的方式,然后用脚本来进行合并。

Sprockets中则是将配置写在一个JS文件中,通过//=的语法来进行引用,同样支持tree 和dicrtory。

####压缩

压缩主要是发生在生产环境,这一步是最好做的,通过在CI Server的Scripts就可以搞定。Sprockets在Rails中则是请求到达时进行判断,然后启用压缩合并。

####文件组织方式

虽然通过配置文件理论对文件存放位置没有要求,但实际上,好的命名和路径很容易理解和查找,并在合并时减少代码行数。现实的隐喻也要求将相似功能代码放在一处。

之所以提起这个点,是因为大多数的库都是以目录来进行管理(约定胜于配置)。参见Knapsack,Sprockets中则针对3种场景设置不同目录/app/asset; /lib/asset/; /verdor/asset; 分别对应本项目,公共类库,第三方类库。每个目录下都有对应的JavaScript/CSS/Images目录。Sprockets会依次查找相应目录来取资源,清晰明了。

####重复引用

一个文件在任何时候都应该只被引用一次,压缩时更应做判断,之前碰到过该问题,在压缩时将一个文件引入两次导至一些Bug。

####不同环境的不同压缩合并策略

合并一般是在全部环境下的,至少Sprockets是这样认为的,但压缩却只是应用在生产环境。刚才提到过,无论是在测试环境还是生产环境,这种事情都很容易实现,毕竟这些自动化的步骤放在CI Server上每次被重复执行的成本很低,但在开发人员本地的话,合并就是一个小问题,每次修改好的JavaScript如何被直接使用?现行的方式是在页面使用前用脚本来进行合并,恩,很挫的方式。我们计划在VS里加入一个功能,每当修改JS/CSS文件时进行自动脚本合并。但这样就太依赖于VS了,不喜欢。好办法还得继续想。

####通过HTTP进行配置

在启用合并压缩后,一旦线上出了问题,调试是一件非常痛苦的事情。所以要有一种方式,支持Site启用非压缩合并的文件集。在页面中会是单个的文件,便于调试和分析问题。

因为是线上环境,通过修改配置不大实际,通常的做法是在HTTP请求中加入参数来开启该项功能。

参加HTML5大会了,未完