2019年Gulp自动化压缩合并构建的解决方案

@lin-xin 2017-03-09 10:59:40发表于 lin-xin/blog gulpweb tools

虽然网上有很多的 gulp 构建文章,但是很多都已经随着 gulp 插件的更新无法运行了。因此,我写了这个比较简单的构建方案。本文基于 gulp 最新的 4.0.2 版本进行了修改。现在前端组件化项目大多是基于 webpack 进行构建,但是有一个零散的小业务,静态页面之类的,使用 gulp 反而会更加简单方便。

如果还不熟悉 gulp 的插件,可以阅读上一篇文章:精通gulp常用插件

这个方案主要是为了实现es6转es5、js/css的压缩合并、自动添加版本号和压缩html。

  • gulp-babel es6转es5
  • gulp-csso 压缩优化css
  • gulp-uglify 压缩js
  • gulp-htmlmin 压缩html
  • gulp-filter 过滤文件
  • gulp-rev-all 生成版本号

主要通过上面插件实现功能,其他插件配合使用。

安装相关依赖:npm i gulp gulp-uglify gulp-htmlmin gulp-useref gulp-csso gulp-filter gulp-rev-all gulp-base64 gulp-autoprefixer del gulp-babel @babel/core @babel/preset-env -D

// gulpfile.js
const { series, parallel, src, dest } = require('gulp');
const uglify = require('gulp-uglify');
const htmlmini = require('gulp-htmlmin');
const useref = require('gulp-useref');
const csso = require('gulp-csso');
const filter = require('gulp-filter');
const babel = require('gulp-babel');
const RevAll = require('gulp-rev-all');
const base64 = require('gulp-base64');
const autoprefixer = require('gulp-autoprefixer');
const del = require('del');

// 压缩html配置
const options = {
    removeComments: true,
    collapseWhitespace: true,
    collapseBooleanAttributes: true,
    removeEmptyAttributes: true,
    removeScriptTypeAttributes: true,
    removeStyleLinkTypeAttributes: true,
    minifyJS: true,
    minifyCSS: true
};

const defaultTask = cb => {
    const jsFilter = filter('**/*.js', { restore: true });
    const cssFilter = filter('**/*.css', { restore: true });
    const htmlFilter = filter(['**/*.html'], { restore: true });
    src('*.html')
        .pipe(useref())                     // 解析html中的构建块
        .pipe(jsFilter)                     // 过滤所有js
        .pipe(babel({
            presets: ['@babel/env'],
            sourceType: 'script'
        }))
        .pipe(uglify())                     // 压缩js
        .pipe(jsFilter.restore)
        .pipe(cssFilter)                    // 过滤所有css
        .pipe(autoprefixer())               // 添加css前缀
        .pipe(base64())
        .pipe(csso())                       // 压缩优化css
        .pipe(cssFilter.restore)
        .pipe(RevAll.revision({             // 生成版本号
            dontRenameFile: ['.html'],      // 不给 html 文件添加版本号
            dontUpdateReference: ['.html']  // 不给文件里链接的html加版本号
        }))
        .pipe(htmlFilter)                   // 过滤所有html
        .pipe(htmlmini(options))            // 压缩html
        .pipe(htmlFilter.restore)
        .pipe(dest('./dist'))
        .on('error', function (err) {
            throw new Error(err.toString())
        })
    cb();
}

const delDist = cb => {
    del.sync(['./dist']);
    cb();
}

const copyAssets = cb => {
    src('static/img/**').pipe(dest('./dist/static/img/'));
    cb();
}

exports.default = series(delDist, parallel(defaultTask, copyAssets));

在html中,我们需要先定义好构建块。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>gulp自动化构建解决方案</title>
    <!-- build:css static/css/index.css -->     // 定义了构建后引用的css路径
    <link rel="stylesheet" href="static/css/common.css"/>
    <link rel="stylesheet" href="static/css/index.css"/>
    <!-- endbuild -->
</head>
<body>
    ......
    
    <!-- build:js static/js/index.js -->        // 定义了构建后引用的js路径
    <script src="static/js/jquery.js"></script>
    <script src="static/js/common.js"></script>
    <script src="static/js/index.js"></script>
    <!-- endbuild -->
</body>
</html>

执行构建完成后,会生成 dist 文件夹,目录为:

|-dist
|   |-static
|       |-css
|           |-index.96cf44da.css
|       |-img
|       |-js
|           |-index.42ce3282.js
|   |-index.html

构建完的index.html,我们忽略压缩的html,完成了压缩合并添加版本号等功能。

// dist/index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>gulp自动化构建解决方案</title>
    <link rel="stylesheet" href="static/css/index.96cf44da.css"/>
</head>
<body>
    ......

    <script src="static/js/index.42ce3282.js"></script>
</body>
</html>