前端构建工具gulp使用教程(二)、常用gulp插件以及gulp使用完整实例

gulp的插件数量虽然没有grunt那么多,但也可以说是应有尽有了,下面列举一些常用的插件。

一、常用插件使用说明

1、自动加载插件

使用gulp-load-plugins。详细教程请参考https://github.com/jackfranklin/gulp-load-plugins
安装:npm install --save-dev gulp-load-plugins
要使用gulp的插件,首先得用require来把插件加载进来,如果我们要使用的插件非常多,那我们的gulpfile.js文件开头可能就会是这个样子的:

var gulp = require('gulp'),
    //一些gulp插件,abcd这些命名只是用来举个例子
    a = require('gulp-a'), 
    b = require('gulp-b'),
    c = require('gulp-c'),
    d = require('gulp-d'),
    e = require('gulp-e'),
    f = require('gulp-f'),
    g = require('gulp-g'),
    //更多的插件...
    z = require('gulp-z');   

虽然这没什么问题,但会使我们的gulpfile.js文件变得很冗长,看上去不那么舒服。gulp-load-plugins插件正是用来解决这个问题。
gulp-load-plugins这个插件能自动帮你加载package.json文件里的gulp插件。例如假设你的package.json文件里的依赖是这样的:

{
  "devDependencies": {
    "gulp": "~3.6.0",
    "gulp-rename": "~1.2.0",
    "gulp-ruby-sass": "~0.4.3",
    "gulp-load-plugins": "~0.5.1"
  }
}

然后我们可以在gulpfile.js中使用gulp-load-plugins来帮我们加载插件:

var gulp = require('gulp');
//加载gulp-load-plugins插件,并马上运行它
var plugins = require('gulp-load-plugins')();

然后我们要使用gulp-rename和gulp-ruby-sass这两个插件的时候,就可以使用plugins.rename和plugins.rubySass来代替了,也就是原始插件名去掉gulp-前缀,之后再转换为驼峰命名。
实质上gulp-load-plugins是为我们做了如下的转换

plugins.rename = require('gulp-rename');
plugins.rubySass = require('gulp-ruby-sass');

gulp-load-plugins并不会一开始就加载所有package.json里的gulp插件,而是在我们需要用到某个插件的时候,才去加载那个插件。
最后要提醒的一点是,因为gulp-load-plugins是通过你的package.json文件来加载插件的,所以必须要保证你需要自动加载的插件已经写入到了package.json文件里,并且这些插件都是已经安装好了的。

2、重命名
使用gulp-rename。详细教程请参考https://www.npmjs.com/package/gulp-rename。
安装:npm install --save-dev gulp-rename
用来重命名文件流中的文件。用gulp.dest()方法写入文件时,文件名使用的是文件流中的文件名,如果要想改变文件名,那可以在之前用gulp-rename插件来改变文件流中的文件名。

var gulp = require('gulp'),
    rename = require('gulp-rename'),
    uglify = require("gulp-uglify");
 
gulp.task('rename', function () {
    gulp.src('js/jquery.js')
    .pipe(uglify())  //压缩
    .pipe(rename('jquery.min.js')) //会将jquery.js重命名为jquery.min.js
    .pipe(gulp.dest('js'));
});

3、js文件压缩
使用gulp-uglify。用来压缩js文件,使用的是uglify引擎。详细教程请参考:https://github.com/terinjokes/gulp-uglify
安装:npm install --save-dev gulp-uglify

var gulp = require('gulp'),
    uglify = require("gulp-uglify");
 
gulp.task('minify-js', function () {
    gulp.src(['static/**/*.js', '!**/.min.js'], {allowEmpty: true}) // 要压缩的js文件
    .pipe(uglify())  //使用uglify进行压缩,更多配置请参考:
    .pipe(gulp.dest('static')); //压缩后的路径
});

4、css文件压缩
使用gulp-clean-css来压缩js文件。详细教程请参考https://github.com/scniro/gulp-clean-css。不要用gulp-minify-css,这个插件官方已经不推荐使用。

前端构建工具gulp使用教程(二)、常用gulp插件以及gulp使用完整实例_第1张图片
安装:npm install --save-dev gulp-clean-css

var gulp = require('gulp'),
    cleanCss = require("gulp-clean-css");
 
gulp.task('minify-css', function () {
    gulp.src(['static/**/*.css', '!static/**/*.min.css'],  {allowEmpty: true}) // 要压缩的css文件
    .pipe(cleanCss()) //压缩css
    .pipe(gulp.dest('static'));
});

