首页 > 代码库 > gulp快速入门

gulp快速入门

Gulp是基于流的前端自动化构建工具

使用步骤:

1.安装node和npm

  访问国外服务器网速不好时,安装依赖模块时会缺少文件。可以安装国内的镜像,之后使用cnpm命令代替npm命令。

  npm install cnpm -g --registry=https://registry.npm.taobao.org

2.全局安装gulp

  $npm install -g gulp

  查看gulp的版本:$gulp –v

  结果:cli version -3.0.2为全局安装,local version-3.0.2 为本地安装。

3.在项目根目录新建package.json文件

  $npm ini

  按提示输入相关配置信息即可

4.本地安装gulp

  $npm install gulp  --save-dev

  $npm install [<@scope>/]<name>@<version>

  卸载插件:npm uninstall <name> [-g] [--save-dev];(直接删除文件会报错)

5. 安装gulp的相关插件

  $npm install module-name -save 自动把模块和版本号添加到package.json的dependencies部分

  $npm install gulp-less -save-dve自动把模块和版本号添加到package.json的devdependencies部分

6. 编写gulpfile.js文件定义执行的任务

  在项目根目录下创建gulpfile.js文件,里面定义需要执行的任务。同时新建一个发布目录,和开发目录分开,专门存放处理好的静态资源,将来发布时直接将发布目录下的所有文件拷到服务器即可。

7.运行gulf任务

  CLI执行方式,默认执行gulpfile.js中的任务:$gulp  defaultTask

  如果任务不在项目根目录的gulpfile.js中定义,需要手动指定gulpfile的路径,如下所示:

   $gulp  minifyCssTask  --gulpfile  ./child/task.js

  webstorm开发工具中:右键点击gulpfile.js,选择”Show Gulp Tasks”

常用命令:

$npm install gulp –g

安装到全局环境里面,包安装在Node安装目录下的node_modules文件夹中,一般在 \Users\用户名\AppData\Roaming\ npm\目录下,可以使用npm root -g查看全局安装目录。用户可以在命令行中直接运行该模块包支持的命令。

$npm install gulp --save-dev

包安装在指定项目的node_modules文件夹下,把安装包的信息写入package.json文件的devDependencies字段中。

gulp常用方法

1. gulp.src(globs[, options])
src方法是按照指定的路径将源文件转为Vinyl fs并输出至别的插件。gulp借鉴了Unix操作系统的管道(pipe)思想,前一级的输出,直接变成后一级的输入,类似jQuery的链式操作。当前Node项目的根路径用’./’表示,或者直接从和gulpfile.js平级的目录开始,’/’表示的是盘符根目录。

globs:匹配符合特定规则的文件路径,类型为字符串或字符串组成的数组

glob匹配规则:

*:匹配0个或多个字符,但不会匹配路径分隔符,除非路径分隔符出现在末尾。*结尾时可以匹配到路径分隔符不会被匹配到

 "js/*.js":获取js目录下的所有js文件;
 "js/*":获取js目录下的所有文件,不能匹配子目录下的文件

**:可以匹配路径分隔符,用于匹配0个或多个子目录,需要单独出现。如果出现在末尾,还能匹配任意文件。

   "js/**/*.js":匹配 js 目录及子目录下所有js文件,如 js/a.js 或 js/a/b/c/d.js。

? :匹配文件路径中的一个字符,不会匹配到路径分隔符,也不能匹配空字符

    "js/a?.js"能匹配 js/ab.js,不能匹配 js/a.js。

[...]
 :匹配指定范围内的一个字符,如果指定范围的首字符是 ! 或 ^,则为匹配不在指定范围内一个字符。

    "js/a[0-3].js":获取js目录下以a开头,第二个字符为0-3之间的js文件。

   "js/[^ab].js"匹配 js/c.js,不匹配 js/cb.js、js/ac.js。

!(pattern|pattern|pattern) : 匹配(完全且精确地匹配,且不可组合)不符合任何模型之一的字符。注意 | 前后不能有空格,下同。

    "js/!(a|b).js"匹配 js 目录下的 aa.js、ab.js、ba.js、c.js 不匹配 a.js、b.js。
    "!src/a.js" : 不包含src下的a.js文件;

