Grunt使用2:自动化

记录一下前端自动化工具的使用, 慢慢结合起来用 逐步逃离这种刀耕火种一样的体力活儿…

一:手动grunt的补充:clean

1安装插件:

在工作目录安装插件:

1
npm install grunt-contrib-clean

2.Gruntfile.js

在工作目录新建:package.json文件,

1
2
3
4
5
6
7
8
9
grunt.initConfig({
......
/* 清理 */
clean: {
build: {
src: ["build/dest"] //删除build/dest目录
}
},
......

二:grunt里的变量

1.动态文件名

grunt的配置中,支持使用事先配好的变量. 语法类似jsp: <%= XXX%>

1
2
3
4
5
6
7
8
9
10
11
grunt.initConfig({
config: {
"name": "app2014",
"version": "0.1.0",
"author": "Rt",
"srcPath": "src",
"buildPath": "build/dest/",
"banner": '/*<%=config.name%> v<%=config.version%>:<%=grunt.template.today("yyyy-mm-dd,h:MM:ss TT")%>*/\n'
},
... ...

三:文件命中包含多个”点”的处理

1
2
3
4
5
6
7
8
9
10
11
files: [{
......
//ext: '<%=config.version%>.min.js', //可以在文件名加入版本号, 避免缓存
//rename是来处理文件名中有多个"点"的情况,如果用ext只会保留从左数第一个点之前的文件名,其余会被截掉
rename: function(dest, src) {
var folder = src.substring(0, src.lastIndexOf('/')),
filename = src.substring(src.lastIndexOf('/'), src.length);
filename = filename.substring(0, filename.lastIndexOf('.'));
return '<%=config.buildPath%>' + folder + filename + '.<%=config.version%>.js';
}
}]

四: 自动grunt

1安装插件:

在工作目录安装插件:

1
npm install grunt-contrib-watch

2.Gruntfile.js

1
2
3
4
5
6
7
8
grunt.initConfig({
... ...
/* 监控文件变化,自动执行任务 */
watch: {
files: ['<%=config.srcPath%>/**'],
tasks: ['js_min', 'css_min']
}
... ...

3.运行watch任务

在工作目录执行:
grunt watch
监视成功后, 控制台会输出: Running “watch” task Waiting…
一单js有改动, node就会自动执行之前安排好的任务

五: 完整配置文件

1.package.json

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/**
* 博文作者:ruantao1989{@}gmail.com
* 引自博客:ruantao.duapp.com/blog
*/
{
"name": "grunt",
"version": "0.1.0",
"author": "Rt",
"devDependencies": {
"grunt": "~0.4.2",
"grunt-contrib-uglify": "~0.2.7",
"grunt-contrib-concat": "~0.3.0",
"grunt-contrib-cssmin": "~0.5.0",
"grunt-contrib-jshint": "~0.6.0",
"grunt-contrib-imagemin": "~0.8.0",
"grunt-contrib-clean": "~0.5.0",
"grunt-contrib-watch": "~0.6.0"
}
}

2.Gruntfile.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
/**
* 博文作者:ruantao1989{@}gmail.com
* 引自博客:ruantao.duapp.com/blog
*/
module.exports = function(grunt) {
grunt.initConfig({
config: {
"name": "app2014",
"version": "0.1.0",
"author": "Rt",
"srcPath": "src",
"buildPath": "build/dest/",
"banner": '/*<%=config.name%> v<%=config.version%>:<%=grunt.template.today("yyyy-mm-dd,h:MM:ss TT")%>*/\n'
},
pkg: grunt.file.readJSON('package.json'),
/* js合并 */
concat: {
options: {
separator: ';',
stripBanners: true,
banner: '<%=config.banner%>'
},
js_build: {
files: [{
src: ['<%=config.srcPath%>/**/*.js'], //?匹配单个字符, *匹配任何字符, **是全部匹配
dest: '<%=config.buildPath%>build-all.<%=config.version%>.js' //输出目录
}]
}
},
/* 清理 */
clean: {
build: {
src: ["<%=config.buildPath%>"] //删除build/dest目录
}
},
/* js压缩 */
uglify: {
options: {
//min.js中头部的注释
banner: '<%=config.banner%>'
},
build: {
files: [{
expand: true, // Enable dynamic expansion.
cwd: '<%=config.srcPath%>', //路径是当前目录下的src文件夹
src: ['**/*.js', '!**/*.min.js'], //?匹配单个字符, *匹配任何字符, **是全部匹配
dest: '<%=config.buildPath%>', //输出目录
//ext: '<%=config.version%>.min.js', //可以在文件名加入版本号, 避免缓存
//rename是来处理文件名中有多个"点"的情况,如果用ext只会保留从左数第一个点之前的文件名,其余会被截掉
rename: function(dest, src) {
var folder = src.substring(0, src.lastIndexOf('/')),
filename = src.substring(src.lastIndexOf('/'), src.length);
filename = filename.substring(0, filename.lastIndexOf('.'));
return '<%=config.buildPath%>' + folder + filename + '.<%=config.version%>.js';
}
}]
}
},
/* css压缩 */
cssmin: {
options: {
keepSpecialComments: 0,
banner: '<%=config.banner%>'
},
build: {
files: [{
expand: true, // Enable dynamic expansion.
cwd: '<%=config.srcPath%>', //路径是当前目录下的src文件夹
src: ['**/*.css', '!**/*.min.css'], //?匹配单个字符, *匹配任何字符, **是全部匹配
dest: '<%=config.buildPath%>', //输出目录
//ext: '<%=config.version%>.min.js', //可以在文件名加入版本号, 避免缓存
rename: function(dest, src) {
var folder = src.substring(0, src.lastIndexOf('/')),
filename = src.substring(src.lastIndexOf('/'), src.length);
filename = filename.substring(0, filename.lastIndexOf('.'));
return '<%=config.buildPath%>' + folder + filename + '.<%=config.version%>.css';
}
}]
}
},
/* js校验 */
jshint: {
options: {},
all: ['<%=config.srcPath%>/**.js']
},
/* 图片压缩 */
imagemin: {
build: {
options: {
optimizationLevel: 3 //定义图片优化水平
},
files: [{
expand: true,
cwd: '<%=config.srcPath%>/img/',
src: ['**/*.{png,jpg,jpeg}'], // 优化目录下所有 png/jpg/jpeg 图片
dest: '<%=config.buildPath%>/img/' // 优化后的图片保存位置, 覆盖旧图片, 并且不作提示
}]
}
},
/* 监控文件变化,自动执行任务 */
watch: {
files: ['<%=config.srcPath%>/**'],
tasks: ['js_min', 'css_min']
}
});
// 载入插件
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-cssmin');
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-contrib-imagemin');
grunt.loadNpmTasks('grunt-contrib-clean');
grunt.loadNpmTasks('grunt-contrib-watch');
// 任务名称: 注意任务名称不能和插件名相同, 如不指定任务名称则默认是'default'
grunt.registerTask('js_concat', ["合并全部js文件"], ['concat:js_build']);
grunt.registerTask('all_clean', ["清除全部文件"], ['clean:build']);
grunt.registerTask('js_min', ["压缩js文件"], ['uglify:build']);
grunt.registerTask('css_min', ["压缩css文件"], ['cssmin:build']);
grunt.registerTask('js_test', ["js校验"], ['jshint:all']);
grunt.registerTask('img_min', ["无损压缩图片"], ['imagemin:build']);
grunt.registerTask('default', ["默认全部任务"], [ /*'concat',*/ 'clean:build', 'uglify:build', 'cssmin:build', 'imagemin:build']);
};