如果你的前端项目很小或都者项目不需要通过专门的运维同学走流水线上线部署的话,那么可以略过以下的繁文。

ok,Let's go! 我们看看如何使用grunt来部署上线项目?
前端项目一般分为两种类型:The first,纯静态页面,都是html,类似WebApp(当然也有很多动态页面的WEBAPP); The second,包含一些动态页面,如jsp、php、 asp.net 或者是一些别的web服务语言。
由于第二种类型的前端的项目居多,那么我们先从第二种类型的项目上入手,使用grunt来操作项目的部署:
首先我们的目录假设为

有两个目录,一个src,用来放置我们源码,(使用GIT或SVN等版本管理器只需要维护src这个目录和项目根目录中的其它文件,如Gruntfile.js、package.json)。另外一个目录是release目录,用来存放针对src目录中的代码合并、压缩、添加指纹、发布的最终输出代码。(也就是线上代码)
Gruntfile任务操作
我们在这里先介绍最基本的任务:合并、JS混淆压缩、CSS压缩、清除、添加指纹、替换页面中的静态资源引用。
step 1:
安装grunt包和任务插件;
grunt包安装 : npm install grunt --save-dev
合并插件:npm install grunt-contrib-concat --save-dev
按照上面的插件的安装方式继续安装其它插件
JS混淆压缩 :grunt-contrib-uglify
CSS压缩:grunt-contrib-cssmin
清除:grunt-contrib-clean
添加指纹:grunt-rev
替换页面中的静态资源引用 :grunt-contrib-levin-usemin
或者根据已有的package.json文件中的devDependencies依赖项进行一次安装
npm install
step 2:
完成step1后,会在项目的根目录中生成一个node_modules的包,所有的插件还有grunt都在这个包下。

接下来我们完善Gruntfile.js文件中的任务
先定义一个配置变量,可在后续的任务中直接使用
config :{
static_dest:'release/main/webapp/static/union/'
},
合并任务,将release/js/文件夹下的两个js文件合并为build.js
concat:{
lib:{
files:{
'<%= config.static_dest %>js/build.js':[
'<%= config.static_dest %>js/zepto.min.js',
'<%= config.static_dest %>js/slip-min.js'
]
}
}
},
混淆压缩任务,将release/js/文件夹下的所有js文件进行混淆压缩
uglify:{
options:{
banner:'/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> */\n'
},
my_target:{
files:[
{
expand:true,
cwd:'<%= config.static_dest %>js/',
src:'*.js',
dest:'<%= config.static_dest %>js/'
}
]
} },
css压缩任务,将release/css/文件夹下的所有css文件进行压缩
cssmin:{
options:{
banner:'/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> */\n',
beautify:{
ascii_only:true
}
},
my_target:{
files:[{
expand:true,
cwd:'<%= config.static_dest %>css/',
src:'*.css',
dest:'<%= config.static_dest %>css/'
}]
}
},
消除任务,将release/js/文件夹下不合并之前的js文件清除
clean:[
"<%= config.static_dest %>js/zepto.min.js",
"<%= config.static_dest %>js/slip-min.js"
],
添加指纹任务,将release/目录下的静态资源添加指纹(添加指纹是根据静态文件的内容生成md5其中的8位字符,所以同学们不用担心更新某一个静态文件,会导致别的静态文件的指纹发生变化)
rev: {
options: {
encoding: 'utf8',
algorithm: 'md5',
length: 8
},
assets: {
files: [{
src: [
'<%= config.static_dest %>img/**/*.{jpg,jpeg,gif,png}',
'<%= config.static_dest %>css/*.css',
'<%= config.static_dest %>js/**/*.js'
]
}]
}
},
替换动态页面中的静态文件引用任务(针对静态资源引用的地址进行替换,如果有同学需要使用CDN前缀地址的话,那么大家可以使用我发布的一个grunt插件grunt-contrib-levin-usemin,这个插件大家可以用其它插件的安装方法去安装,与grunt-usemin插件不同的地方是我加了一个替换方法filePrefixer,github地址:https://github.com/levincao1/grunt-contrib-levin-usemin/)
usemin:{
css:{
files:{
src:['<%= config.static_dest %>css/*.css']
}
},
js:['<%= config.static_dest %>js/**/*.js'],
html:['<%= config.views_dest %>**/*.jsp','<%= config.views_dest %>*.jsp'],
options:{
//替换静态文件引地址前缀
filePrefixer:function(url){
if(!url){
return '';
}
return url.replace('../..','<%=request.getContextPath()%>');
},
patterns: {
js: [
[/(img\.png)/, 'Replacing reference to image.png']
]
}
}
}
声明一个发布的task
grunt.registerTask('release',['concat','uglify','clean','cssmin','rev','usemin']);
运维同学添加的编译脚本build.sh
#!/bin/bash /bin/rm -rf release &&\
mkdir release && \
cp -r src/* release/ &&\
#执行grunt发布的release任务
grunt release
发布结果
通过运维的发布脚本会生成一个release目录(也就是我们上面指到的release目录)再执行grunt发布命令操作release目录下的静态资源
比较一下发布前
发布后的静态资源
动态页面中的静态资源引用发布前的

发布后的