?(pattern|pattern|pattern):匹配多个 pattern 中 0 或 1 个(精确匹配,不可以组合)。

    "js/?(a|b).js"匹配 js 目录下的 a.js、b.js,不匹配 ab.js

+(pattern|pattern|pattern) : 至少匹配多个 pattern 中的一个。与*(pattern|pattern|pattern) 不用的是,它必须1个及以上,不能为空。

     "js/+(a|b)b.js"匹配 js 目录下的 ab.js、bb.js、ababab.js,不能匹配 abcd.js(也就是说:只允许匹配出现在范围内的字符) ,也不能像 js/*(a|b)b.js 那样匹配 b.js。

*(a|b|c) : 匹配括号中多个 pattern 中0或任意多个(pattern可相互组合)。

     "js/*(a|b|c).js"匹配 js 目录下的 a.js、ab.js、abc.js、ba.js,不匹配 abcd.js(也就是说:只允许匹配出现在范围内的字符)。

@(pattern|pattern|pattern) 匹配多个 pattern 中的任意一个(即不可以组合,且不能为空或大于1个)。与 ?(pattern|pattern|pattern) 区别是不可为空。

      "js/@(a|b)b.js"匹配 js 目录下的 ab.js、bb.js,不匹配 b.js、abb.js、abc.js。

{}:匹配多个属性

    src/{a,b}.js匹配a.js和b.js文件,src/*.{jpg,png,gif}匹配src下所有jpg/png/gif文件

!:排除文件,当有多种匹配模式时可以使用数组,注意先后顺序,后面的规则会覆盖前面的。

  gulp.src([*.js,‘!b*.js‘]) //匹配所有js文件,但排除掉以b开头的js文件

options: 控制文件流和输出路径,可选配置。

options.buffer:是否以buffer形式返回file.content,默认是true。

options.read:是否读取该文件,fals返回的file.content为null,默认为true。

options.base:用于切除输入流的路径,base指定的部分路径将不作为dest的输入路径,base默认值为第一个glob规则之前的所有路径。

gulp.src(‘client/js/**/*.js‘) // `**/*.js`为glob规则,默认的base为`client/js/`
  .pipe(minify())
  .pipe(gulp.dest(‘build‘));  //输出‘build/somedir/somefile.js‘,base部分client/js/被省略
 
gulp.src(‘client/js/tools/helper.js‘) // `helper.js`为glob规则,默认的base为client/js/tools/
  .pipe(minify())
  .pipe(gulp.dest(‘build‘));  // Writes ‘build/helper.js‘
//如果要保留之前的目录结构,使用{base:’.’},输出build/client/js/tools/helper.js`
 
gulp.src(‘client/js/**/*.js‘, { base: ‘client‘ })
  .pipe(minify())
  .pipe(gulp.dest(‘build‘));  // 输出‘build/js/somedir/somefile.js‘
2.gulp.dest(path[, options])

dest方法将操作完成后的文件流输出到指定目录。可以pipe到多个文件夹,如果某个文件夹不存在,会自动创建它。只能指定路径,不能指定文件名。文件名采用源文件的名字。

文件被输出的路径是以dest()所给的目标路径根据src()相对路径计算而来,src()的base参数会改变输出路径。

path: 指定文件的输出路径,参数类型为字符串或函数。当前项目根目录以’./’表示。

3.gulp.task(name[, deps], fn)

task定义一个gulp任务

name: 指定任务的名称,参数类型为String,名字中不要有空格,将来可以直接运行;

deps:  该任务依赖的任务(被依赖的任务需要return当前任务的事件流),[String]

fn: 执行该任务的具体操作,如果省略,则只完成依赖的任务。fn通常为调用对应插件的方法,不一定在所有依赖的任务完成后才执行,格式如下:

gulp.task(‘buildStuff‘, [‘taskOne’,’taskTwo’],function() {
  // Do something that "builds stuff"
  var stream = gulp.src(/*some source path*/)
  .pipe(somePlugin())
  .pipe(someOtherPlugin())
  .pipe(gulp.dest(/*some destination*/));
  return stream;      //返回才能有先后顺序,否则为并行    
  //taskOne/taskTwo的fn方法中需要返回流对象/Promise对象或使用cb,并在deps中声明,才能保证当前的操作在依赖的任务完成后执行
  });

