NestJs项目的Lint配置

249 阅读3分钟

1. 创建项目

npx create-next-app

// 选择cli中的预设问题,生成项目脚手架
Ok to proceed? (y) y
√ What is your project named? ... nextjs-demo
√ Would you like to use TypeScript? ... Yes
√ Would you like to use ESLint? ... Yes
√ Would you like to use Tailwind CSS? ... Yes
√ Would you like your code inside a `src/` directory? ...Yes
√ Would you like to use App Router? (recommended) ... Yes
√ Would you like to use Turbopack for `next dev`? ...No
√ Would you like to customize the import alias (`@/*` by default)? ...Yes
√ What import alias would you like configured? ... @/*

打开项目

cd next*
code .

分析 eslint

脚手架中的修改.eslintrc.json 文件

{
    "extends": [
        "next/core-web-vitals",
    ],
}
  • next/core-web-vitals

    •   主要是用来识别和修复可能影响网页性能、可访问性和用户体验的代码(如检查是否使用 next/image 优化图片等)

2. 优化

typescript-eslint/recommended

  • 添加了专门针对 TypeScript 语法的检查

  • 自身配置和继承配置了很多工具插件及其规则来解析和处理 TypeScript 文件

    • 内部配置了@typescript-eslint/parser这个插件,用来将ts转为js, 再转成AST,以便eslint检查语法规则问题,因为Eslint本身不能直接识别 TypeScript。

安装

pnpm i -D @typescript-eslint/eslint-plugin @typescript-eslint/parser

修改 tsconfig.json

{
  "compilerOptions": {
    "lib": ["dom", "dom.iterable", "esnext"],
    "allowJs": true,
    "skipLibCheck": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "noEmit": true,
    "incremental": true,
    "esModuleInterop": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "jsx": "preserve",
    "baseUrl": "src",
    "downlevelIteration": true,
    "paths": {
      "@/*": ["./*"]
    },
    "plugins": [
      {
        "name": "next"
      }
    ],
    "typeRoots": ["./node_modules/@types"],
    "strictNullChecks": true
  },
  "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
  "exclude": ["node_modules"]
}

eslint-plugin-tailwindcss

  • 如果使用了 Tailwind CSS 推荐安装 eslint-plugin-tailwindcss
pnpm i tailwindcss eslint-plugin-tailwindcss --save-dev

eslint.config.mjs

{
    "extends": [
        "next/core-web-vitals",
        "plugin:@typescript-eslint/recommended",
        "plugin:tailwindcss/recommended"
    ],
    "rules": {
        "tailwindcss/classnames-order": "off",
        "tailwindcss/no-custom-classname": "off", 
    }
}

eslint-plugin-unused-imports

pnpm i eslint-plugin-unused-imports --save-dev

eslint.config.mjs

{
    "plugins": [
        "unused-imports"
    ],
    "rules": {
        "unused-imports/no-unused-imports": "warn",
        "unused-imports/no-unused-vars": [
            "warn",
            {
                "ignoreRestSiblings": true,
                "vars": "all",
                "varsIgnorePattern": "^_",
                "args": "none",
                "argsIgnorePattern": "^_"
            }
        ]
    }
}

3. 配置 prettier

Prettier 是一个代码格式化工具,专注于代码风格(如缩进、引号、分号等);

  • 安装依赖

    •       pnpm i  prettier eslint-plugin-prettier eslint-config-prettier @ianvs/prettier-plugin-sort-imports --save-dev
      
    • @ianvs/prettier-plugin-sort-imports
    •   用来统一项目的模块导入顺序:内置模块 > 第三方依赖 > 本地模块
    • eslint-config-prettier
    •   ESLint 既能检查代码质量(如未使用的变量),也能检查代码风格;当两者同时使用时,如果 ESLint 的格式规则和 Prettier 不一致,会产生冲突;
    •   eslint-config-prettier 作用是关闭所有与 Prettier 冲突的 ESLint 规则,从而让 ESLint 和 Prettier 可以和谐共存。
  • 添加 prettier.config.js 文件

    •       /** @type {import('prettier').Config} */
            module.exports = {
              endOfLine: 'lf',
              semi: true,
              singleQuote: true,
              tabWidth: 2,
              trailingComma: 'es5',
              importOrder: [
                '^(react/(.*)$)|^(react$)',
                '^(next/(.*)$)|^(next$)',
                '<THIRD_PARTY_MODULES>',
                '',
                '^types$',
                '^@/types/(.*)$',
                '^@/config/(.*)$',
                '^@/lib/(.*)$',
                '^@/hooks/(.*)$',
                '^@/components/ui/(.*)$',
                '^@/components/(.*)$',
                '^@/styles/(.*)$',
                '^@/app/(.*)$',
                '',
                '^[./]',
                '',
                '<TYPES>^[./]',
                '<TYPES>^react',
                '<TYPES>^next',
                '<TYPES>^@/',
                '<TYPES>',
              ],
              importOrderParserPlugins: ['typescript', 'jsx', 'decorators-legacy'],
              importOrderTypeScriptVersion: '5.1.6',
              plugins: ['@ianvs/prettier-plugin-sort-imports'],
            };
      
  • Eslint配置文件配置prettier

    •   prettier 设置为 warn,否则会被识别为报错
    •   eslintrc.json
    •       {
                "extends": [
                    "next/core-web-vitals",
                    "plugin:@typescript-eslint/recommended",
                    "plugin:prettier/recommended",
                    "plugin:tailwindcss/recommended"
                ],
                "plugins": [
                    "unused-imports"
                ],
                "rules": {
                    "@typescript-eslint/no-explicit-any": "off",
                    "@next/next/no-html-link-for-pages": "off",
                    "react/jsx-key": "off",
                    "tailwindcss/classnames-order": "off",
                    "tailwindcss/no-custom-classname": "off",
                    "prettier/prettier": [
                        "warn"
                    ],
                    "unused-imports/no-unused-imports": "warn",
                    "react-hooks/exhaustive-deps": "off",
                    "unused-imports/no-unused-vars": [
                        "warn",
                        {
                            "ignoreRestSiblings": true,
                            "vars": "all",
                            "varsIgnorePattern": "^_",
                            "args": "none",
                            "argsIgnorePattern": "^_"
                        }
                    ]
                }
            }
      

