使用 gulp 压缩静态资源

今天打开浏览器的控制台查看加载耗时的时候,发现 hexo 生成的资源文件都是没有经过压缩的。像下面这个样子:

压缩前-HTML

CSS 和 JavaScript 文件都没有被压缩,我就不贴图了。我们可以使用 gulp 来压缩这些静态资源,提高网站的加载速度。

下面我先直接说说成功的安装步骤,最后再说说遇到的一些坑。

安装 gulp

首先要全局安装 gulp:

npm install -g gulp

然后在项目中安装以下依赖:

yarn add gulp gulp-htmlclean gulp-htmlmin gulp-clean-css gulp-uglify
# 部分 JavaScript 文件需要 Babel
yarn add gulp-babel @babel/core babel-preset-env

配置 gulp

然后在项目的根目录创建 gulpfile.js 文件,写入以下内容:

折叠/展开代码
const gulp = require('gulp')
const cleancss = require('gulp-clean-css')
const uglify = require('gulp-uglify')
const babel = require('gulp-babel')
const htmlmin = require('gulp-htmlmin')
const htmlclean = require('gulp-htmlclean')

const ignoreHTML = ['!./public/pages/qixi/**/*.html']
const ignoreJS = ['!./public/pages/qixi/**/*.js']
const ignoreCSS = ['!./public/pages/qixi/**/*.css']

gulp.task('minify-html', () => {
  return gulp
    .src(['./public/**/*.html', ...ignoreHTML])
    .pipe(htmlclean())
    .pipe(
      htmlmin({
        removeComments: true,
        minifyJS: true,
        minifyCSS: true,
        minifyURLs: true,
      }),
    )
    .pipe(gulp.dest('./public'))
})

gulp.task('minify-css', () => {
  return gulp
    .src(['./public/**/*.css', ...ignoreCSS])
    .pipe(cleancss())
    .pipe(gulp.dest('./public'))
})

gulp.task('minify-js', () => {
  return gulp
    .src(['./public/**/*.js', '!./public/**/*.min.js', ...ignoreJS])
    .pipe(babel({ presets: ['@babel/env'] }))
    .pipe(uglify())
    .pipe(gulp.dest('./public'))
})

gulp.task('default', gulp.parallel('minify-html', 'minify-css', 'minify-js'))

使用方法

只需要在使用 hexo 生成和部署博客的步骤中间加入压缩就可以了:

hexo generate
gulp
hexo deploy

推荐在 package.json 中加入快捷的运行方式(注意是添加一行命令,不需要把之前存在的内容删掉):

{
  "scripts": {
    "d": "hexo generate && gulp && hexo deploy"
  }
}

然后每次部署时,直接使用以下命令即可:

yarn d
# 或者使用 npm
npm run d

查看效果

压缩后-HTML

压缩后-CSS

压缩后-JavaScript

一些坑点

图片压缩

上面的配置中我并没有启用图片压缩,因为我在安装依赖 gulp-imagemin 的时候一直报错:

warning Error running install script for optional dependency: "C:\\some-dir\\gulp-img\\node_modules\\gifsicle: Command failed.
Exit code: 1
Command: node lib/install.js
Arguments:
Directory: C:\\some-dir\\gulp-img\\node_modules\\gifsicle
Output:
‼ getaddrinfo ENOENT raw.githubusercontent.com
  ‼ gifsicle pre-build test failed
  i compiling from source
  × Error: Command failed: C:\\Windows\\system32\\cmd.exe /s /c \"autoreconf -ivf\"

我尝试了很多方法,包括使用代理,但是还是没有安装成功(可能是我代理没配置好?

但是我的博客上的图片都是单独放在图床上的,所以生成的静态资源基本没有什么图片,因此也就跳过这一项了。

Babel

细心的同学可能也发现了我在上面的配置中使用了 gulp-babel。我一开始是没有配置 babel 的,但是在压缩 JavaScript 文件时一直报错,仔细看了一下,报错信息是:

[10:39:47] Starting 'minify-js'...
[10:39:48] 'minify-js' errored after 552 ms
[10:39:48] GulpUglifyError: unable to minify JavaScript
Caused by: SyntaxError: Unexpected token: punc «)»
File: C:\some-dir\blog.xuewen.me\public\js\algolia-search.js
Line: 3
Col: 45

对应的 JavaScript 文件内容是:

/* global instantsearch, CONFIG */

window.addEventListener('DOMContentLoaded', () => {
  const algoliaSettings = CONFIG.algolia

  let search = instantsearch({
    appId: algoliaSettings.appID,
    apiKey: algoliaSettings.apiKey,
    indexName: algoliaSettings.indexName,
    searchFunction: helper => {
      let searchInput = document.querySelector('#search-input input')
      if (searchInput.value) {
        helper.search()
      }
    },
  })
  // 省略其他代码...
})

这个文件第 3 行有一个箭头函数,看来 gulp-uglify 不能很好地支持这些特性,因此我使用了 babel 来转换一下再压缩。