支持 SlimHost 轻量模块打包
This commit is contained in:
1 parent
38b9f47659
commit
83562fe074
3 files changed
+118
-4
No files matched your search
@@ -119,6 +119,29 @@ powershell tools/package-module.ps1 -Project "src/YourModule/YourModule.csproj"
|
||||
|
||||
> 说明:该脚本依赖 Docker(会拉取/使用 `mcr.microsoft.com/dotnet/sdk:8.0` 镜像)。首次执行会比较慢属正常现象。
|
||||
|
||||
### 轻量打包(推荐)
|
||||
|
||||
模块运行时会与宿主共享一批“边界程序集”(例如 `TelegramPanel.*`、`Microsoft.Extensions.*`、`Microsoft.AspNetCore.*`、`MudBlazor` 等)。
|
||||
这些程序集即使被打进模块包里,宿主也会强制从 Default ALC 解析(避免类型身份不一致),因此**携带它们只会徒增包体积**。
|
||||
|
||||
打包时可加 `-Slim` 开关自动剔除这类共享程序集:
|
||||
|
||||
```powershell
|
||||
powershell tools/package-module.ps1 -Project "src/YourModule/YourModule.csproj" -Manifest "src/YourModule/manifest.json" -Slim
|
||||
```
|
||||
|
||||
### 更激进的轻量打包(仅限 TelegramPanel 宿主)
|
||||
|
||||
如果确定目标宿主就是 TelegramPanel 主程序(必带 EFCore/Sqlite/WTelegramClient 等依赖),并且你希望把模块包做到尽可能小,可以使用 `-SlimHost`:
|
||||
|
||||
- 额外剔除:`Microsoft.EntityFrameworkCore*`、`Microsoft.Data.Sqlite`、`SQLitePCLRaw*`、`WTelegramClient`、`SixLabors.ImageSharp`、`PhoneNumbers` 等宿主内置依赖
|
||||
- 剔除 `runtimes/`(多平台 SQLite native,体积占比很高)
|
||||
- 剔除 `wwwroot/_content/MudBlazor`(静态资源由宿主提供)
|
||||
|
||||
```powershell
|
||||
powershell tools/package-module.ps1 -Project "src/YourModule/YourModule.csproj" -Manifest "src/YourModule/manifest.json" -SlimHost
|
||||
```
|
||||
|
||||
## manifest.json(示例)
|
||||
|
||||
```json
|
||||
|
||||
@@ -32,7 +32,14 @@ public sealed class ModuleLoadContext : AssemblyLoadContext
|
||||
|| name.StartsWith("Microsoft.AspNetCore.", StringComparison.OrdinalIgnoreCase)
|
||||
|| name.StartsWith("Microsoft.JSInterop", StringComparison.OrdinalIgnoreCase)
|
||||
|| name.StartsWith("TelegramPanel.", StringComparison.OrdinalIgnoreCase)
|
||||
|| string.Equals(name, "MudBlazor", StringComparison.OrdinalIgnoreCase))
|
||||
|| string.Equals(name, "MudBlazor", StringComparison.OrdinalIgnoreCase)
|
||||
// TelegramPanel 宿主内置依赖:模块可直接复用宿主版本,避免重复携带导致包体积膨胀。
|
||||
|| string.Equals(name, "WTelegramClient", StringComparison.OrdinalIgnoreCase)
|
||||
|| string.Equals(name, "PhoneNumbers", StringComparison.OrdinalIgnoreCase)
|
||||
|| string.Equals(name, "SixLabors.ImageSharp", StringComparison.OrdinalIgnoreCase)
|
||||
|| string.Equals(name, "Microsoft.Data.Sqlite", StringComparison.OrdinalIgnoreCase)
|
||||
|| name.StartsWith("Microsoft.EntityFrameworkCore", StringComparison.OrdinalIgnoreCase)
|
||||
|| name.StartsWith("SQLitePCLRaw", StringComparison.OrdinalIgnoreCase))
|
||||
return null;
|
||||
|
||||
// 2) 其次:如果宿主已经加载过同名程序集,则同样交给 Default ALC(避免重复加载)。
|
||||
|
||||
@@ -6,7 +6,17 @@ param(
|
||||
[string]$Manifest,
|
||||
|
||||
[Parameter(Mandatory = $false)]
|
||||
[string]$OutDir = "artifacts/modules"
|
||||
[string]$OutDir = "artifacts/modules",
|
||||
|
||||
# 轻量打包:剔除会由宿主共享加载的程序集(减少包体积)。
|
||||
# 说明:宿主的 ModuleLoadContext 会强制让这些程序集由 Default ALC 解析,模块包携带它们只会徒增体积。
|
||||
[Parameter(Mandatory = $false)]
|
||||
[switch]$Slim,
|
||||
|
||||
# 更激进的轻量打包:额外剔除宿主已内置的第三方依赖(EFCore/Sqlite/WTelegramClient 等)与多平台 native runtimes。
|
||||
# 适用场景:目标宿主就是 TelegramPanel 主程序(必带这些依赖),并且部署环境固定(例如 Docker linux-x64)。
|
||||
[Parameter(Mandatory = $false)]
|
||||
[switch]$SlimHost
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
@@ -28,10 +38,18 @@ $moduleId = $moduleId.Trim()
|
||||
$version = $version.Trim()
|
||||
if ([string]::IsNullOrWhiteSpace($moduleId)) { throw "manifest.json 缺少 id" }
|
||||
if ([string]::IsNullOrWhiteSpace($version)) { throw "manifest.json 缺少 version" }
|
||||
$entryAssembly = ""
|
||||
try {
|
||||
if ($null -ne $manifestObj.entry -and $null -ne $manifestObj.entry.assembly) { $entryAssembly = [string]$manifestObj.entry.assembly }
|
||||
} catch { }
|
||||
$entryAssembly = [string]$entryAssembly
|
||||
$entryAssembly = $entryAssembly.Trim()
|
||||
if ([string]::IsNullOrWhiteSpace($entryAssembly)) { throw "manifest.json 缺少 entry.assembly" }
|
||||
|
||||
$buildRootRel = "artifacts/_modulebuild/$moduleId/$version"
|
||||
$publishRel = "$buildRootRel/publish"
|
||||
$stagingRel = "$buildRootRel/staging"
|
||||
$runId = ([Guid]::NewGuid().ToString("N"))
|
||||
$publishRel = "$buildRootRel/publish/$runId"
|
||||
$stagingRel = "$buildRootRel/staging/$runId"
|
||||
|
||||
$publishHost = Join-Path $repoRoot $publishRel
|
||||
$stagingHost = Join-Path $repoRoot $stagingRel
|
||||
@@ -56,6 +74,72 @@ New-Item -ItemType Directory -Force -Path $stagingLib | Out-Null
|
||||
Copy-Item -Path $manifestPath -Destination (Join-Path $stagingHost "manifest.json") -Force
|
||||
Copy-Item -Path (Join-Path $publishHost "*") -Destination $stagingLib -Recurse -Force
|
||||
|
||||
if ($Slim -or $SlimHost)
|
||||
{
|
||||
# 与宿主共享的“边界程序集”(见 src/TelegramPanel.Web/Modules/ModuleLoadContext.cs)。
|
||||
# 模块包携带这些 dll 会导致体积膨胀(同时也容易造成类型身份不一致的风险),因此在打包阶段直接剔除。
|
||||
$sharedPatterns = @(
|
||||
"Microsoft.AspNetCore.*.dll",
|
||||
"Microsoft.Extensions.*.dll",
|
||||
"Microsoft.JSInterop*.dll",
|
||||
"TelegramPanel.*.dll",
|
||||
"MudBlazor*.dll"
|
||||
)
|
||||
|
||||
foreach ($pattern in $sharedPatterns)
|
||||
{
|
||||
Get-ChildItem -Path $stagingLib -Filter $pattern -File -ErrorAction SilentlyContinue | ForEach-Object {
|
||||
if ($_.Name -ieq $entryAssembly) { return }
|
||||
try { Remove-Item -Path $_.FullName -Force -ErrorAction Stop } catch { }
|
||||
}
|
||||
|
||||
$pdbPattern = [System.IO.Path]::ChangeExtension($pattern, ".pdb")
|
||||
Get-ChildItem -Path $stagingLib -Filter $pdbPattern -File -ErrorAction SilentlyContinue | ForEach-Object {
|
||||
try { Remove-Item -Path $_.FullName -Force -ErrorAction Stop } catch { }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($SlimHost)
|
||||
{
|
||||
# 宿主已内置且通常在启动早期加载的依赖:把这些也剔除可大幅减小体积(尤其是 SQLitePCL 的多平台 runtimes/native)。
|
||||
$hostBuiltInPatterns = @(
|
||||
"Microsoft.EntityFrameworkCore*.dll",
|
||||
"Microsoft.Data.Sqlite*.dll",
|
||||
"SQLitePCLRaw*.dll",
|
||||
"WTelegramClient*.dll",
|
||||
"SixLabors.ImageSharp*.dll",
|
||||
"PhoneNumbers*.dll"
|
||||
)
|
||||
|
||||
foreach ($pattern in $hostBuiltInPatterns)
|
||||
{
|
||||
Get-ChildItem -Path $stagingLib -Filter $pattern -File -ErrorAction SilentlyContinue | ForEach-Object {
|
||||
if ($_.Name -ieq $entryAssembly) { return }
|
||||
try { Remove-Item -Path $_.FullName -Force -ErrorAction Stop } catch { }
|
||||
}
|
||||
|
||||
$pdbPattern = [System.IO.Path]::ChangeExtension($pattern, ".pdb")
|
||||
Get-ChildItem -Path $stagingLib -Filter $pdbPattern -File -ErrorAction SilentlyContinue | ForEach-Object {
|
||||
try { Remove-Item -Path $_.FullName -Force -ErrorAction Stop } catch { }
|
||||
}
|
||||
}
|
||||
|
||||
# 多平台 native runtimes(SQLite)体积很大;TelegramPanel 宿主自身已携带,这里直接剔除。
|
||||
$runtimesDir = Join-Path $stagingLib "runtimes"
|
||||
if (Test-Path -Path $runtimesDir)
|
||||
{
|
||||
try { Remove-Item -Path $runtimesDir -Recurse -Force -ErrorAction Stop } catch { }
|
||||
}
|
||||
|
||||
# MudBlazor 静态资源由宿主提供;模块包里携带的这份没有实际用途,顺手剔除。
|
||||
$mudWwwroot = Join-Path $stagingLib "wwwroot/_content/MudBlazor"
|
||||
if (Test-Path -Path $mudWwwroot)
|
||||
{
|
||||
try { Remove-Item -Path $mudWwwroot -Recurse -Force -ErrorAction Stop } catch { }
|
||||
}
|
||||
}
|
||||
|
||||
New-Item -ItemType Directory -Force -Path $outRoot | Out-Null
|
||||
$dest = Join-Path $outRoot "$moduleId-$version.tpm"
|
||||
if (Test-Path -Path $dest) { Remove-Item -Path $dest -Force }
|
||||
|
||||
Reference in new issue
Block a user