eslint import/order 在使用打字稿别名时出现故障

eslint import/order breaks down when using typescript aliases

我在大型 React 项目中使用 typescript 路径别名。因此,例如,在我的 tsconfig.json 中,我指定了一些路径别名:

{
  "baseUrl": "./src",
    "paths": {
      "@common/*": ["common/*"],
      "@settings/*": ["settings/*"],
      // other paths
    }
}

很好,现在当我想导入一些模块时,我可以使用这些别名。我们也在使用 eslint,我们使用的规则之一是 import/order。它强制任何来自 node_modules 的东西都应该在任何本地模块之前被导入。我喜欢这个规则。不使用我的别名:

import React, { useEffect } from "react";
import SomeDistantComponent from '../../common/components/SomeDistantComponent'
import { Formik } from 'formik'

这会抛出一个 linting 错误,但是根据 eslint 格式化文件会自动将 formik 导入移到 SomeComponent 导入之上,这正是我想要的。

但是,当使用我的别名时,不会 抛出错误:

import React, { useEffect } from "react";
import SomeComponent from '@common/components/SomeComponent'
import { Formik } from 'formik'

好像 typescript 路径别名欺骗了 import/order 规则,现在该规则失效了。

问题:我的 linter 怎么还能识别这些别名路径?我可以配置此插件的 groupspathGroups options 以正确分组并命令我的别名本地模块出现在我的节点模块之后吗?

奖金问题:

我不一定需要在顺序上区分别名模块和非别名模块。例如

import React, { useEffect } from "react";
import SomeCloseComponent from './SomeCloseComponent'
import SomeComponent from '@common/components/SomeComponent'
import AnotherCloseComponent from './AnotherCloseComponent'
import { Formik } from 'formik'

我可以保留 SomeCloseComponentSomeComponentAnotherCloseComponent 的导入顺序,只要 formik 导入在它们之前进行即可。是否可以将别名导入与非别名导入放在相同的 'priority' 分组级别,这意味着它们不会在它们之间重新排序,但都会在 node_module 导入之后出现?

编辑 - 再次尝试:

根据 Aviv Hadar 的回答,我在我的 eslint 文件中试过了:

"import/order": [
      "warn",
      {
        pathGroups: [
          {
            pattern: "@material-ui/**",
            group: "external",
            position: "after"
          },
          {
            pattern: "@/**",
            group: "internal",
            position: "after"
          }
        ],
        pathGroupsExcludedImportTypes: ["internal", "external", "builtins"],
        groups: [
          "builtin",
          "external",
          "unknown",
          ["internal", "sibling", "parent"],
          "index",
          "object",
          "type"
        ]
      }
    ],

这是因为它将所有以 @ 开头的导入视为内部导入,并将它们与其他内部导入保持在同一级别。所以这不会引起警告:

import { Something } from "@some/aliased/path";
import LocalComponent from "../../local";
import { SomethingElse } from "@another/aliased/path";

这就是我想要的 - 所有内部模块都处于同一分组级别,无论是否使用别名,或 parent/sibling。然而,这个应该显示一个警告,但它没有:

import { Something } from "@some/aliased/path";
import LocalComponent from "../../local";
import { SomethingElse } from "@another/aliased/path";
import { makestyles } from '@material-ui/styles'

最后一次导入确实以 @ 开头,但它是 node_module,应该位于列表的顶部。回想起来,我希望我们选择了不同的别名前缀,但我们没有。有没有办法调整我的配置以正确地将 node_modules 解释为 external,并将它们保留在该组中以便订购?

您需要使用 pathGroups 属性 来指示 eslint@/ 开头的路径的正确位置是 before/after 之一其他组。

我选择使用 ~ 符号而不是 @ 来创建从我的 src 文件夹导入和从以 @ 开头的外部库导入之间的区别,就像这样例如一个:

import {makeStyles} from '@material-ui/core/styles';
import Bar from '~/components/Bar'

所以现在我的文件看起来像这样:

import React from 'react'; // external
import Bar from '~/components/Bar'; // SPECIAL
import {ReactComponent as Logo} from '../logo.svg'; // parent
import './App.css'; // sibling

这是我在 .eslintrc 文件中对 import/order 规则的定义:

    "import/order": [
      "error",
      {
        "pathGroups": [
          {
            "pattern": "~/**",
            "group": "external",
            "position": "after"
          }
        ],
        "groups": [
          "builtin",
          "external",
          "internal",
          "unknown",
          "parent",
          "sibling",
          "index",
          "object",
          "type"
        ]
      }
    ]
  }

如您所见,我正在使用 pathGroups 告诉 eslint 任何以 ~/ 开头的导入的正确位置是 afterexternal组。

因为这里的每个导入都属于不同的组,所以我对此订单所做的任何更改都会导致 ESLint 错误。

P.S. 我在将 eslint-plugin-import 更新为版本 2.23.4

后解决了导入本身的问题