进修前端自动化构建东西Gulp

Gulp是什么?

gulp是前端开辟历程当中一种基于的代码构建东西,是自动化项目的构建利器;她不仅能对网站资本举行优化,而且能帮我们完成前端开辟历程当中的许多反复的使命,运用它,能够大大提高我们的开辟效力。

gulp是基于NodeJs的自动使命运转器,她能自动化的完成JavaScript、coffee、sass、less、html/img、css等文件的测试、搜检、兼并、紧缩、格式化、浏览器自动革新、布置文件天生,并监听文件修改后反复这些步骤。在完成上,她自创了Unix操纵系统的管道头脑,前一级的输出,直接变成后一级的输入,使得在操纵上异常简朴。

什么是流?

,简朴来讲就是竖立在面向对象基本上的一种笼统的数据处置惩罚东西。在流中,定义了一些处置惩罚数据的基本操纵,如读取数据,写入数据等,程序员是对流举行一切操纵的,而不必体贴流的另一头数据的真正流向。流不只能够处置惩罚文件,还能够处置惩罚动态内存、收集数据等多种数据情势。

gulp恰是经由历程流和代码优于设置的战略来只管简化使命编写的事变。当运用流时,gulp去除了中心文件,只将末了的输出写入磁盘,全部历程因而变得更快。

Gulp的特性

  • 易于运用:经由历程代码优于设置的战略,gulp 让简朴的使命简朴,庞杂的使命可治理。

  • 构建疾速:运用 Node.js 流的威力,你能够疾速构建项目并削减频仍的 IO 操纵。

  • 易于进修:经由历程起码的 API,掌握 gulp 毫不费力,构建事变尽在掌握:犹如一系列流管道。

  • 插件高质:gulp 严厉的插件指南确保插件如你希冀的那样简约高质得事变。

装置

起首全局装置gulp:

npm install -g gulp

全局装置gulp后,还须要在每一个要运用gulp的项目中都零丁装置一次。把目次切换到你的项目文件夹中,然后在敕令行中实行:

npm install gulp

假如想在装置的时刻把gulp写进项目package.json文件的依靠中,则能够加上--save-dev

npm install --save-dev gulp

如许就完成了gulp的装置,接下来就能够在项目中运用gulp了。

gulp的运用

一、竖立gulpfile.js文件

gulp也须要一个文件作为它的主文件,在gulp中这个文件叫做gulpfile.js。新建一个文件名为gulpfile.js的文件,然后放到你的项目目次中。以后要做的事变就是在gulpfile.js文件中定义我们的使命了。下面是一个最简朴的gulpfile.js文件内容示例,它定义了一个默许的使命。

var gulp = require('gulp');
gulp.task('default',function(){
    console.log('hello world');
});

二、运转gulp使命

要运转gulp使命,只需切换到寄存gulpfile.js文件的目次(windows平台请运用cmd或许Power Shell等东西),然后在敕令行中实行gulp敕令就好了,gulp背面能够加上要实行的使定名,比方gulp task1,假如没有指定使定名,则会实行使定名为default的默许使命。

事变体式格局

在引见gulp API之前,我们起首来讲一下gulp.js事变体式格局。在gulp中,运用的是Nodejs中的stream(流),起首猎取到须要的stream,然后能够经由历程stream的pipe()要领把流导入到你想要的处所,比方gulp的插件中,经由插件处置惩罚后的流又能够继承导入到其他插件中,固然也能够把流写入到文件中。所以gulp是以stream为序言的,它不须要频仍的天生临时文件,这也是我们运用gulp的一个缘由。

gulp的运用流程平常是:起首经由历程gulp.src()要领猎取到想要处置惩罚的文件流,然后把文件流经由历程pipe要领导入到gulp的插件中,末了把经由插件处置惩罚后的流再经由历程pipe要领导入到gulp.dest()中,gulp.dest()要领则把流中的内容写入到文件中。比方:

var gulp = require('gulp');
gulp.src('script/jquery.js')         // 猎取流的api
    .pipe(gulp.dest('dist/foo.js')); // 写放文件的api

接下来我们将为人人解说gulp api,包含gulp.src(),gulp.task(),gulp.dest(),gulp.watch(),gulp.run()

src

gulp.src()要领恰是用来猎取流的,但要注重这个流里的内容不是原始的文件流,而是一个假造文件对象流(Vinyl files),这个假造文件对象中存储着原始文件的途径、文件名、内容等信息。其语法为:

gulp.src(globs[, options]);

globs参数是文件婚配形式(相似正则表达式),用来婚配文件途径(包含文件名),固然这里也能够直接指定某个详细的文件途径。当有多个婚配形式时,该参数能够为一个数组;范例为StringArray
当有多种婚配形式时能够运用数组:

//运用数组的体式格局来婚配多种文件
gulp.src(['js/*.js','css/*.css','*.html'])

options为可选参数。以下为options的选项参数:

