Skip to content

[Startup MVP Recipes #3] Nest.js Linting (ESLint, Prettier) supports

Credits to

https://v.pincman.com/courses/64.html?chapter=1

Install NPM packages for dev

npm install typescript \
eslint \
prettier \
@typescript-eslint/parser \
@typescript-eslint/eslint-plugin \
eslint-config-airbnb-base \
eslint-config-airbnb-typescript \
eslint-config-prettier \
eslint-plugin-import \
eslint-plugin-prettier \
eslint-plugin-unused-imports \
eslint-plugin-unused-imports \
prettier-plugin-organize-imports \
eslint-plugin-jest --include=dev

This will raise many lint errors on existing files and please make sure to cleanup unused generated files like AppController AppService etc. And also resolve lint errors on existing files (e.g. lint error of default export).

New ESLint and Prettier config

// .eslintrc.js

module.exports = {
  parser: '@typescript-eslint/parser',
  parserOptions: {
    project: 'tsconfig.eslint.json',
    tsconfigRootDir: __dirname,
    ecmaVersion: 'latest',
    sourceType: 'module',
  },
  plugins: [
    '@typescript-eslint',
    'jest',
    'prettier',
    'import',
    'unused-imports',
  ],
  extends: [
    'airbnb-base',
    'airbnb-typescript/base',
    'plugin:@typescript-eslint/recommended',
    'plugin:@typescript-eslint/recommended-requiring-type-checking',
    'plugin:jest/recommended',
    'prettier',
    'plugin:prettier/recommended',
  ],
  root: true,
  env: {
    node: true,
    jest: true,
  },
  ignorePatterns: ['.eslintrc.js'],
  rules: {
    '@typescript-eslint/interface-name-prefix': 'off',
    '@typescript-eslint/explicit-function-return-type': 'off',
    '@typescript-eslint/explicit-module-boundary-types': 'off',
    '@typescript-eslint/no-explicit-any': 'off',
    'no-unused-vars': 0,
    '@typescript-eslint/no-unused-vars': 0,
    'unused-imports/no-unused-imports': 1,
    'unused-imports/no-unused-vars': [
      'error',
      {
        vars: 'all',
        args: 'none',
        ignoreRestSiblings: true,
      },
    ],
    'import/order': [
      'error',
      {
        alphabetize: { order: 'asc', caseInsensitive: false },
        'newlines-between': 'always-and-inside-groups',
        warnOnUnassignedImports: true,
      },
    ],
    'import/no-extraneous-dependencies': [
      'error',
      {
        devDependencies: [
          '**/*.test.{ts,js}',
          '**/*.spec.{ts,js}',
          './test/**.{ts,js}',
          './scripts/**/*.{ts,js}',
        ],
      },
    ],
  },
};

Some of the ignores are not used yet but still good to paste in first:

# .eslintignore

# credits to https://github.com/NeoSOFT-Technologies/rest-node-nestjs/blob/main/.eslintignore

# /node_modules/* in the project root is ignored by default
# build artefacts
dist/*
coverage/*
# data definition files
**/*.d.ts
# 3rd party libs
/src/public/
# custom definition files
/src/types/
// .prettierrc

{
  "singleQuote": true,
  "arrowParens": "avoid",
  "trailingComma": "all"
}
# .prettierignore

# credits to https://github.com/NeoSOFT-Technologies/rest-node-nestjs/blob/main/.eslintignore

# compiled output
/dist

# Ignore artifacts:
build
coverage
documentation
logs
node_modules

# Ignore all HTML files:
*.html
.gitignore
.prettierignore
.husky

tsconfig changes to support eslint better

// tsconfig.build.json

{
  "extends": "./tsconfig.json",
  "exclude": ["node_modules", "dist", "test", "**/*spec.ts"]
}
// tsconfig.eslint.json

{
  "extends": "./tsconfig.json",
  "includes": ["src", "test", "typings/**/*.d.ts", "**.js"]
}
// tsconfig.json

{
  "compilerOptions": {
    "module": "commonjs",
    "declaration": true,
    "removeComments": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "allowSyntheticDefaultImports": true,
    "target": "es2017",
    "sourceMap": true,
    "outDir": "./dist",
    "baseUrl": "./",
    "incremental": true,
    "skipLibCheck": true,
    "strictNullChecks": false,
    "noImplicitAny": false,
    "strictBindCallApply": false,
    "forceConsistentCasingInFileNames": false,
    "noFallthroughCasesInSwitch": false
  }
}

Then run the app again:

npm run prebuild
npm run start:local

Appendix: I encountered the eslint error afterwards and decide to go with this temporary fix, in main.ts

// eslint-disable-next-line no-void
void bootstrap();

References

Follow Up

use husky and lint-staged:

npm install -D husky lint-staged
// package.json
"husky": {
    "hooks": {
      "pre-commit": "lint-staged"
    },
},
"lint-staged": {
    "src/**/*.{js,jsx,ts,tsx,json,css}": [
        "prettier --write",
        "eslint --fix src/",
        "tslint --fix --project .",
    ]
}

2 thoughts on “[Startup MVP Recipes #3] Nest.js Linting (ESLint, Prettier) supports”

  1. Personally I end up feeling `plugin:@typescript-eslint/recommended-requiring-type-checking` to be too rigorous and annoying to use in real world dev. Choose it only if you really need it

  2. Pingback: [Startup MVP recipes #9] Nest.js TypeORM Postgres Unit Testing (service only)with Jest, pg-mem - James Zhang

Leave a Reply

Your email address will not be published. Required fields are marked *