如何在Nginx反向代理下为多Angular应用配置ng serve实现热重载?
解决多Angular应用通过Nginx代理时热重载同时生效的问题
我之前维护多个Angular 6应用的时候,也碰到过完全一样的热重载问题——Nginx里硬编码/sockjs-node/到某个端口,结果只有一个应用能实时刷新。试了几种方法,下面这几个方案亲测有效:
方案一:给每个Angular应用配置独立的热重载路径(推荐)
这个方案让每个应用的热重载请求路径和自身的访问路径绑定,从根源上避免冲突,是最稳妥的做法。
1. 修改Angular项目配置
在每个应用的angular.json中,给serve配置添加servePath和publicHost参数,指定应用的访问前缀:
{ "$schema": "./node_modules/@angular/cli/lib/config/schema.json", "projects": { "my-app-1": { "architect": { "serve": { "options": { "port": 4201, "servePath": "my-app-1", "publicHost": "https://localhost/my-app-1" } } } }, "my-app-2": { "architect": { "serve": { "options": { "port": 4202, "servePath": "my-app-2", "publicHost": "https://localhost/my-app-2" } } } } } }
或者直接用命令行启动应用时指定参数:
# 启动my-app-1 ng serve --port 4201 --serve-path my-app-1 --public-host https://localhost/my-app-1 # 启动my-app-2 ng serve --port 4202 --serve-path my-app-2 --public-host https://localhost/my-app-2
2. 更新Nginx配置
现在每个应用的热重载请求会变成/my-app-1/sockjs-node/和/my-app-2/sockjs-node/,对应修改Nginx的代理规则:
# 代理my-app-1的普通请求 location ^~ /my-app-1/ { proxy_pass http://127.0.0.1:4201/; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; proxy_set_header Host $host; proxy_http_version 1.1; proxy_cache_bypass $http_upgrade; } # 代理my-app-1的热重载请求 location ^~ /my-app-1/sockjs-node/ { proxy_pass http://127.0.0.1:4201/sockjs-node/; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; proxy_set_header Host $host; proxy_http_version 1.1; proxy_cache_bypass $http_upgrade; } # 代理my-app-2的普通请求 location ^~ /my-app-2/ { proxy_pass http://127.0.0.1:4202/; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; proxy_set_header Host $host; proxy_http_version 1.1; proxy_cache_bypass $http_upgrade; } # 代理my-app-2的热重载请求 location ^~ /my-app-2/sockjs-node/ { proxy_pass http://127.0.0.1:4202/sockjs-node/; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; proxy_set_header Host $host; proxy_http_version 1.1; proxy_cache_bypass $http_upgrade; }
方案二:用Nginx Cookie映射路由(无需修改Angular配置)
如果不想改动前端配置,可以通过Nginx的Cookie标记来区分不同应用的热重载请求:
1. 修改应用代理规则,添加识别Cookie
在Nginx的应用location块中,给访问不同应用的用户设置专属Cookie:
location ^~ /my-app-1/ { proxy_pass http://127.0.0.1:4201/; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; proxy_set_header Host $host; proxy_http_version 1.1; proxy_cache_bypass $http_upgrade; # 设置Cookie标记当前应用 add_header Set-Cookie "APP_ID=my-app-1; Path=/; HttpOnly; SameSite=Lax"; } location ^~ /my-app-2/ { proxy_pass http://127.0.0.1:4202/; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; proxy_set_header Host $host; proxy_http_version 1.1; proxy_cache_bypass $http_upgrade; add_header Set-Cookie "APP_ID=my-app-2; Path=/; HttpOnly; SameSite=Lax"; }
2. 配置热重载请求的动态路由
在Nginx的http块中定义Cookie与端口的映射,然后在server块中根据Cookie路由:
# 在http块中添加map规则 map $cookie_APP_ID $sockjs_target_port { default 4201; # 默认路由到my-app-1 my-app-2 4202; } # 在server块中处理热重载请求 location ^~ /sockjs-node/ { proxy_pass http://127.0.0.1:$sockjs_target_port/sockjs-node/; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; proxy_set_header Host $host; proxy_http_version 1.1; proxy_cache_bypass $http_upgrade; }
方案三:修改Angular热重载Socket路径(命令行方式)
如果只是临时测试,也可以通过Angular CLI的--socket-path参数(Angular 6+支持)直接指定热重载的Socket路径:
# 启动my-app-1,将热重载Socket路径设为/my-app-1/sockjs-node ng serve --port 4201 --socket-path /my-app-1/sockjs-node # 启动my-app-2,将热重载Socket路径设为/my-app-2/sockjs-node ng serve --port 4202 --socket-path /my-app-2/sockjs-node
然后Nginx的配置和方案一的热重载代理规则一致即可。
内容的提问来源于stack exchange,提问作者Nathan Friend
相关产品推荐
相关产品推荐

