ESLint 找不到插件

重装系统之后,配置开发环境的时候发现不管是全局安装还是在项目目录下安装都无法使 eslint 正常工作。其实这个问题以前就遇到过,但浪费了大量的时间之后莫名其妙的就可以工作了,也就没有去深究。现在,问题重现,一方面疯狂吐槽 js 开发,自由同时混乱。不管是格式化还是代码检查的规则,高度定制化的同时就是你用你的我用我的搞得白白浪费很多时间。

# 解决问题的过程

正常情况下执行以下命令即可正常使用

npm i -g eslint prettier eslint-plugin-prettier

但不知为何明明已经安装好却报错 eslint-plugin-prettier 无法找到。

根据错误信息 ESLint couldn't find the plugin "eslint-plugin-prettier". 找到模版来自 messages/plugin-missing.txt

再找到 plugin-missing 使用的地方为 lib/cli-engine/config-array-factory.js

从而找到关键点 filePath = ModuleResolver.resolve(request, relativeTo);

继而找到 lib/shared/relative-module-resolver.js 文件中的

module.exports = {
  /**
   * Resolves a Node module relative to another module
   * @param {string} moduleName The name of a Node module, or a path to a Node module.
   *
   * @param {string} relativeToPath An absolute path indicating the module that `moduleName` should be resolved relative to. This must be
   * a file rather than a directory, but the file need not actually exist.
   * @returns {string} The absolute path that would result from calling `require.resolve(moduleName)` in a file located at `relativeToPath`
   */
  resolve(moduleName, relativeToPath) {
    try {
      relativeToPath = '/usr/local/lib/node_modules'; // !!!
      return createRequire(relativeToPath).resolve(moduleName);
    } catch (error) {
      if (
        typeof error === 'object' &&
        error !== null &&
        error.code === 'MODULE_NOT_FOUND' &&
        !error.requireStack &&
        error.message.includes(moduleName)
      ) {
        error.message += `\nRequire stack:\n- ${relativeToPath}`;
      }
      throw error;
    }
  },
};

通过追踪 relativeToPath 的值和来源,得知 eslint 始终从当前工作目录中查找插件,难怪会找不到。不知道为啥会这么搞,按其他提示设计的应该全局 eslint 就在全局 node_modules 文件夹中找,项目的就在项目中找。

暂时的最简单粗暴的解决方法就是增加一行
relativeToPath = '/usr/local/lib/node_modules';
强制让 eslint 去最顶层的 node_modules 目录查找插件。

# 后记

最近天气有点闷热,心情烦躁,遇到这种问题一开始总是不耐烦的,砸了鼠标键盘之后索性丢下不管了。跑个步回来,问题很快就解决。

另外,古老的环境不要贸贸然改动是有道理的,因为你永远不知道这些年对这个环境是做了些什么操作让它能正常工作的🌚