Gulp — 前端自动化构建工具

最近一直在重构公司的前端,感觉有些无能为力。
最大的问题就在于项目太乱了,加上经多人之手,变得更加难以维护。
我总结了下目前所遇到的问题:

  • CSS文件太臃肿,太多无用选择器,太多!important,media查询不合理等等。
  • 各种前端插件满天飞,真正用到的只是其中的一部分。
  • 前端项目目录结构紊乱。
  • html标签的不合理。
  • 网站前端和管理页面前端用的是两套ui框架,两套框架依赖的js库冗余。
  • js/css文件基本没有合并压缩过。
  • 太多的重复js文件,比如jquery.js,但是版本又不同。
  • seo优化的不好
  • 所有代码,包括js,css,php,代码书写没有规范。
  • 没有使用LESS/SASS预编译css。

本来想了很久,要怎么一一处理如上难题,有想过引入webpack,但是发现太难上手,自己没把握能完成,至少以目前的精力是没办法去完美的解决。
那怎么办呢,想来只能暂时用gulp,能修一点就修补一点。相对来说,gulp更加小巧灵活,可以一点点来。

tips: 用gulp之前,得先安装node

下面贴上gulpfile.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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
/**
* created by Joseph
*
**/


// 引入 gulp
var gulp = require('gulp');

var path = require('path');
var fs = require('fs');
// 引入插件
var jshint = require('gulp-jshint');
var sass = require('gulp-sass');
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');
var rename = require('gulp-rename');
var autoprefixer = require('gulp-autoprefixer');
var csso = require('gulp-csso');
var imagemin = require('gulp-imagemin');
var csslint = require('gulp-csslint');
var uncss = require('gulp-uncss');
var cssnano = require('gulp-cssnano');
var plumber = require('gulp-plumber');
var sourcemaps = require('gulp-sourcemaps');

var browserSync = require('browser-sync').create();
// 如果引入的插件多了,可用gulp-load-plugins来代替, 示例如下
// var gulpLoadPlugins = require('gulp-load-plugins'),
// plugins = gulpLoadPlugins();

// 把所有手动更改过的js文件压缩(合并)
// gulp.task('js', function () {
// gulp.src('assets/front/js/*.js')
// .pipe(plugins.jshint())
// .pipe(plugins.jshint.reporter('default')) // 对代码进行报错提示
// .pipe(plugins.uglify())
// .pipe(gulp.dest('dist/js'));
// });

var root = __dirname; // node中自带的项目运行根目录----》 /Applications/MAMP/htdocs/uf/develop
var paths = {
// 源路径
develop: {
front: {
css: path.join(root, "front/css/"), // node中自带的路径拼接
js: path.join(root, "front/js/"),
img: path.join(root, "front/images/"),
scss: path.join(root, "front/scss/")
}
},
// gulp输出路径
out: {
front: {
css: path.join(root, "../", "assets/front/css/"),
js: path.join(root, "../", "assets/front/js/"),
img: path.join(root, "../", "assets/front/images/"),
scss: path.join(root, "../", "assets/front/scss/")
}
},
// 项目根目录,即uf
uf: path.join(root, "../")
}
// 是否为生产环境
var env = {
production: false
}
gulp.task('set-production', function(){
env.production = true;
})
/****** 开发阶段 ******/

// server || proxy 浏览器实时刷新,编译scss等
gulp.task('serve', function() {

browserSync.init({
// server: "./uf"
proxy: "localhost/uf/"
});

// gulp.watch("app/scss/*.scss", ['sass']);
gulp.watch(path.join(root,"front/css/style.css"), ['style']);
gulp.watch(path.join(root,"front/js/uf-main.js"), ['uf-main']);
var watched = [];
var html = paths.uf + "source/app/views/*.html";
var css = paths.uf + "develop/front/css/*.css";
var js = paths.uf + "develop/front/js/*.js";
watched.push(html);
watched.push(css);
watched.push(js);
console.log(watched);
gulp.watch(watched).on('change', browserSync.reload);
});

