ZetCode

Gulp 入门

最后修改于 2023 年 10 月 18 日

本文是关于 Gulp 工具的入门教程,Gulp 是一个 Node.js 构建工具。本教程涵盖 Gulp 4。

Gulp

Gulp 是一个 Node 任务运行器。它是前端 Web 开发中的流式构建系统。它有助于自动化诸如复制文件、代码检查、单元测试、图像处理、最小化 JavaScript 和 CSS 代码,或将 TypeScript 编译为 JavaScript 等任务。Gulp 是平台无关的。除了 Node.js,Gulp 还用于 .NET、Java 或 PHP 平台。

Gulp 倾向于代码而非配置。它使用任务来定义工作流。任务写在 gulpfile.js 文件中。Gulp 任务使用插件,插件是小型、单一用途的代码单元。Gulp 生态系统包含超过 3500 个此类插件。例如,gulp-minify 插件用于最小化 JS 文件。

Gulp 基于 Node 流。它从文件系统读取数据,并通过管道传递以对其进行转换。数据通过 pipe 函数从一个插件传递到另一个插件。一次执行一个任务。在管道中使用插件可以执行复杂任务。原始数据可能会被修改,或者我们可以创建新修改的数据副本。

gulp.src 函数创建用于对其执行管道操作的源文件流。gulp.dest 指定任务完成后文件的输出位置。

Gulp CLI

Gulp 由两部分组成:Gulp 库和 Gulp CLI(命令行界面)。Gulp 库在 JavaScript 代码中使用。gulp-cli 是一个实用程序,允许我们从 shell 访问 Gulp。为了使用 Gulp,我们需要安装这两个包。

Gulp 任务

Gulp 任务是一个异步 JavaScript 函数。该函数返回一个流、Promise、事件发射器、子进程或 Observable。最初,任务是使用 gulp.task 函数创建的。Gulp 现在倾向于基于模块的新语法,而旧语法仍然受支持。

现代语法允许将任务分为私有和公共。公共任务从 gulpfile 导出,允许它们由 gulp 命令运行。私有任务仅供内部使用;我们无法使用 gulp 命令运行它们。

Globbing

Globbing 是使用一个或多个 glob 字符串在文件系统中定位文件。Glob 字符串是字面量和/或通配符字符,例如 ***!,用于匹配文件路径。

*.js

此 glob 匹配所有 JS 文件。

