前言:别怕,gulp 入门比你想象中的简单多了(●ˇ∀ˇ●)……
Gulp 简介
官网:用 自动化构建工具 增强你的工作流程!
Gulp 和 Webpack 是一回事吗:gulp 是 任务管理工具(task runner)。
任务管理工具中我们可以声明若干任务,比如合并、压缩、测试等等。任务间可互相依赖,可以是同步,也可以是异步的。然后我们可以自由地选择运行哪个任务,任务管理工具会帮我们运行它(以及它的依赖)。
简单来说使用流程是这样的:
#1 安装 gulp (使用 npm 安装)
#2 创建 gulpfile.js
文件(用于编写自动化任务)
#3 安装你需要的 gulp 插件(一些完成特定任务的插件)
#4 在 gulpfile.js
文件中编写你需要的自动化任务
#5 在命令行界面中一句命令执行特定的(一个或多个)任务
#6 任务运行成功!你以前手动做的一些事情,现在一句命令就瞬间完成了~
Gulp 使用
#1:安装 gulp
官方的 入门指南 | Getting Started 已经说得蛮清楚的了,但是……我可以再讲一遍!
我们按照官方的操作来,毕竟中文官网翻译可能会有延迟。
首先,如果你已经全局安装过 gulp (npm install gulp -g
),在执行下面步骤前先运行 npm rm --global gulp
(移除全局 gulp 模块)。
安装 gulp
命令行工具
npm install --global gulp-cli
将 gulp
安装在你的开发依赖中
在你的项目根目录下运行以下命令:
npm install --save-dev gulp
#2:创建 gulpfile.js
文件
创建 gulpfile
在你的项目根目录下创建一个 gulpfile.js
文件,文件中包含如下内容:
var gulp = require('gulp');
gulp.task('default', function() { // 'default' 默认任务名,运行命令时可省略,直接 `gulp` 即可,运行其他任务需要 `gulp taskname`
// place code for your default task here
// 在这里编写默认任务代码
// 因为这里啥都没写,所以运行该任务后啥都不会执行
});
测试一下
在你的项目下运行如下命令:
gulp
看吧!默认任务会执行并什么都不做。
接下去你可以从这些方面入手:
API 文档 | API Documentation
秘籍 | Recipes
文章列表 | Help Articles
Plugins(插件)
同理,英文信息更多,中文翻译会有延迟。
Gulp 语法
请大致阅读下:API 文档 | API Documentation
不多,就这4个方法:gulp.src | gulp.dest | gulp.task | gulp.watch
gulp.src(globs[, options])
输出符合所提供的匹配模式(glob)或者匹配模式的数组(array of globs)的文件。 将返回一个 Vinyl files 的 stream,它可以被 piped 到别的插件中。
gulp.src('client/templates/*.jade') // 找到匹配文件,此处为:找到 `client/templates/` 目录下的所有 jade 文件
.pipe(jade()) // 使用相关插件处理匹配到的文件,此处为:编译 jade 模板文件
.pipe(minify()) // 可以链式处理,此处为:将编译后的文件进行压缩处理
.pipe(gulp.dest('build/minified_templates')); // 将处理好的文件进行最后一步操作:导出到 `build/minified_templates` 目录下
globs
:字符串或数组形式。
反向选择:以 !
开头的 glob 的功能为,在直至这个 glob 前所有匹配的文件中移除这个 glob 匹配到的文件。
举个例子:
// 文件目录
client/
a.js
bob.js
bad.js
下面的表达式最终会匹配到 a.js
和 bad.js
:
gulp.src(['client/*.js', '!client/b*.js', 'client/bad.js'])
gulp.dest(path[, options])
能被 pipe
(能将数据导)进来这个方法,它将会写文件(也就是导出文件)。同时这个方法会重新输出所有数据,因此你可以实现将文件 pipe 到多个文件夹。如果某文件夹不存在,它将会被自动创建。
gulp.src('./client/templates/*.jade') // 找到 `./client/templates/` 目录下的所有 jade 文件
.pipe(jade()) // 编译 jade 模板文件
.pipe(gulp.dest('./build/templates')) // 将编译好的文件输出到 `./build/templates` 目录下
.pipe(minify()) // 继续将编译好的文件进行压缩
.pipe(gulp.dest('./build/minified_templates')); // 再次将编译并压缩好的文件输出到 `./build/minified_templates` 目录下
gulp.task(name [, deps] [, fn])
gulp.task('somename', function() {
// Do stuff
});
name
:任务名,用于在命令行中指定任务运行,因此名称不能包含空格。
deps
:一个包含任务列表的数组,这些任务会在你当前任务运行之前完成。
gulp.task('mytask', ['array', 'of', 'task', 'names'], function() {
// Do stuff
});
注意:如果你希望你的任务在这些前置依赖的任务完成之后再开始执行,请一定要确保你所依赖的任务列表中的任务都使用了正确的 异步执行方式:使用一个 callback,或者返回一个 promise 或 event stream,具体查看文档:API 文档 | API Documentation,推荐阅读英文版。
// 简单示例
gulp.task('dep', function(cb){ …; cb() }) // 使用一个 callback
gulp.task('dep', function(){ return gulp.src()… }) // 返回 event stream
如果你就只是想一次性执行多个任务,可以这样做(多个任务会同时开始执行,并没有先后顺序):
gulp.task('build', ['array', 'of', 'task', 'names']);
执行 build 任务,在命令行工具中运行下面语句:
gulp build
fn
:该函数定义任务所要执行的一些操作。通常来说,它会是如下这种形式:
gulp.task('buildStuff', function() {
// Do something that "builds stuff"
var stream = gulp.src(/*some source path*/) // 前面 gulp.src 有提到会返回 stream,理解为数据流就好了
.pipe(somePlugin())
.pipe(someOtherPlugin())
.pipe(gulp.dest(/*some destination*/));
return stream; // 将处理过的数据再返回出来
});
gulp.watch(glob [, opts], tasks) or gulp.watch(glob [, opts, cb])
监视文件,并且可以在文件发生改动时做一些事情。它总会返回一个 EventEmitter 来触发 change
事件。
gulp.watch(glob[, opts], tasks)
var watcher = gulp.watch('js/**/*.js', ['uglify','reload']); // 监视文件:js/**/*.js,文件改动时运行任务:'uglify','reload'
watcher.on('change', function(event) { // 监听文件改动时触发的 change 事件
console.log('File ' + event.path + ' was ' + event.type + ', running tasks...');
});
gulp.watch(glob[, opts, cb])
gulp.watch('js/**/*.js', function(event) { // 监听文件:js/**/*.js,文件改动时执行该回调函数
console.log('File ' + event.path + ' was ' + event.type + ', running tasks...');
});
简单示例
#3:安装你需要的 gulp 插件
下面的示例中我们会用到这些插件(插件的具体使用可以查看相关文档):
browser-sync
:Browsersync 能让浏览器实时、快速响应文件更改(html、js、css、sass、less 等)并自动刷新页面
gulp-autoprefixer
:自动添加兼容性前缀(-webkit-, -moz- …)
gulp-rename
:文件重命名
gulp.spritesmith
:生成精灵图和相应的 css 文件
gulp-cssnano
:压缩 css 代码
可以将其写入 package.json
文件并一次性安装:
{
"name": "gulp-demo",
"version": "1.0.0",
"description": "a simple gulp demo",
"main": "index.js",
"dependencies": {
},
"devDependencies": {
"gulp": "^3.9.1",
"browser-sync": "^2.18.6",
"gulp-autoprefixer": "^3.1.1",
"gulp-rename": "^1.2.2",
"gulp.spritesmith": "^6.3.0"
"gulp-cssnano": "^2.1.2",
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Alexee",
"license": "ISC"
}
根据 package.json
进行安装:
npm install
单独安装:
[-S|--save|-D|--save-dev|-O|--save-optional] [-E|--save-exact] [-B|--save-bundle] [--dry-run]
npm install browser-sync -D
#4:在 gulpfile.js
文件中编写你需要的自动化任务
// 引入插件
var gulp = require('gulp'),
browserSync = require('browser-sync').create(), // 具体可以查看官方文档的使用说明
autoprefixer = require('gulp-autoprefixer'),
rename = require("gulp-rename"),
nano = require('gulp-cssnano'),
spritesmith = require('gulp.spritesmith');
// 启动静态服务器,并实时响应文件改动,页面自动刷新
gulp.task('bs', function() {
browserSync.init({
server: {
baseDir: "./" // 基于项目根目录启动服务器
},
files: ["css/style.css","index.html"] // 监听 "css/style.css","index.html" 文件
});
});
// 重命名 css 文件
gulp.task('rename', function() {
return gulp.src('css/style.css')
.pipe(rename({
suffix: '.min' // style.css => style.min.css
}))
.pipe(gulp.dest('css'));
});
// 生成精灵图和 css 文件
gulp.task('sprite', function () {
var spriteData = gulp.src('images/*.png').pipe(spritesmith({
imgName: 'sprite.png', // 图片文件名:sprite.png
cssName: 'sprite.css', // css 文件名:sprite.css
imgPath: '../images/sprite.png', // css 文件中的图片相对位置:url('../images/sprite.png')
padding: 1 // sprite.png 中图片间距
}));
return spriteData.pipe(gulp.dest('images'));
});
// 处理 css 文件:添加兼容性前缀 =》压缩 =》重命名
gulp.task('css', function () {
return gulp.src('css/styles.css')
.pipe(autoprefixer({ // 添加兼容性前缀
browsers: ['last 4 versions'], // 我填 2 的时候没能将 -webkit- 等前缀添加进去,所以还是填 4 保险点
cascade: false
}))
.pipe(nano()) // 压缩
.pipe(rename({
suffix: '.min' // 重命名
}))
.pipe(gulp.dest('dist/css')); // 输出到 'dist/css' 文件目录下
});
#5:在命令行界面中执行任务
gulp bs
gulp sprite
gulp css
……
#6:任务运行成功!你以前手动做的一些事情,现在一句命令就瞬间完成了~
拓展阅读
前端开发中提到的“脚手架”到底指什么,CLI?gulp 和 gulp-cli有什么区别
使用 Gulp 来构建你的 workflow