eslint+prettier

多人协作时,引入包的顺序、格式化规范每个人不同,修改同一个文件提交时会存在大量变动、甚至会出现代码冲突。

解决:保存时自动格式化、包的排序统一、删除未使用 import(可选)

排序相关插件:

eslint:eslint-plugin-import、eslint-plugin-unused-imports、eslint-plugin-simple-import-sort(它对自动修复的支持更好)

prettier:prettier-plugin-import-sort、import-sort-style-custom

一、eslint实现

javascript 复制代码
# 核心插件:处理 import 排序和解析
yarn add eslint-plugin-import eslint-plugin-unused-imports eslint-import-resolver-typescript -D 

# (可选)Prettier import 排序插件(和 ESLint 互补)
npm install prettier-plugin-import-sort import-sort-style-custom -D

# Git 钩子依赖:强制提交前校验
npm install husky lint-staged -D

我的项目中是新版扁平配置:ESLint 扁平配置(eslint.config.mjs)和 Prettier 配置(.prettierrc.yaml)

如下安装了eslint-plugin-import eslint-plugin-unused-imports后更改了8处配置:其中@root/**、@resources/**是项目中自己定义的别名,要根据项目中自定义的写:

javascript 复制代码
import { defineConfig } from 'eslint/config'
import tseslint from '@electron-toolkit/eslint-config-ts'
import eslintConfigPrettier from '@electron-toolkit/eslint-config-prettier'
import eslintPluginReact from 'eslint-plugin-react'
import eslintPluginReactHooks from 'eslint-plugin-react-hooks'
import eslintPluginReactRefresh from 'eslint-plugin-react-refresh'
// 1、包排序
import eslintPluginImport from 'eslint-plugin-import'
// 2、删除未使用的import
import eslintPluginUnusedImports from 'eslint-plugin-unused-imports'

export default defineConfig(
  { ignores: ['**/node_modules', '**/dist', '**/out'] },
  //TS 推荐规则
  tseslint.configs.recommended,
  // React
  eslintPluginReact.configs.flat.recommended,
  eslintPluginReact.configs.flat['jsx-runtime'],
  // 通用设置
  {
    settings: {
      react: {
        version: 'detect'
      },
      // 3、import 插件解析 TS,需要安装eslint-import-resolver-typescript否则报错:error  Resolve error: typescript with invalid interface loaded as resolver 
      'import/resolver': {
        typescript: true
      }
    }
  },
  // TS / TSX 文件规则
  {
    files: ['**/*.{ts,tsx}'],
    plugins: {
      'react-hooks': eslintPluginReactHooks,
      'react-refresh': eslintPluginReactRefresh,
      import: eslintPluginImport, //4、包排序
      'unused-imports': eslintPluginUnusedImports //5、删除未使用的import
    },
    rules: {
      // React Hooks
      ...eslintPluginReactHooks.configs.recommended.rules,
      ...eslintPluginReactRefresh.configs.vite.rules,

      /** 6、删除未使用的 import(保存即生效) */
      'unused-imports/no-unused-imports': 'error',
      /** 7、import 顺序强制统一(核心):分组固定、组内字母序、自动空行、TS import type 会自动进 type 分组 */
      'import/order': [
        'error',
        {
          groups: [
            'builtin', // fs, path=>Node.js 内置模块(electron 相关也归此类)
            'external', //第三方依赖: react, electron
            'internal', //内部别名 @/xxx
            ['parent', 'sibling'], // 上级目录../ 同级目录./
            'index', // 当前目录索引(./index)
            'object', // 对象导入(import * as xx from '')
            'type' //类型导入(import type {} from '')
          ],
          pathGroups: [
            {
              pattern: 'react', // 匹配模式
              group: 'external', // 分配到哪个组
              position: 'before' // 在组内的位置
            },
            {
              pattern: '@root/**', // 匹配所有 @root/ 开头的导入
              group: 'internal' // 分配到 internal 组
            },
            {
              pattern: '@resources/**',
              group: 'internal'
            }
          ],
          //排除某些导入类型不受 pathGroups 影响:import type { FC } from 'react' 和import React from 'react' =》react 相关的类型导入不受 pathGroups 影响,类型导入会按照默认规则放在最后的 type 组
          pathGroupsExcludedImportTypes: ['react'],
          // 分组间空行分隔(提升可读性)空格不对时如同组内手动插入了空格偶现不能自动修复,或想去掉空格改成never
          'newlines-between': 'always',
          // 同组内按字母升序、忽略大小写
          alphabetize: {
            order: 'asc',
            caseInsensitive: true
          }
        }
      ],
      // 8、辅助规则:禁止重复导入(自动合并重复的导入语句)如antd中引入了两个组件,但是分两条写的
      'import/no-duplicates': 'error'
    }
  },
  eslintConfigPrettier // 一定要放最后:关闭与 Prettier 冲突的规则
)

配置 VS Code 自动格式化(保存时生效)在 settings.json 中添加(主要是1、2):

