gulp的基本使用
yarn init --yes
初始化package.json 文件yarn add gulp --dev
安装gulp包- 创建gulpfile.js 作为gulp 的入口文件
// gulpfile.js文件是 gulp的入口文件
exports.foo = function(done){
console.log("hello foo")
done()
}
// 默认任务
exports.default = function(done){
console.log("hello default")
done()
}
gulp的组合任务
const { series, parallel } = require('gulp')
const task1 = done => {
setTimeout(() => {
console.log('task1');
done();
},1000)
}
const task2 = done => {
setTimeout(() => {
console.log('task2');
done();
},1000)
}
exports.default = series(task1, task2) // 串行任务执行
exports.bar = parallel(task1, task2) // 并行任务执行
gulp的异步任务
const fs = require('fs');
// 第一种直接调用done
exports.callback = done => {
console.log('callback task');
done();
}
exports.callback_error = done => {
console.log('callback_error task');
done(new Error('callback_error task failed'));
}
// 第二种promise的方式
exports.promise = () =>{
console.log('promise task')
return Promise.resolve()
}
const timeout = time =>{
return new Promise((resolve) => {
setTimeout((resolve,time))
})
}
exports.async = async ()=>{
await timeout(1000)
console.log('async task')
}
// 第三种 添加实例方法,调用done
exports.stream = () =>{
const readStream = fs.createReadStream('package.json')
const writeStream = fs.createWriteStream('temp.txt')
readStream.pipe(writeStream)
// return readStream
// 或者写成
readStream.on('end',()=>{
done()
})
}
gulp构建过程核心工作原理
const fs = require('fs');
const { Transform } = require('stream');
exports.default = () =>{
// 创建文件读取流
const read = fs.createReadStream('normalize.css')
// 文件写入流
const write = fs.createWriteStream('normalize.min.css')
// 文件转换流
const transform = new Transform({
transform: (chunk,encoding,callback) => {
// 核心转换过程
// chunk读取流中读取到的内容(Buffer),所以需要toString拿到文件内容
const input = chunk.toString()
const output = input.replace(/\s+/g, '').replace(/\/\*.+?\*\//g, '')
callback(null, output)
}
})
// 把读取出来的文件流导入写入文件流
read
.pipe(transform)
.pipe(write)
return read
}
Gulp文件操作API
读取流 --- 转换流 --- 写入流
const { src, dest } = require('gulp')
const cleanCss = require('gulp-clean-css') // css的转换流
const rename = require('gulp-rename')
exports.default = done =>{
// src读取流,dest写入流,return出去让gulp知道此任务已完成
return src('src/*.css')
.pipe(cleanCss()) // 转换css
.pipe(rename({ extname: '.min.css' }))
.pipe(dest('dist'))
}
Gulp转换项目的案例
// 实现这个项目的构建任务
// watch自动监听通配符,根据文件更新来决定是否要执行某个人物
const { src, dest, parallel, series, watch } = require('gulp')
const del = require('del')
const browserSync = require('browser-sync') // 依靠这个模块加载开发服务器
const loadPlugins = require('gulp-load-plugins')
const plugins = loadPlugins() //loadPlugins导出的是一个方法,通过方法得到plugins
const bs = browserSync.create() // 用提供的creat()方法创建服务器
const data = {
menus: [],
pkg: require('./package.json'),
date: new Date()
}
const clean = ()=>{
return del(['dist','temp'])
}
const page = ()=>{
// swig 为模板引擎的转换插件
// 原来的模板用到了一些数据标记,去标记开发中可能变化的东西
// 通过swig的data参数,把设定的data传入到模板中
return src('src/*.html', { base: 'src'})
.pipe(plugins.swig({ data }))
.pipe(dest('temp'))
.pipe(bs.reload({stream: true})) // 内部以流的方式推到浏览器,
}
const script = ()=>{
// gulp-babel只是帮你唤起@babel/core的转换过程
// preset-env会帮助转换所有的es6模块,他是可以转换所有新特性的集合
return src('src/assets/scripts/*.js', { base: 'src' })
.pipe(plugins.babel({presets: ['@babel/preset-env']}))
.pipe(dest('temp'))
.pipe(bs.reload({stream: true})) // 内部以流的方式推到浏览器,
}
const style = ()=>{
// outputStyle: 'expanded' 是指定转换后结束括号的位置
return src('src/assets/styles/*.scss', { base: 'src' })
.pipe(plugins.sass({ outputStyle: 'expanded'}))
.pipe(dest('temp'))
.pipe(bs.reload({stream: true})) // 内部以流的方式推到浏览器,
}
const image = ()=>{
// imagemin插件用于图片的压缩
return src('src/assets/images/**', { base: 'src'})
.pipe(plugins.imagemin())
.pipe(dest('dist'))
}
const font = ()=>{
// imagemin可以压缩字体文件中的svg
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的变化
watch('src/*.html',page)
watch('src/assets/scripts/*.js',script)
watch('src/assets/styles/*.scss',style)
// 只是去监听iamge,font,public文件的变化,不去构建
watch([
'src/assets/images/**',
'src/assets/fonts/**',
'public/**'
],bs.reload)
// 初始化服务器配置
bs.init({
port: '2080', // 服务器端口号
// browser-sync 启动后用来去监听的路径通配符
// files:'temp/**',
server: {
// 请求过来后先从[0]目录下面去找,如果找不到就去src下面查找...
baseDir: ['temp','src','public'],
// 优先于baseDir的配置
routes: {
'/node_modules': 'node_modules'
}
}
})
}
const useref = () =>{
// useref 自动处理构建注释
return src('temp/*.html', {base: 'temp'})
.pipe(plugins.useref({ searchPath: ['temp', '.'] }))
// 希望对生成的文件进行压缩,因为读取流中有三个不同的文件,希望对不同文件进行不同操作
.pipe(plugins.if(/\.js$/, plugins.uglify()))
.pipe(plugins.if(/\.css$/, plugins.cleanCss()))
// 可以在方法中配置一些自定义的选项,下面的选项是压缩空白字符,压缩行内css,压缩w文件内js
.pipe(plugins.if(/\.html$/, plugins.htmlmin({
collapseWhitespace: true,
minifyCSS: true,
minifyJS: true
})))
.pipe(dest('dist'))
}
// 使用parallel把这些任务通过并行的方式导出
const compile = parallel(page,script,style )
// 一般 iamge,font public 的任务,项目开发阶段不会让他自动化构建,只是再发布的时候去构建项目
const build = series(
clean,
parallel(
series(compile,useref),
image,
font,
extra
)
)
const start = series(compile, serve)
module.exports = {
build,
start,
clean
}
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!