gulp的使用

113 阅读4分钟

谈谈你对工程化的初步认识,结合你之前遇到的问题说出三个以上工程化能够解决问题或者带来的价值

什么是工程化:工程化是以提高工作效率,降低工作成本,提高代码质量都可以称为工程化

价值:

  • 代码的风格不统一,利用eslint可以约定好统一的代码风格
  • 转换ES6及以上的新语法,保证能够在较低版本的浏览器环境上运行
  • 实现代码模块化,组件化
  • 自动发布到服务器,减少人工出错的几率

你认为脚手架除了为我们创建项目结构外,还有什么更深的意义

为开发人员提供了相同的模块依赖,工具配置,基础代码等,当项目需要另一个开发人员经手时,能够直接上手,提高开发效率

gulp的使用

接下来我简单的实现一个基础的gulp使用过程

文件目录

部分依赖

创建gulp的入口文件gulpfile.js

// 实现这个项目的构建任务
// gulp运行时如果是找不到gulp的某个模块,重新安装下gulp
const { src, dest, parallel, series, watch } = require('gulp')

// 删除文件夹的插件
const del = require('del')
// 热更新插件
const browserSync = require('browser-sync')
// 创建一个本地服务器
const bs = browserSync.create()

// gulp-sass安装不了的情况下,可以试着先安装node-sass,再安装gulp-sass
const sass = require('gulp-sass')

// 安装这个模块后,还要安装依赖包@babel/preset-env  @babel/core
const babel = require('gulp-babel')

// 编译html的插件
const swig = require('gulp-swig')
// 压缩图片的插件,如果运行时,报错说找不到这个模块,请重新安装cnpm install gulp-imagemin gifsicle -D
const imagemin = require('gulp-imagemin')
// 压缩js的插件
const uglify = require('gulp-uglify')
// 压缩css的插件
const cleanCss = require('gulp-clean-css')
// 压缩html的插件
const htmlmin = require('gulp-htmlmin')
// 把html的css,js按照注释的规则,整合到一起的插件
const useref = require('gulp-useref')
// 判断插件
const If = require('gulp-if')

// html文件内变量的数据来源
const data = {
  menus: [
    {
      name: 'Home',
      icon: 'aperture',
      link: 'index.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'])
}

// 编译样式文件
const style = () => {
  return src('src/assets/styles/*.scss', {base: 'src'})//这里设置base是为了保持原有的目录结构输出
  .pipe( sass({outputStyle: 'expanded'}) ) // 这里利用gulp-sass把scss文件转成css文件,输出格式为expanded
  .pipe(dest('temp'))
}

/*
const style = () => {
  return src('src/assets/styles/*.scss', {base: 'src'})
  .pipe( sass({outputStyle: 'expanded'}) ) 
  .pipe(dest('temp'))
  //加下面这个是可以监听当这个文件发生变化时,可以自动更新界面,跟bs.init里的files字段一个作用
  .pipe(bs.reload({ stream: true }))
}
*/

// 编译js文件
const script = () => {
  return src('src/assets/scripts/*.js', {base: 'src'})
  .pipe( babel({presets: ['@babel/preset-env']}) ) // 利用@babel/preset-env转换新语法
  .pipe(dest('temp'))
}

// 编译HTML文件
const page = () => {
  return src('src/*.html', {base: 'src'})
  .pipe( swig({data, defaults: { cache: false } }) ) // 使用BrowserSync等查看/编译html模板时,避免缓存可以设置cache :false
  .pipe(dest('temp'))
}

// 编译图片文件
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'))
}

// 直接复制public下的文件
const extra = () => {
  return src('public/**', {base: 'public'})
  .pipe(dest('dist'))
}

/*
把html的css,js按照注释的规则,整合到一起  把代码压缩
这个压缩是在已经编译好的文件进行二次压缩整合,
所以可以把第一次编译的脚本文件放到另一个文件夹temp中,然后经过这次压缩过后再放到dist里
*/ 
const compress = () => {
  // 把html的css,js按照注释的规则,整合到一起
  return src('temp/*.html', {base: 'temp'})
  .pipe(useref({ searchPath: ['temp', '.'] })) // html里的文件路径来源
  // 压缩文件
  .pipe( If(/\.js$/, uglify()) )
  .pipe( If(/\.css$/, cleanCss()) )
  .pipe( If(/\.html$/, htmlmin({
    collapseWhitespace: true, //去掉换行
    minifyCSS: true, // 压缩页面内的css
    minifyJS: true
  })) )
  .pipe(dest('dist'))
}

// 利用本地服务器,在浏览器上运行
const createServe = () => {
  // 监听src下的文件变化,重新编译文件
  watch('src/assets/styles/*.scss', style)
  watch('src/assets/scripts/*.js', script)
  watch('src/*.html', page)
  // 监听src下的静态资源的变化,本地服务器刷新一下
  watch([
    'src/assets/images/**',
    'src/assets/fonts/**',
    'public/**'
  ], bs.reload)

  // 配置本地服务器的一些参数
  bs.init({
    // 关闭bs连接时的提示
    notify: false,
    // 端口号
    port: 1300,
    // 监听文件变化自动更新界面
    files: 'temp/**',
    server: {
      // 文件根目录,第一个找不到找第二个,以此类推
      baseDir: ['temp', 'src', 'public'],
      // 文件的路径,会优先找这个,再找baseDir
      routes: {
        '/node_modules': 'node_modules'
      }
    }
  })
}

// parallel 同时执行多个命令,  series 按顺序执行
// 脚本的编译
const basics = parallel(style, script, page)
// 静态资源的编译
const resources = parallel(image, font, extra)
// 打包编译
const build = series(clean, parallel(
  series(basics, compress),
  resources
) )
// 启动本地调试服务,本地调试时,没必要去编译静态资源文件
const serve = series(clean, basics, createServe)
module.exports = {
  clean,
  build,
  serve
}