<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>C# on 天国福音的博客</title>
        <link>https://blog.250512.xyz/categories/c%23/</link>
        <description>Recent content in C# on 天国福音的博客</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>zh-cn</language>
        <lastBuildDate>Wed, 21 Jan 2026 00:00:00 +0800</lastBuildDate><atom:link href="https://blog.250512.xyz/categories/c%23/index.xml" rel="self" type="application/rss+xml" /><item>
        <title>10版本ABP Bundle的兼容性问题</title>
        <link>https://blog.250512.xyz/p/blazor-webassembly/</link>
        <pubDate>Wed, 21 Jan 2026 00:00:00 +0800</pubDate>
        
        <guid>https://blog.250512.xyz/p/blazor-webassembly/</guid>
        <description>&lt;img src="https://img.250512.xyz/uploads/2026/01/1768983086344.png" alt="Featured image of post 10版本ABP Bundle的兼容性问题" /&gt;&lt;p&gt;Blazor WebAssembly + ABP 10.0.2 + .NET 10 预览版发布兼容性问题记录&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;结论：目前使用 .NET 10 + ABP 10.0.2 做 Blazor WASM 发布，会遇到脚本加载、Service Worker 缓存等框架级问题。短期更推荐使用 .NET 8 稳定版 + ABP 8，或在当前项目中采用少量手动脚本引用作为临时方案。&lt;/p&gt;&lt;/blockquote&gt;
