文章 Gulp 快速入门
Post
Cancel

Gulp 快速入门

什么是gulp?

  gulp是前端开发过程中一种基于流的代码构建工具,是自动化项目的构建利器;它不仅能对网站资源进行优化,而且在开发过程中很多重复的任务能够使用正确的工具自动完成;使用它,不仅可以很愉快的编写代码,而且大大提高我们的工作效率。

  gulp是基于Nodejs的自动任务运行器, 它能自动化地完成 前端代码的测试、检查、合并、压缩、格式化、浏览器自动刷新、部署文件生成,并监听文件在改动后重复指定的这些步骤。

什么是流?

  流,流水,把文件比作河流,那么一条河流流出,另一条河流流进,gulp对于文件流的操作就是这样,一个操作的输出结果作为另一个操作的输入。

gulp 安装

全局安装 gulp:

1
npm install --global gulp

作为项目的开发依赖(devDependencies)安装:

1
npm install --save-dev gulp

在项目根目录下创建一个名为 gulpfile.js 的文件:

1
2
3
4
5
var gulp = require('gulp');
// 默认task
gulp.task('default', () => {
  console.log('Hello World')
});

运行 gulp:

1
gulp

默认的名为 default 的任务(task)将会被运行。

想要单独执行特定的任务(task),请输入

1
gulp <task> <othertask>。

tasks 依赖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var gulp = require('gulp');
// task1
gulp.task('task1', () => {
    console.log('task1');
});
// task2
gulp.task('task2', () => {
    setTimeout(() => {
        console.log('task2')
    }, 1000);
});
// 在执行 default 之前先执行 task1 和 task2
gulp.task('default', ['task1', 'task2'], () => {
    console.log('Hello World');
});

输出顺序为:

task1 Hello World task2

流式处理

(1). 在项目根目录下创建 src 文件目录,里面创建 index.js (2). 在项目根目录下创建 dist 文件目录 (3). 安装 gulp-uglify

1
npm install gulp-uglify --save-dev

(4). 使用 gulp 压缩 index.js 并将结果输出

1
2
3
4
5
6
7
8
var gulp = require('gulp');
var uglify = require('gulp-uglify');
// 压缩js
gulp.task('default', () => {
    gulp.src('src/*.js')
        .pipe(uglify())
        .pipe(gulp.dest('dist'))
});

(5). 运行 “gulp” 命令后发现在 dist 目录下生产了压缩后的 index.js

(6). 解释

gulp.src 是输入; gulp.dest 是输出 pipe 是管道的意思,也是 stream 里核心概念,pipe 将上一个的输出作为下一个的输入。src 里所有 js,经过处理1,处理2,变成输出结果,中间的处理 pipe 可以1步,也可以是n步。第一步处理的结果是第二步的输入,以此类推,就像生产线一样,每一步都是一个 task 是不是很好理解呢?

每个独立操作单元都是一个 task,使用 pipe 来组装 tasks,于是 gulp 就变成了基于 task 的组装工具。

gulp.src()

在上面的例子中,gulp.src() 函数用字符串匹配一个文件或者文件的编号(被称为“glob”),然后创建一个对象流来代表这些文件,接着传递给 uglify() 函数,它接受文件对象之后返回有新压缩源文件的文件对象,最后那些输出的文件被输入 gulp.dest()函数,并保存下来。

gulp.src() 可以接收以下类型的参数:

js/app.js 精确匹配文件 js/.js 仅匹配 js 目录下的所有后缀为 .js 的文件 js//.js 匹配 js 目录及其子目录下所有后缀为 .js 的文件 !js/app.js 从匹配结果中排除 js/app.js,这种方法在你想要匹配除了特殊文件之外的所有文件时非常好用 *.+(js|css) 匹配根目录下所有后缀为 .js 或者 .css 的文件

假如 js 目录下包含了压缩和未压缩的 JavaScript 文件,现在我们想要创建一个任务来压缩还没有被压缩的文件,我们需要先匹配目录下所有的 JavaScript 文件,然后排除后缀为 .min.js 的文件:

1
gulp.src(['js/**/*.js', '!js/**/*.min.js'])

babel

babel 用于转化 JavaScript 代码,比如将 ES6 的语法转化成 ES5,或者将 JSX 语法转化为 JavaScript 语法。

