惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

C
Check Point Blog
AI
AI
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
U
Unit 42
Vercel News
Vercel News
Stack Overflow Blog
Stack Overflow Blog
P
Proofpoint News Feed
Microsoft Security Blog
Microsoft Security Blog
The GitHub Blog
The GitHub Blog
WordPress大学
WordPress大学
Martin Fowler
Martin Fowler
博客园 - 【当耐特】
B
Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Apple Machine Learning Research
Apple Machine Learning Research
博客园_首页
F
Full Disclosure
Google DeepMind News
Google DeepMind News
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
H
Help Net Security
Recorded Future
Recorded Future
N
News and Events Feed by Topic
雷峰网
雷峰网
V
Vulnerabilities – Threatpost
Schneier on Security
Schneier on Security
aimingoo的专栏
aimingoo的专栏
S
Schneier on Security
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
O
OpenAI News
Project Zero
Project Zero
罗磊的独立博客
G
GRAHAM CLULEY
腾讯CDC
P
Privacy International News Feed
V
V2EX
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Hugging Face - Blog
Hugging Face - Blog
爱范儿
爱范儿
H
Heimdal Security Blog
L
LINUX DO - 热门话题
Forbes - Security
Forbes - Security
美团技术团队
MongoDB | Blog
MongoDB | Blog
Security Latest
Security Latest
M
MIT News - Artificial intelligence
T
Tor Project blog
Cisco Talos Blog
Cisco Talos Blog
宝玉的分享
宝玉的分享
T
Threat Research - Cisco Blogs
TaoSecurity Blog
TaoSecurity Blog

皓子的小站

网站字体应用之坑——font-family 篇 糟糕的 meta name="theme-color" How to Automatically Track Newly Supported ESLint Rules in Oxlint How to Gradually Migrate from ESLint to Oxlint (Without Breaking Everything) CVE-2025-70886 Proof of Concept (PoC) | A Script to Crash Halo CMS Comment Backend 自定义网页鼠标指针——一段曲折的旅程 CVE-2025-70886 漏洞复现/PoC | 一个脚本让 Halo CMS 评论后台瘫痪 2025 年终总结 & 博客两周年 老用户专享!已有 Halo 专业版授权可免费升级商业版 自动追踪 Oxlint 对 ESLint 规则的新增支持 Halo 贡献者证书与实体周边盲盒开箱 博客评论系统指南 CDN 回源跟随配置导致登录异常问题排查 SCDN 免费赞助计划:助力高质量博客&博客圈 锐捷校园网:网络共享与带宽叠加方案(哈理工案例) ESLint 到 Oxlint 渐进式迁移快速上手指南 Fixing Vite Breaking Inline JS & CSS in Thymeleaf Templates 解决 Vite 破坏 Thymeleaf 模板内联 JS & CSS 的方法 我的博客,为什么是月更? 博客俱乐部一周年纪念品开箱 网站字体加载之坑——format 篇 经历 1000000000 次 DDoS 请求攻击后,我总结了三条经验 题解分享:[AtCoder Beginner Contest 414 E] Count A%B=C 题解分享:[蓝桥杯 2025 国 Python A] 杨辉三角 P12876 FiF口语训练破解刷分教程(适用于 Windows) 不要与蠢人辩论 小心网络地雷·续篇 当心网络组织“开往”·续篇 当心网络组织“开往” 小心网络地雷 在 Halo CMS 中通过模板实现随机推荐多篇文章 回应某博客上有关“开往”组织在内部会议上对我的污蔑(上) 再遭 DDoS 攻击:CDN 流量限额拦不住请求计费飙升 2025年团体程序设计天梯赛 - Python 个人赛时暴力题解 网站流量分析工具 Umami 中国大陆合规版发布 把握当下,享受生活 Folo 认证功能反成漏洞?警惕 RSS 订阅源所有权被恶意盗取风险 在 Halo CMS 中通过模板实现随机文章跳转功能 从沉默展柜到时代回响:731部队罪证陈列馆参访手记 脚本分享:CDN 流量触顶后自动切换至 Cloudflare 官方 BUG 快薅!Halo 永久/买断用户可额外获得一份买断许可 老用户专享!已有 1Panel 永久授权/买断许可用户可再领免费买断许可证! 限时特惠!1¥ 立即解锁 1Panel 专业版全功能 61 天 混合云架构下的动态 IPv6 智能加速实践:从家庭网络到全球分发的低成本部署指南 如何用 AI 全方面辅助博客创作 - 从博文之内到博文之外 Random Number Generation and Formatting in Thymeleaf Thymeleaf 随机数生成与格式化详解 列举我维护的项目和发布的软件包 快速部署教程 - 通过 Webhook 触发邮件通知的开源自托管服务 Going Against the Grain - Four Websites That Make Your URL Longer 反其道而行 - 四个让你网址变得更长的网站 2024 年终总结 & 博客一周年 基于 OneBot API 的简易异步 QQ 群批量发消息脚本 如何快速完成中文排版优化 如何给文章分类和打标签 群规之敏感违禁词对抗 一图展示​ ​RSS3 世界 - The Open(RSS3) Universe 开源项目发到 bilibili 后可能获得的 PR C/C++:为什么 a[i][j] 等价于 *(*(a+i)+j) Fast Methods to Convert Uppercase Letters to Lowercase in C++ C++ 中快速将字符串大写字母转为小写的方法 Fixing GitHub Actions push to ghcr '403 Forbidden' error Fixing docker pull image "ghcr.io..." Unauthorized error 本站“算法题练习/题解分享”相关文章汇总 不怕流氓多,就怕流氓有文化——站长应该防范的几个问题及对应解决方法分享 题解分享:HRBUST 1132 水数 新手程序员必备的三项技能 如何快速排查插件(模组)的兼容性问题(基于二分法和分治思想) 通过 Umami 最新功能观察定时发布文章的最佳时段 踩坑分享:如何一个人搬运 126.7 斤的书坐动车 两篇文章分享:别像弱智一样提问 & 提问的智慧 论下落式音游/定轨音游中的优质粪铺(文末附铺面推荐) 为什么选择无纸化阅读?为什么买墨水屏电子书?为什么 Kindle“失败”了? 我维护的 Halo 主题,现已发布到 Halo 应用商店! OSU!Standard(osu!std)/OSU!Taiko 转 OSU!Mania 铺面转换器发布 我常用的 OSU!Mania 皮肤分享 电荷守恒辨析:为什么一个离子带多个电荷要乘上所带电荷数而不是除以所带电荷数 注意!align-items: flex-start 会导致 overflow-wrap: break-word 失效 惊人 98 元限定T恤!1Panel, Halo 开发商开启推广积分奖励活动 Minecraft Spigot Bukkit 服务器插件开发 教程收集 中文博客倡议 Windows 10 遇到“只能重装系统”但不想重装的解决方案 Windows 10 文件系统错误 -2144926975 -2147219196 修复 Windows 10 升级 Windows 11 简明教程 CSS 预处理器如何正确的复用样式(stylus 中使用 @extend 继承的坑) 请一定要回复博客下的匿名评论!对于博主和评论者有关匿名评论的倡议 一图解释单一质点运动波动图像和振动图像的关系 解决 Docker pull image "ghcr.io..." Unauthorized error 解决 GitHub Actions push to ghcr '403 Forbidden' error 解决 Umami API 更新延迟问题(如何修改开源项目代码并构建 Docker 镜像-以 Umami 为例) 在国家公祭日自动将网站变灰 中文博客圈列表 解决 Halo CMS 的 Umami Plugin CORS&CSP 跨域报错问题 Windows 创建存储池报错 无法创建池 不支持该请求 (0x00000032) Windows 显示器突然黑白 桌面突然黑白 鼠标和截图还是彩色的 通过指令过滤出正确的公网 IPv6 地址(记一次折腾 IPv6 DDNS) 我的世界免费科技地址 1.7-1.21 网站 Favicon 下载工具发布 键盘 Bios 内可用 系统内无法输入 设备管理器无黄色感叹号 设备管理器 网卡一堆黄色感叹号 例如 WAN, Miniport
静态资源预压缩:零运行时开销,极致节省带宽
HowieHz · 2026-02-12 · via 皓子的小站

前言

你也许在 nginx 上配置过以下内容:

http {
    gzip on; 
    gzip_types application/atom+xml application/javascript application/json application/vnd.api+json application/rss+xml application/vnd.ms-fontobject application/x-font-opentype application/x-font-truetype application/x-font-ttf application/x-javascript application/xhtml+xml application/xml font/eot font/opentype font/otf font/truetype image/svg+xml image/vnd.microsoft.icon image/x-icon image/x-win-bitmap text/css text/javascript text/plain text/xml;

    server {
        // ...
    }
}

上面配置文件中的 gzip on; 即为启动动态压缩:占用服务器的 CPU 和内存资源实时进行压缩。
容易想到,我们可以将文件进行预压缩,在运行时直接提供压缩好的文件。

原理

构建时预压缩,以高压缩等级生成对应文件,服务器在运行时直接提供压缩后的文件。

一般约定:

算法 文件后缀 普及情况
gzip .gz gzip
brotli .br brotli
zstandard .zst zstd

例:如果你看到 1.js.br,说明是由 1.js 使用 brotli 算法预压缩生成的文件。

注:截止于 2026 年 2 月 12 日,zstd 未进入 baseline。建议当前仅部署 gzip 和 brotli 预压缩版本。

优势和缺点

预压缩有以下好处:

  • 节约服务器内存资源。
  • 节约服务器 CPU 资源。
  • 节约服务器带宽。

缺点:

  • 需占用更多的存储空间。
  • 编译时需消耗更多的 CPU 和内存资源,以及更长的耗时。

如何配置

通用配置分享

  • 适合预压缩的文件后缀:

    • 正则表达式形式:/\.(atom|rss|xml|xhtml|js|mjs|ts|html|json|css|eot|otf|ttf|svg|ico|bmp|dib|txt|text|log|md)$/
    • 可根据实际情况补充其他文件,例如:conf, ini, cfg。
  • 对应 MIME:application/atom+xml application/javascript application/json application/vnd.api+json application/rss+xml application/vnd.ms-fontobject application/x-font-opentype application/x-font-truetype application/x-font-ttf application/x-javascript application/xhtml+xml application/xml font/eot font/opentype font/otf font/truetype image/svg+xml image/vnd.microsoft.icon image/x-icon image/x-win-bitmap text/css text/javascript text/plain text/xml text/html

    • 根据文档,nginx 配置 gzip_types, brotli_types, zstd_types 时,均无需填写 text/html。不论 *_types是否包括text/htmltext/html 始终会被动态压缩。相关文档:gzip_typesbrotli_typeszstd_types

系统相关配置

在内存受限环境中使用较高压缩等级时,构建过程可能因内存不足被系统终止。
此时建议增加可用虚拟内存:​Windows 扩大虚拟内存(pagefile),​Linux 增加交换分区(swap)。

例如,在 GitHub Actions 的 ubuntu-latest公开仓库为 ​16GB 内存 + 4GB 交换分区​)中,可在 steps 开头增加以下步骤,额外创建 ​12GB 交换分区,以降低构建失败的风险:

- name: Add swap space
  run: |
    SWAP_FILE="/tmp/github-actions-swap-$$"
    MEMORY_LIMIT_GB=12
    # Add swap space to help with memory issues during build
    sudo fallocate -l ${MEMORY_LIMIT_GB}G "$SWAP_FILE"
    sudo chmod 600 "$SWAP_FILE"
    sudo mkswap "$SWAP_FILE"
    sudo swapon "$SWAP_FILE"
    echo "Added ${MEMORY_LIMIT_GB}GB swap at $SWAP_FILE"
    free -h

请根据项目实际规模调整交换分区的大小。

构建配置分享

  • Vite: 适用于 Vite 的配置
  • Rsbuild: 适用于 Rsbuild 的配置
  • webpack: 适用于 webpack 的配置

适用于 Vite 的配置

安装 vite-plugin-compression2 插件进行预压缩:

选择合适的安装方式:

npm install vite-plugin-compression2 -D
pnpm add vite-plugin-compression2 -D
yarn add vite-plugin-compression2 -D

安装完成后配置 vite.config.ts

// vite.config.ts
import { constants } from "node:zlib";
import { compression, defineAlgorithm } from "vite-plugin-compression2";