deps为多个任务时,默认的gulp会一次性同时运行所有的task并且不做任何等待,执行的顺序没有保证。如果需要严格按照顺序执行,需要特别处理(如上所述,前一个任务返回特定对象并当前任务声明依赖前一个任务)

4.gulp.watch(glob [, opts], tasks)或gulp.watch(glob [, opts, cb])

watch方法是用于监听指定文件的变化,文件一修改就会执行指定的任务或回调函数
glob:需要处理的源文件通配符路径。

opts:类型(可选):Object 具体参看https://github.com/shama/gaze;

tasks:需要执行的任务的名称数组;

cb(event):文件变化时执行的回调函数,event对象描述了所监控到的变动

event.type:发生的变动的类型:added, changed 或者 deleted。

event.path:触发了该事件的文件的路径。

gulp.watch(‘js/**/*.js‘, [‘uglify‘,‘reload‘]);

gulp.watch(‘js/**/*.js‘, function(event) {

  console.log(‘File ‘ + event.path + ‘ was ‘ + event.type);

});

Node的stream有4种,Readable只读)、Writable只写)、Duplex双向)、Transform(操作被写入数据,然后读出结果)。但是Node的stream只处理内容,没有办法处理目录相关的操作。所以gulp使用的是Vinyl File Object Stream,Vinyl主要用路径path)和内容contents)两个属性来描述文件。

可以用vinyl-source-stream把普通的Node Stream转换为Vinyl File Object Stream,在gulp内使用。

//引入工具包
var gulp = require(‘gulp‘); //加载本地gulp
var jshint = require("gulp-jshint");    //js代码检查
var less = require("gulp-less");    //编译less文件生成css文件
var cssMinify = require(‘gulp-clean-css‘);  //压缩css文件
var concat = require("gulp-concat");//将多个js文件合并为一个
var uglify = require("gulp-uglify");//将js文件压缩,如果js有语法错误,任务会终止
var rename = require("gulp-rename");//将文件重命名,参数为String/fn,可以在文件名前配置输出路径
var del = require("del");   //删除文件,原生的Node模块,也需要install
//在编译文件之前删除上次一些不必要的文件,如上次build的temp文件等
gulp.task(‘clean:mobile‘, function (cb) {   //cb是gulp传入的回调函数
  del([
    ‘./src/mobile/**/*‘,    // 删除`mobile`目录中的所有文件及目录;若以文件后缀结尾,目录会保存
    ‘!./src/mobile/deploy.json‘  // 不希望删掉的这个文件
  ], cb);
});
//编译less,压缩css
gulp.task(‘less‘, function () {
    gulp.src("./src/less/**/*.less")   
        .pipe(less())   //调用less模块,将less文件编译为css文件,文件名不变
        .pipe(cssMinify(
              {
          compatibility: ‘ie9,-properties.ieFilters‘, //兼容ie9以上,不保留滤镜
                 debug:true
               },
               function (detail){
                 console.log(details.name + ‘: ‘ + details.stats.originalSize);
                  console.log(details.name + ‘: ‘ + details.stats.minifiedSize);
         }
      ))  //将css文件压缩
        .pipe(gulp.dest("./build/css"));    //输出目录
});
//检查脚本语法
gulp.task(‘jshint‘, function () {
    return gulp.src(‘./src/js/**/*.js‘)
            .pipe(jshint())     //检查js语法
            .pipe(jshint.reporter(‘default‘));  //对错误进行提示
});
//合并js,并压缩
gulp.task(‘scripts‘,[‘jshint‘], function () {
    gulp.src(‘./src/js/**/*.js‘)
        .pipe(concat(‘all.js‘))     //合并后的文件名字
        .pipe(gulp.dest(‘./dest‘))  //合并后的输出目录
        .pipe(rename("all.min.js"))     //将文件重命名
        .pipe(uglify().on(‘error‘, function(e){console.log(e);}))           //压缩问价。添加error事件,如果报错,可以缩小查找范围
        .pipe(gulp.dest("./build"))
});
//default执行全部依赖的任务
gulp.task(‘default‘,[‘clean:mobile‘,‘less‘,‘scripts‘]);

gulp快速入门