魄柜
昨天 15:00
简介
都昌电子病历编辑器(DCwriter)是我司的核心产品。2023 年发布的基于 WASM+Canvas 的 DCWriter 5.0 已成功上线数千家医院,但其依赖资源较大的问题受到用户反馈。为解决这一问题,我们深入优化并研究出了 Blazor WASM 程序打包器。
Blazor WASM 程序打包器能将 Blazor WebAssembly 所有的程序文件(包括 .js、.wasm、.dll、.json 等)经 GZIP 压缩打包成单个 JS 文件,大幅简化部署流程并优化应用加载性能,而且能让 Blazor WASM 实现跨域调用。
目前市面上未发现有类似功能的工具,因此笔者自行开发了这个实用工具。
工具亮点
使用简单
本软件只有一个 BlazorWASMPackager.html 文件,BlazorWASMPackager-en.html 为其英文版本。将 HTML 文件直接放置在 Blazor WebAssembly 程序发布后的根目录下(一般为 wwwroot 目录),用主流浏览器打开即可使用,不依赖任何第三方软件。
核心特性
- 提供可视化进度反馈和详细处理日志
- 支持自定义输出文件名和脚本合并规则
突破跨域与本地运行限制
- 解决传统 Blazor WASM 应用的跨域资源调用问题(CORS),通过资源内嵌避免跨域请求
- 支持直接从本地文件系统启动应用(file:// 协议),无需依赖 Web 服务器
- 适用于离线场景或本地演示环境,无需配置服务器跨域策略
简化部署流程
- 将数十甚至上百个分散的资源文件合并为单个 JS 文件,减少部署文件数量
- 简化软件文件部署、网络缓存、版本升级和回滚等工作
- 降低多文件传输时的网络请求开销
- 减少网络防火墙或代理对多文件请求的限制风险
提升加载性能
- 对所有资源进行最大级别 GZIP 压缩,显著减小传输体积
- 减少 HTTP 请求次数,降低网络延迟影响
- 支持自定义脚本精简,移除冗余代码
增强部署灵活性
- 生成的单一文件可轻松集成到各种静态资源托管服务
- 支持微前端架构(MicroApp / QianKun)的环境适配
- 便于版本管理和缓存策略实施
我是如何开发这个软件的?
本工具借助于豆包 AI(https://www.doubao.com)开发完成。首先,笔者使用了以下提示词逐步创建 HTML 文件的主体:
- 生成一个HTML页面,包含JS代码,实现以下功能:
- 解析当前路径下的 _framework/blazor.boot.json 文件,解析其中的 resources/runtime|assembly|runtimeAssets|pdb 节点下的属性名
- 以这个属性名来当做文件名,然后下载这些文件,获得二进制内容,使用GZIP压缩,然后转换为base64字符串。base64字符串换行,每行128个字符
- 创建一个新字符串,采用JavaScript格式。然后定义 window.__DCFileContents = {"文件名":"base64字符串"}
- 界面上提供一个"下载"按钮,以js的minitype加载生成的js字符串
- 不要使用pako,直接使用浏览器内置的GZIP模块
- 这是一个blazor wasm的程序打包器,修改HTML的文字说明
- base64字符串不能太长,128个字符就自动换行,而且输出文本时自动追加显示在最下面。每次生成前先清空调试输出文本的界面,然后调试输出文本开始追加显示
- 不要输出base64的内容预览,去掉当前的调试文本,只保留下方的调试文本追加方式输出
- 调试输出文本框宽度为100%,下方添加一个进度条。中间的status元素去掉
- 调试输出文本框有个初始化的固定宽度,进度条中间显示进度文本提示信息。添加版权信息"南京都昌信息科技有限公司版权所有"
- 修改 uint8ArrayToBase64(),在这里每32个字节进行一次转换,然后添加换行回车符,在这里面直接生成带换行的BASE64字符串,进度条文本左对齐
- uint8ArrayToBase64() 里面,每组字节是129个,避免base64转换长度不匹配
- 不要使用json中间格式转换,直接拼接生成JS字符串
- 对于base64字符串输出采用 格式,避免 \n 转义字符,JS中直接输出换行的BASE64字符串
- 这里的字节长度都格式化输出,按照大小输出KB,MB单位。精确到小数点后2位。打包时把 blazor.boot.json也包含进去。GZIP采用最大压缩比率。总结报告中添加手动点击下载链接。处理完成后进度条重置。进度条颜色调整一下,蓝色背景黑字看不清楚
- 生成的JS文件名采用 blazor.boot.json 下面的 entryAssembly 数值加上 ".published.js" 后缀
- 不能跳过hash为空的文件,要无条件处理所有的文件
- 放一个多行文本框,让用户输入几个JS文件名,然后打包时,将_framework目录下这些JS文件读取出来,合并成一个Merge.js,并参与打包。如果用户未指定,则不生成Merge.js
- boot.json里面列出的js是要强制打包的,不是合并到merge.js中。文本框中是让用户输入自定义脚本.js文件名。另外最终生成的js文件第一行要显示当前日期和时间
- 添加一个勾选框,让用户选择是否删除merge.js中的注释和无意义的空格
- 放一个单行文本框,用于输入自定义的最终JS文件名,如果为空则采用默认的文件名
- 简化调试输出文本,默认不精简merge.js空格和注释。要确保merge.js精简结果是正确的
- JS中的字符串要考虑到 这种多行字符串,还有JS代码中会出现正则表达式,也不能破坏掉
通过 AI 创建了初步版本后,笔者手动进行了后续的修改和优化,最终形成了现在的版本。
代码执行过程
初始化阶段
页面加载准备
- 初始化 DOM 元素引用(进度条、日志区、按钮等交互组件)
- 重置进度条状态为"准备就绪"(0%)
- 清空日志输出区域
- 禁用下载按钮防止重复点击
用户参数收集
- 读取输出文件名输入框内容(为空时将使用默认命名规则)
- 解析自定义 JS 文件列表(每行一个路径,相对 _framework 目录)
- 检查"精简自定义脚本"复选框状态(决定是否移除注释和冗余空格)
核心处理流程
浏览器兼容性验证
检测当前浏览器是否支持 CompressionStream API(用于 GZIP 压缩)。不支持时终止流程并提示:"请使用最新版 Chrome、Edge 或 Firefox 浏览器"。
解析应用配置文件
下载配置文件:
- 发送请求获取 _framework/blazor.boot.json(Blazor 应用的核心配置)
- 记录配置文件原始大小并计入总统计
- 下载失败(如 404 错误)时终止流程,日志显示具体错误信息
解析配置内容:
- 解析 JSON 格式的配置数据
- 提取 resources 字段中所有资源路径(包括 runtime、assembly、jsModule 等类型)
- 提取 entryAssembly 值(用于生成默认输出文件名)
- 进度条更新至 10%,日志显示"配置文件解析完成"
处理核心资源文件
任务准备:
- 收集需处理的资源文件列表(包含 blazor.webassembly.js 等核心文件)
- 根据文件数量计算单个文件的进度占比(总进度 75% 平分)
逐个处理资源:
循环处理每个资源文件:
- 构造完整 URL:_framework/[文件名]
- 下载文件并转换为 Uint8Array 格式
- 记录原始文件大小(累加至总原始大小)
- 使用 gzipCompress() 函数进行最大级别(level:9)压缩
- 将压缩后的数据转换为 Base64 编码(按 129 字节分块处理)
- 生成包含文件名和 Base64 内容的条目
- 实时更新进度条(如"处理 3/20:dotnet.wasm")
- 单个文件处理失败时记录日志并跳过(不终止整体流程)
处理自定义 JS 文件(可选)
输入解析:
- 过滤空行和无效路径,获取有效自定义 JS 文件列表
- 列表为空时日志显示"未指定自定义 JS 文件,不生成 Merge.js"并跳过
合并与处理:
逐个下载指定的自定义 JS 文件:
- 记录每个文件原始大小
- 启用精简时使用 minifyJs() 处理(保留模板字符串和正则表达式)
- 合并内容(添加来源注释,除非启用精简)
- 对合并内容进行 GZIP 压缩并转换为 Base64 编码
- 生成 Merge.js 条目并添加到资源列表
生成输出文件
内容构建:
- 首行添加生成时间注释(格式:// Generated on: YYYY-MM-DD HH:MM:SS)
- 创建包含所有资源的 JavaScript 对象(键为文件名,值为 Base64 内容)
- 生成自执行函数,包含:
- 资源解压逻辑(使用 DecompressionStream 处理 GZIP 数据)
- Blazor 启动配置(覆盖 loadBootResource 方法注入本地资源)
- 临时 URL 清理逻辑(释放内存占用)
文件名处理:
- 优先使用用户指定文件名(需包含 .js 扩展名)
- 未指定时使用规则:[entryAssembly].published.js
- 无 entryAssembly 时默认使用 blazor-resources.published.js
生成下载链接
统计信息计算:
- 原始总大小:所有资源+配置文件+自定义脚本的原始大小总和
- 生成文件大小:最终 JS 文件的 UTF-8 编码字节数
- 压缩比率:(生成文件大小 / 原始总大小) × 100%
创建下载:
- 将 JS 内容转换为 Blob 对象(MIME 类型:application/javascript)
- 生成临时下载 URL(URL.createObjectURL)
- 自动触发下载并显示总结报告(含大小统计和压缩比率)
- 提供手动下载链接(应对自动下载失败场景)
异常处理与优化
错误处理机制:
- 单个资源下载失败:记录日志并跳过(继续处理其他文件)
- 关键文件(如 blazor.boot.json)失败:终止流程并显示错误
- 页面卸载时清理临时资源链接(URL.revokeObjectURL)
性能优化细节:
- 大文件采用流式压缩,降低内存占用
- Base64 编码分块处理,避免单行过长
- 针对 .NET 8/9 版本的 runtime 做适配处理
- 自定义 JS 精简保留关键语法结构(模板字符串、正则表达式)
版权声明
本软件版权归南京都昌信息科技有限公司所有。
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |
|
|
|
|
|
相关推荐
|
|
|