一、一个让我决定开发工具的需求
上个月接了一个政务系统的项目,技术方案评审会上,客户方的技术负责人提出了一个要求:
"你们的系统要部署在我们的内网环境,完全隔离外网。所有外部依赖必须本地化。"
我看了看我们的前端代码,心里一凉:
Vue 3 从 CDN 引入
Element Plus 从 CDN 引入
十几个工具库都是 CDN 链接
字体文件来自 Google Fonts
这要一个个手动下载、改路径,至少得两天时间。更关键的是,这种需求肯定会反复出现。
作为一个追求效率的开发者,我当晚就开始思考:为什么不开发一个工具,彻底解决这类问题?
二、需求分析与技术调研
在动手之前,我花了两天时间做调研,发现这个需求非常普遍:
典型场景
金融行业
禁止任何外部请求
资源必须通过安全审计
版本需要完全可控
政府机构
内网与外网物理隔离
所有依赖需要报备
源码和资源归档留存
大型企业
限制外网访问
代理配置复杂
统一资源管理
教育培训
课件离线分发
不依赖网络环境
保证资源完整性
现有方案的痛点
我调研了几个可能的方案:
结论:市场上缺少一个专门针对 HTML 资源离线化的轻量级工具。
三、工具设计与实现
核心功能定位
我决定开发 HTML Assets Localizer,专注解决一个问题:
自动将 HTML 文件中的外部 JavaScript 和 CSS 资源下载到本地,并更新引用路径。
功能特性:
🔍 自动扫描 HTML 中的
<script>和<link>标签📥 批量下载外部资源到本地
📂 规范化目录结构(
js/和css/文件夹)✏️ 自动重写 HTML 引用路径
🎯 重名文件自动添加数字后缀避免冲突
技术选型
为了实现跨平台和易用性,我提供了双语言实现:
Node.js 版本
TypeScript 开发,类型安全
支持 pnpm/npm/yarn 安装
提供 CLI 和 UI 两种模式
Python 版本
纯 Python 实现
简单易懂,易于定制
适合 Python 生态集成
实现架构
HTML文件输入
↓
解析HTML,提取外部资源URL
↓
并发下载资源到本地目录
↓
更新HTML中的引用路径
↓
输出离线化的HTML + 资源包
四、CLI 命令行工具
全局安装
# 使用 pnpm(推荐)
pnpm add -g html-assets-localizer
# 使用 npm
npm install -g html-assets-localizer
# 使用 yarn
yarn global add html-assets-localizer
基础使用
安装后可以使用 html-assets-localizer 或简写 hal:
# 基础命令
hal <html-file> <output-dir>
# 实际示例
hal index.html ./offline-bundle
执行后工具会:
在
offline-bundle目录创建js/和css/文件夹下载所有外部 JS 和 CSS 资源
生成更新后的 HTML 文件
打印资源处理摘要
其他命令
# 查看帮助
hal help
# 查看版本
hal version
五、UI 可视化界面
考虑到团队协作,我开发了一个 Web UI,让不熟悉命令行的同事也能使用:
hal ui
UI 功能特性
📤 拖拽上传:直接拖拽 HTML 文件
📊 实时进度:显示下载进度和状态
📋 详细日志:查看每个资源的处理情况
💾 一键下载:处理完成后直接下载压缩包
自定义配置
# 指定端口和主机
hal ui --port 4173 --host 0.0.0.0
# 禁止自动打开浏览器
hal ui --no-open
这样团队成员可以通过局域网访问,产品经理和设计师也能自己处理离线化需求。
六、程序化 API 调用
除了 CLI 和 UI,我还提供了编程接口,方便集成到构建流程:
import { HtmlAssetsLocalizer } from 'html-assets-localizer';
const localizer = new HtmlAssetsLocalizer({
htmlFilePath: './example.html',
targetDir: './offline',
});
const summary = await localizer.process();
console.log(summary.assets);
集成到 CI/CD
// build-offline.js
import { HtmlAssetsLocalizer } from 'html-assets-localizer';
import * as path from 'path';
async function buildOfflineVersion() {
const files = ['index.html', 'dashboard.html', 'settings.html'];
for (const file of files) {
console.log(`📦 处理: ${file}`);
const localizer = new HtmlAssetsLocalizer({
htmlFilePath: path.join('./dist', file),
targetDir: path.join('./dist/offline', path.dirname(file)),
});
await localizer.process();
}
console.log('✅ 离线包构建完成!');
}
buildOfflineVersion();
现在每次发布都会自动生成离线版本。
七、从源码构建
如果你想从源码构建或参与开发:
# 克隆仓库
git clone https://github.com/YangsonHung/html-assets-localizer.git
cd html-assets-localizer
# 安装依赖
pnpm install
# 构建 TypeScript
pnpm run build
# 本地测试
node dist/cli.js example.html offline-bundle
构建完成后,dist/ 目录会包含编译后的代码。
八、实战效果
回到项目场景,使用这个工具后:
$ hal src/index.html dist/offline
Processing: src/index.html
Downloading assets...
✅ vue.global.js (487KB)
✅ element-plus.css (234KB)
✅ element-plus.js (678KB)
✅ axios.min.js (32KB)
Complete!
📦 Total assets: 12
💾 Total size: 1.52MB
📁 Output: dist/offline
效率对比
实际收益
⏱️ 时间节省:从平均 2 天降到 10 分钟
✅ 质量提升:自动化处理,零遗漏
🔄 可重复:标准化流程,任何人都能操作
📦 易维护:版本更新只需重新运行命令
九、最佳实践与技巧
1. 文件组织
建议的项目结构:
project/
├── src/
│ └── index.html # 开发版(CDN引用)
├── dist/
│ ├── online/ # 线上版本
│ │ └── index.html
│ └── offline/ # 离线版本
│ ├── index.html
│ ├── js/
│ └── css/
└── scripts/
└── build-offline.js # 自动化脚本
2. 重名文件处理
工具会自动处理同名文件冲突:
jquery.min.js
jquery.min-1.js
jquery.min-2.js
3. 网络优化建议
保持稳定的网络连接
国外 CDN 可考虑使用代理
大型项目可分批处理
4. 验证完整性
处理完成后建议本地测试:
# 启动本地服务器
cd dist/offline
python -m http.server 8000
# 访问 http://localhost:8000 测试
十、开源与社区
项目信息
开源协议:MIT License(可商用)
项目主页:主页地址
语言支持:英文 + 中文文档(README.zh.md)
双语言实现
项目提供了两种实现:
Node.js 版本:功能完整,提供 CLI + UI + API
Python 版本:简单实用,易于定制
可以根据技术栈选择合适的版本。
参与贡献
欢迎:
🐛 提交 Bug 报告
💡 提出功能建议
🔧 提交 Pull Request
⭐ GitHub Star 支持
十一、开发心得
1. 解决真实痛点
这个工具的诞生源于真实需求。好的工具不一定要复杂,但一定要解决实际问题。
2. 用户体验优先
提供多种使用方式:
CLI:适合开发者和自动化
UI:适合非技术人员
API:适合程序化集成
3. 保持专注
不追求大而全,专注做好一件事:HTML 资源离线化。这让工具保持简单、可靠、易用。
4. 开源的价值
开源让工具获得了:
更多用户的实际反馈
社区贡献的代码和想法
持续改进的动力
5. 文档的重要性
详细的文档(README.md + README.zh.md)让不同语言背景的用户都能快速上手。
写在最后
作为开发者,当我们遇到重复性工作时,应该思考:这能自动化吗?能做成工具吗?能帮助到更多人吗?
html-assets-localizer 就是这样诞生的。从解决自己的问题开始,到开源分享帮助更多人,这个过程让我深刻体会到了技术的价值。
如果你也有内网部署或离线化的需求,欢迎试用这个工具。
如果这篇文章对你有启发,欢迎点赞收藏!期待在评论区看到你的想法,或者到 GitHub 提 Issue 交流~