乐趣区

关于前端:前端工程化5Gulp最基本配置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"
  },

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

退出移动版