前端eslint规范

Recently, I've been getting more involved in front-end development. The more I do, the more my mind and my soul get lost in its chaotic world. Even a simple To–Do–List app can easily require a bunch of tools—ESLint, Babel, Webpack, to name a few—and packages just to get started.

最近,我越来越多地参与前端开发。 我做的越多,在混乱的世界中我的思想和灵魂就会迷失的越多。 即使是一个简单的“待办事项”应用程序,也很容易需要一堆工具( 例如ESLint , Babel , Webpack)以及要开始使用的软件包。

Fortunately, there’re many starter kits out there so we don’t have to do everything from the ground up. With them, everything is already set up so we can start writing the first line of code right away. It saves time on repetitive, boring tasks, which can be great for experienced developers.

幸运的是,那里有许多入门工具包,因此我们不必从头开始做所有事情。 有了它们,一切都已经完成,因此我们可以立即开始编写第一行代码。 它节省了重复的,无聊的任务的时间,这对于有经验的开发人员而言可能非常有用。

However, this benefit comes with a price for beginners. Since everything works out of the box, it seems like magic, and they might not know what's really happening under the hood, which is important to understand at some level. Although the learning curve is not as steep as others—try to compare with some tools you've been learning and using, you'll get what I mean—in this chaotic world, we need a survival guide for the journey.

但是,对于初学者来说,这是有代价的。 由于一切都是开箱即用的,因此看起来就像是魔术,他们可能不知道引擎盖下到底发生了什么,这在某种程度上很重要。 尽管学习曲线并不像其他曲线那么陡峭(尝试与您一直在学习和使用的一些工具进行比较,但是您会明白我的意思),在这个混乱的世界中,我们需要旅途的生存指南。

This series will cover fundamental tools of front-end development and what essentials we need to know about them. This will allow us to rule the tools instead of being controlled by them.

本系列文章将介绍前端开发的基本工具以及我们需要了解哪些基本知识。 这将使我们能够统治工具而不是由工具控制。

In it, we’ll focus on the developer experience of each one of these tools. So the goal of this series is to act as a survival guide and to give a high-level overview of each tool, not to serve as documentation.

在本文中,我们将重点介绍上述每种工具的开发人员经验。 因此,本系列文章的目的是充当生存指南,并提供每个工具的高级概述,而不是作为文档。

What will be included:

内容包括:

  • ESLint <- We are here

    ESLint <-我们在这里
  • Babel

    巴别塔
  • Webpack

    Webpack
  • Flow

    流
  • TypesScript

    TypesScript
  • Jest.

    笑话。

Enough of a preface, let's get started with the first tool: ESLint.

序言已足够,让我们开始使用第一个工具:ESLint。

什么是ESLint?为什么要使用它? (What is ESLint and Why should we use it?)

ESLint is, as the name implies, a linter for ECMAScript. And, the definition of a linter is:

顾名思义,ESLint是ECMAScript的一个lint。 而且,短绒的定义是:

a machine for removing the short fibers from cotton seeds after ginning.
轧花后从棉籽中去除短纤维的机器。

Although code and cotton seeds don't have any relationship, regardless of code or cotton seeds, a linter will help make things cleaner and more consistent. We don't want to see the code like this:

尽管代号和棉籽没有任何关系,但无论代号或棉籽如何,短绒棉将有助于使物品更清洁,更一致。 我们不想看到这样的代码:

const count = 1;
const message  =  "Hello, ESLint"
    count += 1

It both looks ugly and has a mistake. Here's when ESLint steps in to help with that. Instead of letting the error be dumped out to the browser console when we run the code, ESLint will catch it as we're typing (well not really: we’ll need editor or IDE extensions for this, which will be covered later).

它看起来丑陋而且有错误。 这是ESLint介入以提供帮助的时候。 在运行代码时,ESLint不会在运行代码时将错误转储到浏览器控制台,而是会在键入时捕获该错误(不是真的:我们将需要编辑器或IDE扩展,稍后将进行介绍)。

