中文 | English
一个用于压缩 Askama 模板文件的 CLI 工具。支持压缩单个文件或批量处理整个文件夹,提供专业级的 CSS 和 JavaScript 优化。
开发历程可以参考博客 手写一个 Askama 模板压缩工具
- 🗜️ 压缩 HTML、HTM、XML、SVG 文件
- 🎯 完美保留 Askama 模板语法(
{{ }}和{% %}) - ⚡ 专业级 CSS 优化:使用 lightningcss 进行属性合并、颜色优化、规则简化
- 🛡️ 智能 JavaScript 压缩:自定义压缩器,安全处理所有语法
- 📝 全面的注释移除:
- HTML 注释 (
<!-- -->) - CSS 注释 (
/* */) - JavaScript 单行注释 (
//) - JavaScript 多行注释 (
/* */)
- HTML 注释 (
- 🔒 智能边缘情况处理:
- 保护字符串中的注释语法(如
"<!-- not a comment -->") - 正确处理除法运算符 (
/) - 正确处理比较和位运算符 (
>,>>,>=,<<) - 正确处理转义字符(
"test\\",'quote\\') - 保护 URL 中的特殊字符
- 保护正则表达式
- 保护字符串中的注释语法(如
- 📦 保护特殊标签内容(
<pre>,<textarea>) - 📂 支持单文件或文件夹批量处理
- 🔄 递归处理子文件夹
- ⚙️ 自定义输出路径和文件后缀名
- 📊 高压缩率:通常可达 40-55%
# 克隆仓库
git clone https://github.com/wsafight/askama-minify.git
cd askama-minify
# 编译
cargo build --release编译后的二进制文件位于 target/release/askama-minify
# 压缩单个文件
./target/release/askama-minify template.html
# 压缩整个文件夹
./target/release/askama-minify templates/| 选项 | 简写 | 说明 | 默认值 |
|---|---|---|---|
--output <PATH> |
-d |
输出文件或文件夹路径 | 原路径 |
--suffix <SUFFIX> |
-s |
输出文件后缀名 | min |
--recursive |
-r |
递归处理子文件夹 | true |
--help |
-h |
显示帮助信息 | - |
--version |
-V |
显示版本信息 | - |
| 配置 | 结果 | 示例 |
|---|---|---|
无 -d 无 -s |
默认后缀 min |
file.html → file.min.html |
无 -d 有 -s |
自定义后缀 | file.html + -s prod → file.prod.html |
有 -d 无 -s |
不添加后缀 | file.html + -d out.html → out.html |
有 -d 有 -s |
后缀 + 自定义路径 | file.html + -d out/ + -s prod → out/file.prod.html |
基础压缩
# 生成 template.min.html
askama-minify template.html
# 输出:
# ✓ 已压缩: template.html -> template.min.html (1872 → 866 bytes, -53%)自定义后缀
# 生成 template.compressed.html
askama-minify -s compressed template.html指定输出路径
# 不添加后缀
askama-minify -d output.html template.html
# 输出到其他目录并添加后缀
askama-minify -d dist/ -s prod template.html批量处理文件夹
# 压缩整个文件夹(递归)
askama-minify templates/
# 输出到指定目录(保持目录结构)
askama-minify -d dist/ templates/
# 不递归处理子文件夹
askama-minify --recursive=false templates/| 扩展名 | 支持 | 说明 |
|---|---|---|
.html |
✅ | HTML 文件 |
.htm |
✅ | HTML 文件(旧扩展名) |
.xml |
✅ | XML 文件 |
.svg |
✅ | SVG 图像文件 |
注意:自动跳过已压缩的文件(例如 .min.html)
┌─────────────────────────────────────────────┐
│ 输入: template.html │
└─────────────────┬───────────────────────────┘
│
┌─────────────┴──────────────┐
│ HTML 层压缩 │
│ • 移除注释和多余空格 │
│ • 保留模板语法 │
│ • 提取 CSS/JS 内容 │
└─────────────┬──────────────┘
│
┌─────────────┴──────────────┐
│ CSS 层压缩 (lightningcss)│
│ • 属性合并和优化 │
│ • 颜色简化 │
│ • 规则去重 │
└─────────────┬──────────────┘
│
┌─────────────┴──────────────┐
│ JS 层压缩 (自定义) │
│ • 移除注释和空白 │
│ • 保护字符串内容 │
│ • 正确处理转义 │
└─────────────┬──────────────┘
│
┌─────────────┴──────────────┐
│ 输出: template.min.html │
│ 压缩率: 40-55% │
└─────────────────────────────┘
| 类型 | 贡献率 | 示例 |
|---|---|---|
| CSS 优化 | 20-30% | margin-top: 0; margin-bottom: 0; → margin:0 0 |
| JS 压缩 | 15-25% | 移除注释和空白 |
| HTML 压缩 | 10-15% | 移除换行和缩进 |
| 注释移除 | 5-10% | 取决于注释密度 |
| 总计 | 40-55% | 典型场景 |
- ✅ 完全保留模板语法(
{{ }}和{% %}) - ✅ 保留所有属性引号
- ✅ 移除多余空白字符
- ✅ 移除 HTML 注释(
<!-- -->) - ✅ 保护特殊标签(
<pre>,<textarea>) - ✅ 支持 UTF-8 中文和特殊字符
- ✅ 属性合并:
margin-top: 0; margin-bottom: 0;→margin: 0 0 - ✅ 颜色优化:
#ff0000→red,rgb(255,0,0)→red - ✅ 值简化:
0px→0,0.5→.5 - ✅ 规则简化:移除重复规则,合并相同选择器
- ✅ 紧凑输出:移除所有空格和换行
- ✅ 注释移除:单行 (
//) 和多行 (/* */) - ✅ 空白压缩:换行、缩进、多余空格
- ✅ 智能字符串:识别单引号、双引号、模板字面量
- ✅ 转义处理:正确处理
"test\\",'quote\\'等 - ✅ 运算符保护:
/,>,>>,>=,<<等 - ✅ 安全可靠:不破坏任何代码逻辑
| 特性 | Askama Minify | html-minifier | minify-html |
|---|---|---|---|
| 模板语法保留 | ✅ 完美 | ❌ 可能破坏 | ❌ 可能破坏 |
| CSS 专业优化 | ✅ lightningcss | ||
| JS 安全压缩 | ✅ 自定义 | ❌ 不支持 | |
| 转义字符处理 | ✅ 正确 | ❌ 有bug | - |
| 压缩率 | 40-55% | 30-40% | 20-30% |
| Rust 编写 | ✅ | ❌ | ✅ |
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>{{ title }}</title>
<!-- 这是注释 -->
<style>
body {
margin: 0;
padding: 20px;
background-color: #f0f0f0;
}
</style>
</head>
<body>
<h1>{{ heading }}</h1>
{% for item in items %}
<p>{{ item.name }}</p>
{% endfor %}
<script>
// 这是注释
console.log("Hello");
</script>
</body>
</html><!doctype html><html lang=zh-CN><meta charset=UTF-8><title>{{ title }}</title><style>body{background-color:#f0f0f0;margin:0;padding:20px}</style><body><h1>{{ heading }}</h1>{% for item in items %} <p>{{ item.name }}</p>{% endfor %}<script>console.log("Hello");</script>✅ 模板语法:{{ title }}, {% for %} 完整保留
✅ 字符串内容:"Hello" 保持不变
✅ 注释移除:HTML 和 JS 注释已删除
✅ CSS 优化:颜色和属性已优化
✅ 功能完整:所有逻辑保持不变
./test.sh- ✅ 默认行为(生成
.min.html) - ✅ 自定义后缀
- ✅ 指定输出文件
- ✅ 文件夹批量压缩
- ✅ 递归子目录处理
- ✅ 输出到指定目录
- ✅ 压缩效果验证(40-55%)
- ✅ 模板语法保留
- ✅ 注释移除和边缘情况
- ✅ 运算符正确处理(
/,>,>>) - ✅ 转义字符处理(
"test\\",'quote\\')
========================================
Askama Minify v0.2.1 测试脚本
========================================
[1/11] 编译项目...
✓ 编译完成
[2/11] 测试场景 1: 默认行为
✓ 已压缩: example.html -> example.min.html (1872 → 866 bytes, -53%)
✓ 生成了 example.min.html
...
========================================
所有测试通过! ✓
========================================| 技术 | 版本 | 用途 |
|---|---|---|
| Rust | Edition 2024 | 核心语言 |
| clap | 4.5 | 命令行参数解析 |
| lightningcss | 1.0.0-alpha.68 | 专业 CSS 解析和优化 |
| walkdir | 2.5 | 文件系统遍历 |
- Rust Edition 2024:升级到最新的 Rust Edition 2024(2025年2月发布)
- 利用最新语言特性和编译器优化
- 更好的类型推断和错误提示
- 提取重复代码,遵循 DRY 原则
- 添加常量定义(
DEFAULT_SUFFIX,MIN_MARKER,VALID_EXTENSIONS) - 优化文件扩展名比较(使用
eq_ignore_ascii_case避免字符串分配) - 改进错误处理(
generate_output_path返回Result) - 函数拆分和模块化
- 修复 JavaScript 转义字符处理 bug(正确处理
"test\\",'quote\\'等) - 修复字符串中注释语法被误删的问题
- CSS 压缩失败时输出警告信息
- 空文件处理优化
- 统计失败文件数并在输出中显示
- 改进输出信息格式(显示文件大小和压缩率)
- 新增转义字符处理测试(场景 11)
- 11 个测试场景全部通过
- 测试覆盖率提升
- 压缩率:40-55%
- 代码行数:1,344 行(含测试和文档)
- 完整的 HTML/CSS/JS 压缩支持
- 完美保留 Askama 模板语法
- 智能注释移除(HTML、CSS、JS)
- 边缘情况保护(字符串、运算符、正则表达式)
- 自定义 JavaScript 压缩器(替代有 bug 的第三方库)
- 10 个测试场景全部通过
Q: 会破坏 Askama 模板语法吗?
A: 不会。这是本工具的核心设计目标。所有 Askama 模板语法({{ }}、{% %} 等)都会被完整保留,已经过充分测试。
Q: 压缩后的文件还能正常工作吗?
A: 可以。工具只移除不影响功能的空白和注释,不会改变任何逻辑。所有测试都验证了压缩后文件的功能完整性。
Q: 支持中文和其他 Unicode 字符吗?
A: 完全支持。工具正确处理所有 UTF-8 编码的文本,包括中文、日文、表情符号等。
Q: 为什么不用 html-minifier 或其他工具?
A: 通用 HTML 压缩器不了解模板语法,可能会破坏 {% if %} 等结构。本工具专为 Askama 设计,确保 100% 兼容。
Q: 压缩速度如何?
A: 非常快。Rust 编写,性能优秀。处理 100 个模板文件通常只需几秒钟。
Q: 可以集成到构建流程吗?
A: 可以。你可以在 build.rs 或 CI/CD 流程中调用命令行工具。示例:
# 在构建脚本中
./target/release/askama-minify -d dist/ -s prod templates/欢迎贡献!请遵循以下步骤:
- Fork 本仓库
- 创建特性分支(
git checkout -b feature/AmazingFeature) - 提交更改(
git commit -m 'Add some AmazingFeature') - 推送到分支(
git push origin feature/AmazingFeature) - 开启 Pull Request
# 克隆仓库
git clone https://github.com/wsafight/askama-minify.git
cd askama-minify
# 安装依赖并编译
cargo build
# 运行测试
cargo test
./test.sh
# 检查代码风格
cargo fmt --check
cargo clippy- lightningcss - 出色的 CSS 解析和优化工具
- clap - 强大的命令行参数解析库
- Askama - 灵感来源
Made with ❤️ and 🦀 Rust