Gulp 使用方法(教程二)

Gulp 官网


目录

  1. load plugins 简化 gulp 载入流程
  2. Babel 编译你的 JS
  3. 使用 concat 把 babel 生成的 js 文件合并起来
  4. sourcemaps 追踪报错信息
  5. 到目前为止 babel 任务都是要手动执行编译的 让我们加上 watch 吧
  6. Gulp 与 Bower 结合使用
  7. 把 bower 生成的文件夹及文件合并到 dist 文件夹
  8. Bower 补充说明
  9. 网页开发不可或缺的 Webservice
  10. 优化,压缩你的代码
  11. 根据开发环境调整输出内容
  12. 整理你的文件(夹)
  13. 图片压缩
  14. 一键部署 GitHub Pages
  15. 在 pug 中传入数据
  16. 使用外部 sass 文件
  17. 合并来自 NPM 的 JS

相关阅读


load plugins 简化 gulp 载入流程

  1. 安装 gulp-load-plugins
  • npm install --save-dev gulp-load-plugins
  1. 修改配置文件

gulpfile.js

const gulp = require("gulp");
// gulp- 开头的依赖可以删除, gulp-load-plugins 会引入, 使用 $ 接收
// gulp- 开头的依赖 需要以 $.xxx 的形式使用
const $ = require("gulp-load-plugins")();
const autoprefixer = require("autoprefixer");

gulp.task("pug", () => {
  return (
    gulp
      .src("./assets/**/*.pug")
      // gulp- 开头的依赖 需要以 $.xxx 的形式使用
      .pipe($.watch("./assets/**/*.pug"))
      .pipe($.plumber())
      .pipe(
        $.pug({
          pretty: true
        })
      )
      .pipe(gulp.dest("./dist/"))
  );
});

gulp.task("sass", () => {
  const plugins = [
    autoprefixer({
      browsers: ["last 1 version"]
    })
  ];

  return (
    gulp
      .src("./assets/scss/**/*.scss")
      // gulp- 开头的依赖 需要以 $.xxx 的形式使用
      .pipe($.watch("./assets/scss/**/*.scss"))
      .pipe($.plumber())
      .pipe($.sass().on("error", $.sass.logError))
      .pipe($.postcss(plugins))
      .pipe(gulp.dest("./dist/css"))
  );
});

gulp.task("default", ["pug", "sass"]);

Babel 编译你的 JS

  1. 安装 gulp-babel
  • npm install --save-dev gulp-babel babel-core babel-preset-env
  1. 依照 文件树 初始化项目结构
    文件树
.
├── assets
│   ├── index.pug
│   ├── js
│   │   ├── all.js
│   │   └── all2.js
│   └── scss
│       └── all.scss
├── gulpfile.js
├── package-lock.json
└── package.json

gulpfile.js

const gulp = require("gulp");
const $ = require("gulp-load-plugins")();
const autoprefixer = require("autoprefixer");

gulp.task("pug", () => {
  return gulp
    .src("./assets/**/*.pug")
    .pipe($.watch("./assets/**/*.pug"))
    .pipe($.plumber())
    .pipe(
      $.pug({
        pretty: true
      })
    )
    .pipe(gulp.dest("./dist/"));
});

gulp.task("sass", () => {
  const plugins = [
    autoprefixer({
      browsers: ["last 1 version"]
    })
  ];

  return gulp
    .src("./assets/scss/**/*.scss")
    .pipe($.watch("./assets/scss/**/*.scss"))
    .pipe($.plumber())
    .pipe($.sass().on("error", $.sass.logError))
    .pipe($.postcss(plugins))
    .pipe(gulp.dest("./dist/css"));
});

gulp.task("babel", () => {
  gulp
    .src("./assets/js/**/*.js")
    .pipe(
      $.babel({
        // 加入 babel, 注意$ 的使用, 忘记加 $ 等于没引入依赖.会报错
        presets: ["env"]
      })
    )
    .pipe(gulp.dest("./dist/js"));
});

gulp.task("default", ["pug", "sass", "babel"]); // 加入 babel 任务

assets/js/fn.js

const fn = () => console.log(1);

assets/js/fn2.js

const fn2 = () => console.log(2);
  1. 运行 gulp

文件树

