Angular 19 SSR环境下如何配置动态baseHref?
问题描述
旧架构下,我可通过运行时动态确定的baseHref托管多语言Angular应用。Dockerfile启动Nginx服务器,负责分发index.html、polyfills.js等非打包文件;所有打包文件则通过--deploy-url从CDN分发(需多轮构建)。
实现方式为结合APP_BASE_HREF与window.location,配合正确的Kubernetes Ingress配置与单次Docker构建,即可托管多个不同baseHref的Angular应用,例如:
myapp.com/965168ba2981/homemyapp.com/2c17f3db70e2/homemyapp.com/876e04c3d6d2/home
应用路由由Kubernetes Ingress配置管理。
需求保留该架构,CDN资源非优先级
目前我正迁移至带SSR的Angular 19,问题随之出现:APP_BASE_HREF在预渲染阶段(构建时)就会被调用,无法在运行时修改,但我需要保留原架构,CDN资源并非当前优先级。
次优解决方案
目前找到的唯一可行方案是为浏览器端与服务器端的baseHref设置占位符,示例如下:
server.ts代码
import { AngularNodeAppEngine, createNodeRequestHandler, isMainModule, writeResponseToNodeResponse, } from '@angular/ssr/node'; import { environment } from '@env/environment'; import express from 'express'; import * as fs from 'fs'; import https from 'node:https'; import { dirname, resolve } from 'node:path'; import { fileURLToPath } from 'node:url'; import 'zone.js/node'; const serverDistFolder = dirname(fileURLToPath(import.meta.url)); const browserDistFolder = resolve(serverDistFolder, '../browser'); const qaBaseHref = "/ENVIRONMENT_ID_PLACEHOLDER"; const app = express(); const angularApp = new AngularNodeAppEngine(); app.use( baseHref, express.static(browserDistFolder, { maxAge: '1y', index: false, redirect: false }), ); app.get('/**', (req, res, next) => { angularApp .handle(req) .then( response => response ? writeResponseToNodeResponse(response, res) : next(), // TODO: 重定向到404并发送应用洞察事件 ) .catch(next); // TODO: 将错误发送到应用洞察 }); if (isMainModule(import.meta.url)) { const port = process.env['PORT'] || 3000; app.listen(port, () => { console.log(`Node Express server listening on http://localhost:${port}`); }); } /** * Angular CLI使用的请求处理器(开发服务器和构建期间)。 */ export const reqHandler = createNodeRequestHandler(app);
project.json配置
"qa": { "outputPath": "dist-qa", "fileReplacements": [ { "replace": "src/environments/environment.ts", "with": "src/environments/environment.qa.ts" } ], "optimization": true, "outputHashing": "all", "sourceMap": false, "namedChunks": false, "baseHref": "/ENVIRONMENT_ID_PLACEHOLDER/" },
随后在Dockerfile的入口点将占位符替换为实际所需的baseHref。
已尝试的方法
- 在服务器中间件中重写
req.url:多数情况下无效,即便部分文件能正常分发,路由也会丢失动态baseHref(例如myapp.com/965168ba2981/home加载后跳至myapp.com/home,而该路由未在Ingress中配置) - 在index中覆盖
baseHref:参考路径无关Angular应用的实现思路
内容的提问来源于stack exchange,提问作者Lukas
相关产品推荐
相关产品推荐

