为什么需要引入google closure
这边有一篇文章简单介绍了为什么要引入google closure,有兴趣的可看看。
什么是google closure
google closure,简称closure,由大明鼎鼎的google开发的网页前端套件,包括三个主要组件:
- closure compiler
- closure library
- closure templates
详细的介绍看吧,挺详细的。
之前有听到同事说使用closure的门槛相对其他js库较高,使用之后,我感觉这个可能没有什么可比性,因为closure 不仅仅是js库(js库主要是closure library),还包括完整的前端构建工具(closure library与closure compiler)。引入closure
感觉上从头开始构建网站前端项目要比维护旧的项目要容易,不会有太多的历史负担。但现实是大部分项目还是维护及扩展遗留代码居多,考虑到这个问题,让我们来面对它,以维护历史遗留项目者的角色来引入closure。
首先下载closure compiler与closure library,将这两个放入项目根目录build/lib/closure下,项目结构为:
js文件修改
closure里面的一个重要思想便是模块化,将相同功能部分代码切分成一个模块,每个模块放入一个js文件中(认为划分越细越好)。然后在每个模块中申明提供的模块包,以及依赖的模块包。
简单的例子:
goog.provide("a.b");\\输出模块goog.require("a");\\依赖模块当这些完成之后,下一步就是将js外联进html文件中,这里有两个模式(详情可参照这里 ),开发模式有两个js,发布模式只引入 编译的js。我目前工作的项目使用ssi脚本切换,示例如下:
编译环境工作设置
有些同学可能已从上面的截图看出,google closure编译依赖java、python,对于没java背景同学的可能有些犯怵(我不会^_^)。下面为不会设置java及python环境的前端同学简单介绍下在windows下的设置步骤。
首先,到java官网jdk,然后设置环境变量,依次打开,在我的电脑->属性->高级->环境变量->系统变量->Path,双击之后再变量值之后加上(如末尾没';'请加上';')jdk安装路径/bin,例如我的jdk在‘C:\Program Files\Java\jdk1.6.0_13’下,再加上‘C:\Program Files\Java\jdk1.6.0_13\bin’就好了。验证是否安装成功,在控制台下输入java -version就可查看jdk版本。 然后,安装pyhton,pyhton安装包,注意请下载2.7版的,3.3还有些问题。假设安装路径是D:\Python27,那么环境变量之后添加D:\Python27就可以了。验证,在控制台下输入命令python -v。现在我们具备了基本的工具环境,让我们一道开始体验closure提供的便利吧。
开发模式
在开发模式下,我们引入了两个js,一个为closure基础库base.js,这个文件中包含一些基本功能,如动态加载js文件功能。另一个为js内联脚本,引入最终使用的模块。在操作之前,首先说明下target.js文件所依赖模块的js文件是如何引入页面的。浏览器执行解释执行base.js时会在其同路径下找到deps.js,这个文件管理了项目中所以模块依赖关系已模块所在文件路径(相对于base.js),然后加载deps.js。然后执行target.js,当中,会计算出target.js所依赖的所有模块js文件(通过deps.js获知),并按照依赖顺序依次加载js文件。
从以上解释可看出,在开发模式下维护依赖及路径信息的deps.js相当于一个注册表的角色。closure中维护deps.js有一python脚本depswriter.py。使用命令格式为:
python depswriter.py --root {project_path} --output_file {project_path}/build/lib/closure/closure-library/deps.js参数说明: --output_file 如果设置,将替换标准的输出文件路径;
--root 需扫描的js文件路径,可设置多个;
--root_with_prefix 需扫描的js文件路径与前缀,使用‘\’分隔,扫描结果将在路径前加上前缀,可设置多个,(注意这个会与--root叠加,所以不要再这两个参数间有一样的扫描路径);在变更模块时,执行该脚本即可。以下是生成的deps.js示例:
goog.addDependency('../../../../build/lib/closure/closure-library/base.js', ['goog'], []);goog.addDependency('../../../../static/cftcaipiao/v1.0/i/js/cp_buy_bd.js', ['CP.Buy.cft.bd'], ['CP.Buy.bd.common', 'CP.Buy.cft.jc.common', 'CP.Buy.dto', 'CP.Buy.jc']);goog.addDependency('../../../../static/cftcaipiao/v1.0/i/js/cp_buy_bd_rqspf.js', ['CP.Buy.cft.bd.rqspf'], ['CP.Buy.bd.common', 'CP.Buy.cft.bd', 'CP.Buy.cft.hm', 'CP.Buy.cft.jc.common', 'CP.Buy.dto', 'CP.Buy.jc', 'CP.bonus', 'CP.bonus.jczq', 'CP.date']);
发布模式
发布时主要是将各模块js合并编译压缩成一个js文件,对于遗留项目来说,代码可能没有很好的规范,不能使用到closure编译器的所有功能。还好closure有分编译层级:
- WHITESPACE_ONLY 只合并空白字符及移除注释
- SIMPLE_OPTIMIZATIONS 重新组织代码,变量重命名
- ADVANCED_OPTIMIZATIONS 与SIMPLE_OPTIMIZATIONS相似,但提供了更灵活的控制选项
这三种编译层级的详细解释点。
closure也同时提供了python编译脚本,方便自动构建。使用命令如下:python closurebuilder.py --output_mode compiled --compiler_jar ../../closure-compiler/compiler.jar --output_file {path}/target.c.min.js --compiler_flags "--compilation_level=WHITESPACE_ONLY"参数说明: --output_mode 输出模式,有'list', 'script', 'compiled';
--compiler_jar closure compiler jar包路径;
--output_file 输出文件路径; --compiler_flags compiler编译参数,可设置多个;好了,差不多整个流程就算完成了。