.
├── assets
│   ├── index.pug
│   ├── js
│   │   ├── fn.js
│   │   └── fn2.js
│   └── scss
│       └── all.scss
├── dist
│   ├── css
│   │   └── all.css
│   ├── index.html
│   └── js
│       ├── fn.js
│       └── fn2.js
├── gulpfile.js
├── package-lock.json
└── package.json
  • 生成 fn.js, fn2.js 两个文件
  • babel 单纯就生成 对应的 js 文件

使用 concat 把 babel 生成的 js 文件合并起来

  1. 安装 gulp-concat
  • npm i -D gulp-concat
  1. 这一次需要 删除 dist/js 文件夹, 和修改配置文件

gulpfile.js

const gulp = require("gulp");
const $ = require("gulp-load-plugins")();
const autoprefixer = require("autoprefixer");

gulp.task("pug", () => {
  return gulp
    .src("./assets/**/*.pug")
    .pipe($.watch("./assets/**/*.pug"))
    .pipe($.plumber())
    .pipe(
      $.pug({
        pretty: true
      })
    )
    .pipe(gulp.dest("./dist/"));
});

gulp.task("sass", () => {
  const plugins = [
    autoprefixer({
      browsers: ["last 1 version"]
    })
  ];

  return gulp
    .src("./assets/scss/**/*.scss")
    .pipe($.watch("./assets/scss/**/*.scss"))
    .pipe($.plumber())
    .pipe($.sass().on("error", $.sass.logError))
    .pipe($.postcss(plugins))
    .pipe(gulp.dest("./dist/css"));
});

gulp.task("babel", () => {
  gulp
    .src("./assets/js/**/*.js")
    .pipe(
      $.babel({
        presets: ["env"]
      })
    )
    // 加入 concat 把 .src('./assets/js/**/*.js') 中引入的 js 文件都拼接到 all.js 文件中
    .pipe($.concat("all.js"))
    .pipe(gulp.dest("./dist/js"));
});

gulp.task("default", ["pug", "sass", "babel"]);
  1. 运行 gulp

文件树

.
├── assets
│   ├── index.pug
│   ├── js
│   │   ├── fn.js
│   │   └── fn2.js
│   └── scss
│       └── all.scss
├── dist
│   ├── css
│   │   └── all.css
│   ├── index.html
│   └── js
│       └── all.js
├── gulpfile.js
├── package-lock.json
└── package.json
  • 只生成 all.js 一个文件

如果想要按照顺序拼接文件

gulp.task('scripts', function() {
  return gulp.src(['./lib/file3.js', './lib/file1.js', './lib/file2.js'])
    .pipe(concat('all.js'))
    .pipe(gulp.dest('./dist/'));
});

sourcemaps 追踪报错信息

  1. 安装 gulp-sourcemaps

  2. 先看看没有使用 sourcemaps 的状况

  • 修改 assets/index.pug , assets/js/fn.js 文件

assets/index.pug

  • 引入编译后的 all.js
<!DOCTYPE html>
html(lang="en")
  head
    meta(charset="UTF-8")
    meta(name="viewport", content="width=device-width, initial-scale=1.0")
    meta(http-equiv="X-UA-Compatible", content="ie=edge")
    title Document
    script(src="./js/all.js")
  body
    br
    p hello world

assets/js/fn.js

const fn = () => console.log(1);
fn();

assets/js/fn2.js

const fn2 = () => console.log(2);
fn2();
  1. 运行 gulp
  • 在浏览器打开 dist/index.html
  • 查看控制台
1       all.js:4
2       all.js:10

控制台打印出来的是编译后的结果, 当代码多的时候, 压缩后, 这样就会导致排错困难

  1. 使用 sourcemaps

gulpfile.js

const gulp = require("gulp");
const $ = require("gulp-load-plugins")();
const autoprefixer = require("autoprefixer");

gulp.task("pug", () => {
  return gulp
    .src("./assets/**/*.pug")
    .pipe($.watch("./assets/**/*.pug"))
    .pipe($.plumber())
    .pipe(
      $.pug({
        pretty: true
      })
    )
    .pipe(gulp.dest("./dist/"));
});

gulp.task("sass", () => {
  const plugins = [
    autoprefixer({
      browsers: ["last 1 version"]
    })
  ];

  return (
    gulp
      .src("./assets/scss/**/*.scss")
      .pipe($.watch("./assets/scss/**/*.scss"))
      .pipe($.plumber())
      // 在报错之前使用
      .pipe($.sourcemaps.init())
      .pipe($.sass().on("error", $.sass.logError))
      .pipe($.postcss(plugins))
      // 在输出之前 写入 sourcemaps 文件
      .pipe($.sourcemaps.write("."))
      .pipe(gulp.dest("./dist/css"))
  );
});

