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.
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
To build the client app, server app and server run:
npm run build:client-and-server-bundles && npm run compile:server
Right now you can run the server with the command:
npm run serve:ssr
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"
}
}
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();
}