带Areas的ASP.NET MVC项目中Angular懒加载模块deployUrl的替代方案咨询
咱先把问题的核心捋清楚:你在ASP.NET MVC带Areas的场景下,Angular懒加载模块的请求路径总是不符合预期,用了磁盘路径的deployUrl和__webpack_public_path__的临时hack,官方提到的APP_BASE_HREF又解决不了问题,想找更靠谱的替代方案。下面是几个结合实际部署经验的规范做法:
方案一:正确区分baseHref和deployUrl,用构建参数动态配置
首先得搞明白这俩参数的本质区别:
baseHref是Angular路由的基准URL路径,负责处理页面导航的路径前缀deployUrl是Webpack用来加载静态资源(包括懒加载模块)的URL前缀,必须是URL路径,不是磁盘路径
你的场景里,懒加载资源的预期URL是https://localhost:1234/_IISBit/AreaName/..../somelazyloadfile_ts.js,所以构建时要把deployUrl设为对应的URL前缀,而不是磁盘路径。可以在构建命令里直接传递参数:
ng build --base-href "/_IISBit/AreaName/" --deploy-url "/_IISBit/AreaName/Areas/TheArea/Views/SomeFolder/Ang/"
这样Angular会自动把懒加载模块的请求路径拼接到deployUrl后面,同时baseHref处理路由的基准路径,完全不需要hack。之前用磁盘路径的deployUrl能生效只是巧合——刚好你的服务器磁盘路径映射到了对应的URL路径,但这不是规范用法,换个环境可能就失效了。
方案二:从ASP.NET MVC视图动态注入Webpack公共路径
如果你的部署环境经常变化,不想每次构建都改参数,可以把__webpack_public_path__的值从MVC视图里动态注入,替代硬编码:
- 在Angular对应的MCS视图(比如
Areas/TheArea/Views/SomeFolder/Ang/index.cshtml)里,添加一段脚本:
<script> // 用ASP.NET MVC的Url.Content方法生成正确的URL路径 window.__webpack_public_path__ = '@Url.Content("~/Areas/TheArea/Views/SomeFolder/Ang/")'; </script>
- 修改main.ts里的代码,去掉硬编码,改为读取全局变量:
declare let __webpack_public_path__: string; // 从window获取动态生成的公共路径 __webpack_public_path__ = window.__webpack_public_path__;
这个做法的好处是,路径完全由ASP.NET MVC根据站点配置和路由规则生成,不用在Angular代码里写死,适配不同环境更灵活。
方案三:自定义Webpack配置设置publicPath
如果你已经 eject了Angular的Webpack配置,或者用了angular.json里的customWebpackConfig扩展,可以直接配置Webpack的output.publicPath,这是Webpack控制资源加载路径的标准方式:
在自定义Webpack配置文件里添加:
module.exports = { output: { // 设置为懒加载资源的URL前缀 publicPath: '/_IISBit/AreaName/Areas/TheArea/Views/SomeFolder/Ang/' } };
然后在angular.json里指定这个自定义配置(如果没eject的话):
{ "projects": { "your-project-name": { "architect": { "build": { "builder": "@angular-builders/custom-webpack:browser", "options": { "customWebpackConfig": { "path": "./webpack.config.js" } } } } } } }
这个方案和__webpack_public_path__原理一致,但更符合Webpack的规范,不需要在业务代码里加hack。
为什么APP_BASE_HREF解决不了问题?
这里得澄清一下:APP_BASE_HREF是给Angular的路由系统用的,用来处理路由导航的基准路径,比如路由跳转时自动加上前缀。但懒加载模块的路径是由Webpack的公共路径(也就是publicPath或deployUrl)控制的,两者负责的是不同的环节,所以修改APP_BASE_HREF自然解决不了懒加载的路径问题。
内容的提问来源于stack exchange,提问作者tony

