如何用gulp实现一个项目的打包构建

项目目录结构如下

gulp-demo
├─ .gitignore
├─ gulpfile.js
├─ LICENSE
├─ package.json
├─ public
│  └─ favicon.ico
├─ README.md
└─ src
   ├─ about.html
   ├─ assets
   │  ├─ fonts
   │  │  ├─ pages.eot
   │  │  ├─ pages.svg
   │  │  ├─ pages.ttf
   │  │  └─ pages.woff
   │  ├─ images
   │  │  ├─ brands.svg
   │  │  └─ logo.png
   │  ├─ scripts
   │  │  └─ main.js
   │  └─ styles
   │     ├─ demo.scss
   │     ├─ main.scss
   │     ├─ _icons.scss
   │     └─ _variables.scss
   ├─ features.html
   ├─ index.html
   ├─ layouts
   │  └─ basic.html
   └─ partials
      ├─ footer.html
      ├─ header.html
      └─ tags.html

● 样式编译
○ 安装gulp
○ 在入口文件中配置:

const {src,dest} = require("gulp") 
// yarn add gulp-sass sass --dev
const sass = require("gulp-sass")(require('sass'))

const style = ()=>{
  //读入样式文件,base:src表示写入的文件保留src之后的文件层级
  return src('src/assets/styles/*.scss',{base:'src'})
  //将sass文件转换,且样式的括号打开
  .pipe(sass({outputStyle:'expanded'}))
  .pipe(dest('dist'))
}

module.exports = {
  style
}

● 脚本编译
○ 将es6编译成es5

const {src,dest} = require("gulp") 

//yarn add gulp-babel
//yarn add @babel/core @babel/preset-env --dev
const babel = require("gulp-babel")
// yarn add gulp-sass sass --dev
const sass = require("gulp-sass")(require('sass'))

const style = ()=>{
  //读入样式文件,base:src表示写入的文件保留src之后的文件层级
  return src('src/assets/styles/*.scss',{base:'src'})
  //将sass文件转换,且样式的括号打开
  .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
}

● 模板文件编译
○ 将模板html文件渲染编译
○ 安装渲染模块yarn add gulp-swig

const page = ()=>{
  return src("src/**/*.html",{base:'src'})
  //渲染模板,传入数据
  .pipe(swig({data}))
  .pipe(dest('dist'))
  
}

● 对字体和图片的压缩
○ 安装插件:yarn add gulp-imagemin --dev
■ 版本太高可能报错:https://blog.csdn.net/qq_25972233/article/details/123045152


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'))
}

● 处理完src目录下的文件还需要处理public下的文件,这里的文件属于直接调用的文件,之间复制到dist目录中即可

const extra = ()=>{
 return src("public/**",{base:'public'})
 .pipe(dest("dist"))
}
const compile = parallel(style,script,page,image,font)
const bulid = parallel(compile,extra)
 ○ 通过build可以把文件全部打包到dist目录,但是每一次build前需要把之前的dist删除再重新生成,这里就需要一个删除文件夹的命令

○ 安装模块:yarn add del --dev

const del = ()=>{
  return del(['dist'])
}
const bulid = series(del,parallel(compile,extra)) 

● 自动加载插件
○ 随着插件越来越多,每一次引用导致代码太长不易维护
○ 使用模块:yarn add gulp-load-plugins --dev可以自动加载所有插件

const plugins = loadPlugins()
○ 删除gulp插件的引用,以后用到插件只需plugins.插件名

● 创建服务器热更新
○ 安装:yarn add browser-sync --dev
○ 引入模块之后,创建热更新任务

const serve = ()=>{
//bs为安装的模块
  bs.init({
      notify:false,//是否提示
      port:2080,
      //监听的文件,文件改变,浏览器刷新
      files:'dist/**',
      server:{
            //指定网站根目录
          baseDir:'dist',
          routes:{
              //dist中html文件引入node_modules中的模块,这里告诉浏览器如果html中有/node_modules,就直接去根目录下的node_modules中找,后面会将node_modules中需要的文件提取到dist中
              '/node_modules':'node_modules'
          }
      }

  })
}

○ serve中配置的是对打包好的dist下的监听,在实际上线前,如何对开发环境进行监听呢?
■ 可以借助gulp中的watch模块
■ 在serve运行的时候,监听src目录下的变化,同时调用之前的任务打包对应的变化
■ 值得注意的是,我们通常会监听js、css等文件变化,而图片字体的变化一般监听的时候不会让它进行打包,因为很耗费性能,只在最后上线的时候才打包,那么如何保证dist目录中存在这个字体和样式以便被网站显示呢?
■ 其实既然不打包,dist中就不必出现这些文件,只需要修改serve中的baseDir监听,对src或public下的文件也进行搜索,当dist中的文件引用不存在,会依次向src搜索

