Gulp

作者: 浅忆_0810 | 来源:发表于2020-12-29 22:36 被阅读0次

1. Gulp

  1. 初始化package.json文件

    yarn init # or npm init
    
  2. 安装gulp模块

    yarn add gulp --dev
    
  3. 在项目根目录下创建gulpfile.js入口文件,在里面定义一些需要gulp执行的构建任务


2. 基本使用

/*
  gulpfile.js
  gulp 的入口文件
  gulp 的任务函数都是异步的
*/
// 可以通过调用回调函数标识任务完成
exports.foo = done => {
  console.log('foo task working~')
  done() // 标识任务执行完成
}

// default 是默认任务
// 在运行可以省略任务名参数
exports.default = done => {
  console.log('default task working~')
  done()
}

// 注意  v4.0 之前需要通过 gulp.task() 方法注册任务
const gulp = require('gulp');

gulp.task('bar', done => {
  console.log('bar task working~');
  done();
});
gulp-basis

3. 组合任务

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);
series parallel

4. 异步任务

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');
  // resolve()中不需要传入值,因为gulp会自动忽略
  return Promise.resolve();
}

// or
exports.promise_error = () => {
  console.log('promise task')
  return Promise.reject(new Error('task failed'))
}
const timeout = time => {
  return new Promise(resolve => {
    setTimeout(resolve, time)
  })
}
exports.async = async () => {
  await timeout(1000);
  console.log('async task');
}
exports.stream = () => {
  const readStream = fs.createReadStream('package.json');
  const writeStream = fs.createWriteStream('temp.txt');
  readStream.pipe(writeStream);
  return readStream;
}

// => 等价于
exports.stream = () => {
  const readStream = fs.createReadStream('package.json');
  const writeStream = fs.createWriteStream('temp.txt');
  readStream.pipe(writeStream);
  readStream.on('end', () => {
    done();
  });
}

5. Gulp核心工作原理

读取流 -> 插件转换流做处理 -> 写入流
yarn add gulp-clean-css gulp-rename --dev
const { src,dest } = require('gulp');
const cleanCSS = require('gulp-clean-css');
const rename = require('gulp-rename');

exports.default = () => {
  return src('src/*.css')
    .pipe(cleanCSS()) // 转换为压缩后的代码
    .pipe(rename({ extname: '.min.css' })) // 重命名扩展名
    .pipe(dest('dist'))
}

6. 样式编译任务

6.1 对所有 scss文件进行拷贝

const { src,dest } = require('gulp');
const rename = require('gulp-rename');

const style = () => {
  return src('src/assets/styles/*.scss', { base: 'src' }) // 第二个参数:转换的基本路径
    .pipe(dest('dist'))
}

module.exports = {
  style
}

6.2 安装gulp-sass对style进行转换

yarn add gulp-sass --dev

安装gulp-sass时,会安装node-sass

解决办法

const sass = require('gulp-sass');
const style = () => {
  return src('src/assets/styles/*.scss', { base: 'src' }) // 第二个参数:转换的基本路径
    .pipe(sass({ outputStyle: 'expanded' })) // expanded: 将转换后的样式代码完全展开
    .pipe(dest('dist'))
}

注意:sass模块工作时会忽略以_开头的文件,因此这些文件不会被转换


7. js编译任务

7.1 对所有 js文件进行拷贝

const script = () => {
  return src('src/assets/scripts/*.js', { base: 'src' })
    .pipe(dest('dist'))
}

module.exports = {
  style,
  script
}

7.2 安装gulp-babel对js进行转换

const babel = require('gulp-babel');

const script = () => {
  return src('src/assets/scripts/*.js', { base: 'src' })
    .pipe(babel())
    .pipe(dest('dist'))
}

注意:这里命令行使用yarn gulp script后会报Error: Cannot find module '@babel/core'

因为 babel安装时候不像gulp-sass那样自动安装了css的转换模块node-sass

babel只是一个转换平台,我们需要自己去安装转换模块

7.3 安装@babel/core转换模块和@/babel/preset-env(会将ECMAScript全部的新特性进行转换)

yarn add @babel/core @babel/preset-env --dev

