2024/10/25:gulp 已经更新了 5.0,我所使用的配置文件中所用的 gulp-fontmin 是过时的插件,除非安装 gulp4,不然以下配置文件可能会出现不可预料的错误。
在 Web 前端开发工作中有很多 “重复工作”,比如压缩 CSS/JS 文件。而这些工作都是有规律的。找到这些规律,并编写 gulp 配置代码,让 gulp 自动执行这些 “重复工作”。-- form gulp-book!
什么是 gulp Gulp 是一个流行的自动化构建工具,用于简化这些重复性的任务。Gulp 的核心思想是利用代码来自动化处理开发过程中的繁琐任务,从而提高开发效率和代码质量。正如官网上所说: “A toolkit to automate & enhance your workflow” “Leverage gulp and the flexibility of JavaScript to automate slow, repetitive workflows and compose them into efficient build pipelines.”
而 Gulp 的强大之处在于它的插件生态系统。插件是用于处理特定任务的 JavaScript 模块。我们可以安装部分插件来使我们完成对博客静态资源的压缩。
安装 gulp gulp 是基于 node.js 开发的,我们需要先安装 node.js 和 npm,npm 会在安装完 node.js 后自动安装。安装完成后看看是否安装成功。
我使用 hexo 来建站,hexo 本身需要依托 node.js,所以使用 hexo 的朋友可以跳过安装 node.js 这一步。
安装 Gulp 的命令行工具,这样可以使我们在命令行中使用 gulp。
1 2 3 npm install -g gulp-cli gulp -v
安装插件 gulp 拥有着丰富的插件支持,其中就有我们所需要的压缩网页的插件。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 npm install gulp --save-dev npm install gulp-clean --save-dev npm install gulp-clean-css --save-dev npm install gulp-fontmin --save-dev npm install gulp-html-minifier-terser --save-dev npm install gulp-htmlclean --save-dev npm install gulp-terser --save-dev npm install gulp-ttf2woff2 --save-dev
使用 安装完成后,在博客根目录新建 gulpfile.js
,并且输入以下内容
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 const gulp = require ('gulp' );const htmlmin = require ('gulp-html-minifier-terser' );const htmlclean = require ('gulp-htmlclean' );const cleanCSS = require ('gulp-clean-css' );const terser = require ('gulp-terser' );const fontmin = require ('gulp-fontmin' );const ttf2woff2 = require ('gulp-ttf2woff2' );const clean = require ('gulp-clean' );gulp.task ('minify-html' , () => { return gulp.src ('./public/**/*.html' ) .pipe (htmlclean ()) .pipe (htmlmin ({ collapseWhitespace : true , removeComments : true , collapseWhitespace : true , collapseBooleanAttributes : true , removeEmptyAttributes : true , removeScriptTypeAttributes : true , removeStyleLinkTypeAttributes : true , removeAttributeQuotes : true , removeCDATASectionsFromCDATA : true , caseSensitive : true , minifyJS : true , minifyCSS : true , minifyURLs : true , })) .pipe (gulp.dest ('./public' )) }); gulp.task ('minify-css' , () => { return gulp.src (['./public/**/*.css' ]) .pipe (cleanCSS ({ level : { 2 : { mergeAdjacentRules : true , mergeIntoShorthands : true , mergeMedia : true , mergeNonAdjacentRules : true , mergeSemantically : false , overrideProperties : true , removeEmpty : true , reduceNonAdjacentRules : true , removeDuplicateFontRules : true , removeDuplicateMediaBlocks : true , removeDuplicateRules : true , removeUnusedAtRules : false , restructureRules : false , skipProperties : [] } } })) .pipe (gulp.dest ('./public' )); }); gulp.task ('compress' , async () =>{ return gulp.src (['./public/**/*.js' , '!./public/**/*.min.js' ]) .pipe (terser ()) .pipe (gulp.dest ('./public' )); }); gulp.task ('mini-font' , (cb ) => { var buffers = []; gulp .src (['./public/**/*.html' ]) .on ('data' , function (file ) { buffers.push (file.contents ); }) .on ('end' , function ( ) { var text = Buffer .concat (buffers).toString ('utf-8' ); minifyFont (text, cb); }); }); function minifyFont (text, cb ) { gulp .src ('./public/font/*.ttf' ) .pipe (fontmin ({ text : text })) .pipe (gulp.dest ('./public/fonts/' )) .on ('end' , cb); } gulp.task ('convertFonts' , function ( ) { return gulp.src ('./public/fonts/*.ttf' ) .pipe (ttf2woff2 ()) .pipe (gulp.dest ('./public/fonts/' )); }); gulp.task ('clean-files' , function ( ) { return gulp.src (['./public/font' ,'./public/images' ], { read : false , allowEmpty : true }) .pipe (clean ()); }); gulp.task ('default' , gulp.series ( gulp.parallel ('compress' , 'minify-css' , 'minify-html' , 'mini-font' ,), 'convertFonts' , 'clean-files' ))
运行和小小的改进 重新渲染一次,并执行 gulp,接下来就可以看到 gulp 压缩后的效果了。
1 2 3 4 hexo cl hexo g gulp hexo s
上图为 gulp 执行前后的文件大小对比图,其中 public 为未执行 gulp 指令,public-gulp 为执行 gulp 指令。下图两者均去除字体文件和 images 文件夹后只对比 html,css,js 的大小。
可以看出,在去除字体文件和 images 文件夹后,其他的文件压缩了大约 100kb 的大小 o_o …。但是在网站中占大头的字体文件却是狠狠的压缩了,总算是不用担心网站打开速度被字体拖慢了。尽管从上图看,字体的压缩看似是从 15MB 降低至了 8MB,但其实在 tff2woff2
所转化的字体文件夹中,会同时将 tff 转化为 .eot , .woff2 , .woff , .ttf , .svg 多个字体格式,从而做到各个网站的适配。而目前主流浏览器大多使用 woff2 格式,也就是说,我们打开网页的时候,大概率是使用 woff2 字体,如果不去适配 IE 和低版本浏览器,大概也可以再将字体文件删除。下边的代码块是只保留 woff2 字体删除其他字体的。虽然没什么用,毕竟浏览器是按照样式表来下载字体的,多余的字体文件不会被下载,留在这里也没什么影响。 。
1 2 3 4 5 6 7 8 9 10 11 12 gulp.task ('clean-files' , function ( ) { return gulp.src ([ './public/font' , './public/images' , './public/fonts/yourfont.eot' , './public/fonts/yourfont.ttf' , './public/fonts/yourfont.svg' , './public/fonts/yourfont.woff' , ], { read : false , allowEmpty : true }) .pipe (clean ()); });
附上一张不使用任何处理,只是用 ttf2woff2 处理字体后,输出文件夹字体占用大小截图,可以看到,svg 居然占到了丧心病狂的 4M,而 woff2 只有 699kb,删了会清爽很多 。
注意事项 ttf2woff2
会在指定目录生成一个文件夹,其中会有’字体文件名字.css’的 css 文件,将它引入即可使用转化后的字体文件。
使用 gulp 压缩字体必须在本地进行,进一步导致本地文件增大,看着有点难受。我有在想,是否可以做到当博客仓库提交的时候自动触发 action,拉取字体文件进行处理,然后博客再通过网络引入该 css,从而做到 public 文件夹的干净。但是最后实在是不想折腾,也就放弃了。
我所使用的图片均由外链引入,不需要 hexo 的 images 文件夹,所以使用 clean-files 时顺便将其删除。如需使用 images,请自行修改。当然,gulp 也有与压缩图片有关的插件,可自行搜索使用。
更详细的设置请参考所用插件的官方文档。
参考文章 gulp-book 使用 gulp 压缩博客静态资源