export default defineConfig({
  // ...
  plugins: [
    // ...
    compression({
      algorithms: [
        // 设置为最大压缩等级 9
        defineAlgorithm("gzip", { level: 9 }),
        // 设置为最大压缩等级 11
        defineAlgorithm("brotliCompress", {
          params: {
            [constants.BROTLI_PARAM_QUALITY]: 11,
          },
        }),
        // Zstandard 最大压缩等级为 22,但为符合 RFC 9659 规范,实际最大可用值为 19,以防止在 Chrome(v123+)和 Firefox(v126+)中报错
        // 详见 https://github.com/nonzzz/vite-plugin-compression/issues/93
        defineAlgorithm("zstandard", {
          params: {
            [constants.ZSTD_c_compressionLevel]: 19,
          },
        }),
      ],
      include: [
        // 可按需补充其他后缀
        /\.(atom|rss|xml|xhtml|js|mjs|ts|html|json|css|eot|otf|ttf|svg|ico|bmp|dib|txt|text|log|md|conf|ini|cfg)$/,
      ],
    }),
  ],
});

注意:此插件与 VitePress 兼容性不佳,会导致生成的 .js 预压缩文件中出现多余的 __VP_STATIC_START__ and __VP_STATIC_END__ 标记。

适用于 Rsbuild 的配置

安装 compression-webpack-plugin 插件进行预压缩:

选择合适的安装方式:

npm install compression-webpack-plugin -D
pnpm add compression-webpack-plugin -D
yarn add compression-webpack-plugin -D

安装完成后配置 rsbuild.config.ts

// rsbuild.config.ts
import { constants } from "node:zlib";
import CompressionPlugin from "compression-webpack-plugin";

export default defineConfig({
  // ...
  tools: {
    rspack: {
      plugins: [
        new CompressionPlugin({
          algorithm: "gzip",
          include:
            /\.(atom|rss|xml|xhtml|js|mjs|ts|html|json|css|eot|otf|ttf|svg|ico|bmp|dib|txt|text|log|md|conf|ini|cfg)$/,
          // 设置为最大压缩等级 9
          compressionOptions: { level: 9 },
          // minRatio 配置可参考文档:https://github.com/webpack/compression-webpack-plugin#minratio
          minRatio: Number.MAX_SAFE_INTEGER,
        }),
        new CompressionPlugin({
          algorithm: "brotliCompress",
          include:
            /\.(atom|rss|xml|xhtml|js|mjs|ts|html|json|css|eot|otf|ttf|svg|ico|bmp|dib|txt|text|log|md|conf|ini|cfg)$/,
          // 设置为最大压缩等级 11
          compressionOptions: {
            params: {
              [constants.BROTLI_PARAM_QUALITY]: 11,
            },
          },
          minRatio: Number.MAX_SAFE_INTEGER,
        }),
        new CompressionPlugin({
          // 必须,否则此插件会将文件命名为 [path][base].gz 与 gzip 冲突
          filename: "[path][base].zst",
          algorithm: "zstdCompress",
          include:
            /\.(atom|rss|xml|xhtml|js|mjs|ts|html|json|css|eot|otf|ttf|svg|ico|bmp|dib|txt|text|log|md|conf|ini|cfg)$/,
          // Zstandard 最大压缩等级为 22,但为符合 RFC 9659 规范,实际最大可用值为 19,以防止在 Chrome(v123+)和 Firefox(v126+)中报错
          // 详见 https://github.com/nonzzz/vite-plugin-compression/issues/93
          compressionOptions: {
            params: {
              [constants.ZSTD_c_compressionLevel]: 19,
            },
          },
          minRatio: Number.MAX_SAFE_INTEGER,
        }),
      ],
    },
  },
});

适用于 webpack 的配置

安装 compression-webpack-plugin 插件进行预压缩:

选择合适的安装方式:

npm install compression-webpack-plugin -D
pnpm add compression-webpack-plugin -D
yarn add compression-webpack-plugin -D

安装完成后配置 webpack.config.js

// webpack.config.js
const { constants } = require("zlib");
const CompressionPlugin = require("compression-webpack-plugin");

