自动化构建Gulp

ctrl+e ctrl+1
browser-sync . --file **/*.js
https://unpkg.com/

https://www.cnblogs.com/xqbiii/p/8406978.html

yarn init --yes
yarn add gulp --dev
一.基本使用
exports.foo = (done) => {
    console.log('任务foo')
    done() // 标识任务执行完成
}//yarn gulp foo

// 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()
})
二.执行并行任务,串行任务

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

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('回调报错处理')
    done(new Error('task failed'))
}
//二 通过promise,这里也是支持promise的,resolve不需要返回值,就算返回也会被忽略,直接resolve()
exports.promise = done => {
    console.log('promise')
    return Promise.resolve()
}

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

// 三async await
const timeOut = (time) => {
    return new Promise(resolve => {
        setTimeout(resolve(), time);
    })
}
exports.async = async () => {
    await timeOut(1000)
    console.log('1秒后打印')
}

// stream
exports.stream = () => {
    const read = fs.createReadStream('yarn.lock')
    const write = fs.createWriteStream('a.txt')
    read.pipe(write)
    return read
}
四.glup构建过程

image.png
image.png
eg:这里用node自带的读取流写入流

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) // 写入
}

eg:gulp的读取流,写入流
const { src, dest } = require('gulp')

const { src, dest } = require('gulp')
const cleanCSS = require('gulp-clean-css')//转换流插件压缩css
const rename = require('gulp-rename')//重命名后缀

exports.default = () => {
  return src('src/*.css')
    .pipe(cleanCSS())
    .pipe(rename({ extname: '.min.css' }))
    .pipe(dest('dist'))
}
//定义变量,引入gulp及各个插件

const gulp = require("gulp"),
    sass = require("gulp-sass"),
    connect = require("gulp-connect"),
    uglify = require("gulp-uglify"),
    babel = require("gulp-babel"),
    htmlmin = require("gulp-htmlmin");

// 编译SCSS文件
gulp.task("sass", function() {
    gulp.src("./src/scss/*.scss")
        .pipe(sass({outputStyle:"compressed"}))
        .pipe(gulp.dest("./src/css"))
        .pipe(connect.reload());
});
// html文件修改刷新
gulp.task("html", function() {
    gulp.src("./src/**/*.html")
        .pipe(connect.reload());
});
// js文件修改刷新
gulp.task("js", function() {
    gulp.src("./src/js/*.js")
        .pipe(connect.reload());
});
// 启动服务器
gulp.task("connect", function() {
    connect.server({
        root : "src",
        livereload : true
    });
});
// 监视任务
gulp.task("watch", function(){
    gulp.watch("./src/**/*.html", ["html"]);
    gulp.watch("./src/js/*.js", ["js"]);
    gulp.watch("./src/scss/*.scss", ["sass"]);
});
// 开发环境下的gulp任务
gulp.task("dev", ["sass", "html", "js", "connect", "watch"]);

/***************************************************************/
// 生产环境下的 gulp 任务,将项目生成到 dist 目录下
// dist 目录下的资源是直接用于生产环境(发布项目)的资源
// 编译SCSS文件:生产环境
gulp.task("prod_sass", function() {
    gulp.src("./src/scss/*.scss")
        .pipe(sass({outputStyle:"compressed"}))
        .pipe(gulp.dest("./dist/css"))
        .pipe(connect.reload());
});
// html文件压缩
gulp.task("prod_html", function() {
    gulp.src("./src/**/*.html")
        .pipe(htmlmin({collapseWhitespace: true}))
        .pipe(gulp.dest("./dist"))
        .pipe(connect.reload());
});
// JS转换及压缩
gulp.task("prod_js", function() {
    gulp.src("./src/js/*.js")
        .pipe(babel({
            presets: ['env']
        }))
        .pipe(uglify())
        .pipe(gulp.dest("./dist/js"))
        .pipe(connect.reload());
});
// 复制源文件夹下资源到目标文件夹
gulp.task("copy-images", function() {
    gulp.src("./src/images/**/*.*")
        .pipe(gulp.dest("./dist/images"));
});
gulp.task("copy-lib", function() {
    gulp.src("./src/lib/**/*.*")
        .pipe(gulp.dest("./dist/lib"));
});
gulp.task("prod_copy", ["copy-images", "copy-lib"]);
// 监视任务
gulp.task("prod_watch", function(){
    gulp.watch("./src/**/*.html", ["prod_html"]);
    gulp.watch("./src/js/*.js", ["prod_js"]);
    gulp.watch("./src/scss/*.scss", ["prod_sass"]);
});
// 启动服务器
gulp.task("prod_connect", function() {
    connect.server({
        root : "dist",
        livereload : true
    });
});
// 生产环境gulp任务
gulp.task("production", ["prod_sass", "prod_html", "prod_js", "prod_copy", "prod_connect", "prod_watch"]);

