Web前端开发的持续构建环境的搭建,主要完成以下几个目标:
?
- 可以采用jslint/jshint对js代码进行检查,并能够输出报表。
- 能够运行js的UT,并输出报表。
- 能够采用minify工具,对js、css代码进行压缩、合并,输出部署的代码,并且压缩、合并后,能够自动处理HTMl页面中的引用。
- 以上所有的功能,能够集成到自动构建环境(jenkins)中自动执行,并且产生报表。
- 能够根据配置,自动构建测试版本、发布版本,并且自动部署到相应的服务器上。
具体实现如下:
实现概述:
采用Jenkins作为持续集成环境,采用ant作为构建工具,集成jslint4java, jsTestDriver, requriejs(r.js)来完成实际的构建工作,并把构建结果输出的指定的目录,Jenkins从指定的目录中读取结果并展示。
基础环境:
- Java
- Ant
- Jenkins
- Git(可以采用其他源码控制系统)
- Nodejs
源码目录结构:
?
采用jslint对js代码进行检查,并输出报表
- 下载jslint4java。 http://code.google.com/p/jslint4java/。 jslint4java是一个java对jslint工具的封装,可以通过java执行jslint对js代码进行检查。并且,此项目提供了ant task,可以直接ant中调用执行。
- 把下载的jar包(jslint4java-xxx.jar)放到build目录。
- 在Ant脚本中增加如下代码:
<taskdef name="jslint" classname="com.googlecode.jslint4java.ant.JSLintTask" classpath="./build/jslint4java-2.0.2.jar" /> <target name="jslint" depends="clean"> <mkdir dir="${stat.result.folder}/jslintOutput"></mkdir> <jslint failureProperty="false" haltOnFailure="false"> <formatter type="checkstyle" destfile="${stat.result.folder}/jslintOutput/jslintresult.xml"/> <fileset dir="scripts"> <include name="**/*.js"/> <exclude name="require.js"/> </fileset> </jslint> </target>
? ? 参考:http://docs.jslint4java.googlecode.com/git/2.0.1/ant.html
? ? 说明:实际上,是把jslint的检查结果输出成checkstyle的格式,Jenkins中有checkstyle插件可以读取这个格式
采用jsTestDriver执行js的UT
- 下载jsTestDriver。 http://code.google.com/p/js-test-driver/,把下载的jar包放到build目录。 jsTestDriver可以通过java,运行js编写的UT,并且可以同时指定多个浏览器运行环境同时运行。
- 编写jsTestDriver的配置文件,放到build目录
server: http://localhost:9876 load: - ../scripts/*.js - ../scripts-test/*.js?
? ? 3. ?在ant中,采用java task调用 jsTestDriver来运行编写的ut
<target name="jsut" depends="clean"> <mkdir dir="${stat.result.folder}/jsUTOutput"></mkdir> <java jar="build/JsTestDriver-1.3.4.b.jar" fork="true" failonerror="true"> <arg value="--port"/> <arg value="9876"/> <arg value="--config"/> <arg value="build/jsTestDriver.conf"/> <arg value="--browser"/> <arg value="C:\Users\juns6831.CHN\AppData\Local\Google\Chrome\Application\chrome.exe"/> <arg value="--tests"/> <arg value="all"/> <arg value="--testOutput"/> <arg value="${stat.result.folder}/jsUTOutput"/> </java> </target>
? ?说明:jsTestDriver的运行输出的结果是junit格式的,Jenkins的Junit插件可以读取此结果。
采用requriejs的optimizer来压缩js, css
- 下载requirejs.js,放到scripts目录。下载r.js,放到build目录。 http://requirejs.org/。目前,有很多js的minify工具,但是采用这些工具压缩、合并js代码后,html中的js、css引用不容易修改。采用requriejs来管理js代码,会比较容易处理这种情况。
- 编写minify.bat,执行js, css代码的压缩
node r.js -o name=main out=../%1/scripts/main.js baseUrl=../scripts node r.js -o cssIn=../css/main.css out=../%1/css/main.css optimizeCss="standard.keepLines"
? ? ?3. ?采用ant的exec task,调用minify.bat,执行压缩
<target name="minify" depends="clean"> <exec executable="cmd" osfamily="windows" dir="build" failonerror="true"> <arg value="/c"/> <arg value="minify.bat"/> <arg value="${target.folder}"/> <arg value="-p"/> </exec> </target>?
HTML、JS、CSS代码
index.html(根目录)
<!DOCTYPE html> <html> <head> <title>My Sample Project</title> <script data-main="scripts/main" src="scripts/require.js"></script> </head> <body> <h1>My Sample Project</h1> </body> </html>
?JS代码(scripts目录)
main.js
require(["helper/util"], function(util) { //This function is called when scripts/helper/util.js is loaded. //If util.js calls define(), then this function is not fired until //util's dependencies have loaded, and the util argument will hold //the module value for "helper/util". console.log("util js loaded."); console.log(util.a + ',' + util.b); });
?GreatTest.js
GreeterTest = TestCase("GreeterTest"); GreeterTest.prototype.testGreet = function() { var greeter = new myapp.Greeter(); assertEquals("Hello World!", greeter.greet("World")); jstestdriver.console.log("JsTestDriver", greeter.greet("World")); console.log(greeter.greet("Browser", "World")); }; GreeterTest.prototype.testGreet3 = function() { var greeter = new myapp.Greeter(); assertEquals("Hello World!", greeter.greet("World3")); jstestdriver.console.log("JsTestDriver", greeter.greet("World3")); console.log(greeter.greet("Browser", "World3")); }; GreeterTest2 = TestCase("GreeterTest2"); GreeterTest2.prototype.testGreet2 = function() { var greeter = new myapp.Greeter(); assertEquals("Hello World2!", greeter.greet("World2")); jstestdriver.console.log("JsTestDriver", greeter.greet("World2")); console.log(greeter.greet("Browser", "World2")); };
?main.css
@import url("common.css"); body{ color:red }
?common.css
body{ font-size:14px; }
Ant脚本
<project name="js build" default="install" basedir="."> <property name="target.folder" value="target" /> <property name="stat.result.folder" value="stat-result" /> <property name="tomcat.webapp" value="D:\apache-tomcat-6.0.32\webapps"></property> <taskdef name="jslint" classname="com.googlecode.jslint4java.ant.JSLintTask" classpath="./build/jslint4java-2.0.2.jar" /> <target name="jslint" depends="clean"> <mkdir dir="${stat.result.folder}/jslintOutput"></mkdir> <jslint failureProperty="false" haltOnFailure="false"> <formatter type="checkstyle" destfile="${stat.result.folder}/jslintOutput/jslintresult.xml"/> <fileset dir="scripts"> <include name="**/*.js"/> <exclude name="require.js"/> </fileset> </jslint> </target> <target name="jsut" depends="clean"> <mkdir dir="${stat.result.folder}/jsUTOutput"></mkdir> <java jar="build/JsTestDriver-1.3.4.b.jar" fork="true" failonerror="true"> <arg value="--port"/> <arg value="9876"/> <arg value="--config"/> <arg value="build/jsTestDriver.conf"/> <arg value="--browser"/> <arg value="C:\Users\juns6831.CHN\AppData\Local\Google\Chrome\Application\chrome.exe"/> <arg value="--tests"/> <arg value="all"/> <arg value="--testOutput"/> <arg value="${stat.result.folder}/jsUTOutput"/> </java> </target> <target name="minify" depends="clean"> <exec executable="cmd" osfamily="windows" dir="build" failonerror="true"> <arg value="/c"/> <arg value="minify.bat"/> <arg value="${target.folder}"/> <arg value="-p"/> </exec> </target> <target name="build" depends="jslint,jsut,minify"> <copy todir="${target.folder}"> <fileset dir="${basedir}"> <include name="*.html"></include> </fileset> </copy> <copy file="scripts/require.js" todir="${target.folder}/scripts"></copy> </target> <target name="install" depends="build"> <mkdir dir="${tomcat.webapp}/jsci"></mkdir> <copy todir="${tomcat.webapp}/jsci"> <fileset dir="${target.folder}"></fileset> </copy> </target> <target name="clean"> <delete dir="${target.folder}"></delete> <delete dir="${tomcat.webapp}/jsci"></delete> <delete dir="${stat.result.folder}"></delete> </target> </project>?
安装Jenkins插件
- Git plugin
- checkstyle plugin
- ant, junit plugin在安装jenkins是已经自动安装
创建Jenkins项目
- 配置SCM。Git的仓库地址,分支名称(master)
- 配置调用ant
- 选中“ Publish Checkstyle analysis results?”,文件地址输入"stat-result/jslintOutput/*.xml"
- 选中“ Publish JUnit test result report?”,文件地址输入“stat-result/jsUTOutput/*.xml”
- 保存。
- 运行Jenkins构建,可以在项目的主页上看到UT, jslint的运行结果,可以在target目录下面看到完整的压缩、合并后的js、css代码,和HTML代码。
?