Gulp的基本使用

Gulp是自动化构建的一款工具

基本使用

yarn init
yarn add gulp –dev
code gulpfile.js // 创建一个gulpfile.js文件
// gulp的入口文件
// 最新的gulp中取消了同步任务,每一个任务都是异步任务
// 当我们的任务执行完成后需要调用回调函数或其他方式去标记任务已完成
exports.foo = done => {
	console.log('foo task working~')
	done() // 标识任务完成
}
// 默认导出
exports.default = done =>{
	console.log('foo task working~')
	done() // 标识任务完成
}
yarn gulp foo // 调用foo任务
yarn gulp // 调用默认任务

组合任务

串行任务(按顺序依次执行,例如部署)

并行任务(同时执行,例如:编译css和js时,因为2则是互不干扰的,可以用并行任务去执行,来提高构建效率)

const { series,parallel } = require('gulp')

const task1 = done =>{
	setTimeout(()=>{
		console.log('foo task working~')
		done()
	},1000)
}

const task2 = done =>{
	setTimeout(()=>{
		console.log('foo task working~')
		done()
	},1000)
}

const task3 = done =>{
	setTimeout(()=>{
		console.log('foo task working~')
		done()
	},1000)
}

// 串行任务
exprots.foo = series(task1, task2, task3 )
// 并行任务
exprots.bar = parallel(task1, task2, task3 )
yarn gulp foo
yarn gulp bar

异步任务的三种方式

1. 回调函数形式

exports.callback =  done =>{
	console.log('callback task~')
	done()
}
// 错误优先回调函数
// 多个任务同时执行,如果这个任务出错后续的任务就不会执行了
exports.callback_error =  done =>{
	console.log('callback task~')
	done(new Error('task failed!'))
}

2. Promise

exports.promise = () =>{
	console.log('promise task~')
	return Promise.resolve() // 不需要返回值,gulp会忽略这个值
}
exports.promise_error = () =>{
	console.log('promise task~')
	return Promise.reject(new Error('task failed~'))
}

async await

const timeout = time =>{
	return new Promise(res=>{
		setTimeout(res,time)
	})
}
exports.async = async() =>{
	await timeout(1000)
	console.log('async task~')
}

3. stream

const fs = require('fs')
exports.stream = () =>{
	const readStream = fs.createReadStream('packge.json') // 文件流对象
	const writeStream = fs.createWriteStream('temp.txt')
	readStram.pipe(writeStream) // 将readStream导到writeStream
	retunrn readStream
}
// 相当于
// exports.stream = done =>{
//	const readStream = //fs.createReadStream('packge.json')
//	const writeStream = fs.createWriteStream('temp.txt')
//	readStram.pipe(writeStream)
//	readStram.on('end',()=>{
//  	done()
//})
//}

构建过程核心工作原理

在这里插入图片描述

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)
			const input = chunk.toString()
			const output = input.replace(/\s+/g,'').replace(/\/\*.+?\*\//g,'') // 替换空白;注释
			callback(null,output) // 错误优先,第一个是一个对象
		}
	})
	// 把读取出来的文件流导入写入文件流
	read
		.pipe(transform) // 转换
		.pipe(write) // 写入
	// gulp根据流的状态来判定任务是否完成
	retrun read
yarn gulp

案例

在这里插入图片描述

yarn add gulp --dev
// yarn add gulp-sass --dev
// yarn add gulp-babel --dev
yarn add @babel/core @babel/preset-env --dev // 全部的es新特性
// yarn add gulp-swig --dev // 模板引擎
// yarn add gulp-imagemin --dev
yarn add del --dev
yarn add gulp-load-plugins --dev
yarn add browser-sync --dev
yarn add gulp-useref --dev
yarn add gulp-htmlmin gulp-uglify gulp-clean-css --dev
yarn add gulp-if --dev
const { src, dest, parallel, series, watch } = require('gulp')
const del = require('del')
const browser-sync = require('browser-sync')
const plugins = loadPlugins() // 自定义加载所有的gulp插件,名字过程则驼峰命名
const bs = browserSync.create() // 创建browser-sync开发服务器
// const sass = require('gulp-sass')
// const babel = require('gulp-babel')
// const swig =  require('gulp-swig')
// const imagemin =  require('gulp-imagemin')

const data = {
	menus:[],
	pkg: require('./package.json'),
	date: new Date()
}

// 返回一个promise
const clean = () = {
retrun del(['dist','temp'])
}

// 样式编译
const style = () => {
	return src('src/assets/styles/*.scss', {base:'src'} ) // 读取流, 保留基准路径
	.pipe(plugins.sass({outputStyle: 'expanded' })) // {outputStyle: 'expanded' } css属性展开的形势显示
	.pipe(dest('temp')), // 写入流
	.pipe(bs.reload({stream:true})) // 以流的方式往浏览器推 
}

// es6编译
const script = () => {
	return src('src/assets/script/*.js', {base:'src'} ) // 读取流, 保留基准路径
	.pipe(babel({ presets: ['@babel/preset-env'] }))  // preset对象里的方法
	.pipe(dest('temp')), // 写入流
	.pipe(bs.reload({stream:true})) // 以流的方式往浏览器推 
}

