VS Code 操作 “Delete unused imports” 時,不刪除 React 導入
問題
使用 Delete unused imports 操作時,同時刪掉了 import React from 'react';。

為什么不能刪掉呢?因為代碼 push 到遠程倉庫后會走 CI 流程, CI 流程里有代碼檢查節點進行 ESLint 檢查

CI 節點的 ESLint 規則開發者無法修改或者覆蓋。其中有一條規則是
{
"react/react-in-jsx-scope": "error"
}
它表示當 ESLint 檢測到 JSX 代碼但 React 沒有被正確引入時,會報錯。在 React 17+ 版本中,引入了新的 JSX 轉換方式,可以不需要顯式引入 React。為什么這條規則仍然存在,因為有大量使用低版本 React 的倉庫需要兼容。
接下來我們要做的是:
- 保持 tsx 文件中存在
import React from 'react'; - 保持 delete unused imports 時,它不會被刪掉
尋找原因
把鼠標放到 Button 上,顯示了 2 條被檢測出來的錯誤,一條 ESLint 檢測出的,另一條是 TypeScript 的。

把鼠標放到 React 上,只顯示了 1 條被檢測出來的錯誤,是 TypeScript 的。

這表明使用 Delete unused imports 操作時,是 TypeScript 進行了刪除操作, TypeScript 認為 React 是不必導入的, React 被 TypeScript 識別為未使用的變量。現在我們了解到我們要從 typescript 層面解決這個問題,可能跟 tsconfig 有關。
為什么這里沒有拋出 ESLint 錯誤呢?因為此倉庫的 ESLint 配置與 CI 代碼檢查節點的 ESLint 規則是相同的, 這樣在出現 ESLint 錯誤時,本地開發使用的編輯器才能給出錯誤或警告。由于規則集中包含了
{
"react/react-in-jsx-scope": "error"
}
所以此處就不會有 ESLint 錯誤拋出了。
為什么 React 17- 必須 React Must Be in Scope
由于 JSX 編譯為對 React.createElement 的調用,因此 React 庫也必須始終在 JSX 代碼的范圍內。例如:
const element = <div>Hello</div>;
// React 17 及之前編譯為
const element = React.createElement("div", null, "Hello");
關鍵點?是編譯后的代碼直接調用了 React.createElement(),因此 React必須是一個已定義的變量。
React 17 引入了新的 JSX 轉換(New JSX Transform),不再需要手動導入 React:
function Component() {
return <div>Hello</div>; // React 17+ 配合新 JSX 轉換, 編譯為 _jsxRuntime.jsx(...),無需 React
}
新轉換會從 react/jsx-runtime 自動導入 jsx 或 jsxs 函數,不再依賴 React.createElement。簡單說就是新 JSX 轉換可省略導入,但需配置工具鏈支持,相關工具在編譯階段幫我們做了。
解決
上面我們了解到使用 VS Code 的 Delete unused imports 操作時,是 TypeScript 進行了刪除操作,我們要讓 TypeScript 識別到 React 導入不是一個未被使用的變量。我們還了解了為什么 React 17 之前必須 React Must Be in Scope。
接下來我們看看倉庫的 tsconfig
{
"extends": "./src/.umi/tsconfig.json"
}
使用了 "extends"屬性來繼承另一個配置文件,這是 umi 框架內置的 tsconfig,目前很多元框架都是這么做的。我們可以點跳轉過去,看看這個配置文件內容,只看相關的部分
{
"compilerOptions": {
"jsx": "react-jsx",
}
}
jsx 屬性控制JSX結構在JavaScript文件中的輸出方式。它還有以下值:
- react-jsx:生成.js文件時將JSX轉換為針對生產環境優化的_jsx調用
- react-jsxdev:生成.js文件時將JSX轉換為僅用于開發的_jsx調用
- preserve:生成.jsx文件且保持JSX原樣不變
- react-native:生成.js文件且保持JSX原樣不變
- react:生成.js文件時將JSX轉換為等效的 React.createElement 調用
框架內置的 jsx 被配置為 "react-jsx",這是正常的,因為當前版本的框架使用的 React 版本為 18,顯然,它不需要在 tsx 或 jsx 文件頂部導入 React 了。
所以,我們就找到答案了,只要將 jsx 屬性的值改為 react 就可以解決這個問題。但是我們不能修改框架內置的配置文件,怎么辦呢?可以重新聲明此選項以覆蓋框架內置 tsconfig。
{
"extends": "./src/.umi/tsconfig.json",
"compilerOptions": {
"jsx": "react"
}
}
驗證
修改配置后,我們來重啟下 VS Code TS Server。

quick fix 菜單已經沒有 Delete unused imports 選項了,只有一個未使用變量 Button 被檢測到。

我們把鼠標放到 React 上查看是否還有未使用的 ts 錯誤拋出:

錯誤消失了。我們再導入一個變量驗證 Delete unused imports 是否會刪除 React 的導入。

只刪除了未使用的變量, React 導入沒有被刪除,這樣問題就解決了。

浙公網安備 33010602011771號