hi,在这里分享和记录一下 gulp 的基本使用,让我们对 gulp 有一个基本的了解,使我们遇到 gulp 搭建的第三方库或者项目时,不会变的手足无措。
介绍
gulp 是一个异步的,基于流的前端构建工具。
要安装 gulp,首先要确保你的电脑里已经安装了node,可以通过node -v查看你是否已经安装了 node 和你的 node 版本。
安装
全局安装 gulp 命令行工具:npm i -G gulp-cli
使用gulp命令的三种方式:
- 全局安装 gulp-cli,使用
gulp --help查看和使用命令 - 安装 gulp,配置 package.json,使用 npm、yarn 或者 pnpm 运行
- 不安装 gulp-cli,使用
npx gulp --help查看和使用命令
初始化项目:npm init -y
安装 gulp:npm i -D gulp
配置文件
创建 gulp 配置文件有两种方式:
- 创建 gulpfile.js 文件。
- 创建 gulpfile 文件夹,文件夹中创建 index.js 文件。
API
在此仅介绍几个常用 api 的基本用法,要了解详细内容请阅读 官网。 在此还得提一嘴 Vinyl 对象,Vinyl 对象就是 描述文件的元数据对象。globs 即是文件路径匹配规则。
- src() 创建流,从文件系统中读取 vinyl 对象
- dest() 将 vinyl 对象写入到文件系统的流
- series() 串联任务,按顺序依次执行任务
- parallel() 并行任务,同时执行的任务
- watch() 监听 globs 发生更改时运行任务
创建、导出任务
在 gulpfile 文件中有三种 gulp 任务:
- 公开任务:通过 exports 导出,可以被
gulp xxx任务名调用的任务。 - 私有任务:没有通过 exports 导出,不可以被
gulp xxx任务名调用的任务。 - 组合任务:series() 和 parallel(),允许将多个独立的任务组合为一个更大的任务。也可以可以互相嵌套至任意深度。
注意:exports 默认将函数注册为任务。旧版本中,task()用来将函数注册为任务。
const { series, parallel } = require('gulp'); // series、parallel可以接受任意数量的任务
const publicTask = cb => cb();
const privateTask = cb => cb(); // 私有任务
exports.publicTask = publicTask; // 公开任务
exports.seriesTask = series(publicTask, privateTask); // 组合任务
exports.default = parallel(publicTask, series(publicTask, privateTask)); // 组合任务
/** 以下是运行gulp的结果 **/
[16:27:52] Starting 'default'... // Starting 开始任务
[16:27:52] Starting 'publicTask'...
[16:27:52] Finished 'publicTask' after 1.03 ms // Finished 完成的任务和完成时间
[16:27:52] Starting 'publicTask'...
[16:27:52] Finished 'publicTask' after 750 μs
[16:27:52] Starting 'privateTask'...
[16:27:52] Finished 'privateTask' after 455 μs
[16:27:52] Finished 'default' after 4.99 ms
运行任务
gulp 运行任务同 gulp 命令的三种方式一样。以下仅使用一种方式举例:
gulp publicTask // 使用gulp运行指定任务
gulp // 使用gulp运行默认任务,即exports.default的任务
插件和api使用
启动服务
gulp-connect起本地服务
安装npm i -D gulp-connect,配置如下:
const { series } = require('gulp');
const connect = require('gulp-connect');
function serverTask(cb) {
connect.server({
name: 'demo', // 服务器启动、停止时,输出的名称
root: 'dist', // 根路径,运行时默认打开的文件位置。可配置Array或String
livereload: true, // 是否实时加载
host: '127.0.0.1', // 主机号
port: '8080', // 端口号
})
cb();
}
exports.default = series(serverTask);
运行 gulp 后就可以在控制台看到如下内容,就表示你的本地服务已经成功启动啦。
删除文件
del在下一次打包前删除上一次打包的文件
安装npm i -D del,配置如下:
const { src, dest, series } = require('gulp');
function deleteFile() {
return import('del').then(({ deleteSync }) => deleteSync('dist/'))
}
exports.default = series(serverTask, deleteFile, buildHTML);
处理js文件
gulp-babel将ES6+代码转换为ES5
gulp-uglify压缩 js 代码
安装npm i -D gulp-babel @babel/core @babel/preset-env gulp-uglify配置如下:
const { src, dest, series, parallel } = require('gulp');
const connect = require('gulp-connect');
const babel = require('gulp-babel');
const uglify = require('gulp-uglify');
function buildJS() {
return src('src/*.js') // 从文件系统中读取 globs 匹配的 vinyl 对象
.pipe(babel({
"presets": [ // 配置 babel 预设
[
"@babel/preset-env", { // 使用 @babel/preste-env 并配置参数
"useBuiltIns": 'usage', // 指定模块导入模式
"corejs": 3 // 指定 corejs 版本
}
]
]
}))
.pipe(uglify({ // 压缩 js 代码
mangle: {
toplevel: true // 混淆变量名
}
}))
.pipe(dest('dist/')) // 输出到 dist 目录
.pipe(connect.reload()) // 热更新
}
exports.default = series(serverTask, deleteFile, parallel(buildHTML, buildJS));
运行 gulp,查看 dist 目录打包好的 js 文件如下:
处理html文件
gulp-htmlmin压缩 html
安装npm i -S gulp-htmlmin,配置如下:
const { src, dest, series, parallel } = require('gulp');
const connect = require('gulp-connect');
const htmlmin = require('gulp-htmlmin');
function buildHTML() {
return src('src/*.html') // 从文件系统读取 globs匹配的 vinyl 对象
.pipe(htmlmin({
collapseWhitespace: true, // 是否 折叠空格
caseSensitive: true, // 是否 以区分大小写的方式区分属性
collapseBooleanAttributes: true, // 是否 从布尔值中省略属性值
removeAttributeQuotes: true, // 尽可能删除属性两边的引号
removeComments: true, // 去除HTML注释
removeEmptyAttributes: true, // 删除所有仅含空格值的属性
removeEmptyElements: true, // 删除所有内容为空的属性
minifyCSS: true, // 压缩内联css
minifyJS: true, // 压缩内联js
}))
.pipe(dest('dist/')) // 将 vinyl 对象写入文件系统
.pipe(connect.reload()) // 热更新
}
exports.default = series(serverTask, parallel(buildHTML, buildJS));
运行 gulp,查看 dist 目录打包好的 html 文件如下:
处理scss文件
gulp-sass将 sass 文件转换为 css 文件
gulp-autoprefixer自动添加不同浏览器的 css 前缀,使用此插件需要在package.json 文件中添加"browserslist": "last 2 versions"
gulp-clean-css压缩 css
安装npm i -D gulp-sass gulp-autoprefixer gulp-clean-css,配置如下:
const { src, dest, series, parallel } = require('gulp');
const connect = require('gulp-connect');
const sasscss = require('gulp-sass')(require('sass'));
const autoprefixer = require('gulp-autoprefixer');
const cleancss = require('gulp-clean-css');
function buildCSS() {
return src('src/*.scss')
.pipe(sasscss()) // 转换 css
.pipe(autoprefixer({
cascade: false, // 补充前缀 是否 以级联的方式展示
}))
.pipe(cleancss()) // 压缩 css
.pipe(dest('dist/'))
.pipe(connect.reload()) // 热更新
}
exports.default = series(serverTask, parallel(buildCSS, buildHTML, buildJS));
监听文件
监听文件变化,更新对应打包文件。配置如下:
const { src, dest, series, parallel, watch } = require('gulp');
function watchFile(cb) {
// watch 的 change 事件,监听文件变化,获取对应路径 执行对应操作
watch(['src/**/*']).on('change', (path, stat) => {
// 匹配路径调用对应的任务
if (/\.html$/.test(path)) { // 匹配 html
return buildHTML();
}
if (/\.scss$/.test(path)) { // 匹配 scss
return buildCss();
}
if (/\.js$/.test(path)) { // 匹配 js
return buildJS();
}
})
cb(); // 没有任何返回,则需要调用cb结束当前任务
}
exports.default = series(serverTask, parallel(buildCSS, buildHTML, buildJS), watchFile);
大致就是酱子了。