module.exports = {
  // ...
  plugins: [
    new CompressionPlugin({
      algorithm: "gzip",
      include:
        /\.(atom|rss|xml|xhtml|js|mjs|ts|html|json|css|eot|otf|ttf|svg|ico|bmp|dib|txt|text|log|md|conf|ini|cfg)$/,
      // 设置为最大压缩等级 9
      compressionOptions: { level: 9 },
      // minRatio 配置可参考文档:https://github.com/webpack/compression-webpack-plugin#minratio
      minRatio: Number.MAX_SAFE_INTEGER,
    }),
    new CompressionPlugin({
      algorithm: "brotliCompress",
      include:
        /\.(atom|rss|xml|xhtml|js|mjs|ts|html|json|css|eot|otf|ttf|svg|ico|bmp|dib|txt|text|log|md|conf|ini|cfg)$/,
      // 设置为最大压缩等级 11
      compressionOptions: {
        params: {
          [constants.BROTLI_PARAM_QUALITY]: 11,
        },
      },
      minRatio: Number.MAX_SAFE_INTEGER,
    }),
    new CompressionPlugin({
      // 必须,否则此插件会将文件命名为 [path][base].gz 与 gzip 冲突
      filename: "[path][base].zst",
      algorithm: "zstdCompress",
      include:
        /\.(atom|rss|xml|xhtml|js|mjs|ts|html|json|css|eot|otf|ttf|svg|ico|bmp|dib|txt|text|log|md|conf|ini|cfg)$/,
      // Zstandard 最大压缩等级为 22,但为符合 RFC 9659 规范,实际最大可用值为 19,以防止在 Chrome(v123+)和 Firefox(v126+)中报错
      // 详见 https://github.com/nonzzz/vite-plugin-compression/issues/93
      compressionOptions: {
        params: {
          [constants.ZSTD_c_compressionLevel]: 19,
        },
      },
      minRatio: Number.MAX_SAFE_INTEGER,
    }),
  ],
};

部署配置分享

  • nginx: 在 nginx 上使用
  • Apache: 在 Apache 上使用
  • Halo CMS: 在 Halo CMS 上使用

在 nginx 上使用

http {
    # nginx 会根据 Accept-Encoding 决定提供哪种格式的文件,因此不同算法配置顺序不影响结果。

    # 启用 gzip_static 模块以提供预压缩的 .gz 文件
    gzip_static on;

    # 如果找不到静态文件则回退到动态压缩
    gzip on;
    gzip_types application/atom+xml application/javascript application/json application/vnd.api+json application/rss+xml application/vnd.ms-fontobject application/x-font-opentype application/x-font-truetype application/x-font-ttf application/x-javascript application/xhtml+xml application/xml font/eot font/opentype font/otf font/truetype image/svg+xml image/vnd.microsoft.icon image/x-icon image/x-win-bitmap text/css text/javascript text/plain text/xml;
    # 用于在 HTTP 响应头中添加 Vary: Accept-Encoding 字段
    gzip_vary on;
    # 让 nginx 也动态压缩反向代理的内容
    gzip_proxied expired no-cache no-store private auth;

    # 启用 brotli_static 以提供预压缩的 .br 文件
    # 需要 ngx_brotli 模块: https://github.com/google/ngx_brotli
    # 如果你使用 1Panel 面板:
    #     可前往 /websites 页面,点击设置->模块->启用 ngx_brotli->构建,即可启用。
    brotli_static on;

    # 如果找不到静态文件则回退到动态压缩
    brotli on;
    brotli_types application/atom+xml application/javascript application/json application/vnd.api+json application/rss+xml application/vnd.ms-fontobject application/x-font-opentype application/x-font-truetype application/x-font-ttf application/x-javascript application/xhtml+xml application/xml font/eot font/opentype font/otf font/truetype image/svg+xml image/vnd.microsoft.icon image/x-icon image/x-win-bitmap text/css text/javascript text/plain text/xml;

    # 启用 zstd_static 以提供预压缩的 .zst 文件
    # 需要 zstd-nginx-module 模块: https://github.com/tokers/zstd-nginx-module
    zstd_static on;

    # 如果找不到静态文件则回退到动态压缩
    zstd on;
    zstd_types application/atom+xml application/javascript application/json application/vnd.api+json application/rss+xml application/vnd.ms-fontobject application/x-font-opentype application/x-font-truetype application/x-font-ttf application/x-javascript application/xhtml+xml application/xml font/eot font/opentype font/otf font/truetype image/svg+xml image/vnd.microsoft.icon image/x-icon image/x-win-bitmap text/css text/javascript text/plain text/xml;

    server {
        # 其他配置
        listen 80;
        server_name example.com;
        root /var/www/html;

        location / {
            try_files $uri $uri/ /index.html;
        }
    }
}