7.4 对js进行转换

const script = () => {
  return src('src/assets/scripts/*.js', { base: 'src' })
    .pipe(babel({ presets: ['@babel/preset-env'] }))
    .pipe(dest('dist'))
}

8. HTML模板文件编译任务

8.1 安装模板引擎转换插件

# 这里使用的是swig模板
yarn add gulp-swig --dev

8.2 对html进行转换

const swig = require('gulp-swig');

const data = {
  menus: [
    {
      name: 'Home',
      icon: 'aperture',
      link: 'index.html'
    },
    {
      name: 'Contact',
      link: '#',
      children: [
        {
          name: 'About',
          link: 'https://weibo.com/zceme'
        }
      ]
    }
  ],
  pkg: require('./package.json'),
  date: new Date()
}

const page = () => {
  // 如果要转换的 html 目录不只在src下,可以使用 src/**/*.html
  return src('src/*.html', { base: 'src' })
    .pipe(swig({ data }))
    .pipe(dest('dist'))
}

module.exports = {
  style,
  script,
  page
}

9. 组合任务

const { src,dest,parallel } = require('gulp');

// paralle 里的任务可以同时执行
const compare = paralle(style, script, page);

module.exports = {
  compare
}

10. 图片和字体文件编译任务

10.1 安装gulp-imagemin

yarn add gulp-imagemin --dev

注意:这里可能会报一些 c++的二进制文件没安装成功

解决办法

10.2 对图片进行压缩

const imagemin = require('gulp-imagemin');

const image = () => {
  return src('src/assets/images/**', { base: 'src' })
    .pipe(imagemin())
    .pipe(dest('dist'))
}

10.3 对字体进行压缩

const font = () => {
  return src('src/assets/fonts/**', { base: 'src' })
    .pipe(imagemin())
    .pipe(dest('dist'))
}

// paralle 里的任务可以同时执行
const compare = parallel(style, script, page, image, font);

11. 其它文件及文件清除编译任务

11.1 对其它文件进行拷贝

const extra = () => {
  return src('public/**', { base: 'public' })
    .pipe(dest('dist'))
}

const build = parallel(compare, extra);

module.exports = {
  build
}

11.2 自动清除dist下的文件

1. 安装 del
yarn add del --dev

2. 清除dist下的文件
const { src,dest,parallel, series } = require('gulp');
const del = require('del');

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

// series 按顺序依次执行
const build = series(clean, parallel(compare, extra));

module.exports = {
  build
}

12. 自动加载插件

12.1 安装gulp-load-plugins

yarn add gulp-load-plugins --dev

12.2 使用

const loadPlugin = require('gulp-load-plugins');

const plugins = loadPlugin();
// 将所有通过 gulp-xx 引入的文件 可以全部替换成  plugins.xx

// example
const babel = require('gulp-babel');
const script = () => {
  return src('src/assets/scripts/*.js', { base: 'src' })
    .pipe(babel({ presets: ['@babel/preset-env'] }))
    .pipe(dest('dist'))
}

// =>
const script = () => {
  return src('src/assets/scripts/*.js', { base: 'src' })
    .pipe(plugins.babel({ presets: ['@babel/preset-env'] }))
    .pipe(dest('dist'))
}

13 热更新开发服务器

13.1 安装browser-sync(支持修改代码后自动热更新到浏览器中)

yarn add browser-sync --dev

13.2 使用

const browserSync = require('browser-sync');

const bs = browserSync.create(); // 会自动创建一个开发服务器

const serve = () => {
  bs.init({
    notify: false, // 取消右上角提示
    port: 2000, // 端口,默认 3000
    // open: false, // 是否自动打开浏览器
    files: 'dist/**', // 监听哪些文件改变后浏览器自动更新
    server: {
      baseDir: 'dist', // 网站根目录
      routes: {
        '/node_modules': 'node_modules' // 对打包后的 /node_modules 路径进行处理
      }
    }
  })
}

module.exports = {
  build,
  serve
}

14. 监视 src变化以及构建过程优化

14.1 监视 src各文件变化

const { src,dest,parallel, series, watch } = require('gulp');

const serve = () => {
  watch('src/assets/styles/*.scss', style);
  watch('src/assets/scripts/*.js', script);
  watch('src/*.html', page);
  watch('src/assets/image/**', image);
  watch('src/assets/fonts/**', font);
  watch('public/**', extra);

  bs.init({
    notify: false,
    port: 2000,
    // open: false,
    files: 'dist/**',
    server: {
      baseDir: 'dist',
      routes: {
        '/node_modules': 'node_modules'
      }
    }
  })
}

14.2 构建优化

const serve = () => {
  watch('src/assets/styles/*.scss', style);
  watch('src/assets/scripts/*.js', script);
  watch('src/*.html', page);
  /*
    watch('src/assets/image/**', image);
    watch('src/assets/fonts/**', font);
    watch('public/**', extra);
  */
  watch([
    'src/assets/image/**',
    'src/assets/fonts/**',
    'public/**'
  ], bs.reload);

  bs.init({
    notify: false,
    port: 2000,
    // open: false,
    files: 'dist/**',  // 下面介绍不使用 files 来监听
    server: {
      baseDir: ['dist','src','public'],
      routes: {
        '/node_modules': 'node_modules'
      }
    }
  })
}

const compare = parallel(style, script, page);

// 上线之前执行的任务
const build = series(clean, parallel(compare, extra, image, font));

// 应该先编译脚本,样式等  在编译 serve
const develop = series(compare, serve);

module.exports = {
  clean,
  build,
  develop
}
// 注意:这部分不是优化,只是有些代码写法不是用 files监听,而是用的以下方式

const style = () => {
  return src('src/assets/styles/*.scss', { base: 'src' }) // 第二个参数:转换的基本路径
    .pipe(plugins.sass({ outputStyle: 'expanded' })) // expanded: 将转换后的样式代码完全展开
    .pipe(dest('dist'))
    .pipe(bs.reload({ stream: true }))
}

const script = () => {
  return src('src/assets/scripts/*.js', { base: 'src' })
    .pipe(plugins.babel({ presets: ['@babel/preset-env'] }))
    .pipe(dest('dist'))
    .pipe(bs.reload({ stream: true }))
}

const page = () => {
  return src('src/*.html', { base: 'src' })
    .pipe(plugins.swig({ data }))
    .pipe(dest('dist'))
    .pipe(bs.reload({ stream: true }))
}

const serve = () => {
  watch('src/assets/styles/*.scss', style);
  watch('src/assets/scripts/*.js', script);
  watch('src/*.html', page);
  watch([
    'src/assets/image/**',
    'src/assets/fonts/**',
    'public/**'
  ], bs.reload);

  bs.init({
    notify: false,
    port: 2000,
    // open: false,
    server: {
      baseDir: ['dist','src','public'],
      routes: {
        '/node_modules': 'node_modules'
      }
    }
  })
}

15. useref文件引用处理

15.1 安装gulp-userg

yarn add gulp-useref --dev

15.2 使用

const useref = () => {
  return src('dist/*.html', { base: 'dist' })
    .pipe(plugins.useref({ searchPath: ['dist', '.'] })) // 将代码中的构建注释转换
    .pipe(dest('dist'))
}

module.exports = {
  clean,
  build,
  develop,
  useref
}

16. 文件压缩

16.1 安装htmljscss压缩插件

yarn add gulp-htmlmin gulp-uglify gulp-clean-css --dev

16.2 安装gulp-if插件对不同文件类型进行判断

yarn add gulp-if --dev

16.3 使用

const useref = () => {
  return src('dist/*.html', { base: 'dist' })
    .pipe(plugins.useref({ searchPath: ['dist', '.'] })) // 将代码中的构建注释转换
    // 压缩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,
      minifyJS: true 
    })))
    .pipe(dest('release')) // 这里不能也写 'dist' 避免读写冲突
}

17. 重新规划构建过程

// gulp 的入口文件
const { src,dest,parallel, series, watch } = require('gulp');

const loadPlugin = require('gulp-load-plugins');
const plugins = loadPlugin();

const del = require('del');
const browserSync = require('browser-sync');