Of course, this error isn't difficult to figure out, but wouldn't it be nicer to have an assistant reminding us every time we're about to make a mistake and perhaps auto-correcting it for us? Although ESLint can’t catch all kinds of errors, it at least spares us some effort so we can spend time on other things that matter and need human attention.

当然,这个错误并不难找出,但是每次我们要犯一个错误并可能为我们自动更正时,让助手提醒我们会更好吗? 尽管ESLint不能捕获所有类型的错误,但至少可以节省我们一些精力,因此我们可以将时间花在其他重要的事情上,需要人类的注意。

ESLint如何工作? (How does ESLint work?)

Now that we know what ESLint is and why we need it, let's go a bit deeper and check out how it works. In essence, we can break it down to three big steps.

现在我们知道了ESLint是什么以及为什么需要它,让我们更深入地了解它的工作原理。 从本质上讲,我们可以将其分解为三个大步骤。

解析器 (Parser)

The code that we write is nothing more than a sequence of characters. However, this sequence isn't just random characters: they need to follow a set of rules or conventions that is the grammar forming a language.

我们编写的代码只不过是一个字符序列。 但是,此序列不仅仅是随机字符:它们需要遵循一组规则或惯例,即构成一种语言的语法。

For a human, going from reading text or code to understanding it conceptually takes us little effort. For a computer, this is much more difficult to accomplish. For example:

对于人类来说,从阅读文本或代码到从概念上理解文本,我们几乎无需付出任何努力。 对于计算机,这很难完成。 例如:

const tool = 'ESLint' // 1
  const  tool  =  "ESLint" // 2

As we read the two lines above, we immediately know that they are identical, and can be read as "there's a constant named tool with the value of ESLint". For a computer, which doesn't understand the meaning, these two lines look quite different. As a result, if we feed in raw code to ESLint, it's nearly impossible to do anything.

当我们阅读以上两行时,我们立即知道它们是相同的,并且可以读作“存在一个带有ESLint值的常量命名tool ”。 对于不理解其含义的计算机,这两行看起来完全不同。 结果,如果我们将原始代码提供给ESLint,几乎不可能做任何事情。

When things get complicated and hard to communicate—think of how we can have a computer to understand what we do—abstraction can be an escape. By abstracting a thing, we hide all unnecessary details, reduce noise, and keep everyone on the same page, which eases the communication. In the above example, one space or two spaces don’t matter, neither do single quotes or double quotes.

当事情变得复杂而难以沟通时(例如,我们如何拥有一台计算机来了解我们的工作),抽象化可能是一种逃避。 通过抽象化事物,我们隐藏了所有不必要的细节,减少了噪音,并使每个人都在同一页上,从而简化了沟通。 在上面的示例中,一个空格或两个空格无关紧要,单引号或双引号都不重要。

In other words, that's what a parser does. It converts raw code to an Abstract Syntax Tree (AST), and this AST is used as the medium for lint rules to base on. There are still many steps a parser need to do in order to create an AST—if you're interested in learning more about how an AST is generated, this tutorial has a good overview.

换句话说,这就是解析器的工作。 它将原始代码转换为抽象语法树(AST),并且此AST用作基于lint规则的介质。 解析器创建AST仍需要执行许多步骤-如果您有兴趣了解有关AST生成方式的更多信息,则本教程将为您提供很好的概述。

规则 (Rules)

The next step in the process is to run the AST through a list of rules. A rule is a logic of how to figure out potential existing issues in the code from the AST. Issues here aren't necessarily syntactic or semantic errors, but might be stylistic ones as well. The output given out from a rule will include some useful information for later use like lines of code, positions, and informative messages about the issue.

该过程的下一步是通过规则列表运行AST。 规则是如何从AST中找出代码中潜在的现有问题的逻辑。 这里的问题不一定是句法或语义错误,但也可能是风格上的问题。 规则给出的输出将包含一些有用的信息,供以后使用,例如代码行,位置和有关该问题的信息。