options.buffer
范例: Boolean 默许值: true
  假如该项被设置为 false,那末将会以 stream 体式格局返回 file.contents 而不是文件 buffer 的情势。这在处置惩罚一些大文件的时刻将会很有用。注重:插件能够并不会完成对 stream 的支撑

options.read

范例: Boolean 默许值: true

假如该项被设置为 false, 那末 file.contents 会返回空值(null),也就是并不会去读取文件。

options.base

范例: String , 设置输出途径以某个途径的某个组成部分为基本向后拼接。

如, 请想像一下在一个途径为 client/js/somedir 的目次中,有一个文件叫 somefile.js

gulp.src('client/js/**/*.js') // 婚配 'client/js/somedir/somefile.js' 如今 `base` 的值为 `client/js/`
  .pipe(minify())
  .pipe(gulp.dest('build'));  // 写入 'build/somedir/somefile.js' 将`client/js/`替换为build
 
gulp.src('client/js/**/*.js', { base: 'client' }) // base 的值为 'client'
  .pipe(minify())
  .pipe(gulp.dest('build'));  // 写入 'build/js/somedir/somefile.js' 将`client`替换为build

dest

gulp.dest()要领是用来写文件的,其语法为:

gulp.dest(path[,options])

path为写入文件的途径;

options为一个可选的参数对象,以下为选项参数:

options.cwd

范例: String 默许值: process.cwd()

输出目次的 cwd 参数,只在所给的输出目次是相对途径时刻有用。

options.mode

范例: String 默许值: 0777

八进制权限字符,用以定义一切在输出目次中所建立的目次的权限。

var gulp = require('gulp');
gulp.src('script/jquery.js')        // 猎取流
    .pipe(gulp.dest('dist/foo.js')); // 写放文件

下面再说说天生的文件途径与我们给gulp.dest()要领传入的途径参数之间的关联。   
gulp.dest(path)天生的文件途径是我们传入的path参数背面再加上gulp.src()中有通配符最先涌现的那部分途径。比方:

var gulp = reruire('gulp');
//有通配符最先涌现的那部分途径为 **/*.js
gulp.src('script/**/*.js')
    .pipe(gulp.dest('dist')); //末了天生的文件途径为 dist/**/*.js
//假如 **/*.js 婚配到的文件为 jquery/jquery.js ,则天生的文件途径为 dist/jquery/jquery.js

gulp.dest()把文件流写入文件后,文件流依然能够继承运用。

watch

gulp.watch()用来看管文件的变化,当文件发生变化后,我们能够运用它来实行响应的使命,比方文件紧缩等。其语法为:

gulp.watch(glob[, opts], tasks); 

glob 为要看管的文件婚配形式,划定规矩和用法与gulp.src()要领中的glob雷同。 opts 为一个可选的设置对象,一般不须要用到。 tasks 为文件变化后要实行的使命,为一个数组。

gulp.task('uglify',function(){
  //do something
});
gulp.task('reload',function(){
  //do something
});
gulp.watch('js/**/*.js', ['uglify','reload']);

gulp.watch()另有别的一种运用体式格局:

gulp.watch(glob[, opts, cb]);

globopts参数与第一种用法雷同;

cb参数为一个函数。每当看管的文件发生变化时,就会挪用这个函数,而且会给它传入一个对象,该对象包含了文件变化的一些信息,type属性为变化的范例,能够是added,changed,deletedpath属性为发生变化的文件的途径。

gulp.watch('js/**/*.js', function(event){
    console.log(event.type); //变化范例 added为新增,deleted为删除,changed为转变 
    console.log(event.path); //变化的文件的途径
}); 

task

gulp.task要领用来定义使命,内部运用的是Orchestrator(用于排序、实行使命和最大并发依靠关联的模块),其语法为:

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

name 为使定名;

deps 是当前定义的使命须要依靠的其他使命,为一个数组。当前定义的使命会在一切依靠的使命实行终了后才最先实行。假如没有依靠,则可省略这个参数;

fn 为使命函数,我们把使命要实行的代码都写在内里。该参数也是可选的。

当你定义一个简朴的使命时,须要传入使定名字实行函数两个属性。

gulp.task('greet', function () {
   console.log('Hello world!');
});

实行gulp greet的效果就是在掌握台上打印出“Hello world”。

  你也能够定义一个在gulp最先运转时刻默许实行的使命,并将这个使命定名为“default”:

gulp.task('default', function () {
   // Your default task
});

前面已引见了gulp.task的语法,然则当有多个使命时,须要晓得怎样来掌握使命的实行递次。

  能够经由历程使命依靠来完成。比方我想要实行one,two,three这三个使命,那我们就能够定义一个空的使命,然后把那三个使命当作这个空的使命的依靠就好了:

//只需实行default使命,就相当于把one,two,three这三个使命实行了
gulp.task('default',['one','two','three']);

假如使命相互之间没有依靠,使命就会按你誊写的递次来实行,假如有依靠的话则会先实行依靠的使命。然则假如某个使命所依靠的使命是异步的,就要注重了,gulp并不会守候谁人所依靠的异步使命完成,而是会接着实行后续的使命。比方:

