如何为Express+Angular全栈应用配置开发环境热重载?
这套方案不需要写环境判断的临时跨域逻辑,不需要提前构建前端产物,前后端改动各自独立触发热重载,完全匹配生产环境的请求路径逻辑。
1. 配置Angular开发服务代理
利用Angular dev server原生的代理能力,把浏览器发出的API请求透明转发到后端Express服务,从浏览器视角所有请求都发往同个端口,从根源避免跨域问题。
- 在Angular项目根目录新建
proxy.conf.json,配置转发规则,示例(假设Express服务运行在3000端口,所有接口以/api为前缀):
{ "/api/*": { "target": "http://localhost:3000", "secure": false, "changeOrigin": true } }
- 打开
angular.json,找到对应项目的serve配置节点(路径为projects.[你的项目名].architect.serve.options),新增配置项指定代理文件:
"proxyConfig": "proxy.conf.json"
- 前端代码中所有接口请求统一使用相对路径(如
/api/user/list),不要写死带端口的完整后端地址,这套路径在生产环境同域部署时可以直接复用,不需要做环境区分。
2. 解耦前后端热重载逻辑
不需要让nodemon监听前端文件改动、也不需要依赖ng build的产物触发后端重启,两端热重载各自独立运行即可:
- 调整nodemon配置,在
nodemon.json中添加忽略规则,排除前端代码目录,避免前端改动误触发后端服务重启:
{ "ignore": ["src/**", "angular.json", "*.ts", "*.html", "*.scss"] }
后端启动命令保留原有逻辑即可,比如nodemon ./server/index.js,只监听后端服务相关的文件改动。
- 前端启动命令保留原生
ng serve即可,改动前端代码时Angular dev server会自动触发热更新,不需要提前执行构建。
3. 统一开发启动流程
可以用concurrently实现单命令同时启动前后端服务,不需要手动开多个终端:
- 安装依赖:
npm install concurrently -D - 在根目录
package.json中添加脚本:
"scripts": { "start:backend": "nodemon ./server/index.js", "start:frontend": "ng serve", "dev": "concurrently \"npm run start:backend\" \"npm run start:frontend\"" }
执行npm run dev就能同时启动两端服务,直接访问http://localhost:4200即可正常联调。如果不想额外装依赖,也可以开两个终端分别跑前后端启动命令,效果完全一致。
冗余配置清理
完成以上配置后,之前为了开发环境临时添加的CORS跨域允许逻辑可以完全删除:浏览器所有请求都发往Angular dev server的4200端口,不存在跨域场景;生产环境前后端同域部署,同样不需要CORS配置,代码中不会残留环境适配的冗余逻辑。
注意:不要把Angular dev server和Express服务配置为同一个端口,会触发端口冲突;代理是Angular开发服务在自身端口做的请求转发,后端服务照旧运行在自己的端口即可,对外不直接暴露。如果有WebSocket、文件上传等特殊路径的请求,只要在
proxy.conf.json里追加对应的转发规则即可。
内容的提问来源于stack exchange,提问作者Cassiterite