gulp.task("babel", () => {
  gulp
    .src("./assets/js/**/*.js")
    // 初始化 sourcemaps
    // 注意 $ 的使用 忘记加 $ 会报错
    .pipe($.sourcemaps.init())
    .pipe(
      $.babel({
        presets: ["env"]
      })
    )
    .pipe($.concat("all.js"))
    // 在输出之前 写入 sourcemaps 文件
    .pipe($.sourcemaps.write("."))
    .pipe(gulp.dest("./dist/js"));
});

gulp.task("default", ["views", "sass", "babel"]);

assets/index.pug

  • 引入编译后的 css
<!DOCTYPE html>
html(lang="en")
  head
    meta(charset="UTF-8")
    meta(name="viewport", content="width=device-width, initial-scale=1.0")
    meta(http-equiv="X-UA-Compatible", content="ie=edge")
    title Document
    link(rel="stylesheet" href="./css/all.css")
    script(src="./js/all.js")
  body
    br
    p hello world
  1. 运行 gulp
  • 在浏览器打开 dist/index.html

  • 开发者工具 查看 element style 样式表

body {            all.scss:3
    color: red;
}
  • 查看控制台
1       fn.js:1
2       fn2.js:1

文件树

.
├── assets
│   ├── index.pug
│   ├── js
│   │   ├── fn.js
│   │   └── fn2.js
│   └── scss
│       └── all.scss
├── dist
│   ├── css
│   │   ├── all.css
│   │   └── all.css.map
│   ├── index.html
│   └── js
│       ├── all.js
│       └── all.js.map
├── gulpfile.js
├── package-lock.json
└── package.json

启用成功

到目前为止 babel 任务都是要手动执行编译的 让我们加上 watch 吧

  1. gulpfile.js
const gulp = require("gulp");
const $ = require("gulp-load-plugins")();
const autoprefixer = require("autoprefixer");

gulp.task("views", () => {
  return gulp
    .src("./assets/**/*.pug")
    .pipe($.watch("./assets/**/*.pug"))
    .pipe($.plumber())
    .pipe(
      $.pug({
        pretty: true
      })
    )
    .pipe(gulp.dest("./dist/"));
});

gulp.task("sass", () => {
  const plugins = [
    autoprefixer({
      browsers: ["last 1 version"]
    })
  ];

  return gulp
    .src("./assets/scss/**/*.scss")
    .pipe($.watch("./assets/scss/**/*.scss"))
    .pipe($.plumber())
    .pipe($.sourcemaps.init())
    .pipe($.sass().on("error", $.sass.logError))
    .pipe($.postcss(plugins))
    .pipe($.sourcemaps.write("."))
    .pipe(gulp.dest("./dist/css"));
});

const babelHandle = () => {
  gulp
    .src("./assets/js/**/*.js")
    .pipe($.plumber())
    .pipe($.sourcemaps.init())
    .pipe(
      $.babel({
        presets: ["env"]
      })
    )
    .pipe($.concat("all.js"))
    .pipe($.sourcemaps.write("."))
    .pipe(gulp.dest("./dist/js"));
};

gulp.task("babel", () => {
  babelHandle();
  return $.watch("./assets/js/**/*.js", babelHandle);
});

gulp.task("default", ["views", "sass", "babel"]);

注释: 坑!!

// 这里有一个坑

// 按照 gulp-watch 之前的用法 代码应该是这样的
gulp.task("babel", () => {
  return (
    gulp
      .src("./assets/js/**/*.js")
      // 只需要在这里加上一行watch
      // 但是 这样会使 js 编译中断 , 其他sass, pug 还是能运作
      .pipe($.watch("./assets/js/**/*.js"))
      .pipe($.plumber())
      .pipe($.sourcemaps.init())
      .pipe(
        $.babel({
          presets: ["env"]
        })
      )
      .pipe($.concat("all.js"))
      .pipe($.sourcemaps.write("."))
      .pipe(gulp.dest("./dist/js"))
  );
});

// 查看文档, 使用另一种监听方法
$.watch("css/**/*.css", function() {
  gulp.src("css/**/*.css").pipe(gulp.dest("build"));
});

