gulp入门+ES6

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 .,以树状图的形式展示当前目录结构

2015-09-24 20 15 13

然后,安装依赖 gulpgulp-sassgulp-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 是目标文件的路径,返回一个可读的 stream
  • gulp.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 中注册过的任务名称。如果配置文件没有错误地话,执行完成后项目结构如下:

2015-09-25 09 49 05

编译之前,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 作为后缀的文件

这些规则和正则表达式有相似之处,更多信息可以参考 minimatchnode-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 即可自动打开浏览器,实时修改页面的效果:

demo

学习和使用插件最有效地方式就是去相关的文档,然后投入到实际开发中……这里仅仅列出列出几个插件,后续会随着对 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
参考资料

南北

在校学生,本科计算机专业。狂热地想当一名作家,为色彩和图形营造的视觉张力折服,喜欢调教各类JS库,钟爱CSS,希望未来加入一个社交性质的公司,内心极度肯定“情感”在社交中的决定性地位,立志于此改变社交关系的快速迭代。个人博客

如需转载,烦请注明出处:http://www.w3cplus.com/workflow/glup-and-es6.html

返回顶部