From 7efa67af84b60b14724517e634673460bfcef8a1 Mon Sep 17 00:00:00 2001 From: Kristóf Marussy Date: Thu, 21 Mar 2024 12:35:52 +0100 Subject: Also compress Docusaurus-generated files Run the compression manually for files that are not generated by Webpack. We must take over the @docusaurus/plugin-sitemap plugin to make sure we run after it has generated sitemap.xml. Docusaurus runs all plugin post-build actions in parallel with Promise.all, so the only way to do this is to invoke the post-build action in our own one. --- src/plugins/compressionPlugin.ts | 53 +++++++++++++++++++++++++++++++--------- 1 file changed, 41 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/plugins/compressionPlugin.ts b/src/plugins/compressionPlugin.ts index b1cff6a..8b347cf 100644 --- a/src/plugins/compressionPlugin.ts +++ b/src/plugins/compressionPlugin.ts @@ -4,14 +4,35 @@ * SPDX-License-Identifier: MIT */ -import zlib, { type BrotliOptions } from 'node:zlib'; +import { readFile, writeFile } from 'node:fs/promises'; +import path from 'node:path'; +import { promisify } from 'node:util'; +import zlib, { type BrotliOptions, type ZlibOptions } from 'node:zlib'; -import type { Plugin } from '@docusaurus/types'; +import pluginSitemap, { type PluginOptions } from '@docusaurus/plugin-sitemap'; +import type { LoadContext, Plugin } from '@docusaurus/types'; +import { Globby } from '@docusaurus/utils'; import CompressionPlugin from 'compression-webpack-plugin'; -const test = /\.(js|css|html|svg|txt)$/; +const gzipOptions = { + level: 9, +} satisfies ZlibOptions; +const brotliOptions = { + params: { + [zlib.constants.BROTLI_PARAM_QUALITY]: 11, + }, +}; +const test = /\.(js|css|svg|txt)$/; +const paths = ['**/*.html', 'robots.txt', 'sitemap.xml']; -export default function compressionPlugin(): Plugin { +const gzip = promisify(zlib.gzip); +const brotliCompress = promisify(zlib.brotliCompress); + +export default function compressionPlugin( + context: LoadContext, + options: PluginOptions, +): Plugin { + const sitemap = pluginSitemap(context, options); return { name: 'marussy-compression-plugin', configureWebpack: (_config, isServer) => @@ -22,21 +43,29 @@ export default function compressionPlugin(): Plugin { new CompressionPlugin({ test, filename: '[path][base].gz', - compressionOptions: { - level: 9, - }, + compressionOptions: gzipOptions, }), new CompressionPlugin({ test, filename: '[path][base].br', algorithm: 'brotliCompress', - compressionOptions: { - params: { - [zlib.constants.BROTLI_PARAM_QUALITY]: 11, - }, - }, + compressionOptions: brotliOptions, }), ], }, + async postBuild(props) { + await sitemap?.postBuild(props); + const files = await Globby(paths.map((s) => path.join(props.outDir, s))); + for (const file of files) { + console.log(file); + const contents = await readFile(file); + const gzipContents = await gzip(contents, gzipOptions); + await writeFile(`${file}.gz`, gzipContents); + const brotliContents = await brotliCompress(contents, brotliOptions); + await writeFile(`${file}.br`, brotliContents); + } + }, }; } + +export { validateOptions } from '@docusaurus/plugin-sitemap'; -- cgit v1.2.3-70-g09d2