// 页面模板编译
const page = () => {
	return src('src/*.js', {base:'src'} ) // 读取流, 保留基准路径;如果是src目录下的文件的html路径需要src/**/*.html
	.pipe( plugins.swig({ data:data })) // 可简写data
	.pipe(dest('temp')), // 写入流
	.pipe(bs.reload({stream:true})) // 以流的方式往浏览器推 
}

// 编译图片和字体转换(压缩图片、svg)
const image = () => {
	return src('src/assets/images/**', {base:'src'}) // images下的所有文件
	.pipe( plugins.imagemin())
	.pipe(dest('dist')) // 写入流
}
const font = () => {
	return src('src/assets/fonts/**', {base:'src'}) // images下的所有文件
	.pipe(imagemin())
	.pipe(dest('dist')) // 写入流
}

// 其他文件处理
const extra = () => {
	return src('public/**', {base:'public'}) // images下的所有文件
	.pipe(dest('dist')) // 写入流
}

const serve = () => {
// 这几个文件修改后,就会执行相应的任务,覆盖dist下的文件
watch('src/assets/styles/*.scss',style)
watch('src/assets/script/*.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: 3000, // 端口
	open: false, // 自动打开
//	files:'dist/**', // 监听dist文件的变化,同步到浏览器
	server:{
		baseDir: ['temp','src','public'], // 依次请求文件,减少构建次数(可为单个字符串)
		routes:{ // 路由映射,优先baseDir
			'/node_modules':'node_modules'
		}
	}
})
}

// 文件(依赖)引入处理
const useref = () => {
	retrun src('temp/*.html',{base:'dist'})
		.pipe(plugins.useref({searchPath:['dist','.']})) // 将构建注释做转换,查找路径(会创建一些新的文件)
		// 压缩新生成的文件
		.pipe(plugins.if(/\.js$/,plugins.uglify()))
		.pipe(plugins.if(/\.cc$/,plugins.cleanCss()))
		.pipe(plugins.if(/\.html$/,plugins.htmlmin({
			collapseWhitespace:true,
			minifyCSS: true,
			minifyJS: true
		})))
		.pipe(dest('dist'))
}

// src下的任务并行执行
const compile = parallel(style, script, page)

// 上线之前的任务(先删除再bulid)
const build = series(
	clean, 
	parallel(
		series(compile,useref), // 串行
 		extra, image,  font
 	)
 ) 

// 开发环境
const develop = series(compile, serve)

module.exports = {
	// style,
	// script,
	// page,
	// image,
	// font
	clean,
	// compile,
	build,
	develop,
	// useref
}

在package.json中

"scripts":{
	"clean": "gulp clean",
	"build": "gulp build",
	"develop": "gulp develop"
}

在.gitignore中添加dist,temp目录

// yarn gulp style
// yarn gulp script
// yarn gulp page
yarn gulp compile

封装自动化构建工作流

模拟npm构建:yarn link 
			yarn name 

封装

将package.json文件中的生产环境放入开发环境中
新建lib目录下的index.js

const cwd = process.cwd() 获取工作下的根目录
let config = {
	build:{
		src: 'src',
		dist: 'dist',
		temp:'temp',
		public: 'public',
		paths: {
			styles: 'assets/styles/*.scss',
			script: 'assets/script/*.js',
			pages: '*.html',
			image: 'asset/images/**',
			fonts: 'assets/fonts/**'
		}
	}
} // 默认 config
try { 
	const loadConfig = require(`${cwd}/pages.config.js`)
	config = Object.assign({}, config, loadConfig)
} catch (e) {}
// .pipe( plugins.swig({ data:config.data }))
// retrun src( config.build.paths.styles,{ base: config.build.src,cwd: config.build.src })
// watch('**',{cwd:config.build.public},bs.reload) //因为寻找的目录不一致,需要分开写

.pipe(babel({ presets: [require('@babel/preset-env')] })) // 本目录下没有就会向上去寻找到node_modules

新建bin/name.js(cli,会先去找node_modules下的bin文件cmd node运行, 指向该文件)

#!/usr/bin/env node
// 获取命令行输入的内容(数组)
process.argv.push('--cwd')
process.argv.push(process.cwd())
process.argv.push('--fulpfile')
process.argv.push(require.resolve('..')) // lib/index.js
require('gulp/bin/gulp')

在package.json中配置

"files":[
	"lib",
	"bin" // 发布的时候添加的新目录
],
"bin": "bin/name.js"
yarn unlink ;
yarn link

引用

新建gulpfile.js文件(没封装前的2种方式)
module.exports = require('name') // 引入,导出
用指令的方式来代替创建gulpfile.js
yarn gulp --gulpfile ./node_modules/name/lib/index.js
yarn gulp build--gulpfile ./node_modules/name/lib/index.js --cwd .

新建pages.config.js(配置文件)

module.exports = {
	build:{ // 可配置目录
		src: 'src',
		dist: 'dist',
		temp:'temp',
		public: 'public',
		paths: {
			styles: 'assets/styles/*.scss',
			script: 'assets/script/*.js',
			pages: '*.html',
			image: 'asset/images/**',
			fonts: 'assets/fonts/**'
		},
	data: { // 模板数据
		menus: []
	}
} 
yarn add name --dev
"script":{
	"clean": "name clean",
	"build": "name build",
	"develop": "name develop",
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值