In addition to catching issues, a rule can even auto-correct code if possible. For example, when no-multi-spaces is applied to the code above, it will trim all redundant spaces, which makes the code look clean and consistent.

除了捕获问题之外,规则甚至可以在可能的情况下自动更正代码。 例如,将no-multi-spaces应用于上面的代码时,它将修剪所有冗余空间,这使代码看起来干净且一致。

const  tool  =  "ESLint" // 2
// becomes
const tool = "ESLint" // 2

In different scenarios, a rule can be used at different levels—opted-out, warning only, or strict error—and have various options, which gives us control on how to use the rule.

在不同的情况下,规则可以在不同的级别上使用-停用,仅警告或严格错误-并且具有多种选择,这使我们可以控制如何使用该规则。

结果 (Result)

Here comes the end of the process. With the output from a rule, it's just the matter of how we display it in a human friendly manner, thanks to all the useful information we mentioned earlier. Then from the result, we can quickly point out the issue, where it is, and make a fix, or maybe not.

该过程结束了。 有了规则的输出,这就是我们如何以人类友好的方式显示它的问题,这要归功于我们前面提到的所有有用信息。 然后,从结果中,我们可以快速指出问题所在,找出问题所在,并进行修复,也许不行。

积分 (Integration)

ESLint can be used as a standalone tool with its robust CLI, but that’s a bare-bones way to use ESLint. We don't want to type in a command every time we want to lint code, especially in a development environment. The solution for this is to integrate ESLint into our development environment so we can write code and see issues caught by ESLint all in one place.

ESLint可以通过其强大的CLI用作独立工具,但这是使用ESLint的简单方法。 我们不想每次都想插入代码时都键入命令,尤其是在开发环境中。 解决方案是将ESLint集成到我们的开发环境中,这样我们就可以在一个地方编写代码并查看ESLint捕获的问题。

This kind of integration comes from extensions specific to IDEs or editors. These extensions require ESLint to work since they run ESLint behind the scene—no wonder that we still need to install ESLint along with them, they are nothing without ESLint. This principle applies to other IDE or editor extensions we are using daily.

这种集成来自特定于IDE或编辑器的扩展。 这些扩展要求ESLint可以运行,因为它们在后台运行ESLint-难怪我们仍然需要与它们一起安装ESLint,没有ESLint的话,它们什么都不是。 该原理适用于我们每天使用的其他IDE或编辑器扩展。

Remember the output from a rule we talked above? An extension will use it to display in the IDE or editor. How exactly the output is displayed depends on how the extension is implemented and how the IDE or editor is open to its extensions. Some extensions also take advantage of the abilities of issue correction from rules to change code on save if we enable it.

还记得我们上面讨论的规则的输出吗? 扩展将使用它显示在IDE或编辑器中。 输出的确切显示方式取决于扩展的实现方式以及IDE或编辑器对其扩展的打开方式。 如果我们启用了某些扩展,还可以利用规则中问题更正的功能在保存时更改代码。

组态 (Configuration)

Configuration is the main power that gives versatility to a tool. ESLint is not different from that, except it has the most comprehensive configuration among other tools. In general, we need a file or a place to put the configuration, and there's a couple of options of us.

配置是赋予工具多功能性的主要力量。 ESLint与此没有什么不同,除了它具有其他工具中最全面的配置之外。 通常,我们需要一个文件或一个放置配置的位置,并且我们有两个选择。

All of them boil down to two main ways: either we have a separate configuration file for each tool, or we bundle them all in package.json.  .eslintrc.js is one of the files that ESLint will be looking for its configuration, and also the one with the highest priority.

它们全部归结为两种主要方式:要么为每个工具都有一个单独的配置文件,要么将它们全部打包在package.json 。 .eslintrc.js是ESLint将寻找其配置的文件之一,也是优先级最高的文件。

