How to use express server in dev mode in Angular 17 application builder?

808 views Asked by At

The documentation (https://angular.dev/guide/ssr) states that:

Angular CLI will scaffold an initial server implementation focused on server-side rendering your Angular application. This server can be extended to support other features such as API routes, redirects, static assets, and more. See Express documentation for more details.

And this is fine, but when you run angular (ng serve) the server (server.ts) is not even used so none of our API routes are registered.

What is the recommended approach here? Should we spin our own express.js server for API routes in development?

2

There are 2 answers

0
Suman Mandal On

use npm run watch instead of ng serve . (It does not open the default port 4200). after that you need to run npm run serve:ssr:<project_name> . The project will run on server port http://localhost:4000 But it does not make auto reload. For the time being I found this solution to run server.ts.

0
Ben On

I just ran into this problem myself. The solution I came up with was to (1) create a barebones copy of the server that runs on a different local port, (2) set up ng serve to proxy requests to my API over to that second server, and (3) change my start command over to concurrently run both of these.

1. Barebones API server

I kept all of my API-specific code in /src/api, so this file is /src/api/dev-server.ts:

import express from "express";
import {configureAPI} from "./index";

// This is ONLY used to start the server in development mode; do not use in production, and do not add any special
// handling logic in here.

const server = express();

server.use('/api', configureAPI(express.Router()));
// configureAPI takes a router, adds all my routes, then returns it; do whatever
// server config here you want

const port = process.env['API_PORT'] || 3000;
server.listen(port, () => {
  console.log(`Dev API server listening on port ${port}`);
});

I then set up nodemon with this nodemon.json (you'll need to npm install -D nodemon ts-node):

{
  "ignore": ["**/*.test.ts", "**/*.spec.ts", "node_modules"],
  "watch": ["src/api"],
  "exec": "ts-node src/api/dev-server.ts",
  "ext": "ts"
}

So now, if I run nodemon, my API starts up on port 3000.

2. ng serve proxying

This is actually built in! Make a new file, proxy.conf.json:

{
  "/api":
  {
    "target": "http://localhost:3000",
    "secure": false,
    "changeOrigin": true,
    "cookieDomainRewrite": "localhost:4200"
  }
}

Now if you run ng serve --proxy-config proxy.conf.json, it'll start up your server as normal, but any requests to /api will be sent to the API server running over on port 3000.

3. Putting it all together

First, npm install -D concurrently. Here's the relevant scripts in my package.json:

{
  "scripts": {
    "start": "concurrently 'npm:start:angular' 'npm:start:dev-server'",
    "start:angular": "ng serve --proxy-config proxy.conf.json",
    "start:dev-server": "nodemon",
  }
}

Now, just npm start, and it all just works :D