如何在现有Express服务器中集成Angular Universal实现服务端渲染
现有JavaScript Express服务集成Angular Universal步骤
第一步:生成Angular Universal编译产物
在你的Angular项目根目录执行ng add @nguniversal/express-engine,自动生成服务端渲染所需的AppServerModule、构建配置等文件。随后执行npm run build:ssr完成编译,编译后dist目录会得到两个核心产物:
- 浏览器端静态资源包:默认路径为
dist/{你的项目名称}/browser - 服务端渲染CommonJS格式bundle:默认路径为
dist/{你的项目名称}/server/main.js
官方生成的server.ts文件不需要用到,直接忽略即可。
第二步:现有Express服务安装依赖
在你的Express服务项目中执行以下命令安装必要依赖:
npm install @angular/ssr @angular/common @angular/core @angular/platform-server
如果你使用的是Angular 16及更早版本,将@angular/ssr替换为@nguniversal/express-engine即可。
第三步:修改Express服务代码
路由匹配顺序非常关键,必须按照「现有业务接口 -> 非Angular静态资源 -> Angular静态资源 -> SSR通配路由」的顺序编写,避免业务逻辑被SSR路由拦截。
完整示例代码如下:
const express = require('express'); // Angular 17+引入方式,Angular 16及以下改为 require('@nguniversal/express-engine') const { ngExpressEngine } = require('@angular/ssr'); const { join } = require('path'); // 引入编译好的Angular服务端bundle,路径替换为你实际的产物路径 const { AppServerModule } = require('./dist/你的项目名称/server/main'); const app = express(); // Angular浏览器端静态资源目录路径,替换为你实际的产物路径 const browserDistPath = join(__dirname, 'dist/你的项目名称/browser'); // 配置Angular模板渲染引擎 app.engine('html', ngExpressEngine({ bootstrap: AppServerModule })); app.set('view engine', 'html'); app.set('views', browserDistPath); // ---------------------- 原有业务逻辑放在最前面 ---------------------- // 你的原有业务接口 app.get('/api/*', (req, res) => { // 原有逻辑不变 res.json({ code: 0 }); }); // 其他非Angular静态资源托管,比如上传文件、后台系统静态页等 app.use('/upload', express.static(join(__dirname, 'upload'))); app.use('/admin', express.static(join(__dirname, 'admin-static'))); // ---------------------- Angular相关逻辑放在后面 ---------------------- // 托管Angular浏览器端静态资源(js、css、图片等) app.get('*.*', express.static(browserDistPath, { maxAge: '1y' })); // SSR通配路由,处理所有未匹配到前面规则的请求 app.get('*', (req, res, next) => { // 如有特殊路由不需要走SSR,可在此处过滤直接返回静态index.html if (req.path.startsWith('/test-no-ssr')) { return res.sendFile(join(browserDistPath, 'index.html')); } res.render('index', { req, res }); }); // 原有启动逻辑不变 app.listen(3000, () => { console.log('服务启动在3000端口'); });
注意事项
- 如果Angular项目中用到了
window、document等浏览器专属API,需要提前做兼容处理:可通过isPlatformServer判断运行环境,避免服务端渲染时报错 - 每次更新Angular项目代码后,都需要重新执行
npm run build:ssr更新产物,再重启Express服务生效 - 如需配置SSR缓存、请求透传等能力,可直接在
res.render的第二个参数中传入自定义参数,在Angular服务端代码中通过REQUEST注入token读取
内容的提问来源于stack exchange,提问作者NeNaD
相关产品推荐
相关产品推荐

