gulp是大家比较熟悉的一个打包编译工具,这里介绍下它的基本使用和封装
gulp基本使用
首先我们捋一下思路:
开发环境:
- 增加js,css,html相关编译任务,把编译文件存放到开发环境文件夹
- 增加启动服务,请求文件地址按照 生产环境文件夹 => src => public 的顺序查找
- 增加watch实时监控,监控src下html,js,css,images,fonts的文件变化,其中html,css,js调用相关编译任务,全部重载浏览器页面
生产环境:
- 增加images,fonts,其他文件的相关压缩任务(不包括js,css,html,js,css,html开发环境直接存放到存放到开发环境文件夹,生产环境通过读取开发环境文件夹html找到引用的js,css,然后进行合并压缩),把压缩文件存放到生产环境文件夹
- 读取 开发环境文件夹 里面html,对html及其引用文件用相应插件合并,压缩
- 把压缩后的文件存放到 生产环境文件夹
- 在建相应的任务之前,我们可以根据文件的目录结构,增加一个配置文件,比如文件目录结构如截图,则可增加配置文件
let config={
build:{
src:'src',
temp:'.temp', //开发环境压缩文件存放目录
dist:'release', //生产环境压缩文件存放目录
public:'public',
paths:{
styles:'assets/styles/*.scss', //匹配当前文件夹所有scss文件
scripts:'assets/scripts/*.js',//匹配当前文件夹所有js文件
pages:'*.html',//匹配当前文件夹所有html文件
images:'assets/images/**',//匹配当前文件夹所有图片文件
fonts:'assets/fonts/**'//匹配当前文件夹所有字体文件文件
}
}
}
- 安装需要的模块
- 安装gulp模块
yarn add gulp --dev
- 安装编译sass的插件
yarn add gulp-sass@^4.0.0 --dev //有坑,这里要安装4.0.0版本,否则提示你要再安装一遍node-sass
- 安装编译js的插件
yarn add gulp-babel --dev
yarn add @babel/core @babel/preset-env --dev
- 安装编译html的插件
yarn add gulp-swig --dev
- 安装压缩image,fonts的插件
//有坑,这里要安装7.0.0版本,否则报错:require() of ES modules is not supported.
yarn add gulp-imagemin@^7.0.0 --dev
- 最后安装一下gulp-load-plugins,这个插件可以一次性包括 package.json 里面的所有的 gulp 依赖包,无需在 gulpfile.js 使用require 关键字一个一个的把依赖包导入进去
yarn add gulp-imagemin --dev
3.开发环境编译
let config={
data:{ //data是传给html的数据,可以通过{{}}在html模板中直接嵌套
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'),
data: new Date()
},
build:{//路径配置
src:'src',
temp:'.temp',
dist:'release',
public:'public',
paths:{
styles:'assets/styles/*.scss',
scripts:'assets/scripts/*.js',
pages:'*.html',
images:'assets/images/**',
fonts:'assets/fonts/**'
}
}
}
const {src,dest,series,parallel}=require('gulp')
const del=require('del')
const loadPlugins=require('gulp-load-plugins')
const plugins=loadPlugins();
//style编译任务
const style=()=>{
return src(config.build.paths.styles,{base:config.build.src,cwd:config.build.src}).pipe(plugins.sass({outputStyle:'expand'}))
.pipe(dest(config.build.temp))
//base:copy的时候按照该文件夹的目录结构,cwd:查找从哪开始找
}
//js编译任务
const script=()=>{
return src(config.build.paths.scripts,{base:config.build.src,cwd:config.build.src}).pipe(plugins.babel({presets:[require('@babel/preset-env')]}))
.pipe(dest(config.build.temp))
//@babel/preset-env:是一个智能预设,它允许你使用最新的 JavaScript ,无须语法转换
}
//html编译任务
const page=()=>{
return src(config.build.paths.pages,{base:config.build.src,cwd:`${config.build.src}/**`}).pipe(plugins.swig({data:config.data,defaults:{cache:false}}))
.pipe(dest(config.build.temp))
}
//image编译任务
const image=()=>{
return src(config.build.paths.images,{base:config.build.src,cwd:config.build.src}).pipe(plugins.imagemin())
.pipe(dest(config.build.temp))
}
//字体编译任务
const font=()=>{
return src(config.build.paths.fonts,{base:config.build.src,cwd:config.build.src}).pipe(plugins.imagemin())
.pipe(dest(config.build.temp))
}
//public的其他文件,直接copy到.temp文件夹内
const extra=()=>{
return src('**',{base:config.build.public,cwd:config.build.public}).pipe(plugins.imagemin())
}
//编译之前先删掉这些文件夹内的文件
const clean=()=>{
return del([config.build.temp])
}
//需要先clean所以用series串联任务,style,script,page,image,font,extra这些任务用parallel串联
const develop=series(clean,parallel(style,script,page,image,font,extra))
//导出develop任务
module.exports={
develop
}
运行命令编译
yarn gulp develop
得到如下
- 开发环境增加服务器及监视变化
Browsersync能让浏览器实时、快速响应您的文件更改(html、js、css、sass、less等)并自动刷新页面。
- 安装插件Browsersync
yarn add browser-sync --dev
- 引入browser-sync插件,并监视相应的html,js,css,images,fonts
const browserSync=require('browser-sync')
const bs=browserSync.create();
- html,js,css发生变化调用对应的编译方法
const {src,dest,series,parallel,watch}=require('gulp')
const server = ()=>{
//watch 实时监控
watch(config.build.paths.styles,{cwd:config.build.src},style)
watch(config.build.paths.scripts,{cwd:config.build.src},script)
watch(config.build.paths.pages,{cwd:`${config.build.src}/**`},page)
watch([config.build.paths.images,config.build.paths.fonts],{cwd:config.build.src},bs.reload)
watch('**',{cwd:config.build.public},bs.reload)
bs.init({
port:'2099',
server:{
baseDir:[config.build.temp,config.build.src,config.build.public],
routes:{
'/node_modules':'node_modules'
}
}
})
}
- html,js,css调用编译方法后需要重载,故style,scrpit,page方法需要加上bs.reload({stream:true}),代码更改后如下
const style=()=>{
return src(config.build.paths.styles,{base:config.build.src,cwd:config.build.src}).pipe(plugins.sass({outputStyle:'expand'}))
.pipe(dest(config.build.temp)).pipe(bs.reload({stream:true}))
}
const script=()=>{
return src(config.build.paths.scripts,{base:config.build.src,cwd:config.build.src}).pipe(plugins.babel({presets:[require('@babel/preset-env')]}))
.pipe(dest(config.build.temp)).pipe(bs.reload({stream:true}))
}
const page=()=>{
return src(config.build.paths.pages,{base:config.build.src,cwd:`${config.build.src}/**`}).pipe(plugins.swig({data:config.data,defaults:{cache:false}}))
.pipe(dest(config.build.temp)).pipe(bs.reload({stream:true}))
}
- images,fonts发生改变,直接重载,不需要重新编译,为了节省编译时间,images,fonts到生产环境才需要编译,故page,font方法可以直接copy到config.build.dist里面,且develop里面移除page、font方法
const image=()=>{
return src(config.build.paths.images,{base:config.build.src,cwd:config.build.src}).pipe(plugins.imagemin())
.pipe(dest(config.build.dist))
}
const font=()=>{
return src(config.build.paths.fonts,{base:config.build.src,cwd:config.build.src}).pipe(plugins.imagemin())
.pipe(dest(config.build.dist))
}
const extra=()=>{
return src('**',{base:config.build.public,cwd:config.build.public}).pipe(plugins.imagemin())
.pipe(dest(config.build.dist))
}
const develop=series(clean,parallel(style,script,page),server)
- 生产环境文件的合并和压缩
- 合并:把config.build.temp里面的相关文件进行合并,需要安装gulp-useref。如图中圈住的部分,注释内多个文件会被合并成一个文件
yarn add gulp-useref --dev
- 安装条件判断插件 gulp-if
yarn add gulp-if --dev
- 安装css的压缩插件gulp-clean-css,html的压缩插件gulp-htmlmin,js的压缩插件gulp-uglify
yarn add gulp-clean-css gulp-htmlmin gulp-uglify --dev
- 读取config.build.temp里面的html文件,根据文件类型进行压缩,最后存放到dist文件
const useRef=()=>{
return src(config.build.paths.pages,{base:config.build.temp,cwd:config.build.temp})
.pipe(plugins.useref({searchPath:['.','..',config.build.temp]}))
.pipe(plugins.if(/\.css$/,plugins.cleanCss()))
.pipe(plugins.if(/\.js$/,plugins.uglify()))
.pipe(plugins.if(/.html$/,plugins.htmlmin({
collapseWhitespace:true,
minifyCss:true,
minifyJs:true
})))
}
- 构建生产环境的build任务
const compile=parallel(style,script,page,image,font,extra)
const build=series(clean,compile,useRef)
gulp的封装
思路:zce-pages-lulu为封装的脚手架文件,pages-boilerplate为需要编译压缩的项目,我们现在把写过的gulpfile.js文件抽取成一个脚手架文件并在npm上发布,然后在pages-boilerplate安装使用
- 新建一个文件夹,并且初始化配置文件,初始化git配置
mkdir zce-pages-lulu
cd zce-pages-lulu
yarn init
git init
- 把我们安装过的插件全部copy到zce-pages-lulu的package.json的依赖里面
- 新建入口文件lib/index.js
- 把我们上次写的gulpfile.js里面的文件全部拷进去
- 抽取gulpfile.js的配置项文件
- 把原本gulpfile.js的配置项文件抽取成config.pages.js文件,放到执行pages-boilerplate项目中
--在index.js中引入执行项目的配置文件
let config={
}
try {
const loadConfig=require(`${process.cwd()}/pages.config.js`)
config=Object.assign({},config,loadConfig)
}catch (e) {
}
- 新建执行命令文件bin-zce-pages.js,增加执行代码
#!/usr/bin/env node
//必填,指明执行环境node
process.argv.push('--cwd')
process.argv.push(process.cwd()) //增加执行时所在项目的路径
process.argv.push('--gulpfile')
process.argv.push(require.resolve('..')) //增加执行的gulpfile文件
console.log(process.argv)
require('gulp/bin/gulp') //载入gulp文件
- 在脚手架项目package.json文件内增加入口文件和执行文件
"main": "lib/index.js",
"bin": "bin/zce-pages.js"
package.json文件一览
{
"name": "zce-pages-lulu", //npm publish的时候需要改成自己的名字,否则会提示没有权限
"version": "0.3.1", //每次npm publish需要修改版本号
"description": "Awesome node modules.",
"keywords": [
"zce-pages",
"zce"
],
"repository": "zce/zce-pages",
"license": "MIT",
"author": "lilulu <799335607@qq.com> (https://zce/me)",
"main": "lib/index.js", //项目入口文件
"files": [ //npm publish的时候包括的文件
"lib",
"bin"
],
"scripts": {},
"bin": "bin/zce-pages.js", //脚手架执行文件
"renovate": {
"extends": [
"zce"
]
},
"standard": {
"env": [
"jest"
]
},
"dependencies": { //开发环境,生产环境的依赖
"@babel/core": "^7.18.2",
"@babel/preset-env": "^7.18.2",
"browser-sync": "^2.27.10",
"del": "^6.1.1",
"gulp": "^4.0.2",
"gulp-babel": "^8.0.0",
"gulp-clean-css": "^4.3.0",
"gulp-htmlmin": "^5.0.1",
"gulp-if": "^3.0.0",
"gulp-imagemin": "^7.0.0",
"gulp-load-plugins": "^2.0.1",
"gulp-sass": "^4.0.0",
"gulp-swig": "^0.9.1",
"gulp-uglify": "^3.0.2",
"gulp-useref": "^5.0.0",
"jquery": "3.4.1",
"popper.js": "1.16.1",
"sass": "^1.52.1"
},
"devDependencies": { //开发环境的依赖
"gulp-imagemin": "^8.0.0",
"jest": "27.5.1",
"standard": "16.0.4"
},
"engines": {
"node": ">=14"
},
"publishConfig": {
"registry": "https://registry.npmjs.org"
},
"private": false
}
-
在gitee/github上新建仓库,把地址和本地的脚手架项目zce-pages-lulu连接,并且发布
-
发布zce-pages-lulu到npm
- registry记得切到npm
- 登录npm
npm login
- 输入账号,密码,邮箱及一次性密码后,发布项目
npm publish
- 项目内使用
- cd到项目内后,直接在项目内安装,如果刚发布,国内淘宝镜像还没有更新,建议registry切换到npm,进行下载,运行以下命令安装
yarn add zce-pages-lulu //zce-pages-lulu 需要换成你的脚手架名称
- 执行相应命令即可
yarn zce-pages-lulu clean//zce-pages-lulu 需要换成你的脚手架名称
yarn zce-pages-lulu develop//zce-pages-lulu 需要换成你的脚手架名称
yarn zce-pages-lulu build//zce-pages-lulu 需要换成你的脚手架名称