gulp.task('one',function(){
  //one是一个异步实行的使命
  setTimeout(function(){
    console.log('one is done')
  },5000);
});
 
//two使命虽然依靠于one使命,但并不会比及one使命中的异步操纵完成后再实行
gulp.task('two',['one'],function(){
  console.log('two is done');
});

上面的例子中我们实行two使命时,会先实行one使命,但不会去守候one使命中的异步操纵完成后再实行two使命,而是紧接着实行two使命。所以two使命会在one使命中的异步操纵完成之前就实行了。

  那假如我们想守候异步使命中的异步操纵完成后再实行后续的使命,该怎样做呢?

  有三种要领能够完成:

  第一:在异步操纵完成后实行一个回调函数来关照gulp这个异步使命已完成,这个回调函数就是使命函数的第一个参数。

gulp.task('one',function(cb){ //cb为使命函数供应的回调,用来关照使命已完成
  //one是一个异步实行的使命
  exec(function(){
    console.log('one is finish');
    cb();  //实行回调,示意这个异步使命已完成
  },5000);
});
 
//这时候two使命会在one使命中的异步操纵完成后再实行
gulp.task('two',['one'],function(){
  console.log('two is finish');
});

第二:定义使命时返回一个流对象。适用于使命就是操纵gulp.src猎取到的流的状况。

gulp.task('one',function(cb){
  var stream = gulp.src('client/**/*.js')
      .pipe(exec()) //exec()中有某些异步操纵
      .pipe(gulp.dest('build'));
    return stream;
});
 
gulp.task('two',['one'],function(){
  console.log('two is done');
});

第三:返回一个promise对象,比方

var Q = require('q');
gulp.task('one', function() {
  var deferred = Q.defer();
 
  // 实行异步的操纵
  setTimeout(function() {
    deferred.resolve();
  }, 1);
  return deferred.promise;
});
 
gulp.task('two',['one'],function(){
  console.log('two is done');
});

run

gulp.run()示意要实行的使命。能够会运用单个参数的情势通报多个使命。以下代码:

gulp.task('end',function(){
gulp.run('task1','task3','task2');
});

注重:使命是只管多的并行实行的,而且能够不会根据指定的递次运转。

插件装置

在我们编写gulp代码时刻,须要用到一些gulp的插件,能够经由历程npm install --save-dev 插件称号 来装置。以下代码来装置自动加载插件:

npm install --save-dev gulp-load-plugins

要运用gulp的插件,起首得用require来把插件加载进来。

var gulp=require('gulp'),
    plugins=require('gulp-load-plugins')(),
    uglify = require('gulp-uglify'),
    minifyHtml = require('gulp-minify-html'),
    rename = require('gulp-rename');

gulp的插件有许多种,我们将在本节内容中为同学们解说几个插件的用法。如还想相识更多插件,请查阅相干材料。

自动加载

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-renamegulp-ruby-sass这两个插件的时刻,就能够运用plugins.rename和plugins.rubySass来替代了,也就是原始插件名去掉gulp-前缀,以后再转换为驼峰定名。

重定名

gulp-rename插件用来重定名文件流中的文件。用gulp.dest()要领写入文件时,文件名运用的是文件流中的文件名,假如要想转变文件名,那能够在之前用gulp-rename插件来转变文件流中的文件名。

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

js文件紧缩

gulp-uglify插件用来紧缩js文件。

var gulp = require('gulp'),
    uglify = require("gulp-uglify");
 
gulp.task('minify-js', function () {
    gulp.src('src/*.js')          // 要紧缩的js文件
    .pipe(uglify())              //运用uglify举行紧缩
    .pipe(gulp.dest('dist/js')); //紧缩后的途径
});

css文件紧缩

gulp-minify-css插件用来紧缩css文件。

var gulp = require('gulp'),
    minifyCss = require("gulp-minify-css");
 
gulp.task('minify-css', function () {
    gulp.src('src/*.css') // 要紧缩的css文件
    .pipe(minifyCss())    //紧缩css
    .pipe(gulp.dest('dist/css'));
});

html文件紧缩

gulp-minify-html插件用来紧缩html文件。

var gulp = require('gulp'),
    minifyHtml = require("gulp-minify-html");
 
gulp.task('minify-html', function () {
    gulp.src('src/*.html') // 要紧缩的html文件
    .pipe(minifyHtml())    //紧缩
    .pipe(gulp.dest('dist/html'));
});

js代码搜检

运用gulp-jshint插件,用来搜检js代码。

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

文件兼并

运用gulp-concat插件,用来把多个文件兼并为一个文件,我们能够用它来兼并jscss文件等。

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

图片紧缩

能够运用gulp-imagemin插件来紧缩jpg、png、gif等图片。

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-livereload插件,当代码变化时,它能够帮我们自动革新页面。

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的基本用法都已解说完了,最主要的照样在项目中多多运用才尽快掌握。本文来源于笔者进修汇智网教室的进修笔记。原课程作者:草莓。

    原文作者:司想君
    原文地址: https://segmentfault.com/a/1190000004527820
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