In modern development workflows, maintaining clean, readable, and consistent code is essential for collaboration and long-term project sustainability. Linting and code formatting help ensure that your codebase follows consistent styles, reduces errors, and improves the overall quality of the code. Additionally, automating these processes through CI/CD (Continuous Integration/Continuous Deployment) ensures that quality checks are run on every commit, promoting efficient collaboration and reducing the chances of bugs being introduced.
In this module, we will focus on setting up linting, code formatting, and CI/CD integration in a NestJS project to streamline development and maintain code quality.
Table of Contents
- Introduction to Linting, Formatting, and CI/CD
- Setting Up Linting with ESLint
- Setting Up Prettier for Code Formatting
- Integrating Linting and Formatting into CI/CD
- Running Linting and Formatting in Pre-Commit Hooks
- Setting Up Continuous Integration (CI) with GitHub Actions
- Best Practices for Linting, Formatting, and CI/CD
- Conclusion
Introduction to Linting, Formatting, and CI/CD
Before diving into the specifics, let’s first understand the importance of linting, code formatting, and CI/CD integration:
- Linting: The process of checking the code for potential errors, coding style violations, or problematic patterns. Linting helps catch errors early in the development process and ensures that the code adheres to a consistent style.
- Code Formatting: Consistent formatting across the entire codebase helps make the code more readable and easier to maintain. It automatically enforces rules such as indentation, spacing, and line breaks.
- CI/CD Integration: Automating the testing, linting, and formatting checks in a CI/CD pipeline ensures that every change is validated before it is merged into the main branch. This helps maintain code quality and accelerates the development process by detecting issues early.
Setting Up Linting with ESLint
To enforce consistent code quality, we use ESLint in NestJS. ESLint is a static analysis tool for identifying problematic patterns in JavaScript and TypeScript code.
Step 1: Install ESLint and Related Plugins
First, you need to install the necessary ESLint packages for your NestJS project:
bashCopyEditnpm install --save-dev eslint @nestjs/eslint-plugin @typescript-eslint/eslint-plugin @typescript-eslint/parser
Step 2: Initialize ESLint Configuration
Create a .eslintrc.js
file in the root of your project:
bashCopyEdittouch .eslintrc.js
Now, configure the ESLint settings. Below is an example configuration:
jsCopyEditmodule.exports = {
root: true,
parser: '@typescript-eslint/parser',
parserOptions: {
project: './tsconfig.json',
},
plugins: ['@nestjs', '@typescript-eslint'],
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'plugin:@nestjs/eslint-plugin',
],
rules: {
'@typescript-eslint/no-unused-vars': 'warn',
'no-console': 'off',
'@nestjs/no-missing-dependencies': 'warn',
},
};
In this configuration:
- We are using the TypeScript parser for TypeScript files.
- We are extending some recommended ESLint rules, as well as NestJS-specific rules.
- Custom rules like
no-console
andno-unused-vars
can be tailored to fit the needs of your project.
Step 3: Add ESLint Script to package.json
In your package.json
, add a script to run ESLint:
jsonCopyEdit"scripts": {
"lint": "eslint 'src/**/*.ts' --fix"
}
You can now run the linting script with:
bashCopyEditnpm run lint
Setting Up Prettier for Code Formatting
While ESLint helps with code quality, Prettier focuses on formatting. Prettier automatically formats your code to make sure it follows a consistent style.
Step 1: Install Prettier
bashCopyEditnpm install --save-dev prettier eslint-config-prettier eslint-plugin-prettier
Step 2: Create Prettier Configuration
Create a .prettierrc
file to define formatting options. Here’s an example configuration:
jsonCopyEdit{
"semi": true,
"singleQuote": true,
"trailingComma": "all",
"printWidth": 80
}
Step 3: Integrate Prettier with ESLint
In the .eslintrc.js
file, add Prettier as an extension:
jsCopyEditmodule.exports = {
root: true,
parser: '@typescript-eslint/parser',
parserOptions: {
project: './tsconfig.json',
},
plugins: ['@nestjs', '@typescript-eslint', 'prettier'],
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'plugin:@nestjs/eslint-plugin',
'plugin:prettier/recommended',
],
rules: {
'@typescript-eslint/no-unused-vars': 'warn',
'no-console': 'off',
'@nestjs/no-missing-dependencies': 'warn',
'prettier/prettier': 'error',
},
};
Step 4: Add Prettier Script to package.json
Add the following script to your package.json
:
jsonCopyEdit"scripts": {
"format": "prettier --write 'src/**/*.{ts,js}'"
}
Now, you can format your code with:
bashCopyEditnpm run format
Integrating Linting and Formatting into CI/CD
Incorporating linting and code formatting checks into your CI/CD pipeline ensures that any code pushed to your repository adheres to the set rules.
Step 1: Setting Up GitHub Actions (CI)
Create a .github/workflows/ci.yml
file in the root of your project. This file will define the GitHub Actions workflow for continuous integration.
Here’s an example configuration for linting, formatting, and testing:
yamlCopyEditname: CI Workflow
on:
push:
branches:
- main
pull_request:
branches:
- main
jobs:
lint:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Set up Node.js
uses: actions/setup-node@v2
with:
node-version: '14'
- name: Install dependencies
run: npm install
- name: Run linting
run: npm run lint
- name: Run Prettier formatting check
run: npm run format -- --check
test:
runs-on: ubuntu-latest
needs: lint
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Set up Node.js
uses: actions/setup-node@v2
with:
node-version: '14'
- name: Install dependencies
run: npm install
- name: Run tests
run: npm run test
This configuration ensures that:
- Linting is run on every push and pull request to the main branch.
- Prettier is used to check formatting.
- Tests are executed after linting passes.
Running Linting and Formatting in Pre-Commit Hooks
To ensure that linting and formatting checks are always run before commits, you can use Husky and lint-staged to run these checks in a pre-commit hook.
Step 1: Install Husky and lint-staged
bashCopyEditnpm install --save-dev husky lint-staged
Step 2: Set Up Husky
Enable Husky by running:
bashCopyEditnpx husky install
Then, add the following script to your package.json
:
jsonCopyEdit"scripts": {
"prepare": "husky install"
}
Step 3: Configure lint-staged
Add the following lint-staged
configuration to your package.json
:
jsonCopyEdit"lint-staged": {
"*.ts": [
"eslint --fix",
"prettier --write"
]
}
Now, every time you commit, Husky will run the configured linting and formatting checks.
Best Practices for Linting, Formatting, and CI/CD
- Enforce Linting and Formatting Locally and Remotely: Set up Husky pre-commit hooks and CI/CD pipelines to enforce linting and formatting both locally and on remote branches.
- Automate Testing in CI: Integrate automated tests into your CI pipeline to run with every commit or pull request.
- Use Strict Rules: Use stricter linting and formatting rules to catch issues early and maintain consistency across the codebase.
- Keep the CI Configuration Simple: Focus on the essential tasks like linting, formatting, and testing in your CI pipeline to ensure fast feedback.
Conclusion
In this module, we have explored how to set up linting and code formatting in a NestJS project using ESLint and Prettier. We also integrated these tools into a CI/CD pipeline with GitHub Actions to automate quality checks on every commit or pull request. Finally, we explored how to run linting and formatting checks using Husky and lint-staged in pre-commit hooks to enforce code quality locally.
By automating these processes, you ensure that your project maintains high standards of code quality, improving collaboration and reducing errors in production.