• 作者:老汪软件技巧
  • 发表时间:2024-08-30 00:02
  • 浏览量:

时间是2024年8月28日,当时我正在上班摸鱼,猛然间想起一件令我难堪的事……

大概三个月前,我冲着自己的电脑,大言不惭的大放厥词,我一定要从头好好做一个优秀的管理后台系统。

如今我望着自己两袖清风的项目代码,我悟了,黑神话虎先锋我也打不过,代码我也弄不好,我究竟……

一想到这里我就头脑发热,立志要继续完成自己伟大的愿望(bushi)。

于是乎我打开了自己尘封已久的项目,上次的提交记录还停留在初始化项目。

我 win + R,cmd 快速的打开终端,疯狂的输入指令:

node -v

终端立马给予我回应;

—— v18.20.2 。

原来是 v18.20.2 的node版本啊,就现在而言,还够用!

就在这时,一个声音从我的键盘中发出,那是一个苍老的,沙哑的声音——工欲善其事,必先利其器,而没有规矩不成方圆啊~

我一愣神,难道我的键盘中觉醒了器灵???

这不可能的吧,一定是幻听了!但是这句话立马让我想到了前端编码中比较重要的工具—— ESlint。

我立刻打开了 ESlint 的官方文档,已经更新到 9.x 版本了啊,我仔细地查看先决条件:

必须安装并构建 Node.js(^18.18.0、^20.9.0 或 >=21.1.0)并支持 SSL。(如果你使用的是官方 Node.js 发行版,则始终内置 SSL。)

我的 Node 版本号是 v18.20.2,刚好可以!

我继续查找文档,我马上找到了可以安装和配置 ESlint 的命令:

pnpm create @eslint/config@latest

抑制不住心中的喜悦的同时,我迫不及待地打开 vscode ,找了一个之前创建的 vite 项目,打开终端并在终端中输入了命令:

pnpm create @eslint/config@latest

在我敲下回车的那一瞬间,终端向我发起了一系列的提问:

? How would you like to use ESLint? ... 
  To check syntax only
> To check syntax and find problems

这熟悉的感觉,我没有任何犹豫,疯狂的选择他给我的选项:

√ How would you like to use ESLint? · problems
√ What type of modules does your project use? · esm
√ Which framework does your project use? · vue
√ Does your project use TypeScript? · typescript
√ Where does your code run? · browser
The config that you've selected requires the following dependencies:
​
eslint, globals, @eslint/js, typescript-eslint, eslint-plugin-vue
? Would you like to install them now? » No / Yes  

我肯定需要立刻下载,不然自己的三分钟热度就要过期了。

我果断选择了 pnpm 立刻下载依赖,此番操作之后我已经浑身是汗了,看到终端的提示我才放下心来,eslint开始下载了…

很快下载便完成了,我的心中暗喜 pnpm 就是快!

我立刻打开 package.json 文件,找到 devDependencies,里面赫然多出了几个依赖,都是 ESlint 需要的东西啊~

突然我又发现我的项目文件夹中,多出来了一个文件 —— eslint.config.js,不应该是 .eslintrc.js 吗?等等!!!安装和配置的指令不也应该是下面这样的吗:

pnpm install eslint -D  # 安装
npx eslint --init       # 配置

难道最新版本的 ESlint 已经改变了这些吗?

果然我在下面的官方文档中找到了答案:

运行 npm init @eslint/config 后,你的目录中将有一个 eslint.config.js(或 eslint.config.mjs)文件。

ESLint 配置文件可以命名为以下任意名称:

它应该放在你的项目的根目录下,导出一个 的数组。

原来 9.x 之后的版本已经变成了这个模样,直觉告诉我如果是数组的话,出现相同的规则肯定是后者覆盖前者,这个猜测只能慢慢进行了解了。

我接着往下看,配置对象中只有这几种属性:

这么多属性,大类属性后面可能还有更多的小属性,我肯定不能全都记下来,我心想。

不如先挑几个看起来常用的学一下吧!

