WebStorm 自动合并相同的 import 引入
如图所示
git提交时

代码保存时

两处设置的路径
上面两张图分别对应两个不同的触发时机,配置在不同的地方:
git 提交时 — Commit 面板底部的勾选区,勾上 Optimize imports。老版本 WebStorm 在 Settings → Version Control → Commit 里。
代码保存时 — Settings → Tools → Actions on Save,勾上 Optimize imports。这个页面是 WebStorm 2021.2 之后新增的,把原来散落在各处的「保存时自动做什么」集中到了一起。同一页面下还有 Reformat code、Run eslint --fix、Run Prettier 等选项。
Actions on Save 页面右侧可以给每一项配 All file types 或指定文件类型。我的配法是 Optimize imports 只对 JavaScript、TypeScript、Vue 生效,避免它去动别的语言的文件。
Optimize Imports 具体做了什么
这个功能实际做三件事,名字里只体现了一件:
1. 删掉未使用的 import。这是最主要的作用。改代码时删掉一段逻辑,对应的 import 很容易忘删,ESLint 的 no-unused-vars 会报 warning,Optimize Imports 直接帮你清掉。
2. 合并同一来源的多条 import。这是本文标题说的那件事:
// 优化前
import { ref } from 'vue';
import { computed } from 'vue';
import { onMounted } from 'vue';
// 优化后
import { computed, onMounted, ref } from 'vue';
3. 排序。默认按字母序对 import 语句和花括号内的具名导入排序。上面例子里 computed, onMounted, ref 就是排过序的结果。
手动触发的快捷键是 Ctrl + Option + O(macOS)/ Ctrl + Alt + O(Windows),不想开自动的话记这个快捷键就行。
有一类 import 不能删,要加白名单
Optimize Imports 判断「有没有被使用」是基于符号引用分析的,但有些 import 是为了副作用而引入的,代码里根本不出现它的符号名:
// 引入 polyfill,纯副作用
import 'core-js/stable';
// 引入全局样式
import './styles/global.scss';
// 注册 Element Plus 的所有图标
import 'element-plus/dist/index.css';
好消息是 WebStorm 认得这种「无绑定的 import」(import 'xxx' 形式,没有 from 前面的部分),不会删。真正会被误删的是这种:
// 看起来没用到 Vue,但 JSX/TSX 编译后需要它(旧的 JSX transform)
import Vue from 'vue';
// 装饰器场景,类型只在类型位置使用
import { Injectable } from '@nestjs/common';
现代工具链下这类问题少了很多(新的 JSX transform 不需要手动 import React),遇到误删可以在 Settings → Editor → Code Style → JavaScript/TypeScript → Imports 里配置,或者在那一行加注释抑制:
// noinspection ES6UnusedImports
import Something from 'somewhere';
相关的 import 设置值得一起调
Settings → Editor → Code Style → TypeScript(或 JavaScript)→ Imports 标签页下有几项影响日常体验的:
Use paths relative to the project, resource or sources roots — 决定自动导入时生成相对路径(../../utils/format)还是从根开始的路径。前端项目一般配了 @ 别名,这项配合下面一条用。
Use path mappings from tsconfig.json — 勾上之后 WebStorm 会读 tsconfig.json 的 paths 配置,自动导入时生成别名路径。这项非常值得开,不然自动导入永远给你一串 ../../../:
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["src/*"]
}
}
}
配了这个之后自动导入会生成 import { formatDate } from '@/utils/date'。注意 tsconfig.json 里配了 paths 只是让 TS 和 IDE 认,构建工具那边(Vite 的 resolve.alias、webpack 的 resolve.alias)还得单独配一份,两边不一致会出现「IDE 不报错但构建失败」。
Merge imports for members from the same module — 就是本文的合并行为,这里也可以单独控制。
Sort imported members — 花括号内的具名导入是否排序。
Always use import type for type-only imports(TS)— 类型导入自动加 type 关键字:
import type { User } from './types';
import { getUser } from './api';
这项建议开。加了 type 之后打包工具能确定这个 import 只用于类型检查,编译时直接擦除,不会在产物里留下一个无用的模块引用。配合 TS 的 verbatimModuleSyntax 或 isolatedModules 用效果更好。
和 ESLint / Prettier 的分工
这里有个常见的冲突:WebStorm 的 import 排序规则和 ESLint 插件的规则不一致,于是保存时 WebStorm 排一遍、ESLint 又改一遍,来回打架。
我的处理原则是同一件事只交给一个工具:
- 如果项目用了
eslint-plugin-import的import/order规则,或者eslint-plugin-simple-import-sort,那就关掉 WebStorm 的 Optimize Imports 自动执行,改成在Actions on Save里只开Run eslint --fix。让 ESLint 全权负责。 - 如果项目没配 import 相关的 lint 规则,用 WebStorm 的 Optimize Imports 就够了,不用额外装插件。
eslint-plugin-simple-import-sort 的配置比较简洁,值得推荐:
// eslint.config.js (flat config)
import simpleImportSort from 'eslint-plugin-simple-import-sort';
export default [
{
plugins: { 'simple-import-sort': simpleImportSort },
rules: {
'simple-import-sort/imports': 'error',
'simple-import-sort/exports': 'error',
},
},
];
它默认的分组顺序是:副作用导入 → Node 内置模块 → 第三方包 → 别名路径 → 相对路径。这个顺序符合大部分人的直觉,而且因为是 ESLint 规则,CI 里也能检查,不依赖每个人的 IDE 设置。
Prettier 不排 import。Prettier 的设计原则是只管格式不管顺序,调整 import 顺序会改变代码语义(副作用导入的执行顺序),所以它明确不做这件事。看到有人说「Prettier 会帮你排 import」,那是装了 @trivago/prettier-plugin-sort-imports 之类的插件。
保存时自动格式化的取舍
Actions on Save 里最有争议的是 Reformat code。我的建议是开 Prettier / ESLint fix,不开 Reformat code。
原因是 Reformat code 用的是 WebStorm 自己的 Code Style 配置,而项目的格式规范通常由 Prettier 定义。两套规则不完全一致,同一个文件在开了 Reformat 的人和只跑 Prettier 的人手里会被格式化成不同样子,git 里就出现大量与业务无关的格式 diff。
比较稳的组合是:
Actions on Save只勾Run Prettier(或Run eslint --fix).prettierrc提交进 git,作为唯一的格式化真源.editorconfig里设好基础的缩进和换行,让 IDE 的默认行为也对齐- 提交前用 lint-staged 再兜一层,防止有人的 IDE 没配对
这样无论用什么编辑器,产出的格式都一致。

还没有留言,来发表第一条吧~