**/*.js:

此 glob 字符串匹配根文件夹及其任何子目录中以 .js 结尾的任何文件。

!main.scss:

! 表示应排除 main.scss

*.+(scss|sass)

此 glob 字符串匹配任何以 scsssass 结尾的文件。

组合任务

Gulp.js 4.0 引入了 seriesparallel 方法来组合任务。series 按顺序运行任务,而 parallel 同时运行任务。

gulp.series(gulp.parallel(a, b), gulp.series(c, d))

在我们的例子中,首先并行运行 a 和 b 任务,然后,一旦两者都完成,就运行 c 任务,在它完成后,运行 d 任务。

Gulp 默认任务

当我们不为 Gulp CLI 工具提供任何任务名称时,将运行默认任务。

gulp.task('default', function() {
  ...
});

这是定义默认任务的旧语法。

exports.default = function() {
  ...
}

这是新语法。

安装 Gulp

我们初始化一个 Node.js 项目并安装 Gulp 库和 Gulp CLI。

$ nodejs -v
v12.16.1

我们使用 Node.js 版本 12.16.1。

$ npm init -y
$ npm i --global gulp-cli
$ npm i gulp --save-dev

我们初始化一个 Node 项目并安装 Gulp 和 Gulp CLI。

Gulp 重命名文件示例

在下面的示例中,我们使用 gulp-rename 插件来重命名我们的文件。

ls src/
about.htm  contact.htm  index.htm

src 目录中,我们有三个 HTML 文件。我们想将它们的扩展名重命名为 .html。

$ nmp i --save-dev gulp-rename

我们安装 gulp-rename 插件。

gulpfile.js
const { src, dest } = require('gulp');
const rename = require('gulp-rename');


function renameFiles() {

    return src('src/*.htm')
        .pipe(rename({ extname: '.html' }))
        .pipe(dest('dist/'));
}

exports.rename = renameFiles;

我们创建 renameFiles 任务。它重命名 src 目录中的所有 .htm 文件,并将它们复制到 output 目录。

return src('src/*.htm')
    .pipe(rename({ extname: '.html' }))
    .pipe(dest('dist/'));

使用 src 函数,我们从 src 目录中的 htm 文件创建源流。我们使用 globbing 仅选择 htm 文件。pipe 函数从流中获取数据并对其应用 rename 函数。使用 dest 函数,我们指定输出流;这是我们将重命名文件复制到的目录。

$ gulp rename
[12:31:42] Using gulpfile ~/Documents/prog/js/gulp-lib/gulpfile.js
[12:31:42] Starting 'rename'...
[12:31:42] Finished 'rename' after 35 ms

使用 gulp 工具,我们运行 rename 任务。

$ ls dist/
about.html  contact.html  index.html

文件已重命名。

gulp-minify 示例

gulp-minify 插件用于最小化 JS 文件。

$ npm i --save-dev gulp-minify

我们安装 gulp-minify 插件。

src/js/main.js
function hello() {

    return 'Hello there!';
}

hello();

我们有一个简单的 main.js 文件,其中包含一个函数。

gulpfile.js
const { src, dest } = require('gulp');
const minify = require("gulp-minify");


exports.default = () => {

    return src('src/js/main.js', { allowEmpty: true })
        .pipe(minify({noSource: true}))
        .pipe(dest('dist/js'))
}

我们读取 JS 文件,将其通过 minify 函数,并将结果写入 dist/js 目录。

$ gulp
[14:01:21] Using gulpfile ~/Documents/prog/js/gulp-lib/gulpfile.js
[14:01:21] Starting 'default'...
[14:01:21] Finished 'default' after 75 ms

我们运行默认的 Gulp 任务。

$ cat dist/js/main-min.js
function hello(){return"Hello there!"}hello();

这些是最小化的 main-min.js 文件的内容。

Gulp 组合任务

在下一个示例中,我们使用 seriesparallel 组合任务。在此示例中,我们需要 gulp-minifygulp-renamegulp-clean-cssdel 插件。

gulp-clean-css 用于最小化 CSS。del 用于删除文件和目录。

src/
├── js
│   └── main.js
└── styles
    └── main.css

我们有这个目录结构。

src/js/main.js
function hello() {

    return 'Hello there!';
}

hello();

这是一个简单的 main.js 文件。

src/styles/main.css
body {
  font-family:georgia; font-size:1em;
  line-height:1.7em;
  background: #333;
  text-align:center;
}

这是一个简单的 main.css 文件。

gulpfile.js
const { src, dest, series, parallel } = require('gulp');
const minify = require("gulp-minify");
const rename = require("gulp-rename");
const cleanCSS = require('gulp-clean-css');
const del = require('del');


const clean = () => del([ 'dist' ]);

function styles() {

    return src('src/styles/main.css', { allowEmpty: true })
        .pipe(cleanCSS())
        .pipe(rename({
          basename: 'main',
          suffix: '.min'
        }))
        .pipe(dest('dist/styles'))
}

function scripts() {

    return src('src/js/main.js', { allowEmpty: true })
        .pipe(minify({noSource: true}))
        .pipe(dest('dist/js'))
}

const build = series(clean, parallel(styles, scripts));

exports.styles = styles;
exports.scripts = scripts;
exports.clean = clean;
exports.build = build;

exports.default = build;

gulpfile 会最小化 CSS 和 JS 文件。它会清理分发目录。工作流被分成几个任务。

const clean = () => del([ 'dist' ]);

clean 任务会删除 dist 目录。

function styles() {

    return src('src/styles/main.css', { allowEmpty: true })
        .pipe(cleanCSS())
        .pipe(rename({
          basename: 'main',
          suffix: '.min'
        }))
        .pipe(dest('dist/styles'))
}

styles 任务会最小化 CSS 文件并重命名它。它会添加 .min 扩展名。

function scripts() {

    return src('src/js/main.js', { allowEmpty: true })
        .pipe(minify({noSource: true}))
        .pipe(dest('dist/js'))
}

scripts 任务会最小化 JS 文件。

const build = series(clean, parallel(styles, scripts));

我们定义了一个 build 任务。它是三个任务的组合。首先,运行 clean 任务。完成后,并行运行 stylesscripts

exports.styles = styles;
exports.scripts = scripts;
exports.clean = clean;
exports.build = build;

exports.default = build;

我们导出了五个函数。任务可以独立调用,也可以在 build 任务中组合。此外,build 任务是默认任务。

$ gulp build
[15:17:01] Using gulpfile ~/Documents/prog/js/gulp-lib/gulpfile.js
[15:17:01] Starting 'build'...
[15:17:01] Starting 'clean'...
[15:17:01] Finished 'clean' after 13 ms
[15:17:01] Starting 'styles'...
[15:17:01] Starting 'scripts'...
[15:17:01] Finished 'scripts' after 53 ms
[15:17:01] Finished 'styles' after 54 ms
[15:17:01] Finished 'build' after 70 ms

我们显式运行 build 任务。

在本教程中,我们介绍了 Gulp。

您可能还对以下相关教程感兴趣:Node Sass 教程Gulp 最小化教程Gulp Sass 教程

列出 所有 JavaScript 教程

作者

我的名字是 Jan Bodnar,我是一名充满激情的程序员,拥有丰富的编程经验。我自 2007 年以来一直在撰写编程文章。迄今为止,我已撰写了 1,400 多篇文章和 8 本电子书。我在编程教学方面拥有超过十年的经验。