基于 Gulp4。
task runner
。可以定义一系列任务,等到任务被执行;是基于文件Stream 的构建流;可以使用 Gulp 的插件体系来完成任务。module bundler
。是一个模块化的打包工具;可以使用各种各样的 Lodaer 来加载不同的模块;可以使用各种各样的插件在打包的生命周期中完成其他的任务。Gulp 相对于 Webpack 来说更加地简单易用,适合编写一些自动化的任务,让它们挨个自动去执行,但是对于目前大型的项目(React、Vue、Angular 等)并不会使用 Gulp 来构建。
Gulp 默认不支持模块化。
每个 Gulp 任务都是一个异步的 JavaScript 函数;接收一个回调函数作为参数;必须明确地表示被执行完成,可以通过两种方式:执行作为参数的回调函数,或者返回一个 stream、promise、event emitter
、child process
或者 observable 类型的函数。
Gulp 中任务可以分为公开任务和私有任务。
gulpfile.js
文件中导出的任务被称为公开任务,这些任务可以通过 gulp 命令直接调用。series()
或者 parallel()
任务组合的组成部分。新建 gulp-demo
文件夹,并 npm init -y
初始化该项目。
在该文件夹下本地安装 Gulp:npm install gulp
。
在项目根目录下新建 gulpfile.js
文件,并定义任务。
// gulpfile.js
// 定义任务
const test = callback => {
console.log('test 任务被执行')
callback()
}
// 导出任务
module.exports = {
test
}
在 Gulp4 之前,定义任务的写法为:
// gulpfile.js const gulp = require("gulp") gulp.task('test', callback => { console.log('test 任务被执行') callback() })
运行 npx gulp test
命令,会自动去 fulpfile.js
文件中查找对应的任务并执行。
如果觉得觉得在 npx gulp
命令还得跟着任务名比较麻烦,可以导出一个 default 任务。直接运行 npx gulp
命令将会自动执行该 default 任务。
// gulpfile.js
// 定义并导出默认任务
module.exports.default = callback => {
console.log('default 任务被执行')
callback()
}
Gulp 提供了两个组合方法,它们都可以接收任意数量的任务函数或者已经组合的操作。
series()
:串行任务组合。多个任务会挨个执行,只有执行完前一个才能执行后一个。parallel()
:并行任务组合。多个任务或同时执行,顺序无法确定。const {parallel} = require('gulp')
// 定义任务
const task1 = callback => {
setTimeout(() => {
console.log('task1 任务被执行')
callback()
}, 2000)
}
const task2 = callback => {
setTimeout(() => {
console.log('task2 任务被执行')
callback()
}, 1000)
}
const parallelTask = parallel(task1, task2)
// 导出任务
module.exports = {
parallelTask
}
Gulp 暴露了 src()
和 dest()
方法用于处理计算机上存放的文件。
src()
:接收一个 glob 字符串或由多个 glob 字符串组成的数组作为参数,将所有从文件系统中匹配到的文件读取到内存中,并产生一个 Stream 流,通过该 Stream 流进行处理。src()
产生的 Stream 流应当从任务函数中返回,发生异步任务完成的信号。
glob 的匹配规则:
*
:在一个字符串中,匹配任意数量的字符。例如 src/*.js
。**
:在多个字符串匹配中,匹配任意数量的字符。通常用在匹配某个目录下的文件。例如 src/**/*.js
。!
:glob 匹配时是按照在数组中的位置依次进行匹配的,glob 数组中的取反 glob 必须跟在一个非取反 glob 后面,表示后面取反 glob 删除掉前面非取反 glob 匹配到的匹配项中的一部分。例如 ['src/**/*.js', 'src/vendor/']
glob 字符串或者 glob 数组至少需要匹配到一个匹配项,否则
src
将会报错。
dest()
:接收一个输出目录作为参数,会产生一个 Node Stream 流,通过该 Stream 流将内容输出到文件中。
Stream 流提供的主要的 API 就是 pipe()
方法,pipe()
方法接收一个转换流或者可写流。
src/index.js
文件,并编写代码。const fn = () => {
console.log('index')
}
fn()
gulpfile.js
中编写 Gulp 读取和写入文件的方法。const {src, dest} = require('gulp')
const output = () => {
// 读取 src 中的所有内容并输出到 dist 目录下
return src('./src/*.js').pipe(dest('./dist'))
}
module.exports = {
output
}
npx gulp output
命令,会发现,生成了 dist 目录,并复制了 src 目录下的文件及其内容。以 gulp-babel
插件和 gulp-terser
插件为例,可以对 JavaScript 代码进行转换。
gulp-babel
:npm install gulp-babel -D
。npm install @babel/core -D
。npm install @babel/preset-env -D
。gulp-terser
:npm install gulp-terser -D
。gulpfile.js
文件中编写代码使用插件。const {src, dest} = require('gulp')
const babel = require('gulp-babel')
const terser = require('gulp-terser')
const output = () => {
// 读取 src 中的所有内容
return src('./src/*.js')
// 使用 babel 进行转换
.pipe(babel({
presets: ['@babel/preset-env'],
}))
// 对其进行压缩和丑化
.pipe(terser())
// 输出到 dist 目录下
.pipe(dest('./dist'))
}
module.exports = {
output
}
npx gulp output
命令,会发现,生成了 dist 目录,复制了 src 目录下的文件及其内容,并对其进行了压缩和丑化。可以使用 Gulp 提供的 watch()
函数监听源文件的变化来执行指定的任务。
const {src, dest, watch} = require('gulp')
const output = () => {
return src('./src/*.js').pipe(dest('./dist'))
}
// 监听 src 中所有内容的变化,只要发生变化就执行 output 任务
watch('./src/*.js', output)
module.exports = {
output
}
src/index.html
文件,并编写代码。// src/index.html
Document
gulp-htmlmin
插件处理 HTML 文件:npm install gulp-htmlmin -D
。src/css/index.less
文件,并编写代码。@mainSize: 24px;
body{
size: @mainSize;
user-select: none;
}
gulp-less
插件处理 Less 文件:npm install gulp-less -D
。
安装
gulp-less
插件会自动安装 Less。
gulp-postcss
自动给 CSS 属性添加浏览器前缀:npm install gulp-postcss -D
。npm install postcss -D
。postcss-preset-env
插件:npm install postcss-preset-env -D
。src/js/index.js
文件,并编写代码。// src/js/index.js
const fn = () => {
console.log('index111')
}
fn()
gulp-babel
插件转换 JavaScript 文件:npm install gulp-babel -D
。npm install @babel/core -D
。npm install @babel/preset-env -D
。gulp-terser
插件压缩丑化 JavaScript 文件:npm install gulp-terser -D
。gulp-inject
插件将打包后的 CSS、JavaScript 文件注入到 HTML 文件中:npm install gulp-inject -D
。src/index.html
中编写要注入文件的魔法注释。
Document
del
插件删除指定的文件夹:npm install del -D
。 browser-sync
插件开启一个本地服务:npm install browser-sync -D
。gulpfile.js
文件,并编写任务。const {src, dest, watch, series, parallel} = require('gulp')
const htmlMin = require('gulp-htmlmin')
const less = require('gulp-less')
const postcss = require('gulp-postcss')
const postcssPresetEnv = require('postcss-preset-env')
const babel = require('gulp-babel')
const terser = require('gulp-terser')
const inject = require('gulp-inject')
const del = require('del')
const browseSync = require('browser-sync')
// 处理 HTML 文件的任务
const htmlTask = () => {
return src('./src/*.html', {base: './src'})// base:基础文件夹,在输出文件夹下会根据此文件夹下的目录生成同样对应的目录
// 对 HTML 文件进行压缩
.pipe(htmlMin({collapseWhitespace: true}))
.pipe(dest('./dist'))
}
// 处理 Less 文件的任务
const lessTask = () => {
return src('./src/css/*.less', {base: './src'})
// 对 HTML 文件进行压缩
.pipe(less())
.pipe(postcss([postcssPresetEnv()]))
.pipe(dest('./dist'))
}
// 处理 JavaScript 文件的任务
const jsTask = () => {
return src('./src/js/*.js', {base: './src'})
// 对 JS 文件进行转换
.pipe(babel({presets: ['@babel/preset-env']}))
// 对 JS 文件进行压缩和丑化
.pipe(terser({mangle: {toplevel: true}}))
.pipe(dest('./dist'))
}
// 将打包后的 CSS、JavaScript 文件注入到 HTML 文件中
const injectHtml = () => {
return src('./dist/*.html')
.pipe(inject(src(['./dist/css/*.css', './dist/js/*.js']), {relative: true})) // relative 属性用来配置注入后使用相对路径
.pipe(dest('./dist'))
}
// 删除指定的文件
const cleanTask = () => {
return del(['dist'])
}
// 开启一个本地服务
const bs = browseSync.create() // 创建本地服务器对象
const serveTask = () => {
// 监听 src 中的文件发生变化自动重新执行任务进行打包和注入
watch('./src/*.html', series(htmlTask, injectHtml))
watch('./src/css/*.less', series(lessTask, injectHtml))
watch('./src/js/*.js', series(jsTask, injectHtml))
bs.init({
port: 8080,
// 自动打开浏览器
open: true,
// dist 中的文件发生变化自动刷新浏览器
files: './dist/*',
server: {
// 服务器服务于哪个文件夹
baseDir: './dist',
}
})
}
// 生产阶段打包
const build = series(cleanTask, parallel(htmlTask, lessTask, jsTask), injectHtml)
// 开发阶段打包并开启本地服务
const serve = series(build, serveTask)
module.exports = {
build,
serve
}
npx gulp serve
,会发现, HTML、CSS、JavaScript 文件都被打包到了 dist 文件夹下,并且 CSS、JavaScript 注入到了 HTML 文件中,而且开启了一个本地父亲。