1.基础

//入门 没有用插件yarn add gulp-load-plugins --dev,来自动加载插件,插件入门学习
const { src, dest, parallel,series } = require('gulp')

const del = require('del')//清除文件。返回的是promise

const sass = require('gulp-sass')
const babel = require('gulp-babel')
const swig = require('gulp-swig')
const imagemin = require('gulp-imagemin')

const data = {
 ...
}

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

const style = () => {
  return src('src/assets/styles/*.scss', { base: 'src' })
    .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'))
}

const page = () => {
  return src('src/*.html')
  .pipe(swig({data}))
  .pipe(dest('dist'))
}

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'))
}
const extra = () => {
  return src('public/**', { base: 'public' })
  .pipe(dest('dist'))
}


const complete =  parallel(script,page,style,image,font)//编译src目录下的组合
const build =  series(clear,parallel(extra,complete))//编译整个public和src,这里用series,先去清除dist文件,再生成新的

module.exports = {
  complete,
  build
}
/**
 * 开发阶段,不去构建图片,字体,公共public,所以下个文件用serev时,baseDir指定为一个数组
 */
const { src, dest, parallel, series, watch } = require('gulp')

const del = require('del')//清除文件。返回的是promise
const browserSync = require('browser-sync')//引入服务器,监听变化
const bs = browserSync.create()//创建一个服务器

const loadPlugins = require('gulp-load-plugins')
const plugins = loadPlugins()

const data = {
  ...
}

const clear = () => {
    return del(['dist'])//删除dist文件
}

const style = () => {
    return src('src/assets/styles/*.scss', { base: 'src' })
        .pipe(plugins.sass({ outputStyle: "expanded" }))
        .pipe(dest('dist'))
}

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

const page = () => {
    return src('src/*.html')
        .pipe(plugins.swig({ data, defaults: { cache: false } }))// 防止模板缓存导致页面不能及时更新
        .pipe(dest('dist'))
}

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 complete = parallel(script, page, style, image, font)//编译src目录下的组合
const build = series(clear, parallel(extra, complete))//编译整个public和src,这里用series,先去清除dist文件,再生成新的
const serve = () => {//初始化服务器配置
    watch('src/assets/styles/*.scss', style),
        watch('src/assets/scripts/*.js', script),
        watch('src/*.html', page),
        watch('src/assets/images/**', image),
        watch('src/assets/fonts/**', font),
        watch('public/**', extra),
        bs.init({
            notify: false,//右上角是否连上browser-sync提示是否关掉
            port: 8080,//默认是3000,
            open: false,//是否默认打开
            files: 'dist/**',//监听dist文件下变化实时更新
            server: {
                baseDir: 'dist',
                routes: {
                    '/node_modules': 'node_modules'//basic.html文件里面node_modules的样式路由到node_modules文件下找
                }
            }
        })
}

module.exports = {
    complete,
    build,
    serve
}
/**
 * 1.开发阶段,不去构建图片,字体,公共public,所以用serev时,baseDir指定为一个数组   baseDir: ['dist','src','public'],这样开发阶段不用构建图片,字体,公共public
 *  2.files: 'dist/**',//监听dist文件下变化实时更新 不用这种方法,就在上面定义各个方法时,reload一下,比如page里面加上.pipe(bs.reload({ stream: true })),这里stream: true指,以流的方式推入浏览器
 * 3.
 */
const { src, dest, parallel, series, watch } = require('gulp')

const del = require('del')//清除文件。返回的是promise
const browserSync = require('browser-sync')//引入服务器,监听变化
const bs = browserSync.create()//创建一个服务器

const loadPlugins = require('gulp-load-plugins')
const plugins = loadPlugins()

const data = {
...
}

const clear = () => {
  return del(['dist'])//删除dist文件
}

