NestJS Project Structure
Examine the details of the default NestJS project structure.
Project structure
NestJS, unlike other frameworks, offers flexibility in how we structure our projects. However, it’s essential to start with a solid foundation that aligns with best practices and real-world development scenarios.
In this lesson, we’ll delve into the NestJS project structure before discussing the core concepts of the framework. After understanding the project structure, we can navigate and comprehend the framework more effectively. We will also introduce some related concepts at the same time.
Let’s first take a look at what the project structure usually looks like.
Project Root├── src│ ├── app.controller.spec.ts│ ├── app.controller.ts│ ├── app.module.ts│ ├── app.service.ts│ ├── main.ts├── test│ ├── jest-e2e.json│ ├── app.e2e-spec.ts├── package.json├── tsconfig.json├── nest-cli.json├── README.md├── dist
Let’s explore the key components and directories of this structure and discover their roles in the development journey.
Entry point
When launching a NestJS application, it begins execution with main.ts
(line 7), which serves as the entry point for bootstrapping the runtime environment. This process involves several vital steps.
The first step is the setup of the essential dependencies required for our application’s functionality. Next, it initializes the application instance, establishing the core of the NestJS project. During this stage, we can tailor the application to our needs. We can apply middleware (which enhances the request-response cycle), introduce custom global configurations, and integrate third-party tools. As the bootstrap process concludes, our application—which often utilizes Express as the default web server—becomes operational, running on port
Root module
In a NestJS application, app.module.ts
(line 5) serves as the root module. Modules in NestJS are used to organize and encapsulate code, acting as containers for registering controllers, services, and components.
By default, in app.module.ts
, we’ll find the registration of two fundamental components: AppController
(defined in app.controller.ts
, see line 4) and AppService
(defined in app.service.ts
, see line 6). We’ll delve deeper into these components later, but, for now, we need to understand that we import all child modules and declare controllers and providers as needed in the root module.
Controller and service
The controller and service components are vital components that collaborate to manage incoming requests and execute business logic. Within our sample project structure, we encounter the following files:
app.controller.ts
: This serves as our primary NestJS controller, handling incoming HTTP requests.app.service.ts
: This service is injected into theAppController
class, enabling it to manage the application’s business logic.app.controller.spec.ts
(line 3): This file functions as our unit test suite for theapp.controller.ts
component. The.spec
suffix signifies that it contains the test specifications.
Manifest file
The package.json
(line 11) file is the most crucial file in a NestJS project. It’s a JSON file and serves as the project manifest, including script commands, metadata, and project dependencies.
Some of the essential commands in the package.json
file are listed below:
npm run build
: This will trigger the build process, compile the TypeScript, and generate a set of app bundle files that can be deployed to the server.npm run start:dev
: This will start the development web server, allowing hot reload, which enables us to change the code and see the updates reflected without needing to restart the server manually.npm run test
: This will trigger the execution of unit tests in the project.
Given the command examples above, what’s the command to start the app in debug mode?
Feature module
Feature modules, such as UserModule
and AddressModule
, serve as containers for related components, like controllers, services, and potentially other modules. They help maintain a clean and organized codebase by grouping related code in one place.
When developing a NestJS application, we typically generate the skeleton of feature modules using the Nest command line tool.
The following illustration shows a root module and its associated feature modules: UserModule
and AddressModule
.
Using UserModule
as an example, it contains UserController
and UserService
, which handle user-related functionalities.
The CommonModule
module is a shared module that contains utilities or cross-cutting concerns, like logging or authentication.
Tests
There are two types of tests in NestJS. They are detailed below:
Unit tests: Unit tests are typically created as separate files, following a naming convention like
[original-file-name].spec.ts
. For example, we haveapp.controller.ts
in the sample project, so the corresponding unit test file isapp.controller.spec.ts
.E2E tests: E2E tests are placed under the
test
folder, following a naming convention ofe2e
ore2e-spec
. In the sample project, there is a file namedapp.e2e-spec.ts
(line 10). In this course, we use Jest for E2E tests.
Note: Jest is an open-source JavaScript testing framework. It’s popular for its simplicity and good performance. It provides rich features, including parallel execution, snapshot testing, built-in code coverage, and more.
The dist
folder
NestJS applications are often written in TypeScript. TypeScript code needs to be transpiled (converted) into standard JavaScript code to be executed by NodeJS or browsers. The dist
folder is where the transpiled JavaScript code is placed.
When we deploy a NestJS application, we deploy the contents of the dist
folder. Keeping the transpiled code separate from the source code, which is typically found in the src
folder, is a good practice. It ensures that the source code remains clean and that there is a clear separation between development and production code.
Other configuration files and the README file
The example project also has a few configuration files and a README file. They are described below:
tsconfig.json
(line 12): This file contains the TypeScript configuration for our NestJS project. It specifies various TypeScript compiler options.nest-cli.json
(line 13): This file provides the project-specific settings for the NestJS CLI, including paths to directories and the naming convention for generated files.README.md
(line 14): This file is the documentation file for the project. It typically contains the overview, installation instructions, and other details that users need to know.