Debugging Nest.js Applications: Examples, Packages & Config
There can be confusion out there given the size of the JS ecosystem. The differences seem pretty trivial, as a lot of tools seem to work in both limited and expanded capacities. But knowing the original or primary intent of a tool like React.js (it’s a library), can make it easier to grasp how it works and with which other JS tools. But this is where the distinctions become important – understanding the role of a progressive framework like Nest.js and how we got here.
Nest.js calls itself a progressive Node.js framework (note Vue.js also defines itself that way). Nest combines a number of developments in the world of JavaScript and positions sees itself filling in the role of providing scalable server-side development (versus frontend).
Sketching the Nest.js Architecture: JS, TypeScript, Node & Express
JavaScript vs. TypeScript
JavaScript is the blood of the web. It’s server-side, shaping web pages. TypeScript is an evolved, object-oriented superset of JS. The extra features do heavy lifting for larger JS projects, primarily by being more specific in code (e.g., explicitly id’ing types of JS variables, hence the name).
With use cases like debugging in particular, type-checking speeds up. You can check large-scale code projects more quickly.
Without supersets like TypeScript, JavaScript wouldn’t have survived in the cloud-native and microservices era.
Plain old French Vanilla JavaScript vs. Node.js
There’s no difference between “vanilla” and “French vanilla,” I just needed to add some flavor to this so I spruced up the h3 here.
Node.js is a JavaScript runtime, over a decade old at the time of writing (not to assume a 2022 tutorial’s longevity into the 2030s, but I’m an optimist).
Ryan Dahl created Node.js with the goal of giving JS (or the websites it constituted) push capability: two-way communication instead of everything depending on the client.
Node is lightweight, so is built for speed and agility – it’s got high throughput while allowing a high number of simultaneous two-way connections. You can also read more about debugging Node.js.
Node scales using a single-threaded connection instead of weaving a new thread for every new connection. Node users have a few options for frameworks, but one of the more popular ones is Express.js.
Nest.js = TypeScript + Node.js (+ other stuff)
Eventually we reach Nest, an increasingly popular “progressive” Node.js framework. Its main reason for being: application architecture. It is built with – and has in mind – TypeScript at its core while supporting basic JS. Simultaneously, it serves as an abstraction layer on top of Express.
Nest has “out-of-the-box” or ready app architecture that it says is highly modeled off of Angular. That is supposed to make it easily scalable, maintainable, testable, and “loosely coupled.” The core element of that architecture is the module, which every Nest.js app is broken into by default. The types of modules – marked by the @module()
decorator – will be one of these four properties: imports
, exports
, controllers
, or providers
.
#Note on Nest Modules
Custom modules, once built, are imported to the root AppModule
via the app.module.ts
file.
Getting Started: A Simple Nest.js App
The only real prerequisite is Node.js, as TypeScript comes packaged with the Nest installation. So the real first step from there is to install the Nest CLI and to open a new project.
Installing and Configuring Nest.js
npm i -g @nestjs/cli
nest new project-name
You’ll have five .ts
files available by default. You’ll see the main project file main.ts
:
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
await app.listen(3000);
}
bootstrap();
Nest is platform-agnostic but comes with two framework options, Express and Fastify, built in. You can customize the main.ts
to create an app in either framework with NestExpressApplication
or NestFastifyApplication
.
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create
(AppModule);
await app.listen(3002);
}
bootstrap();
Run the following command and you’re up and running:
npm run start
Debugging a Nest.js App
As comprehensive as Nest and its documentation are, the one place where its silence is deafening is a detailed rundown of debugging. Considering how many moving parts the Nest.js framework is composed of (Express, Node, TS, etc.), some clarification would be expected. In spite of all that, debugging Nest.js is definitely possible.
In this case, we’re going to show you how to use Rookout to debug Nest. Rookout’s documentation shows you various Node setups, including for TypeScript. We’ll walk through the Nest case here.
Firstly, install the Rookout Node SDK package either by NPM or Yarn:NPM:
npm i -save rookout
OR Yarn:
yarn add rookout
Then add the SDK to your app. You can do that by adding it into your src/main.ts
file.
import { NestFactory } from '@nestjs/core';
import { NestExpressApplication } from '@nestjs/platform-express';
import { AppModule } from './app.module';
const rookout = require('rookout'); rookout.start({ token: ‘somerandomassnumbers123457593903209’ })
async function bootstrap() {
const app = await NestFactory.create<NestExpressApplication>(AppModule);
await app.listen(3010);
}
bootstrap();
Ty–The token here is important for connecting your repo to Rookout. In this case, I put the code in GitHub, but you can easily host your code in another repo like GitLab or Bitbucket.
If you are “transpiling” (syn. ‘decompiling’) or bundling your code, you have to include source maps. TypeScript transpiles into JavaScript, so if you have a TypeScript application as you would with Nest, there are two lines you should add to your tsconfig.json
file:
"sourceMap": true,
"inlineSources": true,
Thus, instead of Rookout alerting you to differences between the two versions of the code, Rookout will know to expect a shift from TypeScript to vanilla JavaScript.
///tsconfig.json file
{
"compilerOptions": {
"module": "commonjs",
"declaration": false,
"noImplicitAny": false,
"removeComments": true,
"sourceMap": true,
"inlineSources": true,
"noLib": false,
"lib": ["es2017"],
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"target": "es6",
"sourceMap": true,
"allowJs": true,
"outDir": "./dist"
},
"include": [
"src/**/*"
],
"exclude": [
"node_modules",
"**/*.spec.ts"
]
}
These instructions will be similar with other JS-related projects. Check out the Rookout SDK docs for moving forward with other JS and Node variants CoffeeScript, Babel, and Webpack.
Finally, Import to Rookout
Open your project in Rookout and head to your main.ts
file. Set breakpoints where you need to and watch the debugging logs flow in.
Conclusion
The objective here was to introduce you to and show you how to take advantage of Nest. This is hardly an exhaustive tutorial, but it did go over examples of debugging Nest.js with Rookout and with VS Code. We tried to show you how different kinds of tools in the JS ecosystem fit together. Rookout is an extremely durable option, meant to fit in with other apps like open-source IDEs and various sorts of frameworks.
Rookout boasts applicability to Node.js, but that encompasses a lot of services in the world of JS and the orbit of Node. That means Rookout works with React, Vue.js, Webpack, Babel, CoffeeScript, Angular.js, Angular, Nest.js, and more. This also includes additional tools, supersets, runtimes, and libraries in the ecosystems of Python, Java, Ruby, Golang, and C# (.NET).
This is a powerful tool for that can debug apps in production without compromising source code security – Rookout never reads your source code and never hosts it.
Happy debugging!