前端工程化一直是前端非常热门的话题之一,开发者不断研究如何使项目更加规范化,如何提升开发效率,围绕着前端工程化,出现了 Webpack,Rollup,Vite 等构建工具,这些都是目前比较主流的方案,但是也有其他的工具能帮我们解决实际的问题,比如本文所要聊的 Glup。
现在很多人都不知道 Gulp,毕竟用得少,感觉似乎好像被取代了,其实并没有,只不过它从台前退居到了幕后,现在 gulp 更多的是做流程化的控制,可以使用它在项目开发过程中自动执行常见任务。那么这篇文章给大家分享 Gulp 的基本使用,以及两个实战例子,让大家了解在实际的项目中如何使用 Gulp 解决项目遇到的一些问题。
一、Gulp的简单介绍
中文文档: www.gulpjs.com.cn/
Gulp.js 是一个自动化构建工具,开发者可以使用它在项目开发过程中自动执行常见任务,它是基于 Node.js 构建的,利用 Node.js 流的威力,你可以快速构建项目并减少频繁的 IO 操作。Gulp 能自动化地完成 javascript/coffee/sass/html/image/css 等文件的合并、压缩、检查、监听文件变化、浏览器自动刷新、测试等任务,它更高效(异步多任务), 更易于使用, 插件高质量。
总的来说,Gulp 将开发流程中让人痛苦或耗时的任务自动化,从而减少我们所浪费的时间、创造更大价值。
下面来看下简单的使用,首先安装 gulp:
js
npm install gulp --save-dev
在项目根目录创建 gulpfile.js 文件,并写入内容:
js
var gulp = require('gulp');
// 定义一个任务,名称为 task_name
gulp.task('task_name', function() {
// do
});
在 package.json 中添加脚本命令 "task_name": "gulp task_name",然后执行构建命令:npm run task_name 即可开启任务的执行:
js
npm run task_name
二、Gulp常见的API
1. gulp.src
gulp.src(filePath/pathArr) :用于读取文件,指向指定路径的所有文件, 并返回文件流对象
js
const { src, dest } = require('gulp');
function copy() {
return src('input/*.js')
.pipe(dest('output/'));
}
pipe():管道流,接通源头文件与目标文件的输出
2. gulp.dest
gulp.dest(dirPath/pathArr):将指定路径的所有文件,输出到指定的文件夹中
js
const { src, dest } = require('gulp');
function copy() {
return src('input/*.js')
.pipe(dest('output/'));
}
3. gulp.task
gulp.task(name, [deps], fn):用于定义一个任务
简单用法:
js
var gulp = require('gulp');
// 定义一个任务,名称为 task_name
gulp.task('task_name', function() {
// do
});
任务执行链,三个参数的情况:gulp.task('任务名称',[任务依赖的模块],回调函数)
,依赖任务之间没有顺序之分,异步执行;依赖任务之间完成后,再执行当前的回调函数。
js
// 默认任务,执行scripts和styles这两个任务
gulp.task('default', ['scripts', 'styles'], function() {...});
// scripts 和 styles 任务都调用了 clean 任务
gulp.task('styles', ['clean'], function() {...});
gulp.task('scripts', ['clean'], function() {...});
// Clean 任务清空了build目录
gulp.task('clean', function() {...});
4. gulp.series
gulp.series(...tasks):将任务函数和/或组合操作组合成更大的操作,这些操作将按顺序依次执行,也就是依次执行一系列的任务(串行)。
js
var gulp = require('gulp');
// 定义两个任务
function javascript(cb) {
// cb();
}
function css(cb) {
// cb();
}
exports.build = gulp.series(javascript, css);
5. gulp.parallel
gulp.parallel 的作用类似于 series,但 parallel 是并行执行,通过一张图来看下他们的区别:
三、Gulp常见的任务
下面来看一些常见任务的定义以及处理,以加深对任务的理解:
js
const gulp = require('gulp'); //引用gulp
const del = require('del'); //引用gulp删除插件
const uglify = require('gulp-uglify'); //引用压缩Js插件
const css = require('gulp-clean-css'); //gulp压缩css文件
var babel = require('gulp-babel'); // 获取babel模块
var concat = require("gulp-concat");
// task():定义任务
// src():源文件
// pipe():管道流,接通源头文件与目标文件的输出
// dest():输出文件的目的地
// watch():监视文件
// 1、复制单个文件
gulp.task('copyHtml',function () {
return gulp.src('./test.js').pipe(gulp.dest("./test2"))
});
// 2、复制多个文件
gulp.task('copyAllHtml', function () {
return gulp.src("./src/utils/*.js").pipe(gulp.dest('./copy'));
});
// 3、复制指定文件
// [指定的文件已,指定的文件2]
gulp.task('copy2Js', function () {
return gulp.src(["./test.js",'./test2/test.js'])
.pipe(gulp.dest("./test3"))
});
// 4、复制多个后缀名的图片
// {选项一,选项二}
gulp.task("copyImage", function () {
return gulp.src('./src/assets/*.{png,jpg,bmp,jpeg,gif}')
.pipe(gulp.dest('./copyimg'))
});
// 5、执行多个任务
gulp.task('build', gulp.series(['hello','copyHtml','copyAllHtml','copy2Js'], done => {
console.log('编译成功')
done()
}));
// 6、Watch:监视文件的变化
gulp.task('myWatch', function () {
gulp.watch('./index.html', ['build'])
});
// 7、删除文件
gulp.task("del", done => {
// del('./dist/public/img/*.{jpg,png,jepg,gif}')
// *:所有文件
// **:所有文件夹
del(['./test.js']);
done()
});
gulp.task('clean', function() {
return del(['build/!*']);
});
gulp.task('default', gulp.series('del', function() {
// default task code here
}));
//因为在压缩js时,uglify 这个模块不支持es6的语法,所以可以先用babel把代码编译成es5
gulp.task("babel", function () {
return gulp.src("./src/utils/*.js")// ES6 源码存放的路径
.pipe(babel())
.pipe(gulp.dest("./es5")); //转换成 ES5 存放的路径
});
// 8、压缩js文件
gulp.task('ysjs', function(){
return gulp.src('./src/utils/*.js')
.pipe(uglify())
.pipe(gulp.dest('./ysjs'));
});
// 9、压缩css文件
gulp.task('css', function () {
return gulp.src('./src/style/*.less')
.pipe(css())
.pipe(gulp.dest('./yscss'))
});
// 添加监听
gulp.task('jtCss', function () {
return gulp.watch('./src/style/*.less',function() {
console.log('css修改');
gulp.src('./src/style/*.less')
.pipe(css())
.pipe(gulp.dest('./yscss'))
})
});
// 10、代码合并
gulp.task("concat", function () {
gulp.src("src/js/*.js")
.pipe(concat("main.js")) //后面要写合并后的文件名
.pipe(uglify()) //可以在后面跟代码压缩
.pipe(gulp.dest("dist/js"))
});
四、Gulp实战例子
1. 压缩图片
首先安装依赖:
js
npm i gulp gulp-imagemin
在项目根目录新建 gulpfile.js 文件:
js
// gulpfile.js
import fs from 'fs';
import path from 'path';
import glob from 'glob';
import { fileURLToPath } from 'url';
import gulp from 'gulp';
import imagemin from 'gulp-imagemin'; // 图片压缩插件
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const imagesAssetsDir = 'src/assets'; //图片资源所在文件夹
let filterList = []; //剔除压缩过的文件列表
// 获取图片资源
const getTargetFiles = async () => {
return new Promise((resove, reject) => {
glob(`${imagesAssetsDir}/**/*`, function (err, files) {
if (err) throw err;
filterList = files.filter(function (file) {
return !fs.statSync(file).isDirectory();
});
resove();
});
});
};
// 压缩图片
const optimizationImages = done => {
if (filterList.length === 0) {
done();
return;
}
return gulp
.src(filterList)
.pipe(imagemin({ verbose: true }))
.pipe(
gulp.dest(file => {
// 兼容windows路径 \
const path = file.path.replace(`${__dirname}/`, '').replace(`${__dirname}\\`, '');
excludesList.push(path);
return file.base;
}),
);
};
// 按顺序执行一系列的任务
gulp.task('imagemin', gulp.series(getTargetFiles, optimizationImages));
在 package.json 中 scripts 中添加脚本命令:
js
// imagemin 表示 gulp.task 中定义的任务名称
"imagemin": "gulp imagemin",
将要上传的资源放到 src/assets 目录中,然后执行命令:
js
npm run imagemin
之后即可完成图片的压缩,这里有一个可以优化的点,就是可能会导致重复压缩,为了防止重复压缩,可以考虑将压缩过的图片名称以及路径记录下来,存到一个文件中(比如:imagemin-record.js),压缩前进行一次过滤操作。
压缩完成之后,在文件中写入记录:
js
// imagemin-record.js
export default [
"src/assets/banner.png",
"src/assets/avatar.png",
]
2. 上传资源到七牛
首先安装依赖:
js
npm i gulp gulp-qiniu
根目录新建 qiniuAssets 目录和 gulpfile.js ,配置如下:
js
const gulp = require('gulp')
const path = require('path')
const qiniu = require('gulp-qiniu') // 插件
const imageSrc = path.resolve(__dirname, 'qiniuAssets/*.*')
gulp.task('qiniu', (done) => {
gulp
.src(imageSrc)
.pipe(
qiniu(
{
accessKey: 'xxxxxxxx',
secretKey: 'xxxxxxxx',
bucket: 'xxxxxxxxxx',
private: false,
},
{
dir: 'static/assets/',
version: false,
},
),
)
.on('finish', done)
})
gulp.task('upload',gulp.series(['qiniu'], (done) => {
done()
}))
在 package.json 中 scripts 中添加脚本命令:
js
"upload": "gulp qiniu",
将要上传的资源放到 qiniuAssets 目录中,然后执行命令:
js
npm run upload
就可以使用上传后的资源 url,如:img.hzd.com/static/...p...