Useful Development

Angular: how to debug a universal Node Express server with Visual Studio Code

banner image
posted on Jul 18, 2019

This post shows how debug an Angular Universal Node Server in Visual Studio Code. If you are already familiar with Universal skip the next section to get to the good stuff. An example repo can be found here.

Updated for Angular 9: please check the new step at the end of the post.

Setting up a Universal project

Run the follow commands to get the project created and add Angular Universal.

 
# create the project
ng n debuggable-universal-server --interactive=false

cd debuggable-universal-server

# add universal
ng add @nguniversal/express-engine --clientProject debuggable-universal-server
 
After adding universal there will now be a server.ts file under the project root.

universal project folder structure

To build the client app, server app and server run:

 
npm run build:client-and-server-bundles && npm run compile:server
 

Debugging the server

Right now you can run the server with the command:

 
npm run serve:ssr
 
As you add your own code and customise the server it would be ideal to be able to step into the code and debug it. To do this we want to use ts-node to execute the TypeScript file server.ts. Press ctrl+shift+D to bring up the debug view in VS Code. Click the settings icon and press enter to open the launch.json file.

vs code debug view

Here change the configuration to the following:

 
"configurations": [
    {
      "type": "node",
      "request": "launch",
      "name": "ts-server",
      "args": ["${workspaceFolder}\\server.ts"],
      "runtimeArgs": ["--nolazy", "-r", "ts-node/register"],
      "env": {
        "TS_NODE_PROJECT": "tsconfig.server.json"
      },
      "sourceMaps": true,
      "cwd": "${workspaceRoot}",
      "protocol": "inspector",
      "stopOnEntry": true
    }
  ]
 

This configuration will run server.ts using ts-node. By default ts-node will use the project root tsconfig.json but the server needs to use tsconfig.server.json (the module resolution is commonjs for Node). So an environment variable called TS_NODE_PROJECT has been set to direct ts-node at that file.

The last change is to add the node typings to tsconfig.server.json.

 
{
  "extends": "./tsconfig.app.json",
  "compilerOptions": {
    "outDir": "./out-tsc/app-server",
    "module": "commonjs",
    "types": ["@types/node"]
  },
  "angularCompilerOptions": {
    "entryModule": "./src/app/app.server.module#AppServerModule"
  }
}
 
After that make sure the debug configuration ts-server is selected and press f5. VS Code will run the server and step into the code so it can be debugged.

Angular 9 update

Universal has changed quite a bit with version 9. If you follow the above steps the error below will be thrown when trying to debug server.ts

 
C:\code\other samples\ng-debug-universal-server\server.ts:72
const mainModule = __non_webpack_require__.main;
                   ^
zone-node.js:2450
ReferenceError: __non_webpack_require__ is not defined
 

To fix this add a check to see if __non_webpack_require__ is undefined and use Node require if it is.

 
declare const __non_webpack_require__: NodeRequire;

const mainModule =
  typeof __non_webpack_require__ !== 'undefined'
    ? __non_webpack_require__.main
    : require.main;
const moduleFilename = (mainModule && mainModule.filename) || '';
if (moduleFilename === __filename || moduleFilename.includes('iisnode')) {
  run();
}