欢迎来个人博客阅读:《Gulp 基础与原理》javascript
Gulp 是基于 NodeJS 的项目,一个用做自动化构建的工具,业界通常用来建造前端的工做流。css
它的核心原理其实很简单,最主要是经过各类 Transform Stream 来实现文件的处理,而后再进行输出。Transform Streams 是 NodeJS Stream 的一种,是可读又可写的,它会对传给它的对象作一些转换的操做。html
文件输入 → Gulp 插件处理 → 文件输出前端
原则上,gulp 能够针对文件作任何有趣、有创造力事情。
而自动化构建,只是你们主要比较喜欢使用的方向。java
Gulp 的特色:node
自动化 - Gulp 为你的工做流而服务,自动运行那些费事费力任务。git
平台透明 - Gulp 被集成到各类 IDE 中,而且除了 NodeJS 以外,其余如 PHP、.NET、Java 平台均可以使用 Gulp。github
强大生态系统 - 你可使用 npm 上 2000+ 的插件来构造你的工做流。正则表达式
简单 - Gulp 只提供几个 API,这能够很快地学习和上手。npm
$ npm install gulp-cli -g // 全局安装 Gulp 命令行工具 $ npm install gulp -D // 在项目中,做为 devDependencies 依赖安装 gulp
在使用 CLI 工具的时候,会执行该文件,它是一个可执行的 NodeJS 文件。原理上,你能够在里面运行任何 NodeJS 代码,而后经过调用 gulp 提供的 API,来执行 gulp 任务。gulpfile.js
文件通常都会放在项目的根目录中。
一个使用 gulp-babel 插件来支持 es2015 语法的案例:
const gulp = require('gulp'); const babel = require('gulp-babel'); gulp.task('default', () => { gulp.src('src/app.js') .pipe(babel({ presets: ['es2015'] })) .pipe(gulp.dest('dist')); });
了解这些概念,对于了解 Gulp 的工做原理,和 API 的使用是颇有帮助的。
Glob 是一种用来匹配路径与文件的模式。有点相似于正则表达式,可是语法又有点差别。
这种模式,被普遍用于命令行、Shell 等场景,你们熟悉的 .gitignore
文件也是使用这种模式。
各大语言都有对于 Glob 的实现,例如 Go 和 PHP 的 Glob
函数,Python 中的 glob
模块。
而 NodeJS 的实现是 minimatch, 而在 Gulp 源码中,就用了对 minimatch 进行封装的 node-glob 模块。
Gulp 的 API gulp.watch
和 gulp.src
都有用到 Glob 来匹配对应的路径和文件。
下面是部分语法:
*
匹配该路径段中 0 个或多个任意字符,
如:js/*.js
, 匹配 js 目录下的全部 js 文件
?
匹配该路径段中 1 个任意字符,
如:js/?.js
,匹配 js 目录下全部名字只有 1 个字的 js
[...]
匹配该路径段中在指定范围内字符,
如:js/a[0-3].js
,匹配 js 目录下 a 开头,第二个字符为 0-3 之间( 包括0和3 )的 js( a03.js不能被匹配到 )
!(pattern|pattern|pattern)
匹配除所给出的模型之外的状况,
如:js/!(a|b).js
,匹配 js 目录下名字中不包含 a ,也不包含 b 的全部文件.
?(pattern|pattern|pattern)
匹配所给出的模型中的 0 个或任意 1 个,
如:js/?(a|a2|b).js
, 匹配 js 目录下 a.js , a2.js , b.js
+(pattern|pattern|pattern)
匹配所给出的模型中的 1 个或者多个,
如:js/+(a|a1|b).js
, 匹配 js 目录下 a.js , a1.js , b.js , 或者 a, a1, b 这几个字符的组合的 js , 好比 ab.js
*(pattern|pattern|pattern)
匹配所给出的模型中的 0 个或多个或任意个的组合.
如:js/*(a|a1|b).js
,匹配 js 目录下 a.js, a1.js, b.js 或者 a, a1, b这几个字符的组合的 js , 好比 ab.js
@(pattern|pat*|pat?erN)
匹配所给出的模型中的任意 1 个,
如:js/@(a|a1|b)
, 匹配 js 目录下的 a.js, a1.js, b.js
**
与 *
同样能够匹配任何内容,但 **
不只匹配路径中的某一段,并且能够匹配 a/b/c
这样带有 /
的内容,因此,它还能够匹配子文件夹下的文件.
如:js/**/*.js
,匹配 js 目录下及子文件夹中全部的 js 文件。
更多 Glob 的知识和语法,能够参考:
Glob - Wiki
Glob Primer
Vinyl 是 Gulp 自创的一种用来描述一个虚拟文件的类,其中主要包括文件的内容和文件的路径两大信息。vinyl 模块,只是提供了一个类,而实现却交由 vinyl-fs
Vinyl-fs,它主要的工做是接受 glob 模式的参数,而后读取匹配的文件。而后利用 Vinyl 制做一个 Transform Stream,称为 Vinyl Stream 对象,并返回。
在 Gulp 中的 API gulp.src
、gulp.watch
、gulp.dest
都返回一个 Vinyl Stream 实例对象。Vinyl Stream 实例之间能够经过管道( vinyl1.pipe(vinyl2)
)的形式来互相传输数据。
从 Gulp 的 源码 中也能看出,这三个 API 都是由 vinyl-fs 提供所有的实现。
再一点是,从这两个模块的实现来看,Gulp 是把文件内容以 Buffer 的形式读到内存中,而后再进行处理的。
Orchestartor,为 gulp.task
提供了所有实现,这能够从 源码 中看出。
它为 Gulp 提供了任务相关的功能,包括任务注册、任务执行以及相对应的任务进度、错误监控等功能。
Orchestartor 模块,只提供了一个 Orchestartor 类,该类的实例维护着一个 tasks 数组,该数组的内容就是一个咱们使用 gulp.task
时注册的函数列表,以及函数的依赖和名字。
经过 源码 中,能够看到 tasks 的数据结构:
... this.tasks[name] = { fn: fn, // 任务的函数体 dep: dep, // 任务所依赖的其余任务名称 name: name // 该任务的名称 }; ...
gulp.src:获取文件
gulp.dest:写入文件
gulp.tasks:注册任务
gulp.watch:监控文件的改动
gulp.src( globs [, options] )
接收一个 globs 模式的对象,能够是 Array 或者 String,返回一个 Vinyl Stream 实例。
而 options 有下面的值:
buffer - Boolean, 控制 file.contents
是返回 buffer 仍是 stream。
read - Boolean,控制是否读取文件,若是 false,则 file.contents
为 null
base - String,控制 glob 的 base,默认值是 glob 全部表达式的前置,例如 client/js/**/*.js
, base 值就为 client/js/
。而 glob 在保存输出路径的时候,取的是 base 以后的路径。因此能够经过该值,来进行输出路径的改写。
gulp.dest( path [, options] )
接收输出路径,返回一个 Vinyl Stream 实例。
而 options 有如下的值:
cwd - String, 默认值 process.pwd()
,输出目录的 cwd 参数,只在所给的输出目录是相对路径时候有效。
mode - String,八进制权限字符,用以定义全部在输出目录中所建立的目录的权限。
gulp.task( name [, deps ], fn )
定义一个使用 Orchestrator 实现的任务(task)。
参数的描述以下:
name - 任务名称
deps - 是当前定义的任务须要依赖的其余任务,为一个数组。当前定义的任务会在全部依赖的任务执行完毕后才开始执行。若是没有依赖,则可省略这个参数
fn - 为任务函数,咱们把任务要执行的代码都写在里面。该参数也是可选的。
gulp.watch( glob [, opts ], tasks )
orgulp.watch( glob [, opts, cb ] )
用来监视文件的变化,当文件发生变化后,咱们能够利用它来执行相应的任务。
各参数的描述以下:
glob - 为要监视的文件 Glob 匹配模式。
opts - 为一个可选的配置对象。
tasks - 为文件变化后要执行的任务,为一个数组
gulp-load-plugins:自动加载 package.json
中的 gulp 插件
gulp-rename: 重命名
gulp-uglify:文件压缩
gulp-concat:文件合并
gulp-less:编译 less
gulp-sass:编译 sass
gulp-clean-css:压缩 CSS 文件
gulp-htmlmin:压缩 HTML 文件
gulp-babel: 使用 babel 编译 JS 文件
gulp-jshint:jshint 检查
gulp-imagemin:压缩jpg、png、gif等图片
gulp-livereload:当代码变化时,它能够帮咱们自动刷新页面
更多插件,能够搜索官方插件库。