在 Apache 上使用

# 启用 mod_deflate 以实现回退动态压缩
<IfModule mod_deflate.c>
    AddOutputFilterByType DEFLATE application/atom+xml application/javascript application/json application/vnd.api+json application/rss+xml application/vnd.ms-fontobject application/x-font-opentype application/x-font-truetype application/x-font-ttf application/x-javascript application/xhtml+xml application/xml font/eot font/opentype font/otf font/truetype image/svg+xml image/vnd.microsoft.icon image/x-icon image/x-win-bitmap text/css text/javascript text/plain text/xml
</IfModule>

# 提供预压缩文件
<IfModule mod_rewrite.c>
    RewriteEngine On

    # 如果存在 .zst 文件且客户端支持 zstd,则提供该文件
    RewriteCond %{HTTP:Accept-Encoding} zstd
    RewriteCond %{REQUEST_FILENAME}.zst -f
    RewriteRule ^(.*)$ $1.zst [L]

    # 如果存在 .br 文件且客户端支持 brotli,则提供该文件
    RewriteCond %{HTTP:Accept-Encoding} br
    RewriteCond %{REQUEST_FILENAME}.br -f
    RewriteRule ^(.*)$ $1.br [L]

    # 如果存在 .gz 文件且客户端支持 gzip,则提供该文件
    RewriteCond %{HTTP:Accept-Encoding} gzip
    RewriteCond %{REQUEST_FILENAME}.gz -f
    RewriteRule ^(.*)$ $1.gz [L]
</IfModule>

# 设置正确的 content-type 和 encoding headers
<FilesMatch "\.js\.gz$">
    Header set Content-Type "application/javascript"
    Header set Content-Encoding "gzip"
</FilesMatch>

<FilesMatch "\.css\.gz$">
    Header set Content-Type "text/css"
    Header set Content-Encoding "gzip"
</FilesMatch>

<FilesMatch "\.js\.br$">
    Header set Content-Type "application/javascript"
    Header set Content-Encoding "br"
</FilesMatch>

<FilesMatch "\.css\.br$">
    Header set Content-Type "text/css"
    Header set Content-Encoding "br"
</FilesMatch>

<FilesMatch "\.js\.zst$">
    Header set Content-Type "application/javascript"
    Header set Content-Encoding "zstd"
</FilesMatch>

<FilesMatch "\.css\.zst$">
    Header set Content-Type "text/css"
    Header set Content-Encoding "zstd"
</FilesMatch>

在 Halo CMS 上使用

经检查,Halo CMS v2.22.14 会自动采用 .br 文件,但不会自动采用 .zst 文件。

如何确定生效

  1. 确定你的浏览器支持所选择的协议:gzipbrotlizstd
  2. 打开浏览器的开发者工具。
  3. 选择“网络”(Network)分页。
  4. 刷新网页,点击你要检查的文件(比如 .js 后缀的文件)
  5. 查看标头(Headers),找到 Content-Encoding,如果是 br, gzip, zstd,说明正确采用了对应的压缩算法传输。

注意:在 114 版本 Edge 上测试,发现在 https 站点/127.0.0.1 的情况下 Accept-Encodinggzip, deflate, br, zstd。而在 http 站点上 Accept-Encodinggzip, deflate
结论:想要使用 brotli 和 zstandard 算法的预压缩文件,需要先给站点配置 https。

后记

欢迎留言交流。

更新记录:

  • 20260312 修改了 Zstd 相关配置,并补充相关说明
  • 20260302 补充了系统相关配置
  • 20260213 补充了 Rsbuild 和 webpack 配置

鸣谢

文章分享的 MIME 配置参考了 google/ngx_brotli,再反向推断出后文件后缀。
文章分享的 Apache 和 nginx 配置是由 nonzzz/vite-plugin-compression 修改而来。

相关文章分享