javascript 复制代码
{
  "editor.formatOnSave": true, //1、新增保存时格式化
  //2、新的配置使用 "explicit" 值,代码操作只会在明确保存时执行(保存时执行eslint完成包排序、规范校验修复等)
  "editor.codeActionsOnSave": {
    "source.fixAll": "explicit", 
    "source.fixAll.eslint": "explicit"
  },
  "eslint.useFlatConfig": true, //3、明确告诉VSCode ESLint 扩展使用正确的解析器,避免找旧的:传统格式(.eslintrc.js, .eslintrc.json)- 旧版本、Flat Config 格式(eslint.config.js, eslint.config.mjs)- ESLint 9.0+ 的新格式
  "[typescript]": {
    "editor.defaultFormatter": "prettier.prettier-vscode" //不同语言指定格式化工具
  },
  "[javascript]": {
    "editor.defaultFormatter": "prettier.prettier-vscode"
  },
  "[json]": {
    "editor.defaultFormatter": "prettier.prettier-vscode"
  },
  "files.eol": "\n",
  "editor.trimAutoWhitespace": true,
  "files.trimTrailingWhitespace": true,
  "prettier.endOfLine": "lf" //多平台统一换行符
}

对于已存在的项目需要全局格式化一次代码:npm run format:lint

javascript 复制代码
"scripts": {
    "format:lint": "npm run format && npm run lint:fix",
    "format": "prettier --write .",
    "lint": "eslint --cache . --ext .js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts",
    "lint:fix": "eslint --cache . --ext .js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix",
    //...其他
}

执行npm run lint:fix时报如下错误,需要安装:eslint-import-resolver-typescript

Git 钩子自动处理(提交代码时强制排序)

通过 husky + lint-staged 结合上述任意方案,实现「提交代码前自动格式化 import」,确保团队所有提交的代码都符合排序规范。

1. 安装依赖

javascript 复制代码
# 安装 husky 和 lint-staged
npm install husky lint-staged -D

#初始化 husky(只做一次),执行后会得到.husky/pre-commit,并且 package.json 中的scripts会自动多一条:"prepare": "husky"
npx husky init

# 启用 husky
#npx husky install
#npm set-script prepare "husky install"
#npx husky add .husky/pre-commit "npx lint-staged"

2、 package.json 中新增

javascript 复制代码
{
  "lint-staged": {
    "*.{ts,tsx,js,jsx}": [
      "eslint --fix", //不要写"eslint . --fix"=》会扫描 node_modules / dist巨慢,只处理 staged files(lint-staged 默认行为)
      "prettier --write"
    ]
  }
}

顺序是 eslint 在前,prettier 在后

原因:

  • ESLint 负责 import 顺序 / 删除未使用

  • Prettier 负责格式兜底

3、.husky/pre-commit:

去掉默认生成的npm test 新增npx lint-staged:

bash 复制代码
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
npx lint-staged

注意不要在husky中直接跑prettier:prettier --write .=》会改非提交文件,git 状态混乱

当执行:git commit -m "feat: xxx"时,实际执行顺序是:

  1. husky 拦截 commit

  2. lint-staged 找到 本次提交的文件

  3. 对这些文件执行:

    • eslint --fix

      • import/order 自动排序

      • unused-imports 自动删除

    • prettier --write

      • 格式统一
  4. 如果:

    • ✅ 全部通过 → 允许提交

    • ❌ ESLint 报错修不了 → commit 直接失败

使用 VS Code 专用插件(无需配置,开箱即用)

如果不想改项目配置,仅想在编辑器层面实现,可直接安装 VS Code 插件,适合个人开发场景:

1. Import Cost(附带排序功能)
  • 插件名:Import Cost
  • 核心功能:不仅能显示 import 包的体积,还支持右键「Sort Imports」一键排序,支持 React/TS/JS。
  • 使用方式:安装后,在代码文件中右键 → 选择「Sort Imports」即可自动排序。
2. Sort Imports(轻量专用插件)
  • 插件名:Sort Imports(作者:amatiasq)
  • 核心功能:专门处理 import 排序,支持自定义排序规则(在插件设置中调整),可绑定快捷键(默认 Alt+Shift+O)。
  • 优势:无需依赖 ESLint/Prettier,纯编辑器层面处理,启动快。

二、其他实现:

1、.prettierrc.yaml:使用prettier-plugin-import-sort实现

