gulp4 & webpack喜结连理!

223 阅读1分钟

gulp4和webpack喜结连理 适用于小活动项目页面

gulp+webpack 在小项目中的实践

通过gulp4自带的增量 + webpack 打包js

gulp传送

webpack-stream传送

常用的gulp插件传送

依赖安装

项目自动化编译js,样式文件,压缩图片。

// 新建一个文件夹 demo
// cd demo
// 初始化项目
npm init -y
"scripts": {
    "dev": "cross-env NODE_ENV=development && gulp dev",
  "build": "cross-env NODE_ENV=production && gulp build"
},
"devDependencies": {
    "autoprefixer": "^10.0.1",
    "babel-core": "^6.26.3",
    "babel-loader": "^7.1.5",
    "babel-preset-env": "^1.7.0",
    "browser-sync": "^2.26.13",
    "chalk": "^4.1.0",
    "cross-env": "^7.0.2",
    "del": "^6.0.0",
    "gulp": "^4.0.2",
    "gulp-base64": "^0.1.3",
    "gulp-imagemin": "^7.1.0",
    "gulp-postcss": "^9.0.0",
    "gulp-rename": "^2.0.0",
    "gulp-sass": "^4.1.0",
    "gulp-sourcemaps": "^2.6.5",
    "node-sass": "^4.14.1",
    "postcss": "^8.1.2",
    "postcss-import": "^13.0.0",
    "through2": "^4.0.2",
    "vinyl-named": "^1.1.0",
    "webpack-stream": "^6.1.0"
  },
  "browserslist": [
    "defaults",
    "not ie < 10",
    "last 2 versions",
    "> 1%",
    "iOS 7",
    "last 3 iOS versions"
  ]


webpack 只用到打包js

通过 webpack-stream 包来整流到gulp流中。

// gulpfile.js

const { src, dest, watch, lastRun, series, parallel } = require("gulp");
const gulpWebpack = require("webpack-stream"); 
const rename = require("gulp-rename"); // 重命名
const named = require("vinyl-named"); // 用来保持输入和输出的文件名相同, 否则会自动生成一个hash.

// scripts webpack打包js
const scriptsSrcDir = srcPath + "js/**/*.js"; // 监测js
const excludeScripts = `!${srcPath}js/utils/**/*`;// 排除指定的文件夹或文件
const webpackConfig = require("./webpack.config");
function scripts() {
  return src([scriptsSrcDir, excludeScripts], { since: lastRun(scripts) }) // lastRun 增量编译
    .pipe(named())
    .pipe(gulpWebpack(webpackConfig))
    .pipe(
      rename({
        suffix: ".min",
      })
    )
    .pipe(dest(distPath + "js"))
}
exports.scripts = scripts;
// ./webpack.config

// 判断环境变量
const isDev = process.argv[2] === "dev" ? true : false;

module.exports = {
  mode: isDev ? "development" : "production",
  devtool: isDev ? "cheap-module-eval-source-map" : "",
  resolve: {
    extensions: [".js"],
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        use: {
          loader: "babel-loader",
          options: {
            presets: ["babel-preset-env"],
          },
        },
      },
    ],
  },
};

样式打包

主要用到 gulp-sass

const { src, dest, watch, lastRun, series, parallel } = require("gulp");
const sass = require("gulp-sass");
const autoprefixer = require("autoprefixer");
const postcss = require("gulp-postcss");
const base64 = require("gulp-base64");
const postcssImport = require("postcss-import");
sass.compiler = require("node-sass"); //  指定编译器为node-sass

// scss 打包scss文件
const styleSrcDir = srcPath + "style/sass/**/*.scss";
const excludeStyle = `!${srcPath}style/sass/utils/**/*`;
function styles() {
  function callback(file) {
    return {
      plugins: [autoprefixer(), postcssImport({ root: file.dirname })],
    };
  }
  return src([styleSrcDir, excludeStyle], { since: lastRun(styles), sourcemaps: isDev ? true : false })
    .pipe(
      sass({
        outputStyle: "compact",
      }).on("error", sass.logError) // 要先编译,预处理器要运行在PostCSS之前,防止预处理器不能按预期运行
    )
    .pipe(postcss(callback))
    .pipe(
      base64({
        extensions: ["png,jpg,gif"],
        maxImageSize: 8 * 1024,
      })
    )
    .pipe(
      rename({
        suffix: ".min",
      })
    )
    .pipe(dest(distPath + "css", { sourcemaps: isDev ? "." : false }))
    .pipe(browserSync.stream());
}
exports.styles = styles;

图片压缩

图片压缩 需要更详细的配置,可以参照gulp-imagemin

const imagemin = require("gulp-imagemin");
// images
const imagesSrcDir = srcPath + "images/**/*";
function images() {
  return src([imagesSrcDir], { since: lastRun(images) })
    .pipe(imagemin())
    .pipe(dest(distPath + "images"))
}
exports.images = images;

检测文件改动自动增量编译+开启本地服务

const browserSync = require("browser-sync").create();
// watch 检测文件改动
function watchList() {
  browserSync.init({
    proxy: `http://localhost/website/special/${project}`
  });
  const watchJs = watch(scriptsSrcDir, series(scripts));
  const watchStyles = watch(styleSrcDir, series(styles));
  const watchImages = watch(imagesSrcDir, series(images));
  
  watchStyles.on("change", function (path, stats) {
    console.log(chalk.green(`css_File ${path} was changed`));
  });
  watchJs.on("change", function (path, stats) {
    console.log(chalk.green(`js_File ${path} was changed`));
  });
  watchImages.on("all", function (path, stats) {
    console.log(chalk.green(`img_File ${path} was changed`));

  });
}
exports.watch = watchList;

本文使用 mdnice 排版