• 高效,易用
    • 编写gulpfile.js
    • 基本使用

      1. //gulp入口文件
      2. //4.0以后导出函数成员
      3. //标记任务已完成
      4. exports.foo = (done) => {
      5. console.log("foo task")
      6. done() //标识任务完成
      7. }
      8. exports.default = (done) => {
      9. console.log('defaule task')
      10. done()
      11. }
    • 组合任务 ```javascript //组合任务 //并行任务和串行任务 const { series, parallel } = require(“gulp”) const task1 = (done) => { console.log(“task1 working~”) done() } const task2 = (done) => { setTimeout(() => {

      1. console.log("task2 working")
      2. done()

      }, 1000) } const task3 = (done) => { setTimeout(() => {

      1. console.log("task3 working")
      2. done()

      }, 1000) } exports.foo = series(task1, task2, task3) //依次执行这些任务 exports.bar = parallel(task1, task2, task3) //并行,同时执行

    1. - 异步任务
    2. ```javascript
    3. //异步任务
    4. // 1.回调函数,调用done,错误优先,多个任务执行,后续任务不会工作
    5. exports.callback = (done) => {
    6. console.log("callback task~")
    7. done()
    8. }
    9. exports.callback_error = (done) => {
    10. console.log("callback task~")
    11. done(new Error("task failed")) //执行失败
    12. }
    13. //2.promise
    14. exports.promise = () => {
    15. console.log("promise task")
    16. return Promise.resolve()
    17. }
    18. exports.promise_error = () => {
    19. console.log("promise task")
    20. return Promise.reject()
    21. }
    22. //3.async await
    23. const timeout = (time) => {
    24. return new Promise((resolve) => {
    25. setTimeout(resolve, time)
    26. })
    27. }
    28. exports.async = async () => {
    29. await timeout(1000)
    30. console.log("async task")
    31. }
    32. //4.stream方式最常见,构建系统大多数在处理文件
    33. const fs = require("fs")
    34. exports.stream = () => {
    35. const readStream = fs.createReadStream("package.json")
    36. const writeStream = fs.createWriteStream("temp.txt")
    37. readStream.pipe(writeStream) //复制文件到
    38. return readStream //结束的时机是readStream end的时候 有end事件
    39. }
    40. //原理
    41. // exports.stream = (done) => {
    42. // const readStream = fs.createReadStream("package.json")
    43. // const writeStream = fs.createWriteStream("temp.txt")
    44. // readStream.pipe(writeStream) //复制文件到
    45. // // return readStream //结束的时机是readStream end的时候 有end事件
    46. // //原理是监听end时机
    47. // readStream.on("end", () => {
    48. // done()
    49. // })
    50. // }
    • 构建过程核心工作原理 后文使用gulp提供的方法
      • 大多数将文件读取 -》转换-》另一个位置 ```javascript const fs = require(“fs”) const { Transform } = require(“stream”)

    exports.default = () => { // 定义读取文件流,写入文件流 const readStream = fs.createReadStream(“./nomailze.css”) const writeStream = fs.createWriteStream(“nomailze.min.css”) //转换文件,此处是压缩 const transform = new Transform({ //转换过程 transform: (chunk, encoding, callback) => { //核心转换过程 //chunk文件流读取到的文件内容(Buffer) const input = chunk.toString() const output = input.replace(/\s+/g, “”).replace(/\/*.+?*\//g, “”) callback(null, output) //错误优先 }, }) //读取到的文件流导入写入文件流 readStream.pipe(transform).pipe(writeStream) return readStream }

    1. - Gulp文件操作API
    2. - 以及常规过程见下代码块
    3. ```javascript
    4. // Gulp文件操作API + 插件使用
    5. //通过src方法创建读取流,在通过gulp插件加工,然后dest方法创建写入流
    6. //强大与可以使用通配符
    7. const { src, dest } = require("gulp")
    8. const cleanCss = require("gulp-clean-css")
    9. const rename = require("gulp-rename")
    10. exports.default = () => {
    11. return src("src/*.css")
    12. .pipe(cleanCss())
    13. .pipe(rename({ extname: ".min.css" })) //重命名扩展名
    14. .pipe(dest("dist"))
    15. }
    • Gulp构建案例
    • Gulp自动载入插件
      • gulp-load-plugins
    • 热更新开发服务器
      • borwser-sync 模块
        • 支持代码修改过后自动热更新到浏览器当中
    • useref会对文件进行整合
    • 文件压缩
      • 分别压缩HTML,CSS,JavaScript
      • css,js由useref生成。
    • 构建流程整理

    • ```javascript const { src, dest, parallel, series, watch } = require(“gulp”) const del = require(“del”) const browserSync = require(“browser-sync”) const loadPlugins = require(“gulp-load-plugins”) const { use } = require(“browser-sync”) const plugins = loadPlugins() const bs = browserSync.create() //创建服务器 const data = { menus: [
      1. {
      2. name: "Home",
      3. icon: "aperture",
      4. link: "index.html",
      5. },
      6. {
      7. name: "Features",
      8. link: "features.html",
      9. },
      10. {
      11. name: "About",
      12. link: "about.html",
      13. },
      14. {
      15. name: "Contact",
      16. link: "#",
      17. children: [
      18. {
      19. name: "Twitter",
      20. link: "https://twitter.com/w_zce",
      21. },
      22. {
      23. name: "About",
      24. link: "https://weibo.com/zceme",
      25. },
      26. {
      27. name: "divider",
      28. },
      29. {
      30. name: "About",
      31. link: "https://github.com/zce",
      32. },
      33. ],
      34. },
      ], pkg: require(“./package.json”), date: new Date(), } //自定义clean任务 const clean = () => { return del([“dist”, “temp”]) } //编译样式 const style = () => { //样式编译 return src(“src/assets/styles/*.scss”, { base: “src” }) //base指定原始目录
      1. .pipe(plugins.sass({ outputStyle: "expanded" }))
      2. .pipe(dest("temp"))
      3. .pipe(bs.reload({ stream: true }))
      } //编译脚本 const script = () => { return src(“src/assets/scripts/*.js”, { base: “src” })
      1. .pipe(plugins.babel({ presets: ["@babel/preset-env"] })) //转换es6新特性
      2. .pipe(dest("temp"))
      3. .pipe(bs.reload({ stream: true }))
      } //编译页面 const page = () => { //src任意子目录下的html return src(“src/*.html”, { base: “src” })
      1. .pipe(plugins.swig({ data, defaults: { cache: false } })) // 防止模板缓存导致页面不能及时更新
      2. .pipe(dest("temp"))
      3. .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”)) } //处理public const extra = () => { return src(“public/*”, { base: “public” }).pipe(dest(“dist”)) } //整合js css 压缩 const useref = () => { return src(“temp/.html”, { base: “temp” })
      1. .pipe(plugins.useref({ searchPath: ["temp", "."] }))
      2. .pipe(plugins.if(/\.js$/, plugins.uglify())) //分别处理不同文件
      3. .pipe(plugins.if(/\.css$/, plugins.cleanCss())) //分别处理不同文件
      4. .pipe(plugins.if(/\.html$/, plugins.htmlmin({ collapseWhitespace: true, minifyCSS: true, minifyJS: true }))) //分别处理不同文件
      5. .pipe(dest("dist"))
      } //启动服务器 const serve = () => { //修改文件。执行相应任务 修改dist 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) watch([“src/assets/images/“, “src/assets/fonts/*”, “public/“], bs.reload) bs.init({
      1. notify: false, //关闭提示
      2. port: 2080, //修改端口号
      3. // open: false,
      4. // files: "dist/**", //被监听的路径通配符
      5. server: {
      6. baseDir: ["temp", "src", "public"], //指定根目录,数组依次查找
      7. routes: {
      8. //优先于baseDir
      9. "/node_modules": "node_modules",
      10. },
      11. },
      }) } //组合任务 const compile = parallel(style, script, page) const build = series(clean, parallel(series(compile, useref), extra, image, font)) //自动清除dist下的文件 const develop = series(compile, serve) module.exports = { clean, build, develop, }

    ```