bash 复制代码
singleQuote: true #单引号
semi: false #句尾无分号
printWidth: 100 #单行最大长度100 字符=》超过自动换行
trailingComma: none #多行结构最后一个元素后面是否添加逗号,eg:['item1','item2'] none-不添加  es5-在 ES5 有效的地方添加(对象、数组) all-在所有可能的地方添加(包括函数参数、导入等)
endOfLine: lf
tabWidth: 2 //缩进2个空格
arrowParens: 'avoid', // 箭头函数单个参数省略括号
# # 新增:Prettier import 排序配置
# plugins:
#   - prettier-plugin-import-sort
# importSort:
#   style:
#     groups:
#       - ['^node:', '^electron', '^fs$', '^path$'] # Node/electron 内置
#       - ['^react', '^react-dom'] # React 核心
#       - ['^@?\\w+'] # 其他第三方依赖
#       - ['^@/'] # 项目别名
#       - ['^\\.\\.(?!/?$)', '^\\.\\./?$'] # 上级目录
#       - ['^\\./(?=.*/)(?!/?$)', '^\\.(?!/?$)', '^\\./?$'] # 同级目录
#       - ['^.+\\.s?css$', '^.+\\.less$'] # 样式文件
#     order: asc
#     caseInsensitive: true

2、单独配置@ianvs/prettier-plugin-sort-imports实现排序:importOrder规则按照官方写,下面是测试自定义的

javascript 复制代码
singleQuote: true
semi: false
printWidth: 150
tabWidth: 2
trailingComma: none
plugins:
  - '@ianvs/prettier-plugin-sort-imports'
importOrder:
  - ^electron$
  - ^electron-(.*)$
  - ^@electron-(.*)$
  - ^react$
  - ^react-(.*)$
  - ^(react-router|mobx|mobx-react)(.*)$
  - ^antd$
  - ^@ant-(.*)$
  - <THIRD_PARTY_MODULES>
  - ^@root/(.*)$
  - ^@main/(.*)$
  - ^@renderer/(.*)$
  - ^@/(.*)$
  - ^~/(.*)$
  # 本地 JS 文件
  - '^[./].*(?<!\.less|\.css)$'
  # 样式文件始终最后
  - '^[./].*\.(less|css)$'
  
importOrderParserPlugins:
  - js
  - typescript
  - jsx
  - classProperties
  - decorators-legacy

三、eslint、

1、ESLint

bash 复制代码
npx eslint [目标文件/目录] [参数]



# 检查 src 下所有 TS/TSX 文件
npx eslint src --ext .ts,.tsx
# 修复 src 下所有 TS/TSX 文件的 ESLint 错误
npx eslint src --ext .ts,.tsx --fix
# 输出 JSON 格式报告(便于 CI/CD 解析)
npx eslint src --ext .ts,.tsx --format json > eslint-report.json

npx eslint --cache . --ext .js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix
参数 作用 示例
--fix 自动修复可修复的 ESLint 错误(如 import 排序、未使用变量提示) npx eslint src --fix
--ext 指定要检查的文件扩展名(适配 TS/TSX) npx eslint src --ext .ts,.tsx
--ignore-path 指定忽略文件(如 .eslintignore),默认读取项目根目录的 .eslintignore npx eslint src --ignore-path .eslintignore
--quiet 只显示 error 级别的错误,忽略 warn 级别 npx eslint src --quiet
-c / --config 指定自定义配置文件(默认读取 eslint.config.mjs/.eslintrc) npx eslint src -c ./eslint.config.mjs

2、Prettier

bash 复制代码
# 通用格式
npx prettier [目标文件/目录] [参数]



# 格式化 src 下所有文件(TS/TSX/CSS/MD 等)
npx prettier src --write
# 只格式化 TS/TSX 文件
npx prettier src/**/*.{ts,tsx} --write
# 只格式化 TS/TSX 文件
npx prettier src/**/*.{ts,tsx} --write

# 配置.prettierignore
npx prettier --write .
参数 作用 示例
--write 自动格式化文件(核心参数,修改原文件) npx prettier src --write
--check 检查文件是否符合格式规范(不修改文件,仅输出不符合的文件) npx prettier src --check
--config 指定自定义配置文件(默认读取 .prettierrc.yaml/.prettierrc.js) npx prettier src --config .prettierrc.yaml
--ignore-path 指定忽略文件(如 .prettierignore) npx prettier src --ignore-path .prettierignore
--parser 指定解析器(如 tsx,默认自动识别) npx prettier src --parser tsx
相关推荐
web小白成长日记2 小时前
深入理解 React 中的 Props:组件通信的桥梁
前端·javascript·react.js
tjswk20082 小时前
在ios上动态插入元素的列表使用:last-child样式可能不能及时生效
前端
小小荧2 小时前
CSS 写 SQL 查询?后端慌了!
前端·sql
小高0072 小时前
🔥3 kB 换 120 ms 阻塞? Axios 还是 fetch?
前端·javascript·面试
千寻girling2 小时前
面试官 : “ Vue 选项式api 和 组合式api 什么区别? “
前端·vue.js·面试
小二·2 小时前
从零手写《超级玛丽》——前端 Canvas 游戏开发与物理引擎
前端·游戏
da_vinci_x2 小时前
【2D场景】16:9秒变21:9?PS “液态缩放” + AI 补全,零成本适配全面屏
前端·人工智能·游戏·aigc·设计师·贴图·游戏美术
南知意-3 小时前
3.3K Star ! 超级好用开源大屏设计器!
前端·开源·开源项目·工具·大屏设计