代码检查器简介 – Prettier、ESLint 和 StandardJS

简而言之,linter 是一种分析源代码并标记代码和样式中的错误和 bug 的工具。这个术语起源于 1978 年,来自一个名为 lintUnix 实用程序,该实用程序评估用 C 语言编写的源代码,由贝尔实验室的计算机科学家 Stephen C. Johnson 在调试他正在编写的 Yacc 语法时开发。今天,我们在本书中关注的工具是 PrettierESLintStandardJS。让我们分别了解一下它们。

Prettier

Prettier 是一种代码格式化工具,支持多种语言,如 JavaScriptVueJSXCSSHTMLJSONGraphQL 等。它可以提高代码的可读性,并确保你的代码符合它为你设置的规则。它为你的代码行设置了长度限制;例如,看一下下面的单行代码:

hello(reallyLongArg(), omgSoManyParameters(), IShouldRefactorThis(), isThereSeriouslyAnotherOne())

上面的代码被认为单行过长且难以阅读,因此 Prettier 会为你将其重新排版成多行,如下所示:

hello(
  reallyLongArg(),
  omgSoManyParameters(),
  IShouldRefactorThis(),
  isThereSeriouslyAnotherOne()
);

此外,任何自定义或混乱的样式也会被解析和重新排版,如下例所示:

fruits({ type: 'citrus' },
'orange', 'kiwi')

Prettier 会将其打印并重新格式化为以下更整洁的格式:

fruits({ type: 'citrus' }, 'orange', 'kiwi');

然而,如果 Prettier 在你的代码中找不到分号,它会为你插入它们,就像上面的示例代码一样。如果你像本书中的所有代码一样,更喜欢代码中没有分号,你可以通过以下步骤关闭此功能:

  1. 通过 npmPrettier 安装到你的项目中:

    $ npm i prettier --save-dev --save-exact
  2. 解析特定的 JavaScript 文件:

    $ npx prettier --write src/index.js

    或者,解析递归文件夹中的所有文件:

    $ npx prettier --write "src/**/*"

    甚至尝试并行文件夹中的文件:

    $ npx prettier --write "{scripts,config,bin}/**/*"

在使用 --write 选项就地提交任何更改之前(注意!),你可以使用其他输出选项,例如:

  • 使用 -c--check 来检查给定的文件是否已格式化,并在之后打印一个用户友好的摘要消息,其中包含未格式化文件的路径。

  • 使用 -l--list-different 来打印与 Prettier 的格式不同的文件名。

有关此工具的更多信息,请访问 https://prettier.io/。

现在让我们看一下如何在下一节中配置此工具。

配置 Prettier

Prettier 提供了许多自定义选项。你可以通过以下方式配置 Prettier

  • JavaScript 对象形式的 prettier.config.js.prettierrc.js 脚本

  • 使用 prettier 键的 package.json 文件

  • YAMLJSON 格式的 .prettierrc 文件,可带有可选扩展名:.json.yaml.yml

  • TOML 格式的 .prettierrc.toml 文件

即使你可以选择不自定义,最好还是自定义 Prettier。例如,Prettier 默认强制使用双引号并在语句末尾打印分号。如果我们不想要这些默认设置,可以在项目根目录下创建一个 prettier.config.js 文件。让我们在已经创建的 API 中(我们在 GitHub 仓库的 /chapter-14/apps-to-fix/koa-api/ 中创建了一个副本)使用以下配置,步骤如下:

  1. 在我们的项目根目录下创建一个 prettier.config.js 文件,其代码如下:

    // prettier.config.js
    module.exports = {
      semi: false,
      singleQuote: true
    }
  2. 使用以下命令解析 /src/ 目录中的所有 JavaScript 代码:

    $ npx prettier --write "src/**/*"

    正如你所见,当你运行 npx prettier --write "src/*/" 时,所有文件都会在终端上列出:

    src/config/google.js 40ms
    src/config/index.js 11ms
    src/core/database/mysql.js 18ms
    src/index.js 8ms
    ...

    Prettier 将突出显示已重新打印和格式化的文件。

    有关更多格式选项,请查看 https://prettier.io/docs/en/options.html。你可以在我们的 GitHub 仓库中的 /chapter-14/prettier/ 找到此示例。