// 这种方法 只监听 文件修改行为, 所以封装一个 handle 函数
// 在执行任务的时候 手动调用一下
const babelHandle = () => {
  gulp
    .src("./assets/js/**/*.js")
    .pipe($.plumber())
    .pipe($.sourcemaps.init())
    .pipe(
      $.babel({
        presets: ["env"]
      })
    )
    .pipe($.concat("all.js"))
    .pipe($.sourcemaps.write("."))
    .pipe(gulp.dest("./dist/js"));
};

gulp.task("babel", () => {
  babelHandle();
  return $.watch("./assets/js/**/*.js", babelHandle);
});
  1. 运行 gulp

修改 assets/index.pug assets/scss/all.scss assets/js/fn.js 测试效果


Gulp 与 Bower 结合使用

bower 简易教程

  1. 使用 main-bower-files
  • 安装 npm i -D main-bower-files
  1. 初始化
  • 初始化 bower

    • bower init
    • 生成 bower.json 文件
  • 安装 bootstrap jQuery

    • bower i bootstrap jquery --save
  1. 修改 gulpfile.js 文件
// 省略其他未变动代码
var mainBowerFiles = require("main-bower-files");

gulp.task("bower", function() {
  return (
    gulp
      .src(mainBowerFiles())
      // 输出到临时文件夹 tmp/vendors
      .pipe(gulp.dest("./tmp/vendors"))
  );
});

// 添加任务
gulp.task("default", ["views", "sass", "babel", "bower"]);
  1. 运行 gulp

文件树

.
├── tmp
│   └── vendors
├── assets
│   ├── index.pug
│   ├── js
│   └── scss
├── bower.json
├── bower_components
│   ├── bootstrap
│   └── jquery
├── dist
│   ├── css
│   ├── index.html
│   └── js
├── gulpfile.js
├── package-lock.json
└── package.json

生成 tmp/vendors


把 bower 生成的文件夹及文件合并到 dist 文件夹

  1. 修改 gulpfile.js 文件
// 省略其他未变动代码
// 先执行完 bower 任务再 执行 vendorJs 里的函数
gulp.task("vendorJs", ["bower"], () => {
  return gulp
    .src("./tmp/vendors/**/*.js")
    .pipe($.concat("venders.js"))
    .pipe(gulp.dest("./dist/js"));
});

// 添加 vendorJs任务, 删除 bower任务
gulp.task("default", ["pug", "sass", "babel", "vendorJs"]);
  1. 运行 gulp
  • dist/js 目录下生成 venders.js 文件

Bower 补充说明

并非所有插件对于 bower 的运用都那么友善

以 Vue.js 来说,他就不会正确取得 dist 文件夹内的 vue.js

此時可以透过自定义 mainBowerFiles 方式来做调整

  1. 安装 vuejs
  • bower install vue --save
  1. 修改 gulpfile.js 文件
// 省略其他未变动代码
gulp.task("bower", () => {
  return gulp
    .src(
      mainBowerFiles({
        overrides: {
          vue: {
            // 插件名称
            main: "dist/vue.js" // 对应的文件路径
          }
        }
      })
    )
    .pipe(gulp.dest("./tmp/vendors"));
  cb(err);
});
  1. 另外,如果外部载入的插件如果需要排序

像是 Bootstrap 与 jQuery 会有先后顺序的需求

gulp-order 可以通过 数组 排列自己所需要的顺序

gulpfile.js 文件

// 省略其他未变动代码
gulp.task("vendorJs", ["bower"], () => {
  return gulp
    .src(["./tmp/vendors/**/**.js"])
    .pipe($.order(["jquery.js", "bootstrap.js"]))
    .pipe($.concat("vendor.js"))
    .pipe(gulp.dest("./dist/js"));
});

网页开发不可或缺的 Webservice

开启微型服务器, 并自动刷新浏览器

  1. 安装
  • npm i -D browser-sync
  1. gulpfile.js 文件
const gulp = require("gulp");
const $ = require("gulp-load-plugins")();
const autoprefixer = require("autoprefixer");
const mainBowerFiles = require("main-bower-files");
const browserSync = require("browser-sync").create();

gulp.task("pug", () => {
  return (
    gulp
      .src("./assets/**/*.pug")
      .pipe($.watch("./assets/**/*.pug"))
      .pipe($.plumber())
      .pipe(
        $.pug({
          pretty: true
        })
      )
      .pipe(gulp.dest("./dist/"))
      // 文件导出后 自动刷新 浏览器
      .pipe(browserSync.stream())
  );
});

