前端工程化5:Gulp最基本配置,10分钟看完就会

Posted 拖泥羊

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了前端工程化5:Gulp最基本配置,10分钟看完就会相关的知识,希望对你有一定的参考价值。

Gulp的基本使用

安装

> npm install gulp -g

gulp的配置文件:gulpfile.js
gulp4.0以后不再推荐使用 gulp.task() ,而是推荐使用 exports 的方式定义任务:

exports.foo = done =>{

  done() //标记任务完成
}

组合配置

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

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

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

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

// 让多个任务按照顺序依次执行
exports.foo = series(task1, task2, task3)

// 让多个任务同时执行
exports.bar = parallel(task1, task2, task3)

异步任务

const fs = require(\'fs\')

exports.callback = done => {
  console.log(\'callback task\')
  done()
}

exports.callback_error = done => {
  console.log(\'callback task\')
  done(new Error(\'task failed\'))
}

exports.promise = () => {
  console.log(\'promise task\')
  return Promise.resolve()
}

exports.promise_error = () => {
  console.log(\'promise task\')
  return Promise.reject(new Error(\'task failed\'))
}

const timeout = time => {
  return new Promise(resolve => {
    setTimeout(resolve, time)
  })
}

// Nodejs版本在8以上可以使用async、await
exports.async = async () => {
  await timeout(1000)
  console.log(\'async task\')
}

// 最常用的一种,读写文件
exports.stream = () => {
  const read = fs.createReadStream(\'yarn.lock\')
  const write = fs.createWriteStream(\'a.txt\')
  read.pipe(write) // 导入文件流
  return read // 结束任务
}

// exports.stream = done => {
//   const read = fs.createReadStream(\'yarn.lock\')
//   const write = fs.createWriteStream(\'a.txt\')
//   read.pipe(write)
//   read.on(\'end\', () => { // 结束任务
//     done()
//   })
// }

构建过程核心工作原理

输入 => 加工 => 输出

const fs = require(\'fs\')
const { Transform } = require(\'stream\')

exports.default = () => {
  // 文件读取流
  const readStream = fs.createReadStream(\'normalize.css\')

  // 文件写入流
  const writeStream = fs.createWriteStream(\'normalize.min.css\')

  // 文件转换流
  const transformStream = new Transform({
    // 核心转换过程
    transform: (chunk, encoding, callback) => {
      const input = chunk.toString()
      const output = input.replace(/\\s+/g, \'\').replace(/\\/\\*.+?\\*\\//g, \'\')
      callback(null, output)
    }
  })

  return readStream
    .pipe(transformStream) // 转换
    .pipe(writeStream) // 写入
}

文件操作API

const { src, dest } = require(\'gulp\')
const cleanCSS = require(\'gulp-clean-css\')
const rename = require(\'gulp-rename\')

exports.default = () => {
  return src(\'src/*.css\')
    .pipe(cleanCSS()) // 压缩css代码插件
    .pipe(rename({ extname: \'.min.css\' })) // 重命名文件插件
    .pipe(dest(\'dist\'))
}

Gulp基础配置

准备工作

  • 安装gulp工具:npm install gulp -g
  • 创建gulp配置:在项目根目录下新建文件gulpfile.js,用于写gulp的配置文件;

Task:清空文件

  • 功能:清空构件生产的所有文件
  • 依赖:del
const clean = () => {
    return del([\'dist\',\'temp\'])
}

Task:css文件处理,sass文件转换

  • 功能:将sass文件转换成css文件写入指定目录
  • 依赖:gulp-sass
const style = () => {
    return src(\'src/assets/styles/*.scss\',{ base: \'src\'}) // base指定基础目录,转换后dist目录才会和src保持一样的结构
        .pipe(plugins.sass({ outputStyle: \'expanded\'})) // { outputStyle: \'expanded\'} 参数可以指定结束括号格式化    
        .pipe(dest(\'temp\'))
}

Task:js文件处理,编译es6+为es5

  • 功能:使用babel插件将js文件里的es6+代码转换为es5
  • 依赖:

    1、gulp-babel => babel工具:转换平台,不作具体的工作
    2、@babel/core => babel核心转换模块:完成语言转换工作
    3、@babel/preset-env => babel的转换插件:指定babel对应的转换内容;比如env包含es6+全部新特性,将其转换到es5
const script = () => {
    return src(\'src/assets/scripts/*.js\',{ base: \'src\'})
        .pipe(plugins.babel({ 
            presets: [\'@babel/preset-env\'] // 编译es6,必须传递参数preset-env,否则转换失效(babel配置可以单独放到.babelrc文件)
        }))
        .pipe(dest(\'temp\'))
}

Task:html文件的转换,处理swig模板

  • 功能:将指定的swig模板转换为html文件,注意:

    1、gulp配置的时候可以将数据以对象的形式传递数据给模板引擎;通常将数据定义在文件中:pages.config.js
    2、swig模板的缓存配置可以关闭,防止浏览器在热更新时没有实时刷新
  • 依赖:gulp-swig
const page = () => {
    return src(\'src/**/*.html\',{ base: \'src\'}) // 其中/**/*.html表示在src目录下任意子目录下的匹配
        .pipe(plugins.swig({ data: config.data, defaults: { cache: false } }))   //转换模板页,将data数据传递给模板使用,cache:swig缓存设置,否则热更新时可能不立即生效
        .pipe(dest(\'temp\'))
}

Task:图片压缩,减少图片体积

  • 功能:压缩图片体积
  • 依赖:gulp-imagemin
const image = () => {
    return src(\'src/assets/images/**\',{ base: \'src\'})
        .pipe(plugins.imagemin())
        .pipe(dest(\'dist\'))
}

Task:字体文件压缩,减少字体文件体积

  • 功能:压缩字体体积
  • 依赖:gulp-imagemin
const font = () => {
    return src(\'src/assets/fonts/**\', { base: \'src\' })
      .pipe(plugins.imagemin())
      .pipe(dest(\'dist\'))
}

Task:其它文件移动,例如视频

  • 功能:移动其余所有文件到指定目录
  • 依赖:无
const extra = () => {
    return src(\'public/**\', { base: \'public\' })
        .pipe(dest(\'dist\'))
}

Gulp的本地服务/热更新/文件合并与压缩

Task:本地Web服务与热更新

  • 功能1:本地Web服务

    1、使用插件browser-sync来启动本地Web服务,并支持一些配置(具体参考示例代码)
    2、重要配置:根路径baseDir,配置后gulp从指定的路径按顺序查找
    3、重要配置:路径查找路由routes,例如:/node_modules映射到node_modules
  • 功能2:浏览器的热更新

    在browser-sync插件的配置中使用files: \'temp/**\'监视目录下所有文件
  • 功能3:源文件的热更新

    1、监视源文件,如果源文件修改后立即重新构建
    2、开发模式下:监视的范围不包括图片、字体和其它文件,将他们的访问路径指定为src路径下可提升构建效率
  • 依赖:browser-sync
const serve = () => {
    // 监视src文件,重新构建代码
    watch(\'src/assets/styles/*.scss\', style)
    watch(\'src/assets/scripts/*.js\', script)
    watch(\'src/*.html\', page)

    // 图片、字体在开发阶段没有必要重新执行构建任务;所以让gulp从源文件src、public里面查找  
    // 图片、字体等文件发生变化后,bs.reload 更新浏览器
    watch([
        \'src/assets/images/**\',
        \'src/assets/fonts/**\',
        \'public/**\'
    ], bs.reload)
    
    // 配置web服务器,监视dist
    bs.init({
        notify: false, // 右上角提示
        port: 2080, // 服务的端口,默认300
        // open: false, // 自动打开浏览器
        files: \'temp/**\', // 热更新,dist下的所有文件变化时,同步更新浏览器
        server: {
          //服务启动时,首先访问dist根目录;查询路径:dist=>src=>public
          //因为图片字体等文件没必要热更新重新构建(减少构建时间),所以让gulp从源文件src、public里面查找  
          baseDir: [\'temp\', \'src\', \'public\'], 
          routes: {// 路径查找路由
            \'/node_modules\': \'node_modules\' //优先级高于baseDir,先查找node_modules目录
          }
        }
    })
}

Task:文件合并与压缩混淆

  • 功能1:文件合并

    useref插件查询指定路径,然后将对应的文件合并
  • 功能2:文件压缩

    1、压缩js
    2、压缩css
    3、压缩html
  • 依赖:

    1、gulp-useref => 查询路径,合并文件
    2、gulp-if => 判断条件插件
    3、gulp-uglify => 压缩js
    4、gulp-clean-css=> 压缩css
    5、gulp-htmlmin => 压缩html
const useref = () => {
    return src(\'temp/*.html\', { base: \'temp\' })
        .pipe(plugins.useref({ searchPath: [\'temp\', \'.\'] })) //查询路径:dist、.根目录下(node_modules) 
        // html js css压缩代码
        .pipe(plugins.if(/\\.js$/, plugins.uglify()))
        .pipe(plugins.if(/\\.css$/, plugins.cleanCss()))
        .pipe(plugins.if(/\\.html$/, plugins.htmlmin({
            collapseWhitespace: true, // 折叠空白字符
            minifyCSS: true, // 自动压缩style里面的css
            minifyJS: true // 自动压缩script里面的js
            // 还有删除注释、空属性等配置
            // ...
        })))
        .pipe(dest(\'dist\'))
}

Gulp配置构建任务的类别

如何组合任务?

  1. 使用parallel/series进行组合任务;
  2. 其中parallel是并行执行,series是串行执行

Gulp构建任务的类别

1. 基础构建: 只构建css、js、html便于本地测试

const compile = parallel(style, script, page) 

2. 开发模式: 基础构建 + 启动web服务 + 热更新(图片/字体等文件使用src本地加快构建速度)

// 2、开发模式:只构建各种代码,启动web服务,图片/字体等文件使用src本地加快构建速度
const develop = series(clean, compile, serve)

3. 生产模式: 执行所有任务;包括合并/压缩各种文件,然后将图片/文件也处理了

const build = series(
    clean, 
    parallel(
        series(compile, useref), 
        extra, 
        image, 
        font
    )
)

其它配置,简化配置、提升自定义程度

1、自动加载全部的plugin

  • 功能:避免引入太多常用插件,直接使用plugins替代;例如:需要将sass替换为plugins.sass变量。
  • 依赖:gulp-load-plugins
// const sass = require(\'gulp-sass\') // npm install gulp-sass --save-dev
// ==>
// 自动加载全部的plugin;例如sass,使用plugins.sass替换即可
const loadPlugins = require(\'gulp-load-plugins\') // npm install gulp-load-plugins --save-dev
const plugins = loadPlugins() 

将原始变量替换为plugins.xxx属性

.pipe(sass({ outputStyle: \'expanded\'}))
// ==>
.pipe(plugins.sass({ outputStyle: \'expanded\'}))

2、模板数据可配置

  • 功能:

    1、将模板引擎所需要的数据定义在:pages.config.js,在gulpfile.js中使用默认配置
    2、gulpfile.js中的所有路径可以使用变量替换,实现更高的自定义程度
  • 依赖:无
let config = {
  // default config
  build: {
    src: \'src\',
    dist: \'dist\',
    temp: \'temp\',
    public: \'public\',
    paths: {
      styles: \'assets/styles/*.scss\',
      scripts: \'assets/scripts/*.js\',
      pages: \'*.html\',
      images: \'assets/images/**\',
      fonts: \'assets/fonts/**\'
    }
  }
}

try {
  const loadConfig = require(`${cwd}/pages.config.js`)
  config = Object.assign({}, config, loadConfig)
} catch (e) {}
  • 数据文件:pages.config.js
module.exports = {
  build: {
    src: \'src\',
    dist: \'release\',
    temp: \'.tmp\',
    public: \'public\',
    paths: {
      styles: \'assets/styles/*.scss\',
      scripts: \'assets/scripts/*.js\',
      pages: \'*.html\',
      images: \'assets/images/**\',
      fonts: \'assets/fonts/**\'
    }
  },
  data: {
    menus: [
      {
        name: \'Home\',
        icon: \'aperture\',
        link: \'index.html\'
      },
      ...
    ],
    pkg: require(\'./package.json\'),
    date: new Date()
  }
}

配置Npm Scripts,启动构建任务:

1、导出任务:在gulpfile.js文件中exports

module.exports = {
    clean,
    build,
    develop
}

2、配置scripts:在文件package.json中配置对应任务执行脚本

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

特别鸣谢:拉勾教育前端高薪训练营

以上是关于前端工程化5:Gulp最基本配置,10分钟看完就会的主要内容,如果未能解决你的问题,请参考以下文章

实战5 分钟学会 Nginx 负载均衡

5 分钟学会 Nginx 负载均衡

Python爬虫,爬取网站图片,详细解释(看完就会)

对比webpack,你更应该先掌握gulp10分钟教你彻底掌握gulp

vue3.x新特性之setup函数,看完就会用了

Linux中find命令用法全汇总,看完就没有不会用的!