需要帮助使用Yarn 3和TypeScript在monorepo中设置eslint

iezvtpos  于 2022-11-18  发布在  TypeScript
关注(0)|答案(1)|浏览(267)

我一直在不停地挠头,试图在我的monorepo中设置ESlint配置。我使用Yarn 3.2.4作为包管理器。Here is a GitHub repo containing an example project.。下面是项目结构:

/monorepo
├── /configs
│   ├── /eslint
│   │   ├── index.js
│   │   └── package.json
│   ├── /jest
│   │   ├── index.js
│   │   └── package.json
│   ├── /prettier
│   │   ├── index.js
│   │   └── package.json
│   └── /typescript
│       ├── tsconfig.json
│       └── package.json
├── /packages
│   └── /mypackage
│       ├── .eslintrc.js
│       └── package.json
└── package.json

具有以下内容:

  • /monorepo/package.json(根包.json)
{
  ...,
  "workspaces": [
    "configs/*",
    "packages/*"
  ],
  "scripts": {
    "lint": "yarn workspaces foreach -pt run lint"
  }
}
  • /monorepo/configs/eslint/package.json
{
  ...,
  "name": "@monorepo/eslint-config",
  "main": "index.js",
  "peerDependencies": {
    "eslint": "^8.27.0",
    ...
    * other eslint plugins / configs *
    ...
  }
}
  • /monorepo/configs/eslint/index.js只是我的普通eslint配置文件,它扩展并使用了上面列出的eslint配置包
  • /monorepo/packages/mypackage/package.json
{
  ...,
  "devDependencies": {
    "@monorepo/eslint-config": "workspace:*",
    "eslint": "^8.27.0",
    ...
    * other eslint plugins / configs *
    ...
  }
}
  • /monorepo/packages/mypackage/.eslintrc.js
module.exports = {
  extends: ['@monorepo/eslint-config']
};

现在有了这个配置,IT WORK。但是我发现真正烦人的是,我需要在mono repo的每个包中指定eslint配置/插件依赖项。如果我试图将这些依赖项放在eslint-config包的devDependencies中,并从mypackage包中删除它们(只留下eslint作为dev依赖项),我会收到以下错误消息:

Error: Failed to load plugin '@typescript-eslint' declared in '.eslintrc.js » @monorepo/eslint-config': Your application tried to access @typescript-eslint/eslint-plugin, but it isn't declared in your dependencies; this makes the require call ambiguous and unsound.

Required package: @typescript-eslint/eslint-plugin
Required by: /path/to/monorepo/packages/mypackage/

Require stack:
- /path/to/monorepo/packages/mypackage/__placeholder__.js
Referenced from: /path/to/monorepo/.yarn/__virtual__/@monkvision-eslint-config-virtual-abbbf308a5/1/configs/eslint/index.js
    at Function.require$$0.Module._resolveFilename (/path/to/monorepo/.pnp.cjs:16089:13)
    at Function.resolve (node:internal/modules/cjs/helpers:108:19)
    at Object.resolve (/path/to/monorepo/.yarn/cache/@eslint-eslintrc-npm-1.3.3-9e3a462140-f03e9d6727.zip/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:2325:46)
    at ConfigArrayFactory._loadPlugin (/path/to/monorepo/.yarn/cache/@eslint-eslintrc-npm-1.3.3-9e3a462140-f03e9d6727.zip/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:3392:33)
    at ConfigArrayFactory._loadExtendedPluginConfig (/path/to/monorepo/.yarn/cache/@eslint-eslintrc-npm-1.3.3-9e3a462140-f03e9d6727.zip/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:3212:29)
    at ConfigArrayFactory._loadExtends (/path/to/monorepo/.yarn/cache/@eslint-eslintrc-npm-1.3.3-9e3a462140-f03e9d6727.zip/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:3133:29)
    at ConfigArrayFactory._normalizeObjectConfigDataBody (/path/to/monorepo/.yarn/cache/@eslint-eslintrc-npm-1.3.3-9e3a462140-f03e9d6727.zip/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:3074:25)
    at _normalizeObjectConfigDataBody.next (<anonymous>)
    at ConfigArrayFactory._normalizeObjectConfigData (/path/to/monorepo/.yarn/cache/@eslint-eslintrc-npm-1.3.3-9e3a462140-f03e9d6727.zip/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:3019:20)
    at _normalizeObjectConfigData.next (<anonymous>)

所以我的问题是:有没有办法只声明ESlint插件依赖关系一次(在配置项目中),而不是在我的monorepo的每个包中?
很抱歉发了这么长的帖子,提前谢谢你。

ql3eal8s

ql3eal8s1#

好的,在读了几天关于这个主题的书之后,我想我已经对这个主题有了一个很好的概述。
这实际上是一个与ESlint相关的问题,与Yarn工作区无关。这实际上是ESlint的一个限制,强制共享配置使用对等依赖关系。然而,还有一些变通方法/未来的解决方案。对于感兴趣的人,我将复制/粘贴我为我的团队在这里工作时写的消息:
由于ESlint目前工作方式的限制,共享ESlint配置需要指定其依赖关系(例如其它配置,插件等)作为对等依赖项。这迫使希望使用我们的配置的开发人员手动下载我们的每一个依赖项。这显然是非常麻烦的,有点错过了共享配置的全部意义。当涉及到像官方的[MY COMPANY]存储库这样的monorepos时,情况就更是如此,在这个存储库中,每个包都有同样庞大的ESlint依赖项列表,尽管我们在它们旁边有单个共享ESlint配置。有一些方法可以绕过此限制(@rushstack/eslint-patch等),但它们有自己的限制,被视为“补丁”,而不是实际功能。
然而,在2022年8月,ESlint团队提出了a new config system called ESlint Flat Config。(除其他事项外)共享配置将其依赖项声明为dev(或常规)依赖项,并将它们包含在配置文件中(通过将它们作为节点包导入)。这对我们来说显然是个好消息,因为这基本上意味着前面所列的所有问题都将得到解决。然而,我们需要给ESlint配置和插件给予时间来适应这个新的配置系统,就目前而言。例如,typescript-eslint包在08/11创建了an issue,以更新其配置系统。
这意味着现在,我们需要坚持使用旧的配置和它的对等依赖项,并密切关注包的更新,直到新的ESlint配置系统足够成熟,我们可以迁移到它。
阅读更多有关此主题的参考资料:

相关问题