diff options
author | Kristóf Marussy <kristof@marussy.com> | 2024-03-21 12:35:52 +0100 |
---|---|---|
committer | Kristóf Marussy <kristof@marussy.com> | 2024-03-21 12:35:52 +0100 |
commit | 7efa67af84b60b14724517e634673460bfcef8a1 (patch) | |
tree | 84fc64508658eb3130d1a9c9057049cdb8faf83e /src | |
parent | More even heading letter-spacing (diff) | |
download | blog-7efa67af84b60b14724517e634673460bfcef8a1.tar.gz blog-7efa67af84b60b14724517e634673460bfcef8a1.tar.zst blog-7efa67af84b60b14724517e634673460bfcef8a1.zip |
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.
Diffstat (limited to 'src')
-rw-r--r-- | src/plugins/compressionPlugin.ts | 53 |
1 files changed, 41 insertions, 12 deletions
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 @@ | |||
4 | * SPDX-License-Identifier: MIT | 4 | * SPDX-License-Identifier: MIT |
5 | */ | 5 | */ |
6 | 6 | ||
7 | import zlib, { type BrotliOptions } from 'node:zlib'; | 7 | import { readFile, writeFile } from 'node:fs/promises'; |
8 | import path from 'node:path'; | ||
9 | import { promisify } from 'node:util'; | ||
10 | import zlib, { type BrotliOptions, type ZlibOptions } from 'node:zlib'; | ||
8 | 11 | ||
9 | import type { Plugin } from '@docusaurus/types'; | 12 | import pluginSitemap, { type PluginOptions } from '@docusaurus/plugin-sitemap'; |
13 | import type { LoadContext, Plugin } from '@docusaurus/types'; | ||
14 | import { Globby } from '@docusaurus/utils'; | ||
10 | import CompressionPlugin from 'compression-webpack-plugin'; | 15 | import CompressionPlugin from 'compression-webpack-plugin'; |
11 | 16 | ||
12 | const test = /\.(js|css|html|svg|txt)$/; | 17 | const gzipOptions = { |
18 | level: 9, | ||
19 | } satisfies ZlibOptions; | ||
20 | const brotliOptions = { | ||
21 | params: { | ||
22 | [zlib.constants.BROTLI_PARAM_QUALITY]: 11, | ||
23 | }, | ||
24 | }; | ||
25 | const test = /\.(js|css|svg|txt)$/; | ||
26 | const paths = ['**/*.html', 'robots.txt', 'sitemap.xml']; | ||
13 | 27 | ||
14 | export default function compressionPlugin(): Plugin { | 28 | const gzip = promisify(zlib.gzip); |
29 | const brotliCompress = promisify(zlib.brotliCompress); | ||
30 | |||
31 | export default function compressionPlugin( | ||
32 | context: LoadContext, | ||
33 | options: PluginOptions, | ||
34 | ): Plugin<void> { | ||
35 | const sitemap = pluginSitemap(context, options); | ||
15 | return { | 36 | return { |
16 | name: 'marussy-compression-plugin', | 37 | name: 'marussy-compression-plugin', |
17 | configureWebpack: (_config, isServer) => | 38 | configureWebpack: (_config, isServer) => |
@@ -22,21 +43,29 @@ export default function compressionPlugin(): Plugin { | |||
22 | new CompressionPlugin({ | 43 | new CompressionPlugin({ |
23 | test, | 44 | test, |
24 | filename: '[path][base].gz', | 45 | filename: '[path][base].gz', |
25 | compressionOptions: { | 46 | compressionOptions: gzipOptions, |
26 | level: 9, | ||
27 | }, | ||
28 | }), | 47 | }), |
29 | new CompressionPlugin<BrotliOptions>({ | 48 | new CompressionPlugin<BrotliOptions>({ |
30 | test, | 49 | test, |
31 | filename: '[path][base].br', | 50 | filename: '[path][base].br', |
32 | algorithm: 'brotliCompress', | 51 | algorithm: 'brotliCompress', |
33 | compressionOptions: { | 52 | compressionOptions: brotliOptions, |
34 | params: { | ||
35 | [zlib.constants.BROTLI_PARAM_QUALITY]: 11, | ||
36 | }, | ||
37 | }, | ||
38 | }), | 53 | }), |
39 | ], | 54 | ], |
40 | }, | 55 | }, |
56 | async postBuild(props) { | ||
57 | await sitemap?.postBuild(props); | ||
58 | const files = await Globby(paths.map((s) => path.join(props.outDir, s))); | ||
59 | for (const file of files) { | ||
60 | console.log(file); | ||
61 | const contents = await readFile(file); | ||
62 | const gzipContents = await gzip(contents, gzipOptions); | ||
63 | await writeFile(`${file}.gz`, gzipContents); | ||
64 | const brotliContents = await brotliCompress(contents, brotliOptions); | ||
65 | await writeFile(`${file}.br`, brotliContents); | ||
66 | } | ||
67 | }, | ||
41 | }; | 68 | }; |
42 | } | 69 | } |
70 | |||
71 | export { validateOptions } from '@docusaurus/plugin-sitemap'; | ||