const serve = ()=>{
 //监听
 watch('src/assets/styles/*.scss',style)
 watch("src/assets/scripts/*.js",script)
 watch("src/**/*.html",page)
//下面的资源文件监听,服务器执行刷新命令即可
 watch([
     "src/assets/images/**",
     "src/assets/fonts/**",
     "public/**"
 ],bs.reload)

 bs.init({
     notify:false,//是否提示
     port:2080,
     //监听的文件,文件改变,浏览器刷新
     files:'dist/**',
     server:{
           //指定网站根目录
         baseDir:['dist','src','public'],
         routes:{
             //dist中html文件引入node_modules中的模块,这里告诉浏览器如果html中有/node_modules,就直接去根目录下的node_modules中找,后面会将node_modules中需要的文件提取到dist中
             '/node_modules':'node_modules'
         }
     }

 })
}

● useref文件引用处理
○ html中link标签引入很多css文件,这些文件的路径有的是开发者规定好的,有的则在node_modules下
○ 可以使用gulp-useref来提取这些文件,并将它们合并到一起

const useref = ()=>{
  return src("dist/*.html",{base:'dist'})
  //搜索的位置,本项目css文件,一般在dist,node_modules中
  .pipe(plugins.useref({ searchPath:['dist','.'] }))
  .pipe(dest('dist'))
}

● 文件资源压缩
○ 打包之后我们发现html、css、js没有压缩
○ yarn add gulp-htmlmin gulp-uglify gulp-clean-css --dev 分别安装html js css压缩模块
○ 我们将插件放在useref任务中,当扫描html文件时,就可以对引用的文件进行压缩
○ 在扫描时,需要对文件类型进行判断,安装yarn add gulp-if插件实现

const useref = ()=>{
  return src("dist/*.html",{base:'dist'})
  //搜索的位置,本项目css文件,一般在dist,node_modules中
  .pipe(plugins.useref({ searchPath:['dist','.'] }))
  //判断是否.js结尾文件并压缩
  .pipe(plugins.if(/\.js$/,plugins.uglify()))
  .pipe(plugins.if(/\.css$/,plugins.cleanCss()))
  .pipe(plugins.if(/\.html$/,plugins.htmlmin({
      collapseWhitespace:true, //压缩空格
      minifyCSS:true,//压缩行内样式
      minifyJS:true //压缩内部js
  })))
  .pipe(dest('release'))
}

● 重新规划构建流程
○ 可以看到,我们之前打包到dist目录的文件只是中间文件,最后要经过useref压缩之后才是最后的文件,如果想要最后文件为dist,就需要规划一个临时文件夹存放打包的文件,然后最后压缩到dist目录中

const {src,dest,parallel,series,watch} = require("gulp") 
const loadPlugins = require("gulp-load-plugins")
const sass = require("gulp-sass")(require("sass"))
const del = require("del")
const bs = require("browser-sync")
const plugins = loadPlugins()

const clean = ()=>{
  return del(['dist','temp'])
}

const style = ()=>{
  //读入样式文件,base:src表示写入的文件保留src之后的文件层级
  return src('src/assets/styles/*.scss',{base:'src'})
  //将sass文件转换,且样式的括号打开
  .pipe(sass({outputStyle:'expanded'}))
  .pipe(dest('temp'))
}
const script = ()=>{
  return src("src/assets/scripts/*.js",{base:'src'})
  .pipe(plugins.babel({presets:['@babel/preset-env']}))
  .pipe(dest('temp'))
}

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 page = ()=>{
  return src("src/**/*.html",{base:'src'})
  //渲染模板,传入数据
  .pipe(plugins.swig({data}))
  .pipe(dest('temp'))
  
}

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/**",
      "src/assets/fonts/**",
      "public/**"
  ],bs.reload)

  bs.init({
      notify:false,//是否提示
      port:2080,
      //监听的文件,文件改变,浏览器刷新
      files:'dist/**',
      server:{
            //指定网站根目录
          baseDir:['temp','src','public'],
          routes:{
              //dist中html文件引入node_modules中的模块,这里告诉浏览器如果html中有/node_modules,就直接去根目录下的node_modules中找,后面会将node_modules中需要的文件提取到dist中
              '/node_modules':'node_modules'
          }
      }

  })
}
const useref = ()=>{
  return src("temp/*.html",{base:'temp'})
  //搜索的位置,本项目css文件,一般在dist,node_modules中
  .pipe(plugins.useref({ searchPath:['temp','.'] }))
  //判断是否.js结尾文件并压缩
  .pipe(plugins.if(/\.js$/,plugins.uglify()))
  .pipe(plugins.if(/\.css$/,plugins.cleanCss()))
  .pipe(plugins.if(/\.html$/,plugins.htmlmin({
      collapseWhitespace:true, //压缩空格
      minifyCSS:true,//压缩行内样式
      minifyJS:true //压缩内部js
  })))
  .pipe(dest('dist'))
}
const compile = parallel(style,script,page)
const build = series(clean,parallel( series(compile,useref), extra,image,font))
const develop = series(compile,serve) 
module.exports = {
  compile,
  build,
  serve,
  develop,
  useref
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

问也去

创作不易,感谢支持

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值