vscode 导入语句排序和删除未使用的导入

11 阅读8分钟

source.organizeImports

vscode 自带设置中配置项:source.organizeImports

// setting.json
"editor.codeActionsOnSave": {
    "source.organizeImports": "explicit" // 仅在显式保存文件时运行
    // 可选其他值: "always" 总是;“never” 从不
},

主要功能:它是 TS/JS 语言服务提供的一个综合性代码操作。除了排序(Sort)外,它更核心的职责是清理(Organize)——自动删除未使用的导入(Unused imports)、合并来自同一模块的多个导入声明。

排序能力:它的排序逻辑完全由 TypeScript 语言服务决定(通常基于字母顺序,并按类型简单分组:第三方库、相对路径等),规则非常固定和死板

eslint-plugin-simple-import-sort

主要功能:专注于精细化排序。它不负责删除未使用的导入(这个通常交由 no-unused-vars 或 TS 自身处理),而是把全部精力放在“如何让 Import 列表看起来绝对整洁、规范”上。

极致的分组自定义:你可以通过 ESLint 配置精确控制导入的顺序。例如:

  1. 绝对路径的第三方库(如 react, lodash
  2. 公司的内部公共模块(如 @components/...
  3. 当前模块的相对路径(./../
  4. 样式文件(如 *.css*.scss)置底 内置排序很难做到如此灵活的多层级自定义分组。

处理特殊语法和副作用:它能很好地处理像 import "side-effect" 这类纯副作用导入,并强制将其固定在最顶部或特定位置。

使用

npm install --save-dev eslint-plugin-simple-import-sort

配置eslint(例如传统的.eslintrc.js)

module.exports = {
  plugins: ["simple-import-sort"],
  rules: {
    "simple-import-sort/imports": "error",
    "simple-import-sort/exports": "error",
  },
};

配置Vscode自动修复(setting.json)

{
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": "explicit"
  }
}

eslint-plugin-simple-import-sortorganizeImports 组合使用

// setting.json
{
  "editor.codeActionsOnSave": {
    // 1. 负责清理未使用的导入
    "source.organizeImports": "explicit",
    // 2. 负责根据 ESLint 规则重新排序
    "source.fixAll.eslint": "explicit"
  }
}

当按下保存时,VS Code 会先执行 organizeImports 清理掉没用的变量/导入,紧接着执行 ESLint 修复,由 simple-import-sort 接管最终的完美排序。

自定义顺序

eslint-plugin-simple-import-sort 允许通过修改 ESLint 配置文件中的 simple-import-sort/imports 规则来自定义排序逻辑。它的核心机制是使用正则表达式匹配导入路径,将匹配到的模块分拣到不同的数组分组中。

一、 核心配置方式

插件通过 groups 数组来定义分组,代码中的导入会按照 groups 数组从上到下的顺序依次排布。每个元素是一个正则表达式数组,表示该组包含哪些导入。

以下是现代项目中最常用的精细化自定义分组示例:

1. 传统配置文件 (.eslintrc.js)
module.exports = {
  plugins: ["simple-import-sort"],
  rules: {
    "simple-import-sort/imports": [
      "error",
      {
        groups: [
          // 1. 副作用导入 (Side effect imports)
          // 例如: import "./global.css"; 或 import "polyfill";
          ["^\u0000"],
​
          // 2. React / Vue 等核心框架包
          ["^react", "^vue"],
​
          // 3. 其他 Node.js 内置模块和第三方 Node 包 (npm packages)
          ["^@?\w"],
​
          // 4. 内部别名路径 (根据项目配置的 path alias 自定义,如 @/ 或 ~/)
          ["^@/components", "^@/utils", "^@/hooks", "^@/"],
​
          // 5. 相对路径导入 (父级目录 -> 同级目录)
          ["^\.\.(?!/?$)", "^\.\./?$"], // 上级目录 ../
          ["^\./(?=.*\/)(?!/?$)", "^\.(?!/?$)", "^\./?$"], // 当前目录 ./
​
          // 6. 样式文件导入 (通常建议放在最后)
          ["^.+\.(css|less|scss|sass|styl)$"]
        ]
      }
    ],
    "simple-import-sort/exports": "error"
  }
};
ESLint Flat Config (eslint.config.js)

如果项目使用的是最新的 ESLint Flat Config 格式:

import simpleImportSort from "eslint-plugin-simple-import-sort";
​
export default [
  {
    plugins: {
      "simple-import-sort": simpleImportSort,
    },
    rules: {
      "simple-import-sort/imports": [
        "error",
        {
          groups: [
            ["^\u0000"],
            ["^react", "^vue"],
            ["^@?\w"],
            ["^@/"],
            ["^\.\."],
            ["^\."],
            ["^.+\.(css|scss)$"]
          ]
        }
      ]
    }
  }
];
正则表达式匹配规则说明

在编写 groups 正则时,有几个常见的匹配技巧:

匹配模式正则表达式匹配示例
副作用导入^\u0000import "./styles.css" (无变量导入)
框架/库^react / ^@angularimport React from 'react'
第三方 npm 包^@?\wimport lodash from 'lodash'import { Button } from '@mui/material'
绝对路径别名^@/^~/import Header from '@/components/Header'
父级相对路径^\.\.import utils from '../../utils'
同级相对路径^\.import localHelper from './helper'
特定类型文件`^.+.(cssscss)$`import './button.scss'

空行分隔: groups 中的每个子数组代表一个独立的分组。插件会自动在两个分组之间插入一个空行。如果你希望某些导入紧贴在一起不产生空行,可以将它们的正则放在同一个子数组里。

组内排序: 在同一个子数组(同一个分组)内部,插件会自动按照 Unicode / 字母顺序进行升序排列,无需额外配置。

更现代化的 eslint-plugin-perfectionist

是什么?

eslint-plugin-perfectionist 是近年来在前端社区(特别是 TS / React / Vue 社区)非常流行的一个格式化/排序插件。它的目标是替代过时的 eslint-plugin-import 排序规则以及 eslint-plugin-simple-import-sort,提供一个开箱即用、配置更人性化、功能更全面的排序方案。

eslint-plugin-simple-import-sort 主要是依靠正则表达式来手动匹配和分组导入,配置起来有时就像在写正则测试题。

perfectionist(追求完美主义者)采用了全新的设计思路:它内置了丰富且语义化的“类型分类”(Type / Preset) ,让你几乎不需要写复杂的正则表达式,就能实现极其优雅的代码排序。

除了排序 Import,它还能帮你排 Object key、Enum、Interface 属性、JSX props 等,是一个全能型的“代码洁癖”插件。

pnpm add -D eslint-plugin-perfectionist

perfectionist/sort-imports

以 ESLint 传统配置 .eslintrc.js 为例:

module.exports = {
  plugins: ["perfectionist"],
  rules: {
    "perfectionist/sort-imports": [
      "error",
      {
        // 1. 排序算法:alphabetical (字母序), natural (自然序,如 1, 2, 10), line-length (按行长度)
        type: "natural", 
        // 2. 排序方向:asc (升序) 或 desc (降序)
        order: "asc",
        // 3. 定义分组(支持开箱即用的语义化关键词)
        groups: [
          "type",                 // TypeScript 类型导入 (import type ...)
          "react",                // 可自定义的特定框架组
          ["builtin", "external"],// Node 内置模块 和 第三方 npm 包
          "internal-type",        // 内部别名的类型导入
          "internal",             // 内部路径 (如 `@/components`)
          ["parent-type", "sibling-type", "index-type"], // 相对路径的类型导入
          ["parent", "sibling", "index"],               // 相对路径导入
          "object",
          "unknown",
        ],
        // 4. 自定义特定匹配组(例如将 react 归为单独一组)
        customGroups: {
          value: {
            react: ["^react$", "^react-dom/.*"],
          },
        },
        // 5. 新建行隔离策略
        newlinesBetween: "always", // 分组之间总是插入空行
      },
    ],
  },
};

ESLint Flat Config (eslint.config.js)

import perfectionist from 'eslint-plugin-perfectionist';
​
export default [
  {
    // 配置适用的文件范围
    files: ['**/*.{js,mjs,cjs,ts,jsx,tsx}'],
    
    // 1. 注册插件
    plugins: {
      perfectionist,
    },
    
    // 2. 配置具体的排序规则
    rules: {
      // 开启 perfectionist 的 import 排序规则
      'perfectionist/sort-imports': [
        'error',
        {
          // 排序算法:'natural'(自然排序,如 file2 排在 file10 前面), 'alphabetical'(标准字母序), 'line-length'(按行长)
          type: 'natural',
          
          // 排序方向:'asc'(升序,A-Z)或 'desc'(降序,Z-A)
          order: 'asc',
          
          // 忽略大小写
          ignoreCase: true,
          
          // 分组配置:定义 import 语句从上到下的排布顺序
          groups: [
            'type',                      // TypeScript 类型导入 (如 import type { Foo } from '...')
            'react',                     // 自定义的 React 框架组(通过下方 customGroups 匹配)
            ['builtin', 'external'],     // Node.js 内置模块 (fs, path) 和第三方 npm 依赖 (lodash, axios)
            'internal-type',             // 内部路径的类型导入
            'internal',                  // 项目内路径别名(通过下方 customGroups 匹配)
            ['parent-type', 'sibling-type', 'index-type'], // 相对路径的各种类型导入
            ['parent', 'sibling', 'index'],                // 相对路径导入:../ (父级), ./ (同级), ./ (index)
            'side-effect',               // 副作用导入(如 import './styles.css' 或 import 'polyfill')
            'style',                     // 样式文件导入(通过下方 customGroups 匹配)
            'object',                    // 对象的 import 形式
            'unknown',                   // 未能归类的其他导入
          ],
          
          // 自定义分组匹配规则(将正则与上面 groups 中的自定义名称关联起来)
          customGroups: {
            value: {
              react: ['^react$', '^react-dom', '^react/.*'],
              style: ['^.+\.(css|less|scss|sass|styl)$'],
            },
            type: {
              react: ['^react$'],
            },
          },
          
          // 分组之间是否插入空行:'always'(总是插入), 'never'(不插), 'ignore'(忽略)
          newlinesBetween: 'always',
          
          // 多行导入语句中,大括号内部的成员(如 import { a, b, c })是否也参与排序
          internalPattern: ['^@/.*'],
        },
      ],
    },
  },
];
  • 原生的 type 识别:相比旧插件需要写一堆复杂的正则去过滤 import typeperfectionist 直接内置了 'type', 'internal-type', 'parent-type' 等语义化分类,能完美将 TS 类型声明统一归置。
  • customGroups 的直观性:通过 customGroups 可以非常直观地把 react 核心库、样式文件(.scss, .css)精准拦截并指定放在特定的组别,不需要死记硬背底层复杂的正则表达式。
  • Flat Config 的纯净性:现代 Flat Config 不再依赖 plugins: ["plugin-name"] 的字符串形式,而是直接导入插件对象并挂载到 plugins 字段中,类型提示和代码维护都变得更加优雅。

比较

比较维度VS Code 内置 (source.organizeImports)eslint-plugin-simple-import-sorteslint-plugin-perfectionist
原理机制TS 语言服务内置正则表达式自由分组语义化预设 (Presets) + 正则拓展
配置难度0(无需配置,但也无法定制)中等(需要懂正则表达式)极低(开箱即用,语义清晰)
Type 导入支持基础需手写 import type 正则原生内置 (type, internal-type 等)
空行管理不支持自动按分组数组插入支持 always / never / ignore
功能范围仅删除无用 + 基础排序仅 Import / Export 排序涵盖 Import、Object、- JSX、Enum 等全套排序
  • perfectionist 是目前最人性化的选择。你不需要去捣鼓类似 ^\u0000^\.\.(?!/?$) 这种晦涩的正则,直接写 "builtin", "external", "internal" 即可完成绝大多数常见分组。

  • 如果你需要严格区分 TypeScript import type

    • perfectionist 对 TS 的类型导入有极其出色的原生支持,可以非常轻松地把所有类型导入放在最顶部或最底部。
  • 搭配 VS Code 使用方式不变:

    • 如果你换成了 perfectionist,它依然是一个 ESLint 插件。你依然可以在 VS Code 中同时开启 source.organizeImports: "explicit"(负责删掉无用 import)和 source.fixAll.eslint: "explicit"(由 perfectionist 负责排序),二者完美配合。

Perfectionist 其他

sort-imports 只是Perfectionist插件提供的一条子规则。

eslint-plugin-perfectionist 是一个全能型的代码结构排序插件,它包含了数十条自动排序规则,几乎涵盖了 JS/TS/React 开发中的所有场景:

规则名称作用对象效果示例
perfectionist/sort-imports模块导入语句自动将 import 按照规则分行排序
perfectionist/sort-exports模块导出语句自动排序 export 导出声明
perfectionist/sort-objects对象 key-value对象中的 key: value 按字母序排列
perfectionist/sort-interfacesTS Interface 属性TS 接口内部的字段名称排序
perfectionist/sort-object-typesTS Type 结构TS 类型别名的属性字段排序
perfectionist/sort-jsx-propsReact JSX 属性<Button onClick="{...}" size="small" type="primary"/> 属性排序
perfectionist/sort-enumsTS Enum 成员枚举变量内部字段排序
perfectionist/sort-union-types联合类型`type Union = 'c'

所有规则都支持快捷键自动修复,执行 npx eslint --fix .

只开启 sort-imports 规则

只想用它的 Import 排序功能,不想让它去动你代码里的对象或 JSX 属性,只配置单条规则即可:

ESLint Flat Config (eslint.config.js)

import perfectionist from 'eslint-plugin-perfectionist';
​
export default [
  {
    plugins: {
      perfectionist,
    },
    rules: {
      // 只开启 import 排序规则
      'perfectionist/sort-imports': [
        'error',
        {
          type: 'natural', // 排序算法:natural(自然序), alphabetical(字母序), line-length(行长度)
          order: 'asc',    // 升序
        },
      ],
    },
  },
];

传统配置 (.eslintrc.js)

module.exports = {
  plugins: ['perfectionist'],
  rules: {
    'perfectionist/sort-imports': [
      'error',
      {
        type: 'natural',
        order: 'asc',
      },
    ],
  },
};

开启整套预设方案(全局整洁)

想让整个项目的对象、接口、类型、JSX 属性等都自动保持完美对齐,直接使用它提供的预设预载配置:

// eslint.config.js (Flat Config)
import perfectionist from 'eslint-plugin-perfectionist';
​
export default [
  // 继承官方推荐的“自然排序”全套预设
  perfectionist.configs['recommended-natural'],
];

开启全套预设后,不需要写复杂的规则设定,它会在保存代码时把导入、组件属性、类型等全部整理妥当。