用上面这段代码压缩,会发现CSS中图片相对路径会被更改。比如压缩前:background('../../../image/bg.jpg'),压缩后却变成background(../image/bg.jpg)。
这个的处理方案是调用cleanCss()时将rebase参数设置为false。

gulp.task('minify-css', function () {
    gulp.src(['static/**/*.css', '!static/**/*.min.css'],  {allowEmpty: true}) // 要压缩的css文件
    .pipe(cleanCss({
        rebase: false
    })) //压缩css
    .pipe(gulp.dest('static'));
});

gulp-clean-css实际上是利用了clean-css插件。所以在使用过程中有问题,也可以去github clean-css去寻找解决方案。访问地址:https://github.com/jakubpawlowicz/clean-css#formatting-options
5、html文件压缩
使用gulp-htmlmin。用来压缩html文件。详细教程请参考https://github.com/jonschlinkert/gulp-htmlmin
安装:npm install --save-dev gulp-htmlmin

var gulp = require('gulp'),
    htmlmin = require("gulp-htmlmin");
 
gulp.task('minify-html', function () {
    gulp.src('[static/**/*.html', '!**/*.min.html'], {allowEmpty: true}) // 要压缩的html文件
    .pipe(htmlmin ()) //压缩
    .pipe(gulp.dest('static'));
});

6、修改文件版本号,并且在html引入时对应修改

静态文件css、js如果不修改版本号,浏览器访问时可能会从缓存中获取。因此需要实现修改静态文件的版本号,并且页面引入时url也要对应修改。
使用gulp-rev、gulp-rev-collector。通过gulp-rev可以修改css、js文件的版本号,gulp-revCollector是实现在html修改引入文件路径。详细教程请参考https://www.npmjs.com/package/gulp-rev、https://www.npmjs.com/package/gulp-rev-collector

6.1 安装和使用
安装:npm install --save-dev gulp-rev gulp-rev-collector
下面这个实例还用到了merge-stream,也要先安装:npm install --save-dev merge-stream。

var gulp = require('gulp'),
    rev = require('gulp-rev'),
    revCollector = require('gulp-rev-collector'),
    merge = require('merge-stream');
/*修改css、js文件版本号*/
gulp.task('rev', function(){
    var revJS = gulp.src(['static/lib/*.js'], {allowEmpty:true})
      .pipe(rev())
      .pipe(gulp.dest('static'))
      .pipe(rev.manifest())
      .pipe(gulp.dest('rev/js'));
    var revCSS = gulp.src(['static/css/*.css'], {allowEmpty:true})
      .pipe(rev())
      .pipe(gulp.dest('static'))
      .pipe(rev.manifest()) //默认名称是rev-manifest.json。也可以自己设置名称入rev.manifest('test.json')
      .pipe(gulp.dest('rev/css'));
    return merge(revJS, revCSS);
});

/*改变html引用路径*/
gulp.task('revCollector', gulp.series('rev', function(){
    return gulp.src(['rev/**/*.json','static/index.html']) //数组第一个元素是文件版本号映射文件(修改前和修改后文件路径对应关系),后面是需要修改引用路径的文件。
      .pipe(revCollector({
          replaceReved: true //必须设为true。表示已经替换过的文件还可以进行替换
      }))
      .pipe(gulp.dest('static'));
}));

6.2 gulp-rev-collector参数说明

gulp-rev-collector部分参数:

1、replaceReved 
设置replaceReved标识, 用来说明模板中已经被替换的文件是否还能再被替换,默认是false

2、dirReplacements 
标识目录替换的集合

3、revSuffix 
定义reved files 文件的后缀, 默认值是:’-[0-9a-f]{8,10}-?’, 如果使用gulp-rename给文件加版本的话, 这个配置就是必要的了。

dirReplacements设定要替换的目录。比如rev-manifest.json文件如下:

{
    'vue.js': 'vue-12345678.js'
}

设定dirReplacements如下:

gulp.task('revCollector', gulp.series('rev', function(){
    return gulp.src(['rev/**/*.json','static/index.html'])
      .pipe(revCollector({
          replaceReved: true,
          dirReplacements: {
              'lib': 'static/lib'
              'js': 'static/js'
          }
      }))
      .pipe(gulp.dest('static'));
}));

那么index.html引入文件版本替换结果如下:

  
  
  

6.3、文件加版本号方式修改

通过gulp-rev和gulp-rev-collector实现加版本号,其实相当于是修改文件名字。如果希望是在文件真的只是改动版本号,可以更改gulp-rev和gulp-rev-collector。这个我还没实践过,这里是直接参考https://www.cnblogs.com/anxiaoyu/p/6526360.html的解决方案。

