IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    Gulp使用入门

    Jogis发表于 2015-11-12 14:44:57
    love 0

    gulp

    提到 Gulp,不得不说到的是较早的 JS 项目自动化构建工具——Grunt。

    前端开发过程中,特别是最近几年多了 CoffeeScript、Sass、Less 等一些预编译语言,很多代码每次写完需要手动到工作目录去编译才能执行。此外,项目预发布时候需要进行 js、css 文件合并、压缩、重命名等操作,实在是很繁琐。此前很多工程师使用的是 Makefile 构建项目,但是这要求需要一定Linux基础,而且编写配置文件会增大非常多工作量, Grunt 的出现,解放了前端工程师的双手=_=

    Grunt 通过 CLI 配合配置文件 gruntfile.js 去完成自动化构建任务,社区有非常多的 Grunt 插件,比如 concat(合并文件)、 uglify(js压缩),只需要在 gruntfile.js 中配置好路径等一些参数,运行以下命令就可以自动执行。

    grunt takeName

    Gulp是一款 The streaming build system(流式构建系统),如果说 Grunt 是基于 gruntfile.js 任务执行器,Gulp 就是基于 NodeJS 的文件流任务执行器,比起 Grunt 有如下特点

    • 使用方便
      通过代码优于配置的策略,Gulp 可以让简单的任务简单,复杂的任务更可管理。

    • 构建快速
      通过流式操作,减少频繁的 IO 操作,更快地构建项目。

    • 插件高质
      Gulp 有严格的插件指导策略,确保插件能简单高质的工作。

    • 易于学习
      少量的API,掌握 Gulp 可以毫不费力。构建就像流管道一样,轻松加愉快。

    Gulp实现

    Gulp 主要 API 为 gulp.src(使用glob模式匹配获得文件流集)、gulp.dest(输出gulp文件流集到指定路径,路径指定相对于gulpfile.js配置文件)、gulp.watch(监听glob模式匹配的文件集,有改动时执行相应gulp任务),如图:

    gulp实现

    orchestrator

    译作管弦乐演奏家,大多数就是一个老头拿着个小棍的形象,就像这样:

    orchestrator

    一个npmjs模块,就是一个以最大并发方式去排序或执行一系列的任务。这些任务就是我们之后会用到的 Gulp 任务,比如说 css 命名的任务,里面包括css的浏览器前缀添加、合并、压缩等操作。orchestrator 通过实例化一个对象,在对象上调用 add 来添加特定命名的任务、添加任务时候可以声明任务依赖,比如:

    var Orchestrator = require('orchestrator');
    var orchestrator = new Orchestrator();
    orchestrator.add('thing1', function(){
      // do stuff
    });
    orchestrator.add('thing2', function(){
      // do stuff
    });
    orchestrator.add('mytask', ['thing1','thing2'], function() {
      // Do stuff
    });

    以上代码,添加了3个 Gulp 任务,mytask 任务依赖于 thing1 和 thing2 ,即必须执行完后面两个任务,mytask才能执行,通过任务依赖,很容易理清和构建任务时候的执行顺序。需要注意的是,在填写 do stuff 时候,要确保其返回一个 promise 或者是 event stream(最常用),比如一个简单的任务是这样定义的:

    var map = require('map-stream');
    
    orchestrator.add('thing4', function(){
      var stream = map(function (args, cb) {
        cb(null, args);
      });
      // do stream stuff
      return stream;
    });

    或则是返回一个 promise:

    var Q = require('q');
    
    orchestrator.add('thing3', function(){
      var deferred = Q.defer();
    
      // do async stuff
      setTimeout(function () {
        deferred.resolve();
      }, 1);
    
      return deferred.promise;
    });

    orchestrator 调用 start 来执行特定名称的任务,可一次执行多个:

    orchestrator.start('one', 'two');

    以上两个是 orchestrator 最常用的用于实现 Gulp 的函数,除此之外,还有任务检测,任务暂停,任务事件监听,想详细了解可访问npmjs:https://www.npmjs.org/package/orchestrator

    vinyl-fs

    这是 Gulp 采用的一个虚拟文件系统,可以读取 glob 模式匹配到的文件并转成文件流,可以获取文件流并转成文件集。其中 vinyl-fs 使用 vinyl 虚拟文件描述类,来对 glob 匹配到的文件进行描述,所谓的描述,只是简单的文件名与路径,以及文件内容,可以说是一个文件的封装,可以看看 vinyl 是如何描述一个或一组文件的:

    
    var File = require('vinyl');
    
    var coffeeFile = new File({
      cwd: "/",
      base: "/test/",
      path: "/test/file.coffee",
      contents: new Buffer("test = 123")
    });
    

    除了 vinyl ,vinyl-fs 还需要依赖 glob-stream 读写文件流,如图:

    vinyl

    glob-stream

    大家可能有疑问,读写文件流,为什么不用 nodejs 内核的 steam 类来读写呢,骚安勿燥,Gulp 既然是基于 nodejs 构建,最终自然也是依赖 nodejs 内核实现它的功能的。

    只是,stream 类读取文件流只针对一个文件路径,glob-stream 就是实现从获取 glob 模式匹配文件集,到转换成文件路径,再到读取,还是有一段距离的。如图:

    glob-stream

    glob-stream 通过 minimatch 来进行 glob 模式匹配,通过其他路径模块,获得一组文件路径,然后就是 ordered-read-streams 发光发热时候啦,对这组文件路径一个个地读啊,然后就获得一组文件流啦。

    好啦,终于分析完 Gulp 的实现,通过对其中模块的阅读,其实 Nodejs 模块有点像乐高积木,内核给出的就是最基本的积木啦,不过你可以无限次使用它们,来堆出一个个小的物体,通过小小的物体组合,来组成非常徇丽多姿的乐高作品啦~

    当然,也是有一些 c++ 实现的nodejs模块,主要是用于一些需要高性能运算的地方,不过npmjs.org上介绍到的模块,大部分的依赖都是基于 nodejs 内核实现滴。



沪ICP备19023445号-2号
友情链接