假如上文中提到的 index.js 里面的内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
'use strict';
import express, { Router } from 'express';
import bodyParser from 'body-parser';
// 定义app和router
let app = express();
let router = Router();
//中间件
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
//路由
router.get('/', (req, res, next) => {
  res.end('Hello World!');
});
app.use('/', router);
//启动app
app.listen(3000, () => {
  console.log('server listening at port 3000...');
});

使用 babel 转化为 ES5 语法:

(1) 安装 babel-core babel-preset-es2015

1
npm install --save-dev babel-core babel-preset-es2015

(2) 创建 .babelrc 文件, 配置如下

1
2
3
{
presets: [es2015]
}

(3) 手动使用 babel 转译:

1
$ babel src -d lib

(4) 安装 gulp-babel

1
$  npm install --save-dev gulp-babel

(5) 编写 gulpfile

在根目录新建一个 gulpfile.babel.js 文件。 gulp 原生并不支持 ES6 语法,但是我们可以告诉 gulp 使用 babel 将 gulpfile 转换为 ES5,方法就是将 gulpfile 命名为 gulpfile.babel.js。

(6) 使用 ES6 编写 gulpfile.babel.js

1
2
3
4
5
6
7
8
import gulp from 'gulp';
import babel from 'gulp-babel';
// 语法转化+压缩
gulp.task('default', () => {
    gulp.src('src/*.js')
        .pipe(babel())
        .pipe(gulp.dest('lib'))
});

打开 lib 目录下的 index.js 文件,就可以查看 babel 编译后的 ES5 语法的文件了。

gulp-watch

开始工作以后,每次改动 index.js 都要手动 gulp 一下实在太麻烦了,使用 gulp-watch 可以监听文件变化,当文件被修改之后,自动将文件转换。

(1) 安装 gulp-watch

1
npm install gulp-watch --save-dev

(2) 新增 task

1
2
3
4
5
6
7
8
gulp.task('watch', () => {
    gulp.src('src/*.js')
        .pipe(watch('src/*.js'), {
            verbose: true
        })
        .pipe(babel())
        .pipe(gulp.dest('lib'))
});

(3) 启动 watch task

1
gulp watch

修改 index.js 后 lib/index.js 也会随之改变。(≧∀≦)ゞ

查看全部 tasks

1
2
3
4
5
$ gulp -T
[16:06:54] Requiring external module babel-register
[16:06:54] ├── default
[16:06:54] └── watch

gulp 顺序执行

默认的,task 将以最大的并发数执行,也就是说,gulp 会一次性运行所有的 task 并且不做任何等待。如果你想要创建一个序列化的 task 队列,并以特定的顺序执行,需要做两件事:

  1. 给出一个提示,来告知 task 什么时候执行完毕,
  2. 并且再给出一个提示,来告知一个 task 依赖另一个 task 的完成。

假如我想要 task1 执行完成后再执行 task2, 可以用以下三种方式:

直接返回一个流

1
2
3
gulp.task('task1', function () {
    return gulp.watch('src/*.js');
});

//只要加一个return就好了

返回一个promise

1
2
3
4
5
6
7
8
9
10
gulp.task('task1', function () {
  var Q = require('q');
  var deferred = Q.defer();
  // do async stuff
  setTimeout(function () {
    deferred.resolve();
  }, 1);

  return deferred.promise;
});

使用回调callback

task 的执行函数其实都有个回调,我们只需要在异步队列完成的时候调用它就好了。

1
2
3
4
5
6
7
gulp.task('task1', function (cb) {
  // do async stuff
  setTimeout(function () {
    cb()
  }, 1);
});

所以只要依赖的任务是上面三种情况之一,就能保证当前任务在依赖任务执行完成后再执行。这边需要注意的是依赖的任务相互之间还是并行的。需要他们按顺序的话。记得给每个依赖的任务也配置好依赖关系。

1
2
3
4
5
6
7
8
9
10
11
12
var gulp = require('gulp');
gulp.task('one', () => {
    console.log('one');
});
// two 依赖 one
gulp.task('two', ['one'], () => {
    console.log('two');
});
// default 依赖 one,two
gulp.task('default', ['one', 'two'], () => {
    console.log('default');
});
This post is licensed under CC BY 4.0 by the author.

10 分钟快速入门 Python3

ReactJS 组件