@nguniversal/express-engine SSR构建始终使用开发环境配置的问题求助
看起来你遇到的核心问题是SSR构建后,Transloco依然使用开发环境的localhost:4200加载翻译文件,而不是生产环境的http://xxxx.com。我来帮你一步步排查和解决这个问题:
1. 先检查build:ssr脚本是否正确指定了生产环境
Angular默认构建会使用开发环境配置,你需要确保package.json里的build:ssr脚本明确指定生产环境:
打开你的package.json,找到scripts部分,修改build:ssr为:
"scripts": { "build:ssr": "ng build --configuration production && ng run web:server:production", "serve:ssr": "node dist/web/server/main.js" }
这里的web是你的项目名称(从server.ts里的dist/web/browser可以看出来),如果你的项目名不同,记得替换。这个脚本会先构建浏览器端的生产包,再构建服务端的生产包,确保环境文件被正确替换。
2. 验证Angular配置中的环境替换规则
打开angular.json,找到projects -> web -> architect -> server -> configurations -> production,确保存在正确的文件替换配置:
"production": { "fileReplacements": [ { "replace": "src/app/environments/environment.ts", "with": "src/app/environments/environment.prod.ts" } ], // 其他配置... }
如果没有这个配置,构建服务端时不会替换成生产环境的environment.prod.ts,这就会导致服务端依然使用开发环境的baseUrl。
3. 修复Transloco的SSR适配问题
在SSR场景下,服务端直接发起HTTP请求到localhost:4200是不可行的(服务端运行时这个地址可能没启动),而且也没必要——服务端可以直接读取本地的翻译文件。我们可以修改transloco-root.module.ts中的加载器,区分浏览器和服务端环境:
import { Inject, Injectable, PLATFORM_ID } from '@angular/core'; import { isPlatformBrowser, isPlatformServer } from '@angular/common'; import { HttpClient } from '@angular/common/http'; import { Translation, TranslocoLoader } from '@ngneat/transloco'; import { environment } from './environments/environment'; import { readFileSync } from 'fs'; import { join } from 'path'; @Injectable({ providedIn: 'root' }) export class TranslocoHttpLoader implements TranslocoLoader { constructor( private http: HttpClient, @Inject(PLATFORM_ID) private platformId: Object ) {} getTranslation(lang: string) { if (isPlatformServer(this.platformId)) { // 服务端直接读取dist里的翻译文件 const translationPath = join(process.cwd(), 'dist/web/browser/assets/i18n', `${lang}.json`); return Promise.resolve(JSON.parse(readFileSync(translationPath, 'utf8')) as Translation); } else { // 浏览器端正常发起HTTP请求 return this.http.get<Translation>(`${environment.baseUrl}/assets/i18n/${lang}.json`); } } }
这样修改后,服务端渲染时会直接读取本地构建好的翻译文件,不再依赖baseUrl;浏览器端则继续使用生产环境的地址加载。
4. 确保服务端入口文件启用生产模式
检查src/main.server.ts,确保它也正确加载环境并启用生产模式:
import { enableProdMode } from '@angular/core'; import { environment } from './app/environments/environment'; import { AppServerModule } from './app/app.server.module'; if (environment.production) { enableProdMode(); } export { AppServerModule } from './app/app.server.module'; export { renderModule, renderModuleFactory } from '@angular/platform-server';
最后验证步骤
- 执行
npm run build:ssr完成生产构建 - 执行
npm run serve:ssr启动SSR服务 - 查看控制台输出,确认
environment.baseUrl是http://xxxx.com - 打开页面,检查网络请求中的翻译文件是否从生产地址加载(服务端渲染的内容会直接包含翻译,浏览器端后续的请求会用生产地址)
备注:内容来源于stack exchange,提问作者thuleduy