看到你的代码如此轻松地被 “美化”,是不是很棒?让我们继续下一个 linterESLint,看看它如何在下一节中帮助我们整理代码。

ESLint

ESLint 是一个可插拔的 JavaScript 代码检查工具。它的设计使得所有规则都完全可插拔,并允许开发人员自定义代码检查规则。ESLint 附带了一些内置规则,以便开箱即可使用,但你可以在任何时候动态加载规则。例如,ESLint 不允许对象字面量中出现重复的键(no-dupe-keys),对于以下代码,你将会收到一个错误:

var message = {
  text: "Hello World",
  text: "qux"
}

在该规则下,正确的代码如下所示:

var message = {
  text: "Hello World",
  words: "Hello World"
}

ESLint 将标记上述错误,我们必须手动修复它。但是,可以使用命令行中的 --fix 选项来自动修复那些无需人工干预即可轻松修复的问题。让我们看看如何在以下步骤中进行操作:

  1. 通过 npm 在你的项目中安装 ESLint

    $ npm i eslint --save-dev
  2. 设置一个配置文件:

    $ ./node_modules/.bin/eslint --init

    你将被问到一系列类似于以下的问题:

    ? How would you like to use ESLint? To check syntax, find problems,
      and enforce code style
    ? What type of modules does your project use? JavaScript modules
      (import/export)
    ? Which framework does your project use? None of these
    ? Where does your code run? (Press <space> to select, <a> to
      toggle all, <i> to invert selection)Browser
    ? How would you like to define a style for your project? Use
      a popular style guide
    ? Which style guide do you want to follow? Standard
      (https://github.com/standard/standard)
    ? What format do you want your config file to be in? JavaScript
    ...
    Successfully created .eslintrc.js file in /path/to/your/project

    这些问题可能会因你为每个问题选择的选项/答案而有所不同。

  3. lintlint-fix 脚本添加到 package.json 文件:

    "scripts": {
      "lint": "eslint --ignore-path .gitignore .",
      "lint-fix": "eslint --fix --ignore-path .gitignore ."
    }
  4. 创建一个 .gitignore 文件,其中包含我们希望 ESLint 忽略的路径和文件:

    // .gitignore
    node_modules
    build
    backpack.config.js
  5. 启动 ESLint 以扫描错误:

    $ npm run lint
  6. 使用 lint-fix 修复这些错误:

    $ npm run lint-fix

你可以在 https://eslint.org/docs/rules/ 上查看 ESLint 规则列表。ESLint 中的规则按类别分组:可能出现的错误、最佳实践、变量、风格问题、ECMAScript 6 等等。默认情况下,没有任何规则是启用的。你可以在配置文件中使用 "extends": "eslint:recommended" 属性来启用报告常见问题的规则,这些规则在列表中带有一个复选标记 (✓)。

有关此工具的更多信息,请访问 https://eslint.org/。

现在让我们看一下如何在下一节中配置此工具。

配置 ESLint

正如我们之前提到的,ESLint 是一个可插拔的 linter。这意味着它是完全可配置的,你可以关闭所有规则、部分规则,或者混合自定义规则,使 ESLint 特别适合你的项目。让我们在已经创建的 API 中使用 ESLint,采用以下配置之一。配置 ESLint 有两种方法:

  • 直接在文件中使用带有 ESLint 配置信息的 JavaScript 注释,如下例所示:

    // eslint-disable-next-line no-unused-vars
    import authenticate from 'middlewares/authenticate'
  • 使用 JavaScriptJSONYAML 文件为整个目录及其所有子目录指定配置信息。

使用第一种方法可能很耗时,因为你可能需要在每个 .js 文件中提供 ESLint 配置信息,而第二种方法只需要在一个 .json 文件中配置一次。因此,让我们在以下步骤中为我们的 API 使用第二种方法:

  1. 在根目录下创建一个 .eslintrc.js 文件或使用 --init 生成它,并包含以下规则:

    // .eslintrc.js
    module.exports = {
      'rules': {
        'no-undef': ['off'],
        'no-console': ['error'],
        'quotes': ['error', 'double']
      }
    }

    在这些规则中,我们想要确保做到以下几点:

    • 通过将 no-undef 选项设置为 off 来允许使用未声明的变量 (no-undef)。

    • 通过将 no-console 选项设置为 error 来禁止使用 console (no-console)。

    • 通过将 quotes 选项设置为 errordouble 来强制保持使用反引号、双引号或单引号的一致性 (quotes)。

  2. lintlint-fix 脚本添加到 package.json 文件:

    // package.json
    "scripts": {
      "lint": "eslint --ignore-path .gitignore .",
      "lint-fix": "eslint --fix --ignore-path .gitignore ."
    }
  3. 启动 ESLint 以扫描错误:

    $ npm run lint

    如果存在任何错误,你将收到类似以下的报告:

    /src/modules/public/login/_routes/google/me.js
      36:11  error  A space is required after '{'  objectcurly-spacing
      36:18  error  A space is required before '}'  objectcurly-spacing

    即使 ESLint 可以使用 --fix 选项自动修复你的代码,你仍然需要手动修复一些错误,如下例所示:

    /src/modules/public/user/_routes/fetch-user.js
       9:9   error  'id' is assigned a value but never used  no-unused-vars

    有关配置的更多信息,请查看 https://eslint.org/docs/user-guide/configuring。你可以在我们的 GitHub 仓库中的 /chapter-14/eslint/ 找到此示例。

它很用户友好,不是吗?它确实是另一个很棒的工具,就像 Prettier 一样。让我们继续最后一个 linterStandardJS,看看它是如何整理我们的代码的。

StandardJS

StandardJSJavaScript Standard Style 是一种 JavaScript 风格指南、linter 和格式化程序。它是完全固执己见的,这意味着它是完全不可自定义的——不需要配置,因此没有 .eslintrc.jshintrc.jscsrc 文件需要管理。它是不可自定义和不可配置的。使用 StandardJS 最简单的方法是将其全局安装为 Node 命令行程序。让我们在以下步骤中了解如何使用此工具:

  1. 通过 npm 全局安装 StandardJS

    $ npm i standard --global

    你也可以为单个项目本地安装它:

    $ npm i standard --save-dev
  2. 导航到你想要检查的目录,并在终端中键入以下命令:

    $ standard
  3. 如果你本地安装了 StandardJS,则使用 npx 运行它:

    $ npx standard

    你也可以将其添加到 package.json 文件中,如下所示:

    // package.json
    {
      "scripts": {
        "jss": "standard",
        "jss-fix": "standard --fix"
      },
      "devDependencies": {
        "standard": "^12.0.1"
      },
      "standard": {
        "ignore": [
          "/node_modules/",
          "/build/",
          "backpack.config.js"
        ]
      }
    }
  4. 然后,当你使用 npm 运行它时,你的 JavaScript 项目的代码将被自动检查:

    $ npm run jss

    要修复任何混乱或不一致的代码,请尝试以下命令:

    $ npm run jss-fix

即使 StandardJS 是不可自定义的,它也依赖于 ESLintStandardJS 使用的 ESLint 包如下:

  • eslint

  • standard-engine

  • eslint-config-standard

  • eslint-config-standard-jsx

  • eslint-plugin-standard

虽然 Prettier 是一个格式化程序,但 StandardJS 主要是一个 linter,就像 ESLint 一样。如果你在代码中使用 StandardJSESLint--fix,然后再次使用 Prettier 运行它,你会看到任何长行(StandardJSESLint 会忽略这些长行)都会被 Prettier 格式化。

有关此工具的更多信息,请访问 https://standardjs.com/。

你还应该查看标准 JavaScript 规则的摘要:https://standardjs.com/rules.html。你可以在我们的 GitHub 仓库中的 /chapter-14/standard/ 找到一个使用 StandardJS 的示例。

然而,如果你正在寻找一个介于这些工具之间、更灵活和可定制的解决方案,你可以将 PrettierESLint 结合用于你的项目。让我们在下一节中看看如何实现这一点。