eslint-plugin-import Unable to resolve path to module

zhbhun發表於2022-06-19
原文 https://github.com/zhbhun/blo...

eslint-plugin-import 用於檢查 ES Module 的匯入和匯出程式碼,防止檔案路徑和匯入名稱拼寫錯誤的問題。

安裝使用

  1. 安裝

    npm install --save-dev eslint eslint-plugin-import
  2. 配置:.eslintrc

    • 推薦:

      {
          "extends": ["plugin:import/recommended"],
          "plugins": "eslint-plugin-import"
      }
    • TypeScript:

      {
          "extends": [
              "plugin:import/recommended",
              "plugin:import/typescript"
          ],
          "plugins": "eslint-plugin-import"
      }

      ps:需要額外安裝 @typescript-eslint/parsereslint-import-resolver-typescript

模組解析

我們在引入 eslint-plugin-import 外掛後經常會遇到模組無法解析的問題。

Unable to resolve path to module '.../xxx'  import/no-unresolved

通常會出現以下這幾種情況。

  1. 引入了 jsx 或者 vue 模組時缺少副檔名,ESLint 警告找不到模組;

    import Button from "./Button"; // Button.jsx
    // Unable to resolve path to module './Component'

    eslint-plugin-import 預設遵循 node 的模組解析方式,沒有字尾名的模組會先查詢是否有 .js 檔案,沒有的話查詢是否有同名目錄,查詢該目錄是否有 package.json 或 index.js。為了解決這個問題,我們需要修改 eslint-plugin-import 預設解析器的副檔名配置。

    {
        "settings": {
            "import/resolver": {
                "node": {
                    "extensions": [".js", ".jsx"]
                }
            }
        }
    }
  2. 使用了 webpack 等打包工具的模組別名,ESLint 提示找不到模組;

    import Button from "@/components/Button";

    如上文所述,eslint-plugin-import 預設遵循 node 的模組解析方式,而不支援 webpack 的別名。但 eslint-plugin-import 的模組解析是可擴充套件的。為了解決這個問題,我們只需要安裝依賴 eslint-import-resolver-alias,然後按如下方式配置:

    {
      "settings": {
        "import/resolver": {
          "alias": {
            "map": [["@", "./src"]],
            "extensions": [".js", ".jsx"]
          }
        }
      }
    }

    ps:map 的路徑是相對 IED 專案根目錄的,如果 eslintrc 不在根目錄下,建議改用 js 來配置絕對路徑(path.resolve(__dirname, 'src'))。

  3. 引入 jsx 之類非 js 副檔名的程式碼模組時不會進行依賴檢查;

    // Component.jsx
    export const name = "Component";
    
    // index.js
    import Component from "./Component.jsx";

    如上所示的程式碼,Component 並沒有匯出預設模組,而 index.js 卻以預設模組的方式引入,理論上 eslint 應該警告 No default export found in imported module "./Component.jsx"/

    出現這個問題是因為 eslint-plugin-import 預設只會校驗 js 副檔名的模組程式碼,可以按如下配置調整模組支援的副檔名:

    {
        "settings": {
            "import/extensions": [".js", ".jsx"]
        }
    }

配置詳解

import/extensions

import/extensions 為副檔名的模組都會被解析為 ES Module,並檢查目標模組的匯出,預設 ['.js']

{
  "settings": {
    "import/extensions": [
      ".js",
      ".jsx"
    ]
  }
}

如果不在該副檔名範圍的模組被引入時,可以使用命名匯入,也可以用預設匯入,eslint-plugin-import 均不會檢查,否則會檢查。

// Button.js
export default () => null

// Button.css
.button {}

// index.js
import ButtonCSS, { ButtonMainCSS } from './Button.css' // eslint-plugin-import ignore css module
import Button, { ButtonMain } from './Button.js' // `ButtonMain not found in './Component.jsx'`

import/ignore

import/extensions 相反,用於配置哪些模組不要識別為 ESModule,例如:css、scss 和 less 等。

import/core-modules

import/core-modules 用於設定當前專案使用了哪些核心模組,預設內建了 Nodejs 的 fs、path 等模組。這樣在使用引入這些模組時,就不會出現 unresolve 的情況

import/resolver

eslint-plugin-import 預設實現了類似 Node.js 的模組識別機制,但往往無法支撐前端各種各樣的打包環境,例如:webpack 的別名模組,不同框架或語言的自定義副檔名,所以 eslint-plugin-import 開放了 resolver 的自定義配置,可由第三方擴充套件實現自定義的模組解析器。

相關文章