2024-12-02 08:48:09 +00:00
|
|
|
'use strict'
|
|
|
|
const zlib = require('zlib')
|
|
|
|
const { promisify } = require('util')
|
|
|
|
const gzip = promisify(zlib.gzip)
|
|
|
|
const br = promisify(zlib.brotliCompress)
|
|
|
|
const { match, logFn } = require('./tools')
|
|
|
|
|
|
|
|
function gzipFn() {
|
|
|
|
const hexo = this
|
|
|
|
const options = hexo.config.minify.gzip
|
|
|
|
|
2024-12-03 08:18:51 +00:00
|
|
|
const route = hexo.route
|
2024-12-04 08:41:23 +00:00
|
|
|
/** @type {string[]} */
|
2024-12-02 08:48:09 +00:00
|
|
|
const routeList = route.list()
|
|
|
|
const { globOptions, include, verbose } = options
|
2024-12-03 08:18:51 +00:00
|
|
|
let level = options.level
|
2024-12-02 08:48:09 +00:00
|
|
|
if (typeof level !== 'number') level = zlib.constants.Z_BEST_COMPRESSION
|
|
|
|
|
|
|
|
return Promise.all((match(routeList, include, globOptions)).map(path => {
|
2024-12-03 09:26:45 +00:00
|
|
|
return new Promise((/** @type {(value: void) => void} */ resolve, reject) => {
|
2024-12-02 08:48:09 +00:00
|
|
|
const assetPath = route.get(path)
|
|
|
|
let assetTxt = ''
|
|
|
|
assetPath.on('data', chunk => (assetTxt += chunk))
|
|
|
|
assetPath.on('end', async () => {
|
|
|
|
if (assetTxt.length) {
|
|
|
|
try {
|
|
|
|
const result = await gzip(assetTxt, { level })
|
|
|
|
if (verbose) logFn.call(this, assetTxt, result, path, 'gzip')
|
|
|
|
resolve(route.set(path + '.gz', result))
|
2024-12-03 09:26:45 +00:00
|
|
|
return
|
2024-12-02 08:48:09 +00:00
|
|
|
} catch (err) {
|
|
|
|
reject(new Error(`Path: ${path}\n${err}`))
|
|
|
|
}
|
|
|
|
}
|
2024-12-03 09:26:45 +00:00
|
|
|
resolve()
|
2024-12-02 08:48:09 +00:00
|
|
|
})
|
|
|
|
})
|
|
|
|
}))
|
|
|
|
}
|
|
|
|
|
|
|
|
function brotliFn() {
|
|
|
|
const hexo = this
|
|
|
|
const options = hexo.config.minify.brotli
|
|
|
|
|
2024-12-03 08:18:51 +00:00
|
|
|
const route = hexo.route
|
2024-12-04 08:41:23 +00:00
|
|
|
/** @type {string[]} */
|
2024-12-02 08:48:09 +00:00
|
|
|
const routeList = route.list()
|
|
|
|
const { globOptions, include, verbose } = options
|
2024-12-03 08:18:51 +00:00
|
|
|
let level = options.level
|
2024-12-02 08:48:09 +00:00
|
|
|
if (typeof level !== 'number') level = zlib.constants.BROTLI_MAX_QUALITY
|
|
|
|
|
|
|
|
return Promise.all((match(routeList, include, globOptions)).map(path => {
|
2024-12-03 09:26:45 +00:00
|
|
|
return new Promise((/** @type {(value: void) => void} */ resolve, reject) => {
|
2024-12-02 08:48:09 +00:00
|
|
|
const assetPath = route.get(path)
|
|
|
|
let assetTxt = ''
|
|
|
|
assetPath.on('data', chunk => (assetTxt += chunk))
|
|
|
|
assetPath.on('end', async () => {
|
|
|
|
if (assetTxt.length) {
|
|
|
|
try {
|
|
|
|
const result = await br(assetTxt, { params: { [zlib.constants.BROTLI_PARAM_QUALITY]: level } })
|
|
|
|
if (verbose) logFn.call(this, assetTxt, result, path, 'brotli')
|
2024-12-03 09:26:45 +00:00
|
|
|
route.set(path + '.br', result)
|
2024-12-02 08:48:09 +00:00
|
|
|
} catch (err) {
|
|
|
|
reject(new Error(`Path: ${path}\n${err}`))
|
|
|
|
}
|
|
|
|
}
|
2024-12-03 09:26:45 +00:00
|
|
|
resolve()
|
2024-12-02 08:48:09 +00:00
|
|
|
})
|
|
|
|
})
|
|
|
|
}))
|
|
|
|
}
|
|
|
|
|
|
|
|
module.exports = {
|
|
|
|
gzipFn,
|
|
|
|
brotliFn
|
|
|
|
}
|