1)更改gulp-rev

修改node_modules\gulp-rev\index.js:

第144行 manifest[originalFile] = revisionedFile;

更新为: manifest[originalFile] = originalFile + '?v=' + file.revHash;

修改node_modules\rev-path\index.js

10行 return filename + '-' + hash + ext;

更新为: return filename + ext;

修改node_modules\gulp-rev-collector\index.js

31行 if ( !_.isString(json[key]) || path.basename(json[key]).replace(new RegExp( opts.revSuffix ), '' ) !==  path.basename(key) ) {

更新为: if ( !_.isString(json[key]) || path.basename(json[key]).split('?')[0] !== path.basename(key) ) {

修改node_modules\gulp-assets-rev\index.js

78行 var verStr = (options.verConnecter || "-") + md5;

更新为:var verStr = (options.verConnecter || "") + md5;

80行 src = src.replace(verStr, '').replace(/(\.[^\.]+)$/, verStr + "$1");

更新为:src=src+"?v="+verStr;

2) 继续更改gulp-rev-collector

修改node_modules\gulp-rev-collector\index.js

第107行 regexp: new RegExp( '([\/\\\\\'"])' + pattern, 'g' ),

更新为: regexp: new RegExp( '([\/\\\\\'"])' + pattern+'(\\?v=\\w{10})?', 'g' )

再次运行就能成功了

改变单个文件的内容,再次运行gulp,发现版本号又改变了

7、处理多个文件流
上面修改版本号实例中用到了merge-stream插件,这个插件用于实现处理多个文件流。任务里面一般只有一个gulp.src,通过调用merge-stream就多次调用gulp.src,对多个文件流进行处理。详细教程请查看https://www.npmjs.com/package/merge-stream
安装:npm install --save-dev merge-stream
实例:见上面第6节的实例。

8、 js代码检查

1)gulp-jshint安装和使用
使用gulp-jshint来进行js代码的检查。详细教程请参考https://www.npmjs.com/package/gulp-jshint
安装:npm install --save-dev gulp-jshint
用来检查js代码

var gulp = require('gulp'),
    jshint = require("gulp-jshint");
 
gulp.task('jsLint', function () {
    gulp.src('js/*.js')
    .pipe(jshint())
    .pipe(jshint.reporter()); // 输出检查结果
});

2)使用gulp-jshint抛出错误

Gulp Error: Cannot find module 'jshint/src/cli';

问题原因:插件安装不完全,好像是gulp4.0做了一些调整

解决方法:使用npm install --save-dev jshint gulp-jshint

9、文件合并
使用gulp-concat。
安装:npm install --save-dev gulp-concat
用来把多个文件合并为一个文件,我们可以用它来合并js或css文件等,这样就能减少页面的http请求数了

var gulp = require('gulp'),
    concat = require("gulp-concat");
 
gulp.task('concat', function () {
    gulp.src('js/*.js')  //要合并的文件
    .pipe(concat('all.js'))  // 合并匹配到的js文件并命名为 "all.js"
    .pipe(gulp.dest('dist/js'));
});

10、less编译
less使用gulp-less安装:npm install --save-dev gulp-less

var gulp = require('gulp'),
    less = require("gulp-less");
 
gulp.task('compile-less', function () {
    gulp.src('less/*.less')
    .pipe(less())
    .pipe(gulp.dest('dist/css'));
});

11 sass编译
11.1 gulp-sass安装

gulp-sass安装:npm install --save-dev gulp-sass
gulp-sass详细教程请参考https://github.com/dlmanning/gulp-sass#readme

1)安装问题1(通过代理安装引入的问题)
第一个问题是因为公司不支持上外网,要通过代理安装。但是对于比较大的文件通过代理安装似乎会有问题。

> [email protected] install E:\Workspace_WebStorm\angular2\node_modules\angular-cli\node_modules\node-sass
> node scripts/install.js

Downloading binary from https://github.com/sass/node-sass/releases/download/v4.5.0/win32-x64-51_binding.node
Cannot download "https://github.com/sass/node-sass/releases/download/v4.5.0/win32-x64-51_binding.node":

解决方式就是从https://github.com/sass/node-sass/releases/download/v3.8.0/win32-x64-46_binding.node下载win32-x64-46_binding.node。
下载完了之后把它注册成全局环境变量,两种方式:
第一种:直接右键我的电脑--》属性--》高级系统设置--》环境变量--》添加用户变量,添加 SASS_BINARY_PATH,值为F:\lishiming\tools\node-sass\win32-x64-46_binding.node。
第二种:set XXX=文件路经--》set SASS_BINARY_PATH=F:\lishiming\tools\node-sass\win32-x64-46_binding.node。但是这种方式只是临时变量。cmd关闭后就不起作用了
检测环境变量是否更改成功,可以在cmd中输入echo %SASS_BINARY_PATH%,如果打印的是配置值那就ok了