The next thing we need to know about configuration is its hierarchy and cascading behavior. Thanks to these features, we don't need to have a configuration file in every single folder in the project.

关于配置,我们需要了解的下一件事是其层次结构和级联行为。 由于这些功能,我们不需要在项目中的每个文件夹中都有一个配置文件。

If a configuration file doesn't exist in a folder, ESLint simply looks up the folder's parent for one until it can't find one. Then it'll fall back to the user–wide default configuration in ~/.eslintrc. Otherwise, the configuration file will add up or override the ones at upper levels.

如果文件夹中不存在配置文件,则ESLint会简单地在文件夹的父目录中查找一个,直到找不到为止。 然后,它将退回到~/.eslintrc用户范围的默认配置。 否则,配置文件将累加或覆盖较高级别的文件。

There is, however, a special tweak on this. If we specify root: true in a configuration file, the lookup will stop at that file instead of going up like before. Besides, ESLint will use that configuration file as the root configuration, and all child configurations will be based on this one.

但是,对此有一个特殊的调整。 如果我们在配置文件中指定root: true ,则查找将在该文件处停止,而不是像以前那样进行。 此外,ESLint将使用该配置文件作为根配置,并且所有子配置都将基于此配置。

This is not only limited to ESLint - these things are common for other tools. Let's talk about ESLint specific configuration.

这不仅限于ESLint-这些东西在其他工具中很常见。 让我们谈谈ESLint的特定配置。

解析器 (Parser)

The role of the parser in ESLint has been discussed above. By default, ESLint uses Espree as its parser. We can change this parser to another compatible one like babel-eslint or @typescript-eslint/parser if we use Babel or Typescript, respectively.

上面已经讨论了解析器在ESLint中的作用。 默认情况下,ESLint使用Espree作为其解析器。 如果我们分别使用Babel或Typescript,则可以将此解析器更改为另一个兼容的解析器,如babel-eslint或@ typescript-eslint / parser 。

To configure the parser, we use parserOptions. Among options supported by Espree, here are some we often use and need to pay attention to:

要配置解析器,我们使用parserOptions 。 Espree支持的选项中,以下是我们经常使用的选项,需要注意:

  • ecmaVersion

    ecmaVersion

We need to specify the appropriate ECMA version to features we want to use. For example, if emcaVersion: 5, the code below will give some errors.

我们需要为要使用的功能指定适当的ECMA版本。 例如,如果emcaVersion: 5 ,则下面的代码将给出一些错误。

```javascript
let a = [1, 2, 3, 4] // error due to `let` keyword
var b = [...a, 5] // error due to spread syntax
```

The parser can't parse the code because both the let keyword and spread syntax were just introduced in ES6. Changing emcaVersion to 6 or above will simply resolve the errors.

解析器无法解析代码,因为在ES6中刚刚引入了let关键字和spread语法。 将emcaVersion更改为6或更高版本将仅解决错误。

  • sourceType

    sourceType

Nowadays, we mostly write everything in modules, then bundle them together. So this option, most of the time, should be module.

如今,我们通常将所有内容都写在模块中,然后将它们捆绑在一起。 因此,大多数情况下,此选项应为module 。

Another value we can use—as well as the default—is script. The difference is whether we can use JS modules or not, i.e., use import and export keyword. The next time we get this error message Parsing error: 'import' and 'export' may appear only with 'sourceType: module', we know where to look.

我们可以使用的另一个值(以及默认值)是script 。 区别在于我们是否可以使用JS模块 ,即使用import和export关键字。 下次收到此错误消息时, Parsing error: 'import' and 'export' may appear only with 'sourceType: module' ,我们知道在哪里看。

  • ecmaFeatures.jsx

    ecmaFeatures.jsx

There might be additional ES features we want to use, for example JSX syntax. We use ecmaFeatures.jsx: true to enable this feature. Note that, JSX support from Espree isn't the same as JSX in React. If we want React specific JSX, we should use eslint-plugin-react for better results.

