gulp前端自动化

首先是目标,就是想要的效果.

  1. es6模块化并打包 gulp-babelify-browerify
  2. html中的js、css文件做优化处理加md5戳,并且自动替换
  3. 自动刷新

es6模块化并打包

因为es6的模块化只实现了export和import,并没有实现原生的模块化加载,所以最终还是需要使用AMD或者CMD的加载器来实现加载,这次我索性不在前端实现模块化加载,直接打包成一个文件。具体实现看之前写的文章gulp-babelify-browerify

html中的js、css文件做优化处理加md5戳,并且自动替换

这个地方想了很久,也试了很多方式。其实就是两种方法,一是从html中识别出静态文件,然后处理、替换。二是直接从原始目录中抽取出静态文件,然后自动插入html中,最后我想了下还是第一种好,因为我需要在src的html中自由的配置自己开发的、第三方库等文件。所以决定采用第一种方案。用到的插件有:

第一部分是从html中抽取静态资源并处理的

  1. gulp-useref是一个替换、合并、移除html中之前做好标记的的静态资源。
  2. gulp-if 对vinyl object中的内容识别js css分别处理
  3. gulp-rev给文件末尾添加hash值的,防止缓存。
  4. gulp-postcsscss处理器,这个插件本身不带功能,它需要插件配合使用,。
  5. postcss-import postcss插件,使用import功能来管理各个css文件
  6. autoprefixer postcss插件,自动添加兼容前缀比如webkit
  7. cssnano css压缩
  8. gulp-sourcemaps sourcemap,生成.map文件,用来对压缩后的文件进行线上调试的
  9. del 删除之前发布的文件用的

gulpfile中的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
gulp.task('rev',['clean','dis'], function(){
var revAll = new RevAll({

//不重命名文件
dontRenameFile: ['.html'] ,

//无需关联处理文件
dontGlobal: [ /^\/favicon.ico$/ ,'.bat','.txt']
});
var processors=[atImport,autoprefixer,minifycss()];

return gulp.src(['src/index.html'])
.pipe(useref())
.pipe(gulpif('*.css', postcss(processors)))
.pipe(gulpif('*.js',sourcemaps.init({ loadMaps: true })))
.pipe(sourcemaps.write('.'))
.pipe(revAll.revision())
.pipe(gulp.dest('./dist'));
});

第二部分是涉及到js开发的,因为要模块化开发,同时要打包,所以插件主要有

  1. browserify 模块化打包
  2. babel-core 顾名思义,但是没有任何功能,编译es2015需要下面这个插件
  3. babel-preset-es2015 preset包,主要用来预处理es2015的
  4. babelify 在browserify打包后,把es2015转换为es5
  5. vinyl-source-stream将 Node体系中的Stream 转换为gulp所使用的Vinyl File Object Stream
  6. vinyl-buffer 将Stream转成buffer,因为uglify和sourcemap需要buffer
  7. gulp-uglify js压缩

gulpfile中的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 打包 js
gulp.task("dis", ()=>{
return browserify('src/js/index.js')
.transform(babelify)
.bundle()
.pipe(source('bundle.js'))
.pipe(buffer())
.pipe(sourcemaps.init({ loadMaps: true }))
.pipe(uglify()) // Use any gulp plugins you want now
.pipe(sourcemaps.write('./'))
.pipe(gulp.dest('./src/js'));
});

// 同步sourcemap
gulp.task('copy',['dis'],()=>{
gulp.src('src/*.map').pipe(gulp.src('src/*.map'))
});

自动刷新

这部分就主要是用gulp-webserer启动一个本地服务器并且监听文件变化,文件变化了就自动刷新。webserver是监听发布的资源,所以要自己写一个监听src,然后触发发布,导致发布的文件发生变化,进而触发webserver自动更新。
用到的插件

  1. gulp-webserver
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    //监听src文件
    var watcher = gulp.watch(['src/**/*.*','src/index.html'], ['dis']);
    watcher.on('change', function(event) {
    console.log('File ' + event.path + ' was ' + event.type + ', running tasks...');
    });

    //web server
    gulp.task('webserver', ['rev'],() => {
    gulp.src('./dist/')
    .pipe(webserver({
    livereload: true,
    directoryListing: false,
    path: '/',
    open: '/'
    }));
    });

完整的gulpfile

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
import gulp from 'gulp';
import sourcemaps from "gulp-sourcemaps";
import babelify from "babelify";
import browserify from 'browserify';
import source from "vinyl-source-stream";
import uglify from 'gulp-uglify';
import buffer from 'vinyl-buffer';
import webserver from 'gulp-webserver';

import postcss from 'gulp-postcss';
import autoprefixer from 'autoprefixer';
import minifycss from 'cssnano';

import RevAll from 'gulp-rev-all';
import useref from 'gulp-useref';
import atImport from "postcss-import";
import gulpif from 'gulp-if';
import del from 'del';

var watcher = gulp.watch(['src/**/*.*','src/index.html'], ['dis']);

watcher.on('change', (event)=> {
console.log('File ' + event.path + ' was ' + event.type + ', running tasks...');
});

//清理dist目录
gulp.task('clean',()=>{
return del('dist/');
});

// 打包 js
gulp.task("dis",['clean'], ()=>{
return browserify('src/js/index.js')
.transform(babelify)
.bundle()
.pipe(source('bundle.js'))
.pipe(buffer())
.pipe(sourcemaps.init({ loadMaps: true }))
.pipe(uglify()) // Use any gulp plugins you want now
.pipe(sourcemaps.write('./'))
.pipe(gulp.dest('./src/js'));
});


//web server
gulp.task('webserver', ['rev'],() => {
gulp.src('./dist/')
.pipe(webserver({
livereload: true,
directoryListing: false,
port:8099,
path: '/',
open: '/'
}));
});


//默认任务
gulp.task('rev',['dis'], ()=>{
var revAll = new RevAll({
//不重命名文件
dontRenameFile: ['.html'] ,
//无需关联处理文件
dontGlobal: [ /^\/favicon.ico$/ ,'.bat','.txt']
});

var processors=[atImport,autoprefixer,minifycss()];

return gulp.src(['src/index.html'])
.pipe(useref())
.pipe(gulpif('*.css', postcss(processors)))
.pipe(gulpif('*.js',sourcemaps.init({ loadMaps: true })))
.pipe(sourcemaps.write('.'))
.pipe(revAll.revision())
.pipe(gulp.dest('./dist'));

});


gulp.task('default',['webserver'],()=>{

});

gulp插件更新很快,而且鱼龙混杂,官方有一个blacklist可供参考,同时有一个插件可以检测项目中是否使用了不合适的插件,blacklist-gulp