Blazor WASM 程序打包器【都昌電子病歷編輯器最新特性】
簡介
都昌電子病歷編輯器(DCwriter)是我司的核心產(chǎn)品。2023 年發(fā)布的基于 WASM+Canvas 的 DCWriter 5.0 已成功上線數(shù)千家醫(yī)院,但其依賴資源較大的問題受到用戶反饋。為解決這一問題,我們深入優(yōu)化并研究出了 Blazor WASM 程序打包器。
Blazor WASM 程序打包器能將 Blazor WebAssembly 所有的程序文件(包括 .js、.wasm、.dll、.json 等)經(jīng) GZIP 壓縮打包成單個 JS 文件,大幅簡化部署流程并優(yōu)化應用加載性能,而且能讓 Blazor WASM 實現(xiàn)跨域調(diào)用。
目前市面上未發(fā)現(xiàn)有類似功能的工具,因此筆者自行開發(fā)了這個實用工具。
工具亮點
使用簡單
本軟件只有一個 BlazorWASMPackager.html 文件,BlazorWASMPackager-en.html 為其英文版本。將 HTML 文件直接放置在 Blazor WebAssembly 程序發(fā)布后的根目錄下(一般為 wwwroot 目錄),用主流瀏覽器打開即可使用,不依賴任何第三方軟件。
核心特性
- 提供可視化進度反饋和詳細處理日志
- 支持自定義輸出文件名和腳本合并規(guī)則
突破跨域與本地運行限制
- 解決傳統(tǒng) Blazor WASM 應用的跨域資源調(diào)用問題(CORS),通過資源內(nèi)嵌避免跨域請求
- 支持直接從本地文件系統(tǒng)啟動應用(
file://協(xié)議),無需依賴 Web 服務(wù)器 - 適用于離線場景或本地演示環(huán)境,無需配置服務(wù)器跨域策略
簡化部署流程
- 將數(shù)十甚至上百個分散的資源文件合并為單個 JS 文件,減少部署文件數(shù)量
- 簡化軟件文件部署、網(wǎng)絡(luò)緩存、版本升級和回滾等工作
- 降低多文件傳輸時的網(wǎng)絡(luò)請求開銷
- 減少網(wǎng)絡(luò)防火墻或代理對多文件請求的限制風險
提升加載性能
- 對所有資源進行最大級別 GZIP 壓縮,顯著減小傳輸體積
- 減少 HTTP 請求次數(shù),降低網(wǎng)絡(luò)延遲影響
- 支持自定義腳本精簡,移除冗余代碼
增強部署靈活性
- 生成的單一文件可輕松集成到各種靜態(tài)資源托管服務(wù)
- 支持微前端架構(gòu)(MicroApp / QianKun)的環(huán)境適配
- 便于版本管理和緩存策略實施
我是如何開發(fā)這個軟件的?
本工具借助于豆包 AI(https://www.doubao.com)開發(fā)完成。首先,筆者使用了以下提示詞逐步創(chuàng)建 HTML 文件的主體:
-
生成一個HTML頁面,包含JS代碼,實現(xiàn)以下功能:
- 解析當前路徑下的
_framework/blazor.boot.json文件,解析其中的resources/runtime|assembly|runtimeAssets|pdb節(jié)點下的屬性名 - 以這個屬性名來當做文件名,然后下載這些文件,獲得二進制內(nèi)容,使用GZIP壓縮,然后轉(zhuǎn)換為base64字符串。base64字符串換行,每行128個字符
- 創(chuàng)建一個新字符串,采用JavaScript格式。然后定義
window.__DCFileContents = {"文件名":"base64字符串"} - 界面上提供一個"下載"按鈕,以js的minitype加載生成的js字符串
- 解析當前路徑下的
-
不要使用pako,直接使用瀏覽器內(nèi)置的GZIP模塊
-
這是一個blazor wasm的程序打包器,修改HTML的文字說明
-
base64字符串不能太長,128個字符就自動換行,而且輸出文本時自動追加顯示在最下面。每次生成前先清空調(diào)試輸出文本的界面,然后調(diào)試輸出文本開始追加顯示
-
不要輸出base64的內(nèi)容預覽,去掉當前的調(diào)試文本,只保留下方的調(diào)試文本追加方式輸出
-
調(diào)試輸出文本框?qū)挾葹?00%,下方添加一個進度條。中間的status元素去掉
-
調(diào)試輸出文本框有個初始化的固定寬度,進度條中間顯示進度文本提示信息。添加版權(quán)信息"南京都昌信息科技有限公司版權(quán)所有"
-
修改
uint8ArrayToBase64(),在這里每32個字節(jié)進行一次轉(zhuǎn)換,然后添加換行回車符,在這里面直接生成帶換行的BASE64字符串,進度條文本左對齊 -
uint8ArrayToBase64()里面,每組字節(jié)是129個,避免base64轉(zhuǎn)換長度不匹配 -
不要使用json中間格式轉(zhuǎn)換,直接拼接生成JS字符串
-
對于base64字符串輸出采用
格式,避免\n轉(zhuǎn)義字符,JS中直接輸出換行的BASE64字符串 -
這里的字節(jié)長度都格式化輸出,按照大小輸出KB,MB單位。精確到小數(shù)點后2位。打包時把 blazor.boot.json也包含進去。GZIP采用最大壓縮比率??偨Y(jié)報告中添加手動點擊下載鏈接。處理完成后進度條重置。進度條顏色調(diào)整一下,藍色背景黑字看不清楚
-
生成的JS文件名采用 blazor.boot.json 下面的 entryAssembly 數(shù)值加上 ".published.js" 后綴
-
不能跳過hash為空的文件,要無條件處理所有的文件
-
放一個多行文本框,讓用戶輸入幾個JS文件名,然后打包時,將_framework目錄下這些JS文件讀取出來,合并成一個Merge.js,并參與打包。如果用戶未指定,則不生成Merge.js
-
boot.json里面列出的js是要強制打包的,不是合并到merge.js中。文本框中是讓用戶輸入自定義腳本.js文件名。另外最終生成的js文件第一行要顯示當前日期和時間
-
添加一個勾選框,讓用戶選擇是否刪除merge.js中的注釋和無意義的空格
-
放一個單行文本框,用于輸入自定義的最終JS文件名,如果為空則采用默認的文件名
-
簡化調(diào)試輸出文本,默認不精簡merge.js空格和注釋。要確保merge.js精簡結(jié)果是正確的
-
JS中的字符串要考慮到
這種多行字符串,還有JS代碼中會出現(xiàn)正則表達式,也不能破壞掉
通過 AI 創(chuàng)建了初步版本后,筆者手動進行了后續(xù)的修改和優(yōu)化,最終形成了現(xiàn)在的版本。
代碼執(zhí)行過程
初始化階段
頁面加載準備
- 初始化 DOM 元素引用(進度條、日志區(qū)、按鈕等交互組件)
- 重置進度條狀態(tài)為"準備就緒"(0%)
- 清空日志輸出區(qū)域
- 禁用下載按鈕防止重復點擊
用戶參數(shù)收集
- 讀取輸出文件名輸入框內(nèi)容(為空時將使用默認命名規(guī)則)
- 解析自定義 JS 文件列表(每行一個路徑,相對 _framework 目錄)
- 檢查"精簡自定義腳本"復選框狀態(tài)(決定是否移除注釋和冗余空格)
核心處理流程
瀏覽器兼容性驗證
檢測當前瀏覽器是否支持 CompressionStream API(用于 GZIP 壓縮)。不支持時終止流程并提示:"請使用最新版 Chrome、Edge 或 Firefox 瀏覽器"。
解析應用配置文件
下載配置文件:
- 發(fā)送請求獲取
_framework/blazor.boot.json(Blazor 應用的核心配置) - 記錄配置文件原始大小并計入總統(tǒng)計
- 下載失?。ㄈ?404 錯誤)時終止流程,日志顯示具體錯誤信息
解析配置內(nèi)容:
- 解析 JSON 格式的配置數(shù)據(jù)
- 提取 resources 字段中所有資源路徑(包括 runtime、assembly、jsModule 等類型)
- 提取 entryAssembly 值(用于生成默認輸出文件名)
- 進度條更新至 10%,日志顯示"配置文件解析完成"
處理核心資源文件
任務(wù)準備:
- 收集需處理的資源文件列表(包含
blazor.webassembly.js等核心文件) - 根據(jù)文件數(shù)量計算單個文件的進度占比(總進度 75% 平分)
逐個處理資源:
循環(huán)處理每個資源文件:
- 構(gòu)造完整 URL:
_framework/[文件名] - 下載文件并轉(zhuǎn)換為 Uint8Array 格式
- 記錄原始文件大?。ɡ奂又量傇即笮。?/li>
- 使用
gzipCompress()函數(shù)進行最大級別(level:9)壓縮 - 將壓縮后的數(shù)據(jù)轉(zhuǎn)換為 Base64 編碼(按 129 字節(jié)分塊處理)
- 生成包含文件名和 Base64 內(nèi)容的條目
- 實時更新進度條(如"處理 3/20:dotnet.wasm")
- 單個文件處理失敗時記錄日志并跳過(不終止整體流程)
處理自定義 JS 文件(可選)
輸入解析:
- 過濾空行和無效路徑,獲取有效自定義 JS 文件列表
- 列表為空時日志顯示"未指定自定義 JS 文件,不生成 Merge.js"并跳過
合并與處理:
逐個下載指定的自定義 JS 文件:
- 記錄每個文件原始大小
- 啟用精簡時使用
minifyJs()處理(保留模板字符串和正則表達式) - 合并內(nèi)容(添加來源注釋,除非啟用精簡)
- 對合并內(nèi)容進行 GZIP 壓縮并轉(zhuǎn)換為 Base64 編碼
- 生成 Merge.js 條目并添加到資源列表
生成輸出文件
內(nèi)容構(gòu)建:
- 首行添加生成時間注釋(格式:
// Generated on: YYYY-MM-DD HH:MM:SS) - 創(chuàng)建包含所有資源的 JavaScript 對象(鍵為文件名,值為 Base64 內(nèi)容)
- 生成自執(zhí)行函數(shù),包含:
- 資源解壓邏輯(使用 DecompressionStream 處理 GZIP 數(shù)據(jù))
- Blazor 啟動配置(覆蓋 loadBootResource 方法注入本地資源)
- 臨時 URL 清理邏輯(釋放內(nèi)存占用)
文件名處理:
- 優(yōu)先使用用戶指定文件名(需包含 .js 擴展名)
- 未指定時使用規(guī)則:
[entryAssembly].published.js - 無 entryAssembly 時默認使用
blazor-resources.published.js
生成下載鏈接
統(tǒng)計信息計算:
- 原始總大小:所有資源+配置文件+自定義腳本的原始大小總和
- 生成文件大?。鹤罱K JS 文件的 UTF-8 編碼字節(jié)數(shù)
- 壓縮比率:(生成文件大小 / 原始總大小) × 100%
創(chuàng)建下載:
- 將 JS 內(nèi)容轉(zhuǎn)換為 Blob 對象(MIME 類型:application/javascript)
- 生成臨時下載 URL(URL.createObjectURL)
- 自動觸發(fā)下載并顯示總結(jié)報告(含大小統(tǒng)計和壓縮比率)
- 提供手動下載鏈接(應對自動下載失敗場景)
異常處理與優(yōu)化
錯誤處理機制:
- 單個資源下載失敗:記錄日志并跳過(繼續(xù)處理其他文件)
- 關(guān)鍵文件(如 blazor.boot.json)失?。航K止流程并顯示錯誤
- 頁面卸載時清理臨時資源鏈接(URL.revokeObjectURL)
性能優(yōu)化細節(jié):
- 大文件采用流式壓縮,降低內(nèi)存占用
- Base64 編碼分塊處理,避免單行過長
- 針對 .NET 8/9 版本的 runtime 做適配處理
- 自定義 JS 精簡保留關(guān)鍵語法結(jié)構(gòu)(模板字符串、正則表達式)
版權(quán)聲明
本軟件版權(quán)歸南京都昌信息科技有限公司所有。
posted on 2025-11-04 14:09 袁永福 電子病歷,醫(yī)療信息化 閱讀(190) 評論(1) 收藏 舉報
都昌電子病歷編輯器(DCwriter)是我司的核心產(chǎn)品。2023 年發(fā)布的基于 WASM+Canvas 的 DCWriter 5.0 已成功上線數(shù)千家醫(yī)院,但其依賴資源較大的問題受到用戶反饋。為解決這一問題,我們深入優(yōu)化并研究出了 Blazor WASM 程序打包器。
Blazor WASM 程序打包器能將 Blazor WebAssembly 所有的程序文件(包括 `.js`、`.wasm`、`.dll`、`.json` 等)經(jīng) GZIP 壓縮打包成單個 JS 文件,大幅簡化部署流程并優(yōu)化應用加載性能,而且能讓 Blazor WASM 實現(xiàn)跨域調(diào)用。
目前市面上未發(fā)現(xiàn)有類似功能的工具,因此筆者自行開發(fā)了這個實用工具。
浙公網(wǎng)安備 33010602011771號