2)安装问题2:找不到node-sass下面的某些文件等问题

如果出现下面这种情况:

Error: ENOENT: no such file or directory, scandir '{PATH}\node-sass\vendor'
    at Error (native)
    at Object.fs.readdirSync (fs.js:856:18)
    at Object.getInstalledBinaries ({PATH}\node_modules\.npminstall\node-sass\3.7.0\node-sass\lib\extensions.js:74:13)
    at foundBinariesList ({PATH}\node_modules\.npminstall\node-sass\3.7.0\node-sass\lib\errors.js:20:15)
    at foundBinaries ({PATH}\node_modules\.npminstall\node-sass\3.7.0\node-sass\lib\errors.js:15:5)
    at Object.module.exports.missingBinary ({PATH}\node_modules\.npminstall\node-sass\3.7.0\node-sass\lib\errors.js:45:5)
    at Object. ({PATH}\node_modules\.npminstall\node-sass\3.7.0\node-sass\lib\index.js:14:28)
    at Module._compile (module.js:413:34)
    ......

或者出现这种情况

Run `npm rebuild node-sass` to build the binding for your current environment.
    at module.exports ({PATH}\node_modules\node-sass\lib\binding.js:
15:13)
    at Object. ({PATH}\node_modules\node-sass\lib\index.j
s:14:35)
    at Module._compile (module.js:435:26)
    at Object.Module._extensions..js (module.js:442:10)
    ......

打开cmd执行以下命令即可:

npm rebuild node-sass

11.2 gulp-sass使用

var gulp = require('gulp'),
    sass = require("gulp-sass");
 
gulp.task('compile-sass', function () {
    gulp.src('static/sass/*.sass')
    .pipe(sass())
    .pipe(gulp.dest('static/css'));
});

12、 图片压缩

1)安装和使用

可以使用gulp-imagemin插件来压缩jpg、png、gif等图片。详细教程请参考https://www.npmjs.com/package/gulp-imagemin
安装:npm install --save-dev gulp-imagemin

var gulp = require('gulp');
var imagemin = require('gulp-imagemin');
var pngquant = require('imagemin-pngquant'); //png图片压缩插件

gulp.task('default', function () {
    return gulp.src('src/images/*')
        .pipe(imagemin({
            progressive: true,
            use: [pngquant()] //使用pngquant来压缩png图片
        }))
        .pipe(gulp.dest('dist'));
});

gulp-imagemin的使用比较复杂一点,而且它本身也有很多插件,建议去它的项目主页看看文档。
2)安装遇到问题

在家里联网安装gulp-imagemin,能够正常安装。但是公司通过代理安装,出现错误如下:

node lib/install.js tunneling socket could not be established,statusCode=400

这个问题尚未解决,需要后续再关注。

13、自动刷新
使用gulp-livereload插件,安装:npm install --save-dev gulp-livereload。
当代码变化时,它可以帮我们自动刷新页面
该插件最好配合谷歌浏览器来使用,且要安装livereload chrome extension扩展插件,不能下载的请自行FQ。

var gulp = require('gulp'),
    less = require('gulp-less'),
    livereload = require('gulp-livereload');

gulp.task('less', function() {
  gulp.src('less/*.less')
    .pipe(less())
    .pipe(gulp.dest('css'))
    .pipe(livereload());
});

gulp.task('watch', function() {
  livereload.listen(); //要在这里调用listen()方法
  gulp.watch('less/*.less', ['less']);

二、gulp使用完整实例

1、实例说明
实例下载地址:链接:https://pan.baidu.com/s/1i2I9xdaEiDpI1BZjX62dvg 提取码:z32f 
项目大致目录结构如下。把gulp相关配置放在tool目录下。

gulpProject
    |--css
    |--js
    |--lib
    |--pages
    |--router
    |--store
    |--tool
        |--package.json   
        |--gulpfile.js  
        |--.babelrc 
        |--gulp_package.bat   

下载实例后进行解压,项目具体内容先不用管。
1)首先确认gulp已经全局安装。
2)打开cmd,切换到tool目录下后,执行以下命令

npm install