&lt;h2 id=&#34;1-现象开发模式正常发布模式前端白屏&#34;&gt;1. 现象：开发模式正常，发布模式前端白屏
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;开发模式（&lt;code&gt;dotnet run&lt;/code&gt; / IDE 启动）：
&lt;ul&gt;
&lt;li&gt;Blazor WebAssembly 能正常加载。&lt;/li&gt;
&lt;li&gt;登录、OIDC、ABP 组件都工作正常。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;发布模式（&lt;code&gt;dotnet publish&lt;/code&gt; 后从 &lt;code&gt;bin/Release/net10.0/publish&lt;/code&gt; 启动）：
&lt;ul&gt;
&lt;li&gt;页面 HTML 能返回 200。&lt;/li&gt;
&lt;li&gt;静态资源（&lt;code&gt;global.css&lt;/code&gt;、&lt;code&gt;global.js&lt;/code&gt;、&lt;code&gt;dotnet.js&lt;/code&gt; 等）大部分能返回 200。&lt;/li&gt;
&lt;li&gt;但最终前端不渲染内容，控制台出现异常。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;典型错误日志：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;后端日志中多次出现 404：
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;_framework/WHS.Blazor.Client.jqrq8onpr6.wasm&lt;/code&gt; 404。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;service-worker-assets.js&lt;/code&gt; 404。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;前端控制台错误：
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Could not find &#39;AuthenticationService.init&#39; (&#39;AuthenticationService&#39; was undefined).&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;发生在 &lt;code&gt;blazor.web.js&lt;/code&gt; 的 &lt;code&gt;callEntryPoint&lt;/code&gt; 阶段。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;2-service-worker-导致的旧资源缓存问题&#34;&gt;2. Service Worker 导致的旧资源缓存问题
&lt;/h2&gt;&lt;p&gt;Blazor PWA 默认会：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;通过 &lt;code&gt;service-worker.published.js&lt;/code&gt; 加载 &lt;code&gt;service-worker-assets.js&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;根据 &lt;code&gt;assetsManifest&lt;/code&gt; 缓存 &lt;code&gt;blazor.boot.json&lt;/code&gt;、wasm、dll、css、js 等资源。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;在 .NET 10 + ABP 10.0.2 的组合下，遇到的问题是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;首次发布后，Service Worker 会缓存一份旧的 &lt;code&gt;blazor.boot.json&lt;/code&gt; 和 wasm 哈希。&lt;/li&gt;
&lt;li&gt;再次修改代码并发布时，即使服务器上已经是新 wasm 文件：
&lt;ul&gt;
&lt;li&gt;浏览器仍优先从 SW 缓存中拿旧版本的 &lt;code&gt;blazor.boot.json&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;于是前端会请求不存在的 &lt;code&gt;_framework/WHS.Blazor.Client.&amp;lt;old&amp;gt;.wasm&lt;/code&gt;，服务器返回 404。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;临时解决办法：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;在 &lt;code&gt;App.razor&lt;/code&gt; 中对 localhost 特判，启动时注销所有已注册的 Service Worker：&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;9
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;isLocalhost&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;location&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;hostname&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;===&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;localhost&amp;#39;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;||&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;location&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;hostname&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;===&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;127.0.0.1&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;serviceWorker&amp;#39;&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;navigator&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;isLocalhost&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nb&#34;&gt;window&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;addEventListener&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;load&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;async&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;kr&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;registrations&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;navigator&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;serviceWorker&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;getRegistrations&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kr&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;registration&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;of&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;registrations&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;kr&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;registration&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;unregister&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;对于生产环境（非 localhost），仍按正常逻辑注册 &lt;code&gt;service-worker.published.js&lt;/code&gt;，保留 PWA 能力。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;3-abp-核心-js-未正确注入的问题&#34;&gt;3. ABP 核心 JS 未正确注入的问题
&lt;/h2&gt;&lt;p&gt;ABP Blazor 依赖一组核心 JS 文件，例如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;_content/Microsoft.AspNetCore.Components.WebAssembly.Authentication/AuthenticationService.js&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;_content/Volo.Abp.AspNetCore.Components.Web/libs/abp/js/abp.js&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;_content/Volo.Abp.AspNetCore.Components.Web/libs/abp/js/lang-utils.js&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;_content/Volo.Abp.AspNetCore.Components.Web/libs/abp/js/authentication-state-listener.js&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;按照 ABP 的设计，这些脚本通常通过：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;AbpBundlingOptions&lt;/code&gt; + &lt;code&gt;BlazorWebAssemblyStandardBundles.Scripts.Global&lt;/code&gt;；&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;!--ABP:Scripts--&amp;gt;&lt;/code&gt; + &lt;code&gt;app.MapAbpStaticAssets()&lt;/code&gt;；&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;在页面中自动注入。&lt;/p&gt;
&lt;p&gt;在 .NET 10 + ABP 10.0.2 + Blazor 新的 “Razor Components + Interactive WebAssembly” 模式下，实际观测到：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;发布模式中，&lt;code&gt;blazor.web.js&lt;/code&gt; 启动时，以上脚本可能尚未加载完成。&lt;/li&gt;
&lt;li&gt;结果：&lt;code&gt;AuthenticationService&lt;/code&gt; 或 &lt;code&gt;abp&lt;/code&gt; 对象是 &lt;code&gt;undefined&lt;/code&gt;，触发 &lt;code&gt;AuthenticationService.init&lt;/code&gt; 找不到的错误。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;临时解决办法：手动写死核心脚本引用，且放在 &lt;code&gt;blazor.web.js&lt;/code&gt; 之前：&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-html&#34; data-lang=&#34;html&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;body&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;class&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;abp-application-layout&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c&#34;&gt;&amp;lt;!-- .NET 10 + ABP 10.0.2 兼容性修复：核心 JS 提前同步加载 --&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;script&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;src&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;_content/Microsoft.AspNetCore.Components.WebAssembly.Authentication/AuthenticationService.js&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;script&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;script&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;src&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;_content/Volo.Abp.AspNetCore.Components.Web/libs/abp/js/abp.js&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;script&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;script&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;src&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;_content/Volo.Abp.AspNetCore.Components.Web/libs/abp/js/lang-utils.js&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;script&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;script&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;src&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;_content/Volo.Abp.AspNetCore.Components.Web/libs/abp/js/authentication-state-listener.js&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;script&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;script&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;src&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;_framework/blazor.web.js&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;script&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c&#34;&gt;&amp;lt;!-- 下面是应用容器和 ABP 自动注入的 global.js 等 --&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;body&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;这样可以保证：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;当 &lt;code&gt;blazor.web.js&lt;/code&gt; 调用 .NET 入口点时，相关 JS API 已经在 &lt;code&gt;window&lt;/code&gt; 中可用。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;4-为什么手动引用脚本是临时方案&#34;&gt;4. 为什么手动引用脚本是“临时方案”
&lt;/h2&gt;&lt;p&gt;优点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;能迅速绕过当前版本的自动 Bundling/注入问题，让应用在发布模式下可用。&lt;/li&gt;
&lt;li&gt;更容易排查和控制脚本加载顺序。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;缺点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;失去 ABP Bundling 系统带来的自动合并、压缩、版本哈希等好处。&lt;/li&gt;
&lt;li&gt;ABP 或 .NET 升级后，如果脚本路径或文件名变化，需要手动维护这些 &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;可能与 &lt;code&gt;&amp;lt;!--ABP:Scripts--&amp;gt;&lt;/code&gt; 注入内容重复（需要注意不要加载两次相同脚本）。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;因此，在代码中建议明确标注为“兼容性修复 / TODO”，后续框架修复后可以清理掉：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-html&#34; data-lang=&#34;html&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c&#34;&gt;&amp;lt;!--
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c&#34;&gt;.NET 10 + ABP 10.0.2 发布模式兼容性修复：
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c&#34;&gt;手动写死核心 JS 文件, 确保在 blazor.web.js 启动前同步加载。
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c&#34;&gt;ABP 的自动脚本注入在发布模式下可能失效（时机 / 路径问题）。
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c&#34;&gt;TODO: 待 ABP 或 .NET 修复后，移除手动引用，恢复使用 ABP 自动注入。
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c&#34;&gt;--&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;5-小结&#34;&gt;5. 小结
&lt;/h2&gt;&lt;p&gt;​	ABP 10.0.2 搭建 Blazor WebAssembly 在发布模式下确实存在一系列脚本和缓存的兼容性问题。在官方未完全打磨之前，&lt;strong&gt;“考虑回退到 .NET 8 稳定栈”&lt;/strong&gt; 是工程上更务实的选择。&lt;/p&gt;
</description>
        </item>
        
    </channel>
</rss>