gulp.task("sass", () => {
  const plugins = [
    autoprefixer({
      browsers: ["last 1 version"]
    })
  ];

  return (
    gulp
      .src("./assets/scss/**/*.scss")
      .pipe($.watch("./assets/scss/**/*.scss"))
      .pipe($.plumber())
      .pipe($.sourcemaps.init())
      .pipe($.sass().on("error", $.sass.logError))
      .pipe($.postcss(plugins))
      .pipe($.sourcemaps.write("."))
      .pipe(gulp.dest("./dist/css"))
      // 文件导出后 自动刷新 浏览器
      .pipe(browserSync.stream())
  );
});

const babelHandle = () => {
  gulp
    .src("./assets/js/**/*.js")
    .pipe($.plumber())
    .pipe($.sourcemaps.init())
    .pipe(
      $.babel({
        presets: ["env"]
      })
    )
    .pipe($.concat("all.js"))
    .pipe($.sourcemaps.write("."))
    .pipe(gulp.dest("./dist/js"))
    // 文件导出后 自动刷新 浏览器
    .pipe(browserSync.stream());
};

gulp.task("babel", () => {
  babelHandle();
  return $.watch("./assets/js/**/*.js", babelHandle);
});

gulp.task("bower", () => {
  return gulp.src(mainBowerFiles()).pipe(gulp.dest("./tmp/vendors"));
});

gulp.task("vendorJs", ["bower"], () => {
  return (
    gulp
      .src("./tmp/vendors/**/*.js")
      .pipe($.concat("venders.js"))
      .pipe(gulp.dest("./dist/js"))
      // 文件导出后 自动刷新 浏览器
      .pipe(browserSync.stream())
  );
});

gulp.task("browser-sync", () => {
  browserSync.init({
    server: {
      // 指定默认 文件夹
      baseDir: "./dist/"
    }
  });
});

// 添加任务
gulp.task("default", ["pug", "sass", "babel", "vendorJs", "browser-sync"]);
  1. 运行 gulp

编译结束后 会自动打开浏览器 默认是 3000 端口

修改文件 测试效果


优化,压缩你的代码

  1. 安装
  • npm i -D gulp-clean-css gulp-uglify
  1. gulpfile.js 文件
// 省略未修改的代码
gulp.task("sass", () => {
  const plugins = [
    autoprefixer({
      browsers: ["last 1 version"]
    })
  ];

  return (
    gulp
      .src("./assets/scss/**/*.scss")
      .pipe($.watch("./assets/scss/**/*.scss"))
      .pipe($.plumber())
      .pipe($.sourcemaps.init())
      .pipe($.sass().on("error", $.sass.logError))
      .pipe($.postcss(plugins))
      // css 文件输出前 压缩代码
      .pipe($.cleanCss({ compatibility: "ie8" }))
      .pipe($.sourcemaps.write("."))
      .pipe(gulp.dest("./dist/css"))
      .pipe(browserSync.stream())
  );
});

const babelHandle = () => {
  gulp
    .src("./assets/js/**/*.js")
    .pipe($.plumber())
    .pipe($.sourcemaps.init())
    .pipe(
      $.babel({
        presets: ["env"]
      })
    )
    .pipe($.concat("all.js"))
    // js 文件输出前 压缩代码
    .pipe($.uglify())
    .pipe($.sourcemaps.write("."))
    .pipe(gulp.dest("./dist/js"))
    .pipe(browserSync.stream());
};

gulp.task("vendorJs", ["bower"], () => {
  return (
    gulp
      .src("./tmp/vendors/**/*.js")
      .pipe($.concat("venders.js"))
      // js 文件输出前 压缩代码
      .pipe($.uglify())
      .pipe(gulp.dest("./dist/js"))
      .pipe(browserSync.stream())
  );
});
  1. 运行 gulp
  • 未压缩前的 all.js
"use strict";

var fn = function fn() {
  return console.log(1);
};
fn();
("use strict");

var fn2 = function fn2() {
  return console.log(2);
};
fn2();
//# sourceMappingURL=all.js.map
  • 压缩后的 all.js
"use strict";
var fn = function() {
  return console.log(1);
};
fn();
var fn2 = function() {
  return console.log(2);
};
fn2();
//# sourceMappingURL=all.js.map
  • 压缩后的 all.css
body {
  color: #00f;
}
.card {
  -webkit-transform: rotate(91deg);
  transform: rotate(91deg);
}
/*# sourceMappingURL=all.css.map */
  1. 其他配置
  • 压缩配置