我们可能要使用其他ES功能,例如JSX语法。 我们使用ecmaFeatures.jsx: true启用此功能。 注意,Espree对JSX的支持与React中的JSX不同。 如果我们需要特定于React的JSX,则应使用eslint-plugin-react以获得更好的结果。

If we use another parser, these options are more or less the same. Some might have fewer options, and others might have more, but they're all defined under parserOptions.

如果我们使用另一个解析器,这些选项或多或少都是相同的。 有些可能选项较少,有些可能更多,但都在parserOptions下parserOptions 。

环境 (Environment)

It depends on where the code is running: there are different predefined global variables. We have window, document in the browser, for example. It would be irritating if the no-undef rule is enabled, and ESLint keeps telling us window or document is not defined.

这取决于代码在何处运行:有不同的预定义全局变量。 例如,我们在浏览器中有window , document 。 如果启用了no-undef规则,并且ESLint不断告诉我们未定义window或document ,这将很烦人。

The env option is here to help. By specifying a list of environments, ESLint will know about global variables in these environments, and let us use them without a word.

env选项可为您提供帮助。 通过指定环境列表,ESLint将了解这些环境中的全局变量,并让我们使用它们一言不发。

There's a special environment we need to note, es6. It'll implicitly set parserOptions.ecmaVersion to 6, and enable all ES6 features except for modules which we still need to use parserOptions.sourceType: "module" separately.

es6是一个需要特别注意的环境。 它将隐式地将parserOptions.ecmaVersion设置为6,并启用所有ES6功能,但仍需要单独使用parserOptions.sourceType: "module"模块除外。

插件和共享配置 (Plugins and Shareable Configs)

Having the same configuration for rules over and over again across different projects might be tiresome. Luckily, we can reuse a configuration, and only override rules as needed with extends. We call this type of config shareable configs, and ESLint already has two for us: eslint:recommended and eslint:all.

在不同项目之间反复使用相同的规则配置可能很麻烦。 幸运的是,我们可以重用配置,并且仅在需要时使用extends覆盖规则。 我们将这种类型的配置称为可共享配置,ESLint已经为我们提供了两个: eslint:recommended和eslint:all 。

Conventionally, ESLint's shareable configs have eslint-config prefix so we can easily find them via NPM with eslint-config keyword. Among hundreds of results, there're some popular ones, like eslint-config-airbnb or eslint-config-google, you name it.

按照惯例,ESLint的可共享配置具有eslint-config前缀,因此我们可以使用eslint-config关键字通过NPM轻松找到它们。 在数百个结果中,有一些受欢迎的结果,例如eslint-config-airbnb或eslint-config-google ,您都可以将其命名。

Out of the box, ESLint has a bunch of rules to serve different purposes from possible errors, best practices, ES6 to stylistic issues. Moreover, to supercharge its ability, ESLint has a great number of 3rd-party rules provided by almost a thousand plugins. Similar to shareable configs, ESLint's plugins are prefixed with eslint-plugin, and are available on NPM with the eslint-plugin keyword.

ESLint开箱即用,有很多规则可以满足不同目的的使用,从可能的错误,最佳实践,ES6到样式问题。 此外,为了增强其功能,ESLint具有将近一千个插件提供的大量第三方规则。 与可共享的配置类似,ESLint的插件以eslint-plugin为前缀,并且可在NPM上使用eslint-plugin关键字使用。

A plugin defines a set of new rules, and in most cases it exposes its own handy configs. For example, the eslint-plugin-react gives us two shareable configs, eslint-plugin-react:recommended and eslint-plugin-react:all just like eslint:recommended and eslint:all. To use one of them, we need to, firstly, define the plugin name, and secondly extend the config.