const style = () => {
  return src('src/assets/styles/*.scss', { base: 'src' })
    .pipe(plugins.sass({outputStyle:"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')
    .pipe(plugins.swig({ data, defaults: { cache: false } }))// 防止模板缓存导致页面不能及时更新
    .pipe(dest('dist'))
    .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 complete = parallel(script, page, style)//编译src目录下的组合

const build = series(clear, parallel(extra, complete, font, image))//编译整个public和src,这里用series,先去清除dist文件,再生成新的,上线之前执行build任务,开发阶段不需要构建图片字体等,没有必要,本来构建的图片字体就是原样压缩的

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,//右上角是否连上browser-sync提示是否关掉
    port: 8080,//默认是3000,
    open: false,//是否默认打开
    // files: 'dist/**',//监听dist文件下变化实时更新 不用这种方法,就在上面定义各个方法时,reload一下,比如page里面加上.pipe(bs.reload({ stream: true })),这里stream: true指,以流的方式推入浏览器
    server: {
      baseDir: ['dist','src','public'],
      routes: {
        '/node_modules': 'node_modules'//basic.html文件里面node_modules的样式路由到node_modules文件下找
      }
    }
  })
}

const develop = series(build,serve)//开发阶段执行这个就够了
module.exports = {
  complete,
  clear,
  build,
  develop
}

封装了常用的gulpfile.js,在lib下面,在用的时候直接在项目里面link,再引进gulpfile.js,通过config.js可以重新传值,但是为了不用总是写gulpfile.js文件,封装一下利用cli,添加cli时要在packjson文件中,添加bin:‘bin/加上自己的命令文件,最好保持一致’,发布时候记得再file里面添加上bin文件
image.png

  • bin/zce-page.js
#!/usr/bin/env node

// process.argv传参用push
process.argv.push('--cwd')
process.argv.push(process.cwd())
process.argv.push('--gulpfile')
process.argv.push(require.resolve('..'))//..就会到packjson中找到main对应的入口文件

require('gulp/bin/gulp')//   就是找到node_nodules下的gulp/bin/gulp然后走cli   =>require('gulp-cli')();
  • lib/index.js
const { src, dest, parallel, series, watch } = require('gulp')

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

const loadPlugins = require('gulp-load-plugins')

const plugins = loadPlugins()
const bs = browserSync.create()
const cwd = process.cwd()
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) {}

const clean = () => {
  return del([config.build.dist, config.build.temp])
}

const style = () => {
  return src(config.build.paths.styles, { base: config.build.src, cwd: config.build.src })
    .pipe(plugins.sass({ outputStyle: 'expanded' }))
    .pipe(dest(config.build.temp))
    .pipe(bs.reload({ stream: true }))
}

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

const page = () => {
  return src(config.build.paths.pages, { base: config.build.src, cwd: config.build.src })
    .pipe(plugins.swig({ data: config.data, defaults: { cache: false } }))
    .pipe(dest(config.build.temp))
    .pipe(bs.reload({ stream: true }))
}

const image = () => {
  return src(config.build.paths.images, { base: config.build.src, cwd: config.build.src })
    .pipe(plugins.imagemin())
    .pipe(dest(config.build.dist))
}

const font = () => {
  return src(config.build.paths.fonts, { base: config.build.src, cwd: config.build.src })
    .pipe(plugins.imagemin())
    .pipe(dest(config.build.dist))
}

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

const serve = () => {
  watch(config.build.paths.styles, { cwd: config.build.src }, style)
  watch(config.build.paths.scripts, { cwd: config.build.src }, script)
  watch(config.build.paths.pages, { cwd: config.build.src }, page)
  // watch('src/assets/images/**', image)
  // watch('src/assets/fonts/**', font)
  // watch('public/**', extra)
  watch([
    config.build.paths.images,
    config.build.paths.fonts
  ], { cwd: config.build.src }, bs.reload)

  watch('**', { cwd: config.build.public }, bs.reload)

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

const useref = () => {
  return src(config.build.paths.pages, { base: config.build.temp, cwd: config.build.temp })
    .pipe(plugins.useref({ searchPath: [config.build.temp, '.'] }))
    // 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(config.build.dist))
}

const compile = parallel(style, script, page)

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

const develop = series(compile, serve)

module.exports = {
  clean,
  build,
  develop
}

  • 引用项目里面传参zcepage.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'
      },
      {
        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()
  }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值