gulpfile.js 文件

    // some code
    .pipe($.uglify({
      compress: {
        // 把 console 移除
        drop_console: true
      }
    }))
    // some code
  • browser-sync

gulpfile.js 文件

// some code
browserSync.init({
  server: { baseDir: "./dist" },
  // 重新整理间隔 2000ms
  reloadDebounce: 2000
});
// some code

根据开发环境调整输出内容

  • develop

    • js
      • 保留 console
      • 不压缩
    • css
      • 不压缩
  • production

    • js
      • 不保留 console.log(), 压缩
    • css, html
      • 压缩
  • minimist

  • gulp-if

  1. 安装
  • npm i -D minimist gulp-if
  1. 修改相关文件

gulpfile.js 文件

const minimist = require("minimist");

const envOptions = {
  string: "env",
  default: { env: "develop" }
};
const options = minimist(process.argv.slice(2), envOptions);
console.log(options);

gulp.task("sass", () => {
  const plugins = [
    autoprefixer({
      browsers: ["last 1 version"]
    })
  ];

  return (
    gulp
      .src("./assets/scss/**/*.scss")
      .pipe($.watch("./assets/scss/**/*.scss"))
      .pipe($.plumber())
      .pipe($.sourcemaps.init())
      .pipe($.sass().on("error", $.sass.logError))
      .pipe($.postcss(plugins))
      // 加入判断 如果没有传入 env 默认是 develop 不压缩 css
      .pipe(
        $.if(options.env === "production", $.cleanCss({ compatibility: "ie8" }))
      )
      .pipe($.sourcemaps.write("."))
      .pipe(gulp.dest("./dist/css"))
      .pipe(browserSync.stream())
  );
});
  1. 运行 gulp sass

终端打印 { _: [], env: 'develop' }

css 文件没有压缩

  1. 运行 gulp sass --env production

终端打印 { _: [], env: 'production' }

css 文件压缩

  1. gulpfile.js 文件
// 省略大部分未修改代码
gulp.task('pug', () => {
    .pipe( $.pug({
      pretty: options.env !== 'production'
    }))
})

gulp.task('sass', () => {
    .pipe($.if(options.env === 'production', $.cleanCss({
      compatibility: "ie8"
    })))
})

const babelHandle = () => {
    .pipe($.if(options.env === 'production', $.uglify()))
}

gulp.task('vendorJs', ['bower'], () => {
    .pipe($.if(options.env === 'production', $.uglify()))
})
  1. 运行 gulp

文件没有压缩

  1. 运行 gulp --env production

文件被压缩


整理你的文件(夹)

  1. 安装
  • npm i -D gulp-clean gulp-sequence
  1. gulpfile.js 文件
// 省略大部分未修改代码
gulp.task("clean", function() {
  // 多个文件(夹)用数组表示
  return gulp.src(["./tmp", "./dist"], { read: false }).pipe($.clean());
});
  1. 运行 gulp clean

dist tmp 文件夹都被删除了

  1. 使用 gulp-sequence 打包 production 代码

  2. gulpfile.js 文件

// 省略大部分未修改代码
const gulpSequence = require('gulp-sequence')

gulp.task('pug', () => {
  return gulp.src('./assets/**/*.pug')
    .pipe($.if(options.env !== 'production', $.watch('./assets/**/*.pug')))
    .pipe($.plumber())
    .pipe($.pug({
      pretty: options.env !== 'production'
    }))
    .pipe(gulp.dest('./dist/'))
    .pipe(browserSync.stream())
})

gulp.task('sass', () => {
  return gulp.src('./assets/scss/**/*.scss')
    .pipe($.if(options.env !== 'production', $.watch('./assets/scss/**/*.scss')))
    .pipe($.if(options.env === 'production', $.cleanCss({
      compatibility: "ie8"
    })))
})

const babelHandle = () => {
    .pipe($.if(options.env === 'production', $.uglify()))
}

gulp.task('babel', () => {
  $.if(options.env === 'production', () => {
    return $.watch('./assets/js/**/*.js', babelHandle)
  })
})

gulp.task('vendorJs', ['bower'], () => {
  return gulp.src('./tmp/vendors/**/*.js')
    .pipe($.if(options.env === 'production', $.uglify()))
})

// 创建任务
gulp.task('build', gulpSequence('clean', 'pug', 'sass', 'babel', 'vendorJs'))