3)双击gulp_package.bat执行打包任务。执行完后tool目录下有个static目录,那就是打包出来的文件。
(注意:gulp.package.bat刚开始文件名是gulp.bat,结果出现导致死循环。所以文件名不要改成gulp.bat)

2、实例gulpfile.js主要内容

var gulp = require('gulp'),
    uglify = require('gulp-uglify'), //压缩js代码
    cleanCss = require('gulp-clean-css'), //压缩css代码
    htmlmin = require('gulp-htmlmin'),
    rename = require('gulp-rename'), //重命名
    clean = require('gulp-clean'),  //清理档案
    imagemin = require('gulp-imagemin'),
    rev = require('gulp-rev'),
    revCollector = require('gulp-rev-collector'),
    babel = require('gulp-babel');
    merge = require('merge-stream');
    
//删除文件夹
gulp.task('clean', function(){
   //read设置为false可以加快删除进度
   return gulp.src(['static', 'rev'], {read:false, allowEmpty: true}).pipe(clean());
});

//复制文件夹
gulp.task('copy', function(){
   //将父级目录下的static文件夹复制到当前目录下,但是当前文件夹不复制
   return gulp.src(['../**', '!**'], {allowEmpty: true})
    .pipe(gulp.dest("static"));
});

//处理css代码的任务
gulp.task('css',function(){
  return gulp.src('static/**/*.css')
    .pipe(cleanCss())
    .pipe(gulp.dest('static'));
});

//js代码的处理
gulp.task('js', gulp.series(function(){
  return gulp.src(['static/**/*.js', '!**/*.min.js'], {allowEmpty: true})
    .pipe(babel())
    .pipe(uglify()) 
    .pipe(gulp.dest('static'))
}));

//html代码的处理
gulp.task('html', gulp.series(function(){
  return gulp.src(['static/**/*.html', '!**/*.min.html'], {allowEmpty: true})
    .pipe(clean())
    .pipe(htmlmin({
      collapseWhitespace: true,
      removeComments: true
    }));
}));

//图片压缩
gulp.task("imagemin",function() {
    return gulp.src("static/image/*", {allowEmpty: true})
        .pipe(imagemin([
            imagemin.gifsicle({interlaced: true}),
            imagemin.jpegtran({progressive: true}),
            imagemin.optipng({optimizationLevel: 5}),
            imagemin.svgo({
                plugins: [
                    {removeViewBox: true},
                    {cleanupIDs: false}
                ]
            })
        ]))
    .pipe(gulp.dest("static/image"))
});

//给文件加版本号
gulp.task('rev', function() {
    return gulp.src(['rev/**/rev-manifest.json', 'static/*.html', 'router/router.js'])
        .pipe(revCollector({
            replaceReved: true,//允许替换, 已经被替换过的文件            
            dirReplacements: { //rev-manifest.json包含了需要替换版本的文件信息。但是没有限定文件是哪个目录下的。这里设置了目录,将会从这些目录下去查找文件
              '/': '/', 
            }
        }))
        .pipe(gulp.dest('static'));
});

/*修改css、js文件版本号*/
gulp.task('rev', function(){
    var revJS = gulp.src(['static/lib/*.js'], {allowEmpty:true})
      .pipe(rev())
      .pipe(gulp.dest('static/lib'))
      .pipe(rev.manifest())
      .pipe(gulp.dest('rev/js'));
    var revCSS = gulp.src(['static/css/*.css'], {allowEmpty:true})
      .pipe(rev())
      .pipe(gulp.dest('static/css/'))
      .pipe(rev.manifest()) //默认名称是rev-manifest.json。也可以自己设置名称入rev.manifest('test.json')
      .pipe(gulp.dest('rev/css'));
    return merge(revJS, revCSS);
});
 
/*改变html引用路径*/
gulp.task('revCollector', gulp.series('rev', function(){
    return gulp.src(['rev/**/*.json','static/index.html']) //数组第一个元素是文件版本号映射文件(修改前和修改后文件路径对应关系),后面是需要修改引用路径的文件。
      .pipe(revCollector({
          replaceReved: true //必须设为true。表示已经替换过的文件还可以进行替换
      }))
      .pipe(gulp.dest('static'));
}));

//配置默认的任务
gulp.task('default', gulp.series('clean', 'copy', 'css', 'js', 'html', 'imagemin', 'revCollector', function(done){
  done();
}));

三、参考文章
1、前端构建工具gulpjs的使用介绍及技巧:https://www.cnblogs.com/2050/p/4198792.html#!comments
2、修改静态资源版本号时可以对应更新url:http://www.cnblogs.com/lakeInHeart/p/7257443.html

你可能感兴趣的:(前端构建工具)