Gulp
是一个基于 nodejs stream 的流式前端构建工具,与 Grunt
功能相同,专注于前端资源的编译、检查、压缩等自动化工作。
安装 gulp
安装 gulp
之前,更新一下 npm
(可选,避免因版本过低报错):
curl https://www.npmjs.org/install.sh | sudo sh
使用 npm
安装 gulp
到全局:
npm install -g gulp
使用 npm
安装 gulp
到当前项目的 node_modules
, 并更新 package.json
配置信息:
npm install --save-dev gulp
编写 gulpfile.js
最简单的 gulpfile.js
结构:
var gulp = require('gulp');
gulp.task('task-name', function() {
console.log('Hello, Gulp!');
});
在 gulpfile.js
所在路径的终端输入 gulp task-name
就可以看到 Hello, Gulp!
了,这个示例没有实际作用,纯粹是为了演示 gulpfile.js
的基本结构。
下面我们使用 gulp 实现一个实用功能:编译 Sass,并添加浏览器前缀。首先,初始化一个演示目录:
mkdir gulp-in-action
,创建演示目录gulp-in-action
cd gulp-in-action
,进入演示目录gulp-in-action
mkdir sass
,创建 Sass 目录sass
touch sass/demo.scss
,创建 Sass 文件demo.scss
用于演示touch gulpfile.js
,创建 gulp 的配置文件gulpfile.js
tree .
,以树状图的形式展示当前目录结构
然后,安装依赖 gulp
、gulp-sass
和 gulp-autoprefixer
:
npm install --save-dev gulp gulp-sass gulp-autoprefixer
其中,gulp-sass
用于将 Sass 文件编译为 CSS 文件,gulp-autoprefixer
用于为 CSS 属性添加适当的浏览器前缀。此外,在正式的开发项目中,应该使用 npm init
或者自建方式创建一个 package.json
存储依赖关系等配置信息,当然,如果想要获得更优秀的脚手架,你可以尝试一下 yeoman
(号称现代前端开发的脚手架)。
接下来,使用熟悉的编辑器打开 gulpfile.js
,编写 gulp 的自动化构建逻辑:
// 导入 gulp/gulp-sass/gulp-autoprefixer 三个模块
var gulp = require('gulp');
var sass = require('gulp-sass');
var autoprefixer = require('gulp-autoprefixer');
// 使用 gulp.task() 方法注册一个任务
// 第一个参数是任务名称
// 第二个参数是任务的执行逻辑
gulp.task('styles', function() {
return gulp.src('sass/demo.scss')
.pipe(sass())
.pipe(autoprefixer())
.pipe(gulp.dest('css'));
});
在继续下面的操作之前,我们有必要认识一下 gulp 中的五大函数:
gulp.task(name, fn)
,注册一个 gulp 任务gulp.run(...tasks)
,并行运行多个 gulp 任务gulp.watch(glob, fn)
,实时监控内容,当glob
内容变化时,执行fn
gulp.src(glob)
,glob
是目标文件的路径,返回一个可读的 streamgulp.dest(gloc)
,glob
是输出路径,返回一个可写的 stream
那么,什么是 pipe()
呢?先来看一个 unix
命令:
cat gulpfile.js | wc -l
这是一条由管道符(|
)拼接起来的命令,整体由两部分组成,每一部分都是一条独立的命令:cat gulpfile.js
用来获取 gulpfile.js
的文件内容;wc -l
用来统计文件中的行数。管道符(|
)在这里的作用是拼接两条命令,将前者(cat gulpfile.js
)的输出,作为后者的 wc -l
的输入。
gulp 中使用的 pipe()
函数就是模拟了管道符的操作方式,比如下面的 gulp 命令:
gulp.src('sass/demo.scss')
.pipe(sass())
.pipe(autoprefixer())
就可以想象为:
'sass/demo.scss' | sass() | autoprefixer()
基础知识介绍完了,最后我们来执行 gulp 任务,终端中输入:
gulp styles
这里的 styles
就是 gulpfile.js
中注册过的任务名称。如果配置文件没有错误地话,执行完成后项目结构如下:
编译之前,sass/demo.scss
的内容如下:
.container {
display: flex;
}
编译之后,打开 css/demo.css
文件,内容如下:
.container {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
}
可见,gulp styles
已经自动完成了 Sass 到 CSS 的编译,并添加了适当的浏览器前缀。
接下来,我们使用 gulp.watch()
函数优化一下自动化任务,让 Sass 文件每次发生改动时可以自动编译。gulp 官方插件开发说明中建议开发者遵循单一职责原则,所以,我们这里实现 watch
任务最好的方式就是借助 styles
任务的功能,增加下面的代码到 gulpfile.js
配置文件中:
gulp.task('watch', function() {
gulp.watch('sass/demo.scss', ['styles']);
});
然后在终端运行 gulp watch
命令,即可实时修改实时编译了。到此,我们基本实现了既定的自动化目标,当然,只做这么点工作就太让 gulp 屈才了,不过本文定位为入门文章,更多更深入的使用方式,建议学习慕课网《Grunt-beginner前端自动化工具》一课,内容全面深入浅出,值得一学。
gulp.watch()
gulp.watch()
可以返回一个监听对象,用来监听额外的事件,比如 change
:
var watcher = gulp.watch('sass/*.scss');
watcher.on('change', function (event) {
console.log('Event type: ' + event.type);
console.log('Event path: ' + event.path);
});
其他事件:
nomatch
,在glob
没有匹配到文件时触发ready
,在匹配后即将进行自动化任务前触发error
,自动化任务出错时触发end
,自动化任务完成时触发
watcher
对象可以调用的一些方法:
watcher.end()
,中断watcher
watcher.files()
,返回监听的文件列表watch.add(glob[, fn])
,添加文件到监听的文件列表watch.remove(fillpath)
,从监听的文件列表中移除文件
node-glob
在上面的 gulp.src(glob)
和 gulp.dest(glob)
函数中,glob
参数既可以是具体的路径,也可以是一些路径规则,通常来说,路径规则比具体路径更常用,也更灵活,最常见的符号就是 通配符(*)
,比如 sass/*.scss
表示匹配 sass
文件夹下所有以 .scss
作为后缀的文件。
gulp 中使用 gulp-glob来匹配文件,下面列出几种最常见的匹配方式:
sass/demo.scss
,精确匹配sass
文件夹下的demo.scss
文件sass/*.scss
,匹配sass
文件夹下所有以.scss
作为后缀的文件sass/**/*.scss
,匹配sass
文件夹以及子文件夹下所有以.scss
作为后缀的文件!sass/demo.scss
,!
后面跟上述三种模式,可以充匹配结果中排除相关文件,比如这里的!sass/demo.scss
表示从匹配结果中排除sass
文件夹下的demo.scss
文件sass/*.+(sass|scss)
,匹配sass
文件夹下所有以.scss
和.sass
作为后缀的文件
这些规则和正则表达式有相似之处,更多信息可以参考 minimatch和 node-glob(中文版)的官方文档。
常用插件
目前在 gulp 的官方插件页面,已经可以搜索到多达 1800+ 的插件,当你需要使用某种插件时,建议优先使用该页面搜索一下是否有现成的插件可用,然后再考虑造轮子,避免重复工作。
下面列举一些常用插件,善用这些插件才能让 gulp 发挥出最大作用。
gulp-load-plugins
在我们的 gulpfile.js
中,每当需要使用新的插件时,就需要在头部声明并加载一次,如果依赖的插件较多,维护起来就会比较困难,gulp-load-plugins
插件就是针对这一问题而存在的,安装方式:
npm install --save-dev gulp-load-plugins
接下来,我们在 gulpfile.js
中使用 gulp-load-plugins
替代导入依赖的方式:
// var sass = require('gulp-sass');
// var autoprefixer = require('gulp-autoprefixer');
var $ = require('gulp-load-plugins')();
gulp.task('styles', function() {
return gulp.src('sass/demo.scss')
.pipe($.sass())
.pipe($.autoprefixer())
.pipe(gulp.dest('css'));
});
之后再有新的依赖加入开发环境,也无需增加头部的声明,调用即可使用。
使用
gulp-load-plugins
,必须保证项目依赖都写在了package.json
中,这是因为gulp-load-plugins
的加载核心就是调用package.json
的配置信息。 如果你不知道怎么创建一份package.json
,那么我们可以做一个游戏,在终端输入npm init
试一试。
browsersync
browsersync
是一款浏览器实时测试工具,它可以嵌入到多种自动化构建工具中,详细的使用方式请参考官方文档。安装方式:
npm install --save-dev browser-sync
重写 gulp watch
任务:
gulp.task('watch', function() {
browserSync.init({
server: {
baseDir: "./"
}
});
gulp.watch('sass/demo.scss', ['styles'])
.on('change', browserSync.reload);
});
在项目根目录下创建一个 index.html
用于演示项目:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<link rel="stylesheet" href="css/demo.css">
</head>
<body>
<p>help</p>
</body>
</html>
为了更明显的查看效果,我们修改 demo/sass.scss
的内容为:
body {
background-color: red;
}
终端运行 gulp watch
即可自动打开浏览器,实时修改页面的效果:
学习和使用插件最有效地方式就是去相关的文档,然后投入到实际开发中……这里仅仅列出列出几个插件,后续会随着对 gulp 理解的深入继续增加更多插件。
gulp + ES6
在最新的 gulp 3.9 版本上,开发者可以使用 ES6(ES2015) 语法 来编写配置文件了。第一步,先检查一下 CLI 和本地版本:
gulp -v
// => CLI version 3.9.0
// => Local version 3.9.0
第二步,在终端安装依赖 Babel
:
npm install babel-core --save-dev
第三步,将 gulpfile.js
重名为 gulpfile.babel.js
:
mv "gulpfile.js""gulpfile.babel.js"
下面展示一个使用 ES6 语法编写的 gulpfile.babel.js
,其中有箭头函数、模块导入、常量声明和模板字符串(更喜欢叫它插值字符串
)等新语法:
import gulp from 'gulp';
import sass from 'gulp-sass';
import autoprefixer from 'gulp-autoprefixer';
const dirs = {
src: 'scss',
dest: 'css'
};
const sassPaths = {
src: `${dirs.src}/demo.scss`,
dest: `${dirs.dest}`
};
gulp.task('styles', () => {
return gulp.src(paths.src)
.pipe(sass.())
.pipe(autoprefixer())
.pipe(gulp.dest(paths.dest));
});
如果遵循上述步骤遇到了未知错误,可以尝试安装 babel
代替 babel-core
来解决:
npm install babel --save-dev
参考资料
如需转载,烦请注明出处:http://www.w3cplus.com/workflow/glup-and-es6.html