检查配置是否生效

在配置eslint的过程中可能会因为种种原因导致eslint校验不生效,比如

  • 配置文件的问题
  • 依赖版本号的问题
  • 其他

需要一一去排查,如果修改了配置请重启vscode。

查看 编辑器内校验是否生效

打开一个被检测的文件,然后输入一些错误格式

查看校验是否生效

next lint --file .commitlintrc.js --file .lintstagedrc.js --file prettier.config.js --file src\app\layout.tsx --file tailwind.config.ts

npx tsc --noEmit

注意:有些ts校验的报错,只有在 tsc 时才会暴露出来,比如 console.log(a)

4. 添加 huskylint-staged

安装

pnpm i -D lint-staged

配置钩子

npx husky init

  • 修改 钩子文件 .husky/pre-commit
npx lint-staged
  • 会修改 package.json中的配置
{
  "scripts": {
    "dev": "next dev --turbopack",
    "build": "next build",
    "start": "next start",
    "lint": "next lint",
    "prepare": "husky install"
  },
}

添加配置文件

.lintstagedrc.js

const path = require('path')
 
const buildEslintCommand = (filenames) =>
  `next lint --file ${filenames
    .map((f) => path.relative(process.cwd(), f))
    .join(' --file ')}`
 
module.exports = {
  '*.{ts,tsx}': () => 'npx tsc --noEmit',
  '*.{js,jsx,ts,tsx}': [buildEslintCommand],
}
  • 这里又用tsc检测又用next lint检查的原因是,有些报错next lint检测不到,如console.log(aa)

5. 配置commitlint

  • 作用:规范提交信息
  • 格式:git commit -m '类型: 描述性文字'
类型说明
build编译相关的修改,例如发布版本、对项目构建或者依赖的改动
ci持续集成修改(CI配置或脚本的变更)
docs文档修改(README、CHANGELOG、注释等)
feat新增功能/特性
fixBug修复
perf性能优化(提升运行效率、改善用户体验等)
refactor代码重构(既不修复bug也不增加新功能的代码结构调整)
revert版本回退(撤销之前的某次commit)
style代码样式调整(空格、格式化等,不改变代码逻辑)
test测试相关(新增/修改测试用例)
chore其他修改(构建流程、工具配置、依赖管理等杂项变更)

使用

  • 安装

    •       pnpm i -D commitlint @commitlint/config-conventional
      
  • 配置钩子

    • 手动创建钩子文件 .husky/commit-msg,并写入内容
    •       npx --no -- commitlint --edit $1
      

注意:window电脑,使用 echo "npx --no-install commitlint --edit $1" > .husky/commit-msg的话会出现报错。

  • 配置commitlint

    • 修改package.json

      •       {
                  // ...
                  "commitlint": {
                      "extends": [
                          "@commitlint/config-conventional"
                      ]
                  }
              }
        
    • 或者创建.commitlintrc.js文件

      •       module.exports = {
                  extends: ['@commitlint/config-conventional']
              };
        

6. 配置postcss

在 Next.js 中集成 PostCSS 非常简单,因为 Next.js 已经内置了 PostCSS 支持

修改配置文件postcss.config.js

module.exports = {
  plugins: {
    tailwindcss: {},
    autoprefixer: {},
  },
};