You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

@nguniversal/express-engine SSR构建始终使用开发环境配置的问题求助

@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';

最后验证步骤

  1. 执行npm run build:ssr完成生产构建
  2. 执行npm run serve:ssr启动SSR服务
  3. 查看控制台输出,确认environment.baseUrl是http://xxxx.com
  4. 打开页面,检查网络请求中的翻译文件是否从生产地址加载(服务端渲染的内容会直接包含翻译,浏览器端后续的请求会用生产地址)

备注:内容来源于stack exchange,提问作者thuleduy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.22 08:54:50