插件定义了一组新规则,并且在大多数情况下,它公开了自己的便捷配置。 例如, eslint-plugin-react提供了两个可共享的配置, eslint-plugin-react:recommended和eslint-plugin-react:all就像eslint:recommended和eslint:all 。 要使用其中之一,我们首先需要定义插件名称,然后扩展配置。

{
  plugins: ["react"],
  extends: "plugin:react/recommended"
}

// Note that we need to prefix the config by `plugin:react`

One common question to ask is what plugins or configs to use. While it largely depends on our needs, we can use Awesome ESLint as a reference to find useful plugins as well as configs.

一个常见的问题是要使用哪些插件或配置。 虽然这在很大程度上取决于我们的需求,但是我们可以使用Awesome ESLint作为参考来查找有用的插件和配置。

更漂亮 (Prettier)

We're almost there - we've almost gotten to the end. Last but not least, we'll discuss a popular pair of ESLint, Prettier. In short, Prettier is an opinionated code formatter. Though Prettier can be used alone, integrating it to ESLint enhances the experience a lot, and eslint-plugin-prettier does this job.

我们快到了-我们快要结束了。 最后但并非最不重要的,我们将讨论一个流行的对ESLint的更漂亮 。 简而言之,Prettier是自以为是的代码格式化程序。 尽管Prettier可以单独使用,但将其集成到ESLint可以大大改善体验,而eslint-plugin-prettier可以完成这项工作。

The difference between using Prettier alone and using Prettier with ESLint can be summarized to code formatting as an issue. Instead of giving format issues separately, running Prettier with ESLint will treat format issues just like other issues. However, these issues are always fixable, which is equivalent to formatting the code.

可以总结一下单独使用Prettier和将Prettier与ESLint一起使用之间的区别,这是代码格式化的问题。 使用ESLint运行Prettier不会像单独发布格式问题那样对待格式问题,就像处理其他问题一样。 但是,这些问题始终是可修复的,这等效于格式化代码。

That's how eslint-plugin-prettier works. It runs Prettier, as a rule, behind the scene and compares the code before and after being run through Prettier. Finally, it reports differences as individual ESLint issues. To fix these issues, the plugin simply uses the formatted code from Prettier.

这就是eslint-plugin-prettier工作方式。 它通常在后台运行Prettier,并在通过Prettier运行之前和之后比较代码。 最后,它将差异报告为单个ESLint问题。 为了解决这些问题,该插件仅使用Prettier的格式化代码。

To have this integration, we need to install both prettier and eslint-plugin-prettier. eslint-plugin-prettier also comes with eslint-plugin-prettier:recommended config—which extends eslint-config-prettier. Therefore we also need to install eslint-config-prettier to use it.

有这种整合,我们需要安装prettier和eslint-plugin-prettier 。 eslint-plugin-prettier还附带了eslint-plugin-prettier:recommended配置-扩展了eslint-config-prettier 。 因此,我们还需要安装eslint-config-prettier才能使用它。

{
  "plugins": ["prettier"],
  "extends": "plugin:prettier/recommended"
}

结论 (Conclusion)

Code linters or formatters have become the de facto standard in software development in general, and ESLint, specifically, in front-end development.

一般而言,代码钳或格式化程序已成为软件开发(尤其是ESLint)在前端开发中的事实上的标准。

Its benefits go far beyond what it does technically, as it helps developers focus on more important matters. Thanks to delegating code styling to a machine, we can avoid opinionated styles on code review, and use that time instead for more meaningful code review. Code quality also benefits, and we get more consistent and less error-prone code.

它的好处远远超出了技术上的作用,因为它可以帮助开发人员专注于更重要的事情。 通过将代码样式委派给计算机,我们可以避免在代码审查中使用过时的样式,而可以将这段时间用于更有意义的代码审查。 代码质量也有好处,我们可以获得更一致,更不易出错的代码。

This article was originally posted at my blog.

本文最初发布在我的博客上 。

翻译自: https://www.freecodecamp.org/news/the-essentials-eslint/

前端eslint规范

更多推荐