// 编译Sass, 暂时不引入
gulp.task('sass', function() {
gulp.src('./scss/*.scss')
.pipe(plumber())
.pipe(sass())
.pipe(gulp.dest('./css'))
});


/****** 上线前打包 ******/

// 处理CSS

// style.css 语法检查 + 自动加前缀 + 压缩 + 改名
gulp.task('style', function() {
console.log(root); // /Applications/MAMP/htdocs/uf/develop
// 生产环境
if(env.production){
return gulp.src(path.join(root,"front/css/style.css"))
.pipe(plumber())
.pipe(sourcemaps.init())
.pipe(csslint())
.pipe(csslint.formatter())
.pipe(autoprefixer({
browsers: ['last 3 versions','last 3 Explorer versions','last 3 Safari versions','>1%']
}))
.pipe(cssnano())
.pipe(rename('style.min.css'))
.pipe(sourcemaps.write('../maps'))
.pipe(gulp.dest(paths.out.front.css))
.pipe(browserSync.stream());
}else {
return gulp.src(path.join(root,"front/css/style.css"))
// .pipe(csslint())
// .pipe(csslint.formatter())
.pipe(autoprefixer({
browsers: ['last 3 versions','last 3 Explorer versions','last 3 Safari versions','>1%']
}))
.pipe(rename('style.min.css'))
.pipe(gulp.dest(paths.out.front.css))
}

});

// 处理各css插件
gulp.task('css-task', function(){
var files = fs.readdirSync(paths.develop.front.css);
var css_files = [];
for(var i in files){
if(files[i].indexOf(".css") > -1 && files[i].indexOf(".min") < 0){ // 过滤非css文件,和已压缩过的css文件
css_files.push(files[i]);
}
}
for(var j in css_files){
gulp.src(path.join(paths.develop.front.css, css_files[j]))
.pipe(cssnano())
.pipe(rename({
suffix: ".min"
}))
.pipe(gulp.dest(paths.out.front.css))
}

})

// 压缩图片
gulp.task('imgmin', function() {
gulp.src(path.join(root,"front/images/*"))
.pipe(imagemin())
.pipe(gulp.dest(paths.out.front.img))
});

// 测试脚本用
gulp.task('test', function () {
console.log(paths.uf);
console.log("Testing...");
console.log(env.production);
// gulp.src(path.join(root,"front/css/style.css"))
// .pipe(autoprefixer({
// browsers: ['last 3 versions','last 3 Explorer versions','last 4 Safari versions','>1%'],
// cascade: true,
// remove: true
// }))
// .pipe(gulp.dest('dist'));
});


// js处理

// uf-main.js语法检查
gulp.task('uf-main', function() {
gulp.src(path.join(paths.develop.front.js,"uf-main.js"))
.pipe(sourcemaps.init())
.pipe(jshint())
.pipe(jshint.reporter('default'))
.pipe(uglify())
.pipe(rename({
suffix: ".min"
}))
.pipe(sourcemaps.write('../maps'))
.pipe(gulp.dest(paths.out.front.js))
.pipe(browserSync.stream());
});


// js压缩 + 重命名处理
gulp.task('jsmin', function(){
var files = fs.readdirSync(paths.develop.front.js); // node中读取该目录下的所有文件(包括文件夹)
var js_files = [];
for(var i in files){
if(files[i].indexOf(".js") > -1){
js_files.push(files[i]);
}
}
for(var j in js_files){
gulp.src(path.join(paths.develop.front.js, js_files[j]))
.pipe(uglify())
.pipe(rename({
suffix: ".min"

}))
.pipe(gulp.dest(paths.out.front.js));
}
});


// 监视文件的变化
gulp.task('watch', function(){
gulp.watch(path.join(paths.develop.front.js, "uf-main.js"), ['uf-main']);
gulp.watch(path.join(paths.develop.front.css, "style.css"), ['style'])
});


// 默认任务
gulp.task('default', ['test']);

// 开发环境任务
gulp.task('develop', ['serve','watch']);

// 上线环境任务
gulp.task('publish', ['set-production', 'style', 'uf-main', 'jsmin', 'css-task']);