name 、files、ignores、rules —— 对象名字、指定的文件、排除的文件、处理的规则,这四个属性看起来也不难,说罢我便开始写了起来:

{
    name: "example",
    files: ["**/*.{js,ts}"],
    ignores: [
        "**/*.config.js",
    ],
    rules: {  "no-undef": "error""no-unused-vars": "error" },
},

对象名称是 example,对于匹配所有文件夹中的 .js 和 .ts 文件,忽略掉所有文件夹中的 .config.js 文件,他们的规则是,直接使用未定义的变量以及变量声明了没有读取或使用值,两者的错误严重性都是 error(2) 。

严重性等级中分为三类:

我分析着刚刚写好的内容,并验证了一下,结果如我所料,确实如此,于是我立马开始完善这部分内容,丰富了规则

import globals from "globals";
import pluginJs from "@eslint/js";
import tseslint from "typescript-eslint";
import pluginVue from "eslint-plugin-vue";
​
export default [
  {
    files: ["src/**/*.{js,mjs,cjs,ts,vue}"],
    ignores: [
      "node_modules/*",
      "dist/*",
      ".git/*",
      ".vscode/",
      "**/*.config.*",
    ],
  },
​
  { languageOptions: { globals: globals.browser } },  // 不加入 window会变成undefined console.log 也会报错
​
  pluginJs.configs.recommended, // js推荐规则
​
  ...tseslint.configs.strict, // 取代 tseslint.configs.recommended
  ...tseslint.configs.stylistic, // 取代 tseslint.configs.recommended
​
  ...pluginVue.configs["flat/essential"],  // vue插件 防止vue出现未知错误
​
  {
    rules: {
      "@typescript-eslint/no-non-null-assertion": "off", // 允许使用 TypeScript 的 Non-null assertion operator
      "@typescript-eslint/no-empty-function": "warn", // 当函数没有内容时会警示
​
      // 当 unused 警惕时,可以用 underscore by pass
      "@typescript-eslint/no-unused-vars": [
        "warn",
        {
          argsIgnorePattern: "^_",
          varsIgnorePattern: "^_",
          caughtErrorsIgnorePattern: "^_",
          destructuredArrayIgnorePattern: "^_",
        },
      ],
​
      "@typescript-eslint/no-unused-expressions": [
        "error",
        {
          allowTernary: true, // 允许 ternary expressions call function. e.g. true ? fn1() : fn2();
        },
      ],
​
      "@typescript-eslint/unified-signatures": "off", // 允许 overload function
​
      "require-await": "error", // async 函数内一定要有 await
​
      eqeqeq: ["error", "always", { null: "ignore" }], // 强制用 === 而不是 ==, 除了 == null 是允许的
​
      "no-constant-condition": ["error", { checkLoops: false }], // 不允许 if(true),但是 white(true) 可以
​
      "no-useless-rename": ["error"], // const { width: width } = dimension <-- 报错.对象解构时 rename 一定要真的换名字 width: width 等于没有
​
      "object-shorthand": ["error"], // const { width: width } <-- 报错, variable name same as object key name is not necessary
​
      "no-restricted-globals": [
        // 不允许直接用 global,必须加上 prefix window.setTimeout 这样。
        "error",
        "localStorage",
        "location",
        "alert",
        "setTimeout",
        "clearTimeout",
        "setInterval",
        "clearInterval",
        "requestAnimationFrame",
        "cancelAnimationFrame",
        "navigator",
      ],
    },
  },
​
  {
    files: ["**/*.vue"],
    languageOptions: { parserOptions: { parser: tseslint.parser } },
    rules: {
      "vue/multi-word-component-names": [
        "warn",
        {
          ignores: ["index", "App", "Register", "[id]", "[url]"],
        },
      ],
    },
  },
];

我十分高兴地欣赏自己的杰作,三分钟热度也在此时失效了,我迫切希望明天可以继续坚持,我关上了eslint的官网,关上了显示器和电脑,也关上了今天的太阳……