const bs = browserSync.create();

// 网页所需要的数据
const data = {  }

const clean = () => {
  return del(['dist', 'temp']) // temp: 临时生成的目录
}

const style = () => {
  return src('src/assets/styles/*.scss', { base: 'src' }) // 第二个参数:转换的基本路径
    .pipe(plugins.sass({ outputStyle: 'expanded' })) // expanded: 将转换后的样式代码完全展开
    .pipe(dest('temp'))
    .pipe(bs.reload({ stream: true }))
}

const script = () => {
  return src('src/assets/scripts/*.js', { base: 'src' })
    .pipe(plugins.babel({ presets: ['@babel/preset-env'] }))
    .pipe(dest('temp'))
    .pipe(bs.reload({ stream: true }))
}

const page = () => {
  return src('src/*.html', { base: 'src' })
    .pipe(plugins.swig({ data }))
    .pipe(dest('temp'))
    .pipe(bs.reload({ stream: true }))
}

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/image/**', image);
  watch('src/assets/fonts/**', font);
  watch('public/**', extra);
 */
  watch([
    'src/assets/image/**',
    'src/assets/fonts/**',
    'public/**'
  ], bs.reload);

  bs.init({
    notify: false,
    port: 2000,
    // open: false,
    // files: 'dist/**',
    server: {
      baseDir: ['temp','src','public'],
      routes: {
        '/node_modules': 'node_modules'
      }
    }
  })
}

const useref = () => {
  return src('temp/*.html', { base: 'dist' })
    .pipe(plugins.useref({ searchPath: ['dist', '.'] })) // 将代码中的构建注释转换
    // 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,
      minifyJS: true 
    })))
    .pipe(dest('dist'))
}

const compare = parallel(style, script, page);

// 上线之前执行的任务
const build = series(
  clean, 
  parallel(
    series(compare, useref), 
    extra, 
    image, 
    font
  )
);

const develop = series(compare, serve);

module.exports = {
  clean,
  build,
  develop
}
// package.json
{
  "name": "gulp-cli",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT",
  "scripts": {
    "clean": "gulp clean",
    "build": "gulp build",
    "develop": "gulp develop"
  },
  "dependencies": {
    "bootstrap": "4.4.1"
  },
  "devDependencies": {
    "@babel/core": "^7.12.3",
    "@babel/preset-env": "^7.12.1",
    "browser-sync": "^2.26.13",
    "del": "^6.0.0",
    "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.1.0",
    "gulp-load-plugins": "^2.0.5",
    "gulp-sass": "^4.1.0",
    "gulp-swig": "^0.9.1",
    "gulp-uglify": "^3.0.2",
    "gulp-useref": "^4.0.1"
  }
}
// .gitignore
dist

temp

相关文章

  • gulp

    gulp gulp.src gulp.dest gulp.task gulp.watch gulp.pipe() ...

  • gulp自动化项目构建

    var gulp = require('gulp');//引用gulp var $ = require('gulp...

  • gulp压缩合并文件

    gulp压缩合并文件流程 //引入gulp和gulp插件var gulp = require('gulp');va...

  • Gulp 使用方法(教程一)

    Gulp 官网 目录 Gulp 环境 Gulp 环境 初始化目录结构 安装 gulp gulp 的简单使用 使用 ...

  • gulp讲解

    一、gulp的四个主要的API gulp.src、gulp.pipe、gulp.dest、gulp.watch 二...

  • JS: gulp.js

    var gulp = require('gulp'), minify = require('gulp-minify...

  • gulp的简单使用

    gulp使用流程:安装nodejs -> 全局安装gulp -> 项目安装gulp以及gulp插件 -> 配置gu...

  • gupl 的基本压缩

    // 获取 gulp var gulp = require('gulp'); // 获取 uglify 模块(用于...

  • gulp+webpack+experss

    var gulp = require('gulp'); var gls = require('gulp-live-...

  • gulp与webpack的区别

    gulp webpack 相同功能: 功能 gulp webpack gulp.task('sass'...

网友评论

    本文标题:Gulp

    本文链接:https://www.haomeiwen.com/subject/yfqubktx.html