Gulp 的基本使用
安装 gulp
yarn add gulp --dev
在项目根目录下创建 gulp入口文件 gulpfile.js
// 实现这个项目的构建任务
exports.foo = done => {
console.log('foo123')
done() // gulp 任务都为异步任务,所以需要调用done函数来标识任务结束
}
// default 为默认任务
exports.default = done => {
console.log('defalut task')
done() // gulp 任务都为异步任务,所以需要调用done函数来标识任务结束
}
执行任务命令
yarn gulp foo
执行默认任务命令
yarn gulp
Gulp 创建组合任务
使用 gulp 的 series、parallel 模块来创建组合任务
series 用来创建串行任务
parallel 用来创建并行任务
const { series, parallel } = require('gulp')
const task1 = done => {
setTimeout(() => {
console.log('task1 working')
done()
}, 1000)
}
const task2 = done => {
setTimeout(() => {
console.log('task2 working')
done()
}, 1000)
}
const task3 = done => {
setTimeout(() => {
console.log('task3 working')
done()
}, 1000)
}
exports.foo = series(task1, task2, task3)
exports.bar = parallel(task1, task2, task3)
Gulp 创建异步任务的几种方式
const fs = require('fs')
// 使用回调函数
exports.callback = done => {
console.log('callback task')
done()
}
exports.callback_error = done => {
console.log('callback task')
done(new Error('task failed'))
}
// 使用 promise
exports.promise = () => {
console.log('promise task')
return Promise.resolve()
}
exports.promise_error = () => {
console.log('promise task')
return Promise.reject(new Error('task failed'))
}
// 使用 async await
exports.async = async () => {
await timeout(1000)
console.log('async task')
}
const timeout = time => {
return new Promise(resolve => {
setTimeout(resolve, time)
})
}
// 使用 stream
// readStream 有一个 end 的事件,一旦读取的文件流完成后,就会触发end事件,gulp就会知道任务完成了
exports.stream = () => {
const read = fs.createReadStream('yarn.lock')
const write = fs.createWriteStream('a.txt')
read.pipe(write)
return read
}
使用gulp完成代码压缩
const fs = require('fs')
const { Transform } = require('stream')
exports.default = () => {
// 文件读取流
const readStream = fs.createReadStream('normalize.css')
// 文件写入流
const writeStream = fs.createWriteStream('normalize.min.css')
// 文件转换流
const transformStream = new Transform({
// 核心转换过程
transform: (chunk, encoding, callback) => {
const input = chunk.toString()
const output = input.replace(/\s+/g, '').replace(/\/\*.+?\*\//g, '')
callback(null, output)
}
})
return readStream
.pipe(transformStream) // 转换
.pipe(writeStream) // 写入
}
Gulp 文件操作API + 插件的使用
const { src, dest } = require('gulp') // src: 读取流 dest: 写入流
const cleanCSS = require('gulp-clean-css') // 压缩 css文件
const rename = require('gulp-rename') // 写入后的文件重命名
exports.default = () => {
return src('src/*.css')
.pipe(cleanCSS())
.pipe(rename({ extname: '.min.css' })) // extname:重新命名扩展名
.pipe(dest('dist'))
}
样式编译
const { src, dest } = require('gulp')
const sass = require('gulp-sass') // 编译 sass 文件
// sass文件编译后,样式尾部 } 会跟在最后一个属性后面,
// 设置 outputStyle: 'expanded',可以让 尾部 }换行
const style = () => {
return src('src/assets/styles/*.scss', { base: 'src' }) // base:保留基准路径
.pipe(sass({ outputStyle: 'expanded' }))
.pipe(dest('dist'))
}
module.exports = {
style
}
脚本编译
安装 babel 依赖 yarn add gulp-bable --dev
安装 babel 核心转换模块 yarn add @babel/core @babel/preset-env --dev
const { src, dest } = require('gulp')
const sass = require('gulp-sass') // 编译 sass 文件
const babel = require('gulp-babel') // 使用babel转换es6语法
// sass文件编译后,样式尾部 } 会跟在最后一个属性后面,
// 设置 outputStyle: 'expanded',可以让 尾部 }换行
const style = () => {
return src('src/assets/styles/*.scss', { base: 'src' }) // base:保留基准路径
.pipe(sass({ outputStyle: 'expanded' }))
.pipe(dest('dist'))
}
const script = () => {
return src('src/assets/scripts/*.js', { base: 'src' })
.pipe(babel({ presets: ['@babel/preset-env'] }))
.pipe(dest('dist'))
}
module.exports = {
style,
script
}
页面模板编译
如果页面有使用模板引擎,则要安装 对应的模板引擎转换插件
例如页面使用了 swig, 需要安装 swig 转换插件 yarn add gulp-swig --dev
然后使用 parallel 完成 并行任务
const { src, dest, parallel } = require('gulp')
const sass = require('gulp-sass') // 编译 sass 文件
const babel = require('gulp-babel') // 使用babel转换es6语法
const swig= require('gulp-swig') // 页面模板引擎转换插件
// 准备页面模板引擎渲染数据
const data = {
menus: [
{
name: 'Home',
icon: 'aperture',
link: 'index.html'
},
{
name: 'Features',
link: 'features.html'
},
{
name: 'About',
link: 'about.html'
},
{
name: 'Contact',
link: '#',
children: [
{
name: 'Twitter',
link: 'https://twitter.com/w_zce'
},
{
name: 'About',
link: 'https://weibo.com/zceme'
},
{
name: 'divider'
},
{
name: 'About',
link: 'https://github.com/zce'
}
]
}
],
pkg: require('./package.json'),
date: new Date()
}
// sass文件编译后,样式尾部 } 会跟在最后一个属性后面,
// 设置 outputStyle: 'expanded',可以让 尾部 }换行
const style = () => {
return src('src/assets/styles/*.scss', { base: 'src' }) // base:保留基准路径
.pipe(sass({ outputStyle: 'expanded' }))
.pipe(dest('dist'))
}
const script = () => {
return src('src/assets/scripts/*.js', { base: 'src' })
.pipe(babel({ presets: ['@babel/preset-env'] }))
.pipe(dest('dist'))
}
// 防止模板缓存导致页面不能及时更新
const page = () => {
return src('src/*.html', { base: 'src' })
.pipe(swig({ data }))
.pipe(dest('dist'))
}
const compile = parallel(style, script, page)
module.exports = {
compile
}
图片和字体文件的转换
安装图片压缩插件 yarn add gulp-imagemin --dev 此压缩是无损压缩,也可以对字体文件的 svg 文件进行压缩
const { src, dest, parallel } = require('gulp')
const sass = require('gulp-sass') // 编译 sass 文件
const babel = require('gulp-babel') // 使用babel转换es6语法
const swig= require('gulp-swig') // 页面模板引擎转换插件
const imagemin= require('gulp-imagemin')
// 准备页面模板引擎渲染数据
const data = {
menus: [
{
name: 'Home',
icon: 'aperture',
link: 'index.html'
},
{
name: 'Features',
link: 'features.html'
},
{
name: 'About',
link: 'about.html'
},
{
name: 'Contact',
link: '#',
children: [
{
name: 'Twitter',
link: 'https://twitter.com/w_zce'
},
{
name: 'About',
link: 'https://weibo.com/zceme'
},
{
name: 'divider'
},
{
name: 'About',
link: 'https://github.com/zce'
}
]
}
],
pkg: require('./package.json'),
date: new Date()
}
// sass文件编译后,样式尾部 } 会跟在最后一个属性后面,
// 设置 outputStyle: 'expanded',可以让 尾部 }换行
const style = () => {
return src('src/assets/styles/*.scss', { base: 'src' }) // base:保留基准路径
.pipe(sass({ outputStyle: 'expanded' }))
.pipe(dest('dist'))
}
const script = () => {
return src('src/assets/scripts/*.js', { base: 'src' })
.pipe(babel({ presets: ['@babel/preset-env'] }))
.pipe(dest('dist'))
}
// 防止模板缓存导致页面不能及时更新
const page = () => {
return src('src/*.html', { base: 'src' })
.pipe(swig({ data }))
.pipe(dest('dist'))
}
const image = () => {
return src('src/assets/images/**', { base: 'src' })
.pipe(imagemin())
.pipe(dest('dist'))
}
const font = () => {
return src('src/assets/fonts/**', { base: 'src' })
.pipe(imagemin())
.pipe(dest('dist'))
}
const compile = parallel(style, script, page, image, font)
module.exports = {
compile
}
public等不需要编译的额外文件的目录下文件构建
建立 build 任务,用 parallel 并行执行任务模块,同时进行 extra, 和compile的任务
const { src, dest, parallel } = require('gulp')
const sass = require('gulp-sass') // 编译 sass 文件
const babel = require('gulp-babel') // 使用babel转换es6语法
const swig= require('gulp-swig') // 页面模板引擎转换插件
const imagemin= require('gulp-imagemin')
// 准备页面模板引擎渲染数据
const data = {
menus: [
{
name: 'Home',
icon: 'aperture',
link: 'index.html'
},
{
name: 'Features',
link: 'features.html'
},
{
name: 'About',
link: 'about.html'
},
{
name: 'Contact',
link: '#',
children: [
{
name: 'Twitter',
link: 'https://twitter.com/w_zce'
},
{
name: 'About',
link: 'https://weibo.com/zceme'
},
{
name: 'divider'
},
{
name: 'About',
link: 'https://github.com/zce'
}
]
}
],
pkg: require('./package.json'),
date: new Date()
}
// sass文件编译后,样式尾部 } 会跟在最后一个属性后面,
// 设置 outputStyle: 'expanded',可以让 尾部 }换行
const style = () => {
return src('src/assets/styles/*.scss', { base: 'src' }) // base:保留基准路径
.pipe(sass({ outputStyle: 'expanded' }))
.pipe(dest('dist'))
}
const script = () => {
return src('src/assets/scripts/*.js', { base: 'src' })
.pipe(babel({ presets: ['@babel/preset-env'] }))
.pipe(dest('dist'))
}
// 防止模板缓存导致页面不能及时更新
const page = () => {
return src('src/*.html', { base: 'src' })
.pipe(swig({ data }))
.pipe(dest('dist'))
}
const image = () => {
return src('src/assets/images/**', { base: 'src' })
.pipe(imagemin())
.pipe(dest('dist'))
}
const font = () => {
return src('src/assets/fonts/**', { base: 'src' })
.pipe(imagemin())
.pipe(dest('dist'))
}
const extra = () => {
return src('public/**', { base: 'public' })
.pipe(dest('dist'))
}
const compile = parallel(style, script, page, image, font)
const build = parallel(compile, extra)
module.exports = {
build
}
文件清除
每次构建项目前,需要先对dist目录进行清除
安装清除插件 yarn add del --dev
由于项目构建前应先清除原有目录文件,所以用 series 串行任务模块,先执行 clean,再执行 build
const { src, dest, parallel, series } = require('gulp')
const del = require('del')
const sass = require('gulp-sass') // 编译 sass 文件
const babel = require('gulp-babel') // 使用babel转换es6语法
const swig= require('gulp-swig') // 页面模板引擎转换插件
const imagemin= require('gulp-imagemin')
// 准备页面模板引擎渲染数据
const data = {
menus: [
{
name: 'Home',
icon: 'aperture',
link: 'index.html'
},
{
name: 'Features',
link: 'features.html'
},
{
name: 'About',
link: 'about.html'
},
{
name: 'Contact',
link: '#',
children: [
{
name: 'Twitter',
link: 'https://twitter.com/w_zce'
},
{
name: 'About',
link: 'https://weibo.com/zceme'
},
{
name: 'divider'
},
{
name: 'About',
link: 'https://github.com/zce'
}
]
}
],
pkg: require('./package.json'),
date: new Date()
}
const clean = () => {
return del(['dist'])
}
// sass文件编译后,样式尾部 } 会跟在最后一个属性后面,
// 设置 outputStyle: 'expanded',可以让 尾部 }换行
const style = () => {
return src('src/assets/styles/*.scss', { base: 'src' }) // base:保留基准路径
.pipe(sass({ outputStyle: 'expanded' }))
.pipe(dest('dist'))
}
const script = () => {
return src('src/assets/scripts/*.js', { base: 'src' })
.pipe(babel({ presets: ['@babel/preset-env'] }))
.pipe(dest('dist'))
}
// 防止模板缓存导致页面不能及时更新
const page = () => {
return src('src/*.html', { base: 'src' })
.pipe(swig({ data }))
.pipe(dest('dist'))
}
const image = () => {
return src('src/assets/images/**', { base: 'src' })
.pipe(imagemin())
.pipe(dest('dist'))
}
const font = () => {
return src('src/assets/fonts/**', { base: 'src' })
.pipe(imagemin())
.pipe(dest('dist'))
}
const extra = () => {
return src('public/**', { base: 'public' })
.pipe(dest('dist'))
}
const compile = parallel(style, script, page, image, font)
const build = series(clean, parallel(compile, extra))
module.exports = {
build
}
自动加载插件
安装 gulp-load-plugins 可以使用 一些gulp插件,这样就不用再单独安装很多插件 yarn add gulp-load-plugins --dev
const { src, dest, parallel, series } = require('gulp')
const del = require('del')
const loadPlugins = require('gulp-load-plugins')
const plugins = loadPlugins()
// const sass = require('gulp-sass') // 编译 sass 文件
// const babel = require('gulp-babel') // 使用babel转换es6语法
// const swig= require('gulp-swig') // 页面模板引擎转换插件
// const imagemin= require('gulp-imagemin') // 图片压缩插件 对字体下的svg文件也可以压缩
// 准备页面模板引擎渲染数据
const data = {
menus: [
{
name: 'Home',
icon: 'aperture',
link: 'index.html'
},
{
name: 'Features',
link: 'features.html'
},
{
name: 'About',
link: 'about.html'
},
{
name: 'Contact',
link: '#',
children: [
{
name: 'Twitter',
link: 'https://twitter.com/w_zce'
},
{
name: 'About',
link: 'https://weibo.com/zceme'
},
{
name: 'divider'
},
{
name: 'About',
link: 'https://github.com/zce'
}
]
}
],
pkg: require('./package.json'),
date: new Date()
}
const clean = () => {
return del(['dist'])
}
// sass文件编译后,样式尾部 } 会跟在最后一个属性后面,
// 设置 outputStyle: 'expanded',可以让 尾部 }换行
const style = () => {
return src('src/assets/styles/*.scss', { base: 'src' }) // base:保留基准路径
.pipe(plugins.sass({ outputStyle: 'expanded' }))
.pipe(dest('dist'))
}
const script = () => {
return src('src/assets/scripts/*.js', { base: 'src' })
.pipe(plugins.babel({ presets: ['@babel/preset-env'] }))
.pipe(dest('dist'))
}
// 防止模板缓存导致页面不能及时更新
const page = () => {
return src('src/*.html', { base: 'src' })
.pipe(plugins.swig({ data }))
.pipe(dest('dist'))
}
const image = () => {
return src('src/assets/images/**', { base: 'src' })
.pipe(plugins.imagemin())
.pipe(dest('dist'))
}
const font = () => {
return src('src/assets/fonts/**', { base: 'src' })
.pipe(plugins.imagemin())
.pipe(dest('dist'))
}
const extra = () => {
return src('public/**', { base: 'public' })
.pipe(dest('dist'))
}
const compile = parallel(style, script, page, image, font)
const build = series(clean, parallel(compile, extra))
module.exports = {
build
}
热更新开发服务器
安装开发服务器模块,支持代码修改后,自动更新到浏览器中, yarn add browser-sync --dev
const { src, dest, parallel, series } = require('gulp')
const del = require('del')
const loadPlugins = require('gulp-load-plugins')
const browserSync = require('browser-sync')
const plugins = loadPlugins()
const bs = browserSync.create()
// const sass = require('gulp-sass') // 编译 sass 文件
// const babel = require('gulp-babel') // 使用babel转换es6语法
// const swig= require('gulp-swig') // 页面模板引擎转换插件
// const imagemin= require('gulp-imagemin') // 图片压缩插件 对字体下的svg文件也可以压缩
// 准备页面模板引擎渲染数据
const data = {
menus: [
{
name: 'Home',
icon: 'aperture',
link: 'index.html'
},
{
name: 'Features',
link: 'features.html'
},
{
name: 'About',
link: 'about.html'
},
{
name: 'Contact',
link: '#',
children: [
{
name: 'Twitter',
link: 'https://twitter.com/w_zce'
},
{
name: 'About',
link: 'https://weibo.com/zceme'
},
{
name: 'divider'
},
{
name: 'About',
link: 'https://github.com/zce'
}
]
}
],
pkg: require('./package.json'),
date: new Date()
}
const clean = () => {
return del(['dist'])
}
// sass文件编译后,样式尾部 } 会跟在最后一个属性后面,
// 设置 outputStyle: 'expanded',可以让 尾部 }换行
const style = () => {
return src('src/assets/styles/*.scss', { base: 'src' }) // base:保留基准路径
.pipe(plugins.sass({ outputStyle: 'expanded' }))
.pipe(dest('dist'))
}
const script = () => {
return src('src/assets/scripts/*.js', { base: 'src' })
.pipe(plugins.babel({ presets: ['@babel/preset-env'] }))
.pipe(dest('dist'))
}
// 防止模板缓存导致页面不能及时更新
const page = () => {
return src('src/*.html', { base: 'src' })
.pipe(plugins.swig({ data }))
.pipe(dest('dist'))
}
const image = () => {
return src('src/assets/images/**', { base: 'src' })
.pipe(plugins.imagemin())
.pipe(dest('dist'))
}
const font = () => {
return src('src/assets/fonts/**', { base: 'src' })
.pipe(plugins.imagemin())
.pipe(dest('dist'))
}
const extra = () => {
return src('public/**', { base: 'public' })
.pipe(dest('dist'))
}
const serve = () => {
bs.init({
notify: false, // 关闭提示,以免影响样式调试
port: 2080, // 默认端口 3000
// open: false, // 自动打开浏览器设置,默认是 true
// files: 'dist/**', // 设置让 browser-sync 监听的文件
server: {
baseDir: 'dist',
routes: { // routes 会先于 baseDir执行
'/node_modules': 'node_modules'
}
}
})
}
const compile = parallel(style, script, page, image, font)
const build = series(clean, parallel(compile, extra))
module.exports = {
build,
serve
}
监视变化
引入 gulp 的 watch 模块
在 serve 任务中加入 watch 任务
const { src, dest, parallel, series, watch } = require('gulp')
const del = require('del')
const loadPlugins = require('gulp-load-plugins')
const browserSync = require('browser-sync')
const plugins = loadPlugins()
const bs = browserSync.create()
// const sass = require('gulp-sass') // 编译 sass 文件
// const babel = require('gulp-babel') // 使用babel转换es6语法
// const swig= require('gulp-swig') // 页面模板引擎转换插件
// const imagemin= require('gulp-imagemin') // 图片压缩插件 对字体下的svg文件也可以压缩
// 准备页面模板引擎渲染数据
const data = {
menus: [
{
name: 'Home',
icon: 'aperture',
link: 'index.html'
},
{
name: 'Features',
link: 'features.html'
},
{
name: 'About',
link: 'about.html'
},
{
name: 'Contact',
link: '#',
children: [
{
name: 'Twitter',
link: 'https://twitter.com/w_zce'
},
{
name: 'About',
link: 'https://weibo.com/zceme'
},
{
name: 'divider'
},
{
name: 'About',
link: 'https://github.com/zce'
}
]
}
],
pkg: require('./package.json'),
date: new Date()
}
const clean = () => {
return del(['dist'])
}
// sass文件编译后,样式尾部 } 会跟在最后一个属性后面,
// 设置 outputStyle: 'expanded',可以让 尾部 }换行
const style = () => {
return src('src/assets/styles/*.scss', { base: 'src' }) // base:保留基准路径
.pipe(plugins.sass({ outputStyle: 'expanded' }))
.pipe(dest('dist'))
}
const script = () => {
return src('src/assets/scripts/*.js', { base: 'src' })
.pipe(plugins.babel({ presets: ['@babel/preset-env'] }))
.pipe(dest('dist'))
}
// defaults: { cache: false } 防止模板缓存导致页面不能及时更新
const page = () => {
return src('src/*.html', { base: 'src' })
.pipe(plugins.swig({ data, defaults: { cache: false } }))
.pipe(dest('dist'))
}
const image = () => {
return src('src/assets/images/**', { base: 'src' })
.pipe(plugins.imagemin())
.pipe(dest('dist'))
}
const font = () => {
return src('src/assets/fonts/**', { base: 'src' })
.pipe(plugins.imagemin())
.pipe(dest('dist'))
}
const extra = () => {
return src('public/**', { base: 'public' })
.pipe(dest('dist'))
}
const serve = () => {
watch('src/assets/styles/*.scss', style)
watch('src/assets/scripts/*.js', script)
watch('src/*.html', page)
watch('src/assets/images/**', image)
watch('src/assets/fonts/**', font)
watch('public/**', extra)
bs.init({
notify: false, // 关闭提示,以免影响样式调试
port: 2080, // 默认端口 3000
// open: false, // 自动打开浏览器设置,默认是 true
// files: 'dist/**', // 设置让 browser-sync 监听的文件
server: {
baseDir: 'dist',
routes: { // routes 会先于 baseDir执行
'/node_modules': 'node_modules'
}
}
})
}
const compile = parallel(style, script, page, image, font)
const build = series(clean, parallel(compile, extra))
module.exports = {
build,
serve
}
构建优化
image,font,public 下的文件不会频繁改动,因此无需在开发的时候实时监听,因为监视更多的文件意味着更大的开销
将 image,font 任务从 compile 任务中取出,在开发阶段中不做编译,
将image, font 任务放入 build 任务中
增加 develop 任务,使用 series串行模块,先执行 compile 任务,再执行 serve 任务
给 style, script, html 任务 增加 bs.reload({ stream: true }),使得浏览器监听到修改的变化并更新,
stream: true:以流的方式推送给浏览器
const { src, dest, parallel, series, watch } = require('gulp')
const del = require('del')
const loadPlugins = require('gulp-load-plugins')
const browserSync = require('browser-sync')
const plugins = loadPlugins()
const bs = browserSync.create()
// const sass = require('gulp-sass') // 编译 sass 文件
// const babel = require('gulp-babel') // 使用babel转换es6语法
// const swig= require('gulp-swig') // 页面模板引擎转换插件
// const imagemin= require('gulp-imagemin') // 图片压缩插件 对字体下的svg文件也可以压缩
// 准备页面模板引擎渲染数据
const data = {
menus: [
{
name: 'Home',
icon: 'aperture',
link: 'index.html'
},
{
name: 'Features',
link: 'features.html'
},
{
name: 'About',
link: 'about.html'
},
{
name: 'Contact',
link: '#',
children: [
{
name: 'Twitter',
link: 'https://twitter.com/w_zce'
},
{
name: 'About',
link: 'https://weibo.com/zceme'
},
{
name: 'divider'
},
{
name: 'About',
link: 'https://github.com/zce'
}
]
}
],
pkg: require('./package.json'),
date: new Date()
}
const clean = () => {
return del(['dist'])
}
// sass文件编译后,样式尾部 } 会跟在最后一个属性后面,
// 设置 outputStyle: 'expanded',可以让 尾部 }换行
const style = () => {
return src('src/assets/styles/*.scss', { base: 'src' }) // base:保留基准路径
.pipe(plugins.sass({ outputStyle: 'expanded' }))
.pipe(dest('dist'))
.pipe(bs.reload({ stream: true }))
}
const script = () => {
return src('src/assets/scripts/*.js', { base: 'src' })
.pipe(plugins.babel({ presets: ['@babel/preset-env'] }))
.pipe(dest('dist'))
.pipe(bs.reload({ stream: true }))
}
// defaults: { cache: false } 防止模板缓存导致页面不能及时更新
const page = () => {
return src('src/*.html', { base: 'src' })
.pipe(plugins.swig({ data, defaults: { cache: false } }))
.pipe(dest('dist'))
.pipe(bs.reload({ stream: true }))
}
const image = () => {
return src('src/assets/images/**', { base: 'src' })
.pipe(plugins.imagemin())
.pipe(dest('dist'))
}
const font = () => {
return src('src/assets/fonts/**', { base: 'src' })
.pipe(plugins.imagemin())
.pipe(dest('dist'))
}
const extra = () => {
return src('public/**', { base: 'public' })
.pipe(dest('dist'))
}
const serve = () => {
watch('src/assets/styles/*.scss', style)
watch('src/assets/scripts/*.js', script)
watch('src/*.html', page)
// watch('src/assets/images/**', image)
// watch('src/assets/fonts/**', font)
// watch('public/**', extra)
watch([
'src/assets/images/**',
'src/assets/fonts/**',
'public/**'
], bs.reload) // 监视这三种文件的变化,当有变化时,浏览器自动更新
bs.init({
notify: false, // 关闭提示,以免影响样式调试
port: 2080, // 默认端口 3000
// open: false, // 自动打开浏览器设置,默认是 true
// files: 'dist/**', // 设置让 browser-sync 监听的文件
server: {
baseDir: ['temp', 'src', 'public'], // 会从第一个目录寻找,如果没有寻找到,以此向后寻找,image,font在开发阶段就直接用原文件,节省构建速度
routes: { // routes 会先于 baseDir执行
'/node_modules': 'node_modules'
}
}
})
}
const compile = parallel(style, script, page)
const build = series(clean, parallel(compile, extra, image, font))
const develop = series(compile, serve)
module.exports = {
build,
develop
}
引用文件处理
安装引用依赖插件 yarn add gulp-useref --dev
添加 useref 任务,会将引用的外部依赖文件 写入新建的文件中
要对这些新建的文件进行压缩
安装 html,js,css 的压缩插件 yarn add gulp-htmlmin gulp-uglify gulp-css-clean --dev
安装 gulp-if 插件,针对文件的读取流分别做不同的操作 yarn add gulp-if --dev
将压缩后的文件先放在 release 目录里,防止读取文件在一个目录下会产生冲突
因为多了 release 目录,之前的构建目录需要做调整
将 style, script, page 这三个在开发阶段需要构建的任务,在构建后放入 temp 目录
相应的 useref 任务改成从 temp 目录中读取文件
将 useref 任务 放入 build 任务, compile 任务执行完后,才能执行 useref 任务
const { src, dest, parallel, series, watch } = require('gulp')
const del = require('del')
const loadPlugins = require('gulp-load-plugins')
const browserSync = require('browser-sync')
const plugins = loadPlugins()
const bs = browserSync.create()
// const sass = require('gulp-sass') // 编译 sass 文件
// const babel = require('gulp-babel') // 使用babel转换es6语法
// const swig= require('gulp-swig') // 页面模板引擎转换插件
// const imagemin= require('gulp-imagemin') // 图片压缩插件 对字体下的svg文件也可以压缩
// 准备页面模板引擎渲染数据
const data = {
menus: [
{
name: 'Home',
icon: 'aperture',
link: 'index.html'
},
{
name: 'Features',
link: 'features.html'
},
{
name: 'About',
link: 'about.html'
},
{
name: 'Contact',
link: '#',
children: [
{
name: 'Twitter',
link: 'https://twitter.com/w_zce'
},
{
name: 'About',
link: 'https://weibo.com/zceme'
},
{
name: 'divider'
},
{
name: 'About',
link: 'https://github.com/zce'
}
]
}
],
pkg: require('./package.json'),
date: new Date()
}
const clean = () => {
return del(['dist', 'temp'])
}
// sass文件编译后,样式尾部 } 会跟在最后一个属性后面,
// 设置 outputStyle: 'expanded',可以让 尾部 }换行
const style = () => {
return src('src/assets/styles/*.scss', { base: 'src' }) // base:保留基准路径
.pipe(plugins.sass({ outputStyle: 'expanded' }))
.pipe(dest('temp'))
.pipe(bs.reload({ stream: true }))
}
const script = () => {
return src('src/assets/scripts/*.js', { base: 'src' })
.pipe(plugins.babel({ presets: ['@babel/preset-env'] }))
.pipe(dest('temp'))
.pipe(bs.reload({ stream: true }))
}
// defaults: { cache: false } 防止模板缓存导致页面不能及时更新
const page = () => {
return src('src/*.html', { base: 'src' })
.pipe(plugins.swig({ data, defaults: { cache: false } }))
.pipe(dest('temp'))
.pipe(bs.reload({ stream: true }))
}
const image = () => {
return src('src/assets/images/**', { base: 'src' })
.pipe(plugins.imagemin())
.pipe(dest('dist'))
}
const font = () => {
return src('src/assets/fonts/**', { base: 'src' })
.pipe(plugins.imagemin())
.pipe(dest('dist'))
}
const extra = () => {
return src('public/**', { base: 'public' })
.pipe(dest('dist'))
}
const serve = () => {
watch('src/assets/styles/*.scss', style)
watch('src/assets/scripts/*.js', script)
watch('src/*.html', page)
// watch('src/assets/images/**', image)
// watch('src/assets/fonts/**', font)
// watch('public/**', extra)
watch([
'src/assets/images/**',
'src/assets/fonts/**',
'public/**'
], bs.reload) // 监视这三种文件的变化,当有变化时,浏览器自动更新
bs.init({
notify: false, // 关闭提示,以免影响样式调试
port: 2080, // 默认端口 3000
// open: false, // 自动打开浏览器设置,默认是 true
// files: 'dist/**', // 设置让 browser-sync 监听的文件
server: {
baseDir: ['temp', 'src', 'public'], // 会从第一个目录寻找,如果没有寻找到,以此向后寻找,image,font在开发阶段就直接用原文件,节省构建速度
routes: { // routes 会先于 baseDir执行
'/node_modules': 'node_modules'
}
}
})
}
const useref = () => {
return src('temp/*.html', { base: 'temp' })
.pipe(plugins.useref({ searchPath: ['temp', '.'] }))
.pipe(plugins.if(/\.js$/, plugins.uglify()))
.pipe(plugins.if(/\.css$/, plugins.cleanCss()))
.pipe(plugins.if(/\.html$/, plugins.htmlmin({
collapseWhitespace: true, // 压缩空白符和换行符
minifyCSS: true, // 压缩css代码
minifyJS: true // 压缩js代码
})))
.pipe(dest('dist')) // 将压缩后的文件先放在 release 目录里
}
const compile = parallel(style, script, page)
const build = series(clean, parallel(series(compile, useref), extra, image, font))
const develop = series(compile, serve)
module.exports = {
build,
develop
}
配置启动命令
将 build, develop启动命令配置到 package.json 文件中去
"scripts": {
"build": "gulp build",
"develop": "gulp develop"
}
发布并使用模块
发布模块
yarn publish --registry https://registry.yarnpkg.com
1