坑!!

  // 这一类(监视)代码 需要判断环境
  // gulpSequence() 执行的是一个任务执行完再执行下一个任务 clean, pug, sass
  // 如果启用 watch 就会一直等 watch 停止再继续, 所以这里需要通过 环境变量判断是否开启 watch
  .pipe($.if(options.env !== 'production', $.watch('./assets/scss/**/*.scss')))

    $.if(options.env === 'production', () => {
    return $.watch('./assets/js/**/*.js', babelHandle)
  })
  1. ... 上面的代码太丑了, 重新整理一下
  • gulpfile.js 完整文件
const gulp = require("gulp");
const minimist = require("minimist");
const $ = require("gulp-load-plugins")();
const autoprefixer = require("autoprefixer");
const gulpSequence = require("gulp-sequence");
const mainBowerFiles = require("main-bower-files");
const browserSync = require("browser-sync").create();

const envOptions = {
  string: "env",
  default: {
    env: "develop"
  }
};
const options = minimist(process.argv.slice(2), envOptions);

const pugHandle = () => {
  return gulp
    .src("./assets/**/*.pug")
    .pipe($.plumber())
    .pipe(
      $.pug({
        pretty: options.env !== "production"
      })
    )
    .pipe(gulp.dest("./dist/"))
    .pipe(browserSync.stream());
};

const sassHankdle = () => {
  const plugins = [
    autoprefixer({
      browsers: ["last 1 version"]
    })
  ];

  return gulp
    .src("./assets/scss/**/*.scss")
    .pipe($.plumber())
    .pipe($.sourcemaps.init())
    .pipe($.sass().on("error", $.sass.logError))
    .pipe($.postcss(plugins))
    .pipe(
      $.if(
        options.env === "production",
        $.cleanCss({
          compatibility: "ie8"
        })
      )
    )
    .pipe($.sourcemaps.write("."))
    .pipe(gulp.dest("./dist/css"))
    .pipe(browserSync.stream());
};

const babelHandle = () => {
  gulp
    .src("./assets/js/**/*.js")
    .pipe($.plumber())
    .pipe($.sourcemaps.init())
    .pipe(
      $.babel({
        presets: ["env"]
      })
    )
    .pipe($.concat("all.js"))
    .pipe($.if(options.env === "production", $.uglify()))
    .pipe($.sourcemaps.write("."))
    .pipe(gulp.dest("./dist/js"))
    .pipe(browserSync.stream());
};

const bowerHanle = () => {
  return gulp.src(mainBowerFiles()).pipe(gulp.dest("./tmp/vendors"));
};

gulp.task("pug", pugHandle);
gulp.task("sass", sassHankdle);
gulp.task("babel", babelHandle);
gulp.task("bower", bowerHanle);

gulp.task("clean", function() {
  return gulp
    .src(["./tmp", "./dist"], {
      read: false
    })
    .pipe($.clean());
});

gulp.task("vendorJs", ["bower"], () => {
  return gulp
    .src("./tmp/vendors/**/*.js")
    .pipe($.concat("vendors.js"))
    .pipe($.if(options.env === "production", $.uglify()))
    .pipe(gulp.dest("./dist/js"))
    .pipe(browserSync.stream());
});

gulp.task("browser-sync", () => {
  browserSync.init({
    server: {
      baseDir: "./dist/"
    }
  });
});

gulp.task("watch", () => {
  $.watch("./assets/**/*.pug", pugHandle);
  $.watch("./assets/scss/**/*.scss", sassHankdle);
  $.watch("./assets/js/**/*.js", babelHandle);
});

gulp.task("build", gulpSequence("clean", "pug", "sass", "babel", "vendorJs"));

gulp.task("default", [
  "pug",
  "sass",
  "babel",
  "vendorJs",
  "watch",
  "browser-sync"
]);
  1. 运行 gulp build

仅仅进行编译, 并不会监视, 和运行 webservice

  1. 运行 gulp

跟之前一样, 编译, 启动 webservice

  1. 运行 gulp --env production 或者 gulp build --env production

得到的结果是结果 压缩


图片压缩

  1. 安装 gulp-imagemin
  • npm i -D gulp-imagemin
  1. 修改文件

gulpfile.js

gulp.task("image-min", () =>
  gulp
    .src("./assets/img/*")
    // 因为图片压缩十分耗时 所以只在 生产环境下压缩图片
    .pipe($.if(options.env === "production", $.imagemin()))
    .pipe(gulp.dest("./dist/img"))
);

// 添加任务
gulp.task(
  "build",
  gulpSequence("clean", "pug", "sass", "babel", "vendorJs", "image-min")
);

gulp.task("default", [
  "pug",
  "sass",
  "babel",
  "vendorJs",
  "image-min",
  "watch",
  "browser-sync"
]);

一键部署 GitHub Pages

  1. 安装 gulp-gh-pages
  • npm install --save-dev gulp-gh-pages
  1. 修改文件

gulpfile.js

gulp.task("deploy", function() {
  return gulp.src("./dist/**/*").pipe($.ghPages());
});

把 deploy 加到 任务列表, 每次运行会自动上传到 gh-pages


在 pug 中传入数据

  1. 安装
  • npm i -D gulp-data
  1. 修改文件

添加文件 assets/_pug/head.pug

meta(charset="UTF-8")
meta(name="viewport", content="width=device-width, initial-scale=1.0")
meta(http-equiv="X-UA-Compatible", content="ie=edge")
title Document
link(rel="stylesheet" href="./css/all.css")
script(src="./js/all.js")

assets/index.pug

<!DOCTYPE html>
html(lang="en")
  head
    include _pug/head.pug
  body
    h1 #{user[0].url}

添加文件 assets/data/data.json

meta(charset="UTF-8")
meta(name="viewport", content="width=device-width, initial-scale=1.0")
meta(http-equiv="X-UA-Compatible", content="ie=edge")
title Document
link(rel="stylesheet" href="./css/all.css")
script(src="./js/all.js")

gulpfile.js

const pugHandle = () => {
  return (
    gulp
      // 多个匹配规则用数组
      // "./assets/**/*.pug" 来源是assets文件下所有的 pug文件
      //  "!./**/_pug/**/*" 排除 _pug 目录
      .src(["./assets/**/*.pug", "!./**/_pug/**/*"])
      .pipe($.plumber())
      .pipe(
        // 把数据输入到 pug 模板内
        $.data(() => {
          // 引入 data.json 数据文件
          const user = require("./assets/data/data.json");
          const data = {
            user
          };
          return data;
        })
      )
      .pipe(
        $.pug({
          pretty: options.env !== "production"
        })
      )
      .pipe(gulp.dest("./dist/"))
      .pipe(browserSync.stream())
  );
};

gulp.task(
  "build-no-bower",
  gulpSequence("clean", "pug", "sass", "babel", "image-min")
);
  1. 运行 gulp build-no-bower

dist/index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
    <meta http-equiv="X-UA-Compatible" content="ie=edge"/>
    <title>Document</title>
    <link rel="stylesheet" href="./css/all.css"/>
    <script src="./js/all.js"></script>
  </head>
  <body>
    <p>hello world</p>
    <div class="container">
      <form action="">
        <label for="email">请输入邮箱</label>
        <input id="email" type="text"/>
      </form>
    </div>
  </body>
</html>

使用外部 sass 文件

gulpfile.js

const sassHankdle = () => {
  const plugins = [autoprefixer({
    browsers: ["last 1 version"]
  })]

  return gulp.src('./assets/scss/**/*.scss')
    .pipe($.plumber())
    .pipe($.sourcemaps.init())
    .pipe($.sass({
      // 引入路径
      includePaths: ['./node_modules/bootstrap/sass/']
    }).on('error', $.sass.logError))
    .pipe($.postcss(plugins))
    .pipe($.if(options.env === 'production', $.cleanCss({
      compatibility: "ie8"
    })))
    .pipe($.sourcemaps.write('.'))
    .pipe(gulp.dest('./dist/css'))
    .pipe(browserSync.stream())
}

assets/scss/all.css

// 这里的路径会直接补齐 ./node_modules/bootstrap/sass/bootstrap
@import 'bootstrap';

合并来自 NPM 的 JS

gulpfile.js

gulp.task('vendorJs', ['bower'], () => {
  return gulp.src([
    './tmp/vendors/**/*.js',
    // 加入要引入的 js 文件
    './node_modules/bootstrap/dist/js/bootstrap.bundle.min.js'
  ])
    .pipe($.concat('vendors.js'))
    .pipe($.if(options.env === 'production', $.uglify()))
    .pipe(gulp.dest('./dist/js'))
    .pipe(browserSync.stream())
})
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,911评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,014评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 142,129评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,283评论 1 264
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,159评论 4 357
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,161评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,565评论 3 382
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,251评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,531评论 1 292
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,619评论 2 310
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,383评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,255评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,624评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,916评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,199评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,553评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,756评论 2 335

推荐阅读更多精彩内容