Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
lin-xin opened this issue Mar 9, 2017 · 22 comments
Open

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

lin-xin opened this issue Mar 9, 2017 · 22 comments

Comments

@lin-xin
Copy link
Owner

lin-xin commented Mar 9, 2017

虽然网上有很多的 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>
@lin-xin lin-xin added the gulp label Mar 9, 2017
@mercer08
Copy link

mercer08 commented Apr 6, 2017

对于图片这种静态资源发布到cdn的话,是不是也要生成md5指纹呢?

@lin-xin
Copy link
Owner Author

lin-xin commented Apr 6, 2017

@2lei 是啊,不然的话你图片更改之后,在页面访问一直是访问到缓存的未改之前的图片

@vincent-cong
Copy link

@lin-xin 你好 这个 gulpfile.js 可以完善一下吗?

@lin-xin
Copy link
Owner Author

lin-xin commented Jul 10, 2017

@vincent-cong 这个哪里有问题吗?

@vincent-cong
Copy link

vincent-cong commented Jul 10, 2017

@lin-xin 打包完了 并没有dist文件夹。。。。这个是什么原因?这个你可以出一个案列吗?非常感谢。

@lin-xin
Copy link
Owner Author

lin-xin commented Jul 10, 2017

@vincent-cong 像上面涉及到的路径,你要按照你实际项目的路径修改一下

@vincent-cong
Copy link

vincent-cong commented Jul 10, 2017

@lin-xin
var jsFilter = filter('src/js/.js',{restore:true}),
cssFilter = filter('src/js/
.css',{restore:true}),
htmlFilter = filter(['src/.html'],{restore:true});
gulp.src('src/
.html')
加过了,也没用。。。你可以自己试试看

我的文件目录是 src --js --aa.js src --css-aa.css src --aa.html
*.js *.css *.html 星号都是有的

@lin-xin
Copy link
Owner Author

lin-xin commented Jul 10, 2017

@vincent-cong 我没有你的文件我怎么试呢,我这边是没问题的哦

@vincent-cong
Copy link

@lin-xin 好吧 你那是好的,那估计是我的目录不对。。。我再按照你上面的目录弄一下吧,灰常感谢。如果方便的话可以加个例子么?

@dumuchenglin123
Copy link

dumuchenglin123 commented Jul 26, 2017

怎么html压缩 语句不起作用啊?
image

@lin-xin
Copy link
Owner Author

lin-xin commented Jul 26, 2017

@dumuchenglin123 压缩的代码你注释掉了。用了 gulpif( ) 你的condition ,你有定义吗?condition 为true时才会执行后面的压缩。

@MagicHacker
Copy link

@lin-xin 为什么要进行文件过滤呢?

@lin-xin
Copy link
Owner Author

lin-xin commented Oct 10, 2017

@MagicHacker
因为 gulp.src('/*.html') 源文件是针对 html 的,所以过滤出这个html里面引用的js和css进行操作

@MagicHacker
Copy link

@lin-xin ok,明白了,谢谢。没注意到路径是/*.html的。我刚用这个东西不久,平时都是单独定义任务的。

@Pulset
Copy link

Pulset commented Oct 10, 2017

gulp.task('test', function () {
    var jsFilter = filter(['src/js/**/*.js', '!src/js/libs/**/*.js'],{restore:true}),
        cssFilter = filter('src/css/**/*.css',{restore:true}),
        htmlFilter = filter(['src/html/**/*.html'],{restore:true});
    gulp.src('src/html/**/*.html')
        .pipe(useref())                         // 解析html中的构建块
        .pipe(jsFilter)                         // 过滤所有js
        .pipe(uglify())                         // 压缩js
        .pipe(jsFilter.restore)
        .pipe(cssFilter)                        // 过滤所有css
        .pipe(minifycss())                           // 压缩优化css
        .pipe(cssFilter.restore)
        .pipe(RevAll.revision({                 // 生成版本号
            dontRenameFile: ['.html'],          // 不给 html 文件添加版本号
            dontUpdateReference: ['.html']      // 不给文件里链接的html加版本号
        }))
        .pipe(htmlFilter)                       // 过滤所有html
        .pipe(htmlmini())                       // 压缩html
        .pipe(htmlFilter.restore)
        .pipe(gulp.dest('dist/'))
})

为什么我过滤所有js之后,后面进行压缩,好像没有执行这个操作?大神,帮我看看哪里写错了

@lin-xin
Copy link
Owner Author

lin-xin commented Oct 11, 2017

@Pulset html里有没有加上 < ! -- build:css xxx --> < ! -- endbuild -->

@Pulset
Copy link

Pulset commented Oct 11, 2017

@lin-xin 加上了,js、css也能合并之后输出,但是都没有压缩

@lin-xin
Copy link
Owner Author

lin-xin commented Oct 11, 2017

@Pulset 那是不是忘了安装 gulp-uglify 等压缩插件还是引入的出了问题

@Pulset
Copy link

Pulset commented Oct 11, 2017

@lin-xin 原来是路径问题,改成这样就行了

var jsFilter = filter('**/*.js', { restore: true }),
  cssFilter = filter('**/*.css', { restore: true }),
  htmlFilter = filter('**/*.htm', { restore: true });

@BiYuqi
Copy link

BiYuqi commented Oct 15, 2017

请问博主,针对多页面有什么好的解决方案吗,除了index.html 我还有htm/**/*.html等页面 自动化压缩打版本加hash自动替换,有什么好的解决方法吗

@lin-xin
Copy link
Owner Author

lin-xin commented Oct 16, 2017

@BiYuqi 多页面也适合用这个方案的

@Yibangyu
Copy link

那页面中的图片该怎么处理勒?

@lin-xin lin-xin changed the title gulp自动化压缩合并、加版本号解决方案 2019年Gulp自动化压缩合并构建的解决方案 Nov 7, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants