ESLint

ESLint

ESLint - Pluggable JavaScript linter. A pluggable and configurable linter tool for identifying and reporting on patterns in JavaScript. Maintain your code quality with ease.

7 Essential Prominent Configuration on Github

In today's post we will learn about 7 Essential Prominent Configuration on Github.

Table of contents:

  • Adjunct - A reasonable collection of plugins to use alongside your main ESLint configuration.
  • Ash-Nazg - One config to rule them all!
  • Cecilia - ESLint configuration for awesome projects.
  • ES - Shareable config for very strict code.
  • Hardcore - The most strict (but practical) ESLint config out there.
  • Problems - Shareable config that only catches actual problems, and doesn't enforce stylistic preferences.
  • Supermind - Shareable config for Supermind style.

What is a Config file?

Configuration files (configs) are text files containing commands the console will execute when you run said config. It is basically an easier way of having to re-enter commands every time you launch the game.
A configuration file, often shortened to config file, defines the parameters, options, settings and preferences applied to operating systems (OSes), infrastructure devices and applications in an IT context. Software and hardware devices can be profoundly complex, supporting myriad options and parameters.

1 - Adjunct: A reasonable collection of plugins to use alongside your main ESLint configuration.

ESlint-config-adjunct

A reasonable collection of plugins to use alongside your main esLint configuration

Install

To install this config, run the following command.

npm install eslint-config-adjunct --save-dev

Configure

Extend your .eslintrc, with adjunct, which should be the last item in the extends array. For example if your using eslint-config-airbnb as your main rule set, your .eslintrc should look like the following. For more advanced use cases see the example configurations for TypeScript and Vue.

{
  "extends": ["airbnb", "adjunct"]
}

You can now include html, json and markdown in the list of files passed to eslint to lint any JavaScript contained.

{
  "scripts": {
    "eslint": "eslint --color --ext .html,.js,.json,.jsx,.md *.* src",
    "eslint:fix": "npm run eslint -- --fix"
  }
}

View on Github

2 - Ash-Nazg: One config to rule them all!

ESlint-config-ash-nazg

A ruthless--though not arbitrary--degree of control for your kingdom!

Installation

npm i -D eslint-config-ash-nazg
install-peerdeps -d eslint-config-ash-nazg

Other bundled configs

The ash-nazg/node config expands upon the regular ash-nazg rules to add rules specific to Node environments. Specifically, plugin:node/recommended-module has been adopted for now along with some stylistic choices. However, if you are using more CJS exports, you can override this by adding plugin:node/recommended-script to your extends array (after ash-nazg) or, for Sauron-Node, by using sauron-node-script.

The ash-nazg/node configs also detect minimum Node from engines and set env to use the highest supported ES globals, e.g., ES2021 (and also sets node: true) as well as sets ecmaVersion.

The ash-nazg/sauron config expands upon the regular ash-nazg rules to indicate what are generally best practices but are less likely to be due to an error and may possibly also require a high (and possibly tyrannical) degree of refactoring for existing projects. See below for the rationales for inclusion.

The ash-nazg/great-eye and ash-nazg/great-eye-node configs expands on ash-nazg/sauron (and ash-nazg/sauron-node) to include rules which enforce good practices, but which are so cumbersome and may flag too much legitimate code that I personally won't regularly use them. Still, I like to track them here, including in the event that their config changes to make them less all-encompassing.

The ash-nazg/sauron-node config incorporates both ash-nazg/node and ash-nazg/sauron. It adds specific rules of its own which may be unduly strict for ash-nazg/node.

A few experimental configs have been added as well, though this might be removed or significantly modified in a future version:

  • +script-node.js: Applies script source type with Node; used by sauron-node-script
  • +script.js: Applies script source type for non-Node; used by sauron-script
  • sauron-node-overrides.js: sauron-node with rc and mocha
  • sauron-node-script-overrides.js): sauron-node-script with rc and mocha
  • sauron-overrides.js: sauron with rc and mocha
  • sauron-script.js: sauron with +script.js file
  • sauron-script-overrides.js: sauron-script with rc and mocha
  • +babel.js: Wraps a module to support equivalent babel/eslint-parser rules
  • mocha.js: Sets up Mocha (and chai global) on test directories (via overrides)
  • mocha-plus.js: Strict but reasonable rules for checking Mocha/Chai (not naming "sauron" as not bundling with Sauron)
  • cypress.js: Strict but reasonable rules for checking Cypress
  • rc.js: Config for using overrides to give Rollup and RC config files to support modules where available (and script where not)

View on Github

3 - Cecilia: ESLint configuration for awesome projects.

ESlint-config-cecilia

ESLint configuration for awesome projects

Installation

Install ESLint config Cecilia.

Step 1 - Install with Yarn

yarn add eslint-config-cecilia --dev

Or install with npm

npm install -D eslint-config-cecilia

Configure

Step 2 - Create a .eslintrc.js file in your project root directory and use the extends attribute.

Paste this code to extend the ESLint ruleset:

module.exports = {
  extends: 'cecilia',
}

Optional - Override Rules

For more information, see "Configuring Rules" in the ESLint Help.

module.exports = {
  extends: 'cecilia',
  rules: {
    //
    // rules to override.
    //
  }
}

Pro tip

Check the list of available rules.

Optional - Specifying Environments

For more information, see "Specifying Environments" in the ESLint Help.

module.exports = {
  extends: 'cecilia',
  env: {
    browser: true,
    node: true,
    ...
  },
}

View on Github

4 - ES: Shareable config for very strict code.

ESlint-config-es

eslint-config-es contains a strict ESLint configuration for ES2015+ and TypeScript.

Installation

$ npm install eslint-config-es \
              eslint

Quick Start

This module contains a very strict ESLint configuration for ES2015 and above, both for Node.js and browser development. Its aims to eradicate any variation in code style. If you can not tell any more, based on little individual manners, who of your co-workers wrote a piece of code, this module succeeded. This helps you to narrow down your focus to pure functionality, as you do not have to think about code styling any more at all.

To use one of those configurations, create a .eslintrc.json file in your project and use the extends keyword.

{
  "extends": "es/node"
}

Alternatively, you may also use es/browser.

If you want to override any rules, you can do so in your configuration file. For details on how to do this, e.g. to get an explanation on how to enable or disable specific rules, see the ESLint documentation on extending configuration files.

Running quality assurance

To run quality assurance for this module use roboter:

$ npm run roboter

Note: npx roboter will not work as our ESLint Rules are written in TypeScript, so they have to be compiled before usage. npm run roboter will do this.

View on Github

5 - Hardcore: The most strict (but practical) ESLint config out there.

ESlint-config-hardcore

The most strict (yet practical) ESLint config. 37 plugins. 1236 rules. React, Vue, Node, and pure JS/TS.

Usage

npm install eslint-config-hardcore --save-dev

Available configs:

  • hardcore - base framework-agnostic config
  • hardcore/ts - additional config for TypeScript
  • hardcore/node- additional config for Node.js
  • hardcore/react - additional config for React
  • hardcore/vue - additional config for Vue 3/Nuxt 3
  • hardcore/react-testing-library - additional config for React Testing Library
  • hardcore/jest - additional config for Jest
  • hardcore/fp - additional config for functional programming
  • hardcore/ts-for-js - additional config for linting JavaScript with typescript-eslint

Example .eslintrc.json for a React project:

{
  "extends": [
    "hardcore",
    "hardcore/react",
    "hardcore/react-testing-library",
    "hardcore/jest",
    "hardcore/fp"
  ],

  "env": {
    "browser": true
  },

  "overrides": [
    {
      "files": ["server/**/*.js"],
      "extends": ["hardcore/node"],
      "env": {
        "browser": false
      }
    }
  ]
}

View on Github

6 - Problems: Shareable config that only catches actual problems, and doesn't enforce stylistic preferences.

ESlint-config-problems

An eslint config that catches problems in your code, without checking style. For use with prettier.

Rules

Rules were chosen based on the following criteria:

  • No stylistic rules; nothing that Prettier can fix
  • Prevent guaranteed runtime errors (i.e. no undefined variables)
  • Disallow "evil" things like eval
  • Disallow archaic language features like with
  • Disallow obvious bad practices like new Number(13)
  • Point out places the code could be made shorter. For example:
if (someCondition) return someValue;
else {
  // Do something else
}
  • The else block is unneeded, since the if block contains a return statement. eslint-config-problems will point this out to you (or auto-fix with the --fix option).

ES2015+

By default eslint-config-problems forces the use of ES2015+ features supported by Node.js versions 10 and higher. Here are the rules enforced:

  • no-var - Use let/const instead.
  • object-shorthand - Use object shorthand where possible.
  • prefer-arrow-callback - Use arrow functions as callbacks where possible.
  • prefer-numeric-literals - Don't use parseInt() to write binary, octal, and hexadecimal numbers, use the literal form instead.
  • prefer-template - Use template strings instead of string concatenation.
  • prefer-spread - Use the spread operator instead of .apply where possible.
  • prefer-rest-params - Use rest parameters instead of arguments.
  • Use the exponentiation operator (**) instead of Math.pow() (enforced via no-restricted-properties).
  • prefer-object-spread - Use object spread where possible, instead of Object.assign()
  • Use optional catch bindings when not using the error variable in the catch block (enforced by no-unused-vars with caughtErrors: 'all')
  • prefer-const - I realize this is very opinionated; if you don't like it, add prefer-const: off to your config.

It also sets ecmaVersion: 2020 in the parserOptions, so that ESLint can parse modern code (including BigInt in Node 10.8+) with no additional setup.

View on Github

7 - Supermind - Shareable config for Supermind style.

Supermind ESLint Config

Linting rules for supermind projects

Install yarn globally:

npm install yarn --global

Add eslint and eslint-config-supermind as a devDependency to your project:

yarn add eslint eslint-config-supermind --dev

Create an .eslintrc.js file at the root of your project and add the following configuration:

module.exports = {
  root: true, // Prevent ESLint from inheriting configuration above this file
  extends: [
    'supermind',          // Extend base config
    'supermind/react',    // Extend react config (optional)
    'supermind/inferno',  // Extend inferno config (optional)
    'supermind/jsx-a11y', // Extend jsx-a11y config (optional)
    'supermind/flowtype'  // Extend flowtype config (optional)
  ]
}

Add a lint script in your project package.json file:

{
  "name": "kitten-socks",
  "scripts": {
    "lint": "eslint source"
  }
}

To lint the source directory of your project run:

yarn run lint

View on Github

Thank you for following this article. 

#javascript #configuration #eslint 

7 Essential Prominent Configuration on Github

4 Trending Prominent Configuration on Github

In today's post we will learn about 4 Trending Prominent Configuration on Github. 

Table of contents:

  • Auto - Automatically configure ESLint based on your project's dependencies.
  • Canonical - Shareable config for Canonical style guide.
  • Standard - Shareable config for JavaScript Standard Style.
  • XO - Shareable config for XO.

What is a Config file?

Configuration files (configs) are text files containing commands the console will execute when you run said config. It is basically an easier way of having to re-enter commands every time you launch the game.
A configuration file, often shortened to config file, defines the parameters, options, settings and preferences applied to operating systems (OSes), infrastructure devices and applications in an IT context. Software and hardware devices can be profoundly complex, supporting myriad options and parameters.

1 - Auto: Automatically configure ESLint based on your project's dependencies.

ESlint-config-auto

Automatically configure ESLint based on project dependencies

Install

To install this config, run the following command.

npm install eslint-config-auto --save-dev

Configure

Create an .eslintrc file with the following contents.

{
  "extends": ["auto"]
}

You can now include html, json and markdown in the list of files passed to eslint to lint any JavaScript contained.

{
  "scripts": {
    "eslint": "eslint --color --ext .html,.js,.json,.jsx,.md,.ts,.tsx *.* src",
    "eslint:fix": "npm run eslint -- --fix"
  }
}

Install Dependencies

After you have configured eslint to include this package, the first time you run eslint it will output the npm command to install the dependencies required for your project. Copy and paste this command into the console, and you are then ready to start linting.

View on Github

2 - Canonical: Shareable config for Canonical style guide.

Canonical ESLint Config

The most comprehensive ES code style guide.

Usage

This package includes the following configurations:

Example configuration

For maximum efficiency, use overrides to only apply relevant style guides. This reduces the linting time and the number of false-positives.

This is an example configuration of a React project using TypeScript and Jest:

{
  "extends": [
    "canonical"
  ],
  "overrides": [
    {
      "extends": [
        "canonical/typescript"
      ],
      "files": "*.ts",
      "parserOptions": {
        "project": "./tsconfig.json"
      }
    },
    {
      "extends": [
        "canonical/react",
        "canonical/jsx-a11y",
        "canonical/typescript"
      ],
      "files": "*.tsx",
      "parserOptions": {
        "project": "./tsconfig.json"
      }
    },
    {
      "extends": [
        "canonical/jest"
      ],
      "files": "*.test.{ts,tsx}",
      "parserOptions": {
        "project": "./tsconfig.json"
      }
    },
    {
      "extends": [
        "canonical/json"
      ],
      "files": "*.json"
    },
    {
      "extends": [
        "canonical/yaml"
      ],
      "files": "*.yaml"
    },
    {
      "extends": [
        "canonical/graphql"
      ],
      "files": "*.graphql"
    }
  ],
  "root": true
}

View on Github

3 - Standard: Shareable config for JavaScript Standard Style.

ESlint-config-standard

ESLint Config for JavaScript Standard Style

Install

This module is for advanced users. You probably want to use standard instead :)

npm install eslint-config-standard

Usage

Shareable configs are designed to work with the extends feature of .eslintrc files. You can learn more about Shareable Configs on the official ESLint website.

If you want to set up the config automatically, follow these steps in your project directory:

  1. npx eslint --init
  2. Select "Use a popular style guide."
  3. Select "Standard."
  4. Select a config file format.
  5. If prompted, confirm the installation of the necessary dependencies.

The above steps will automatically set up an ESLint configuration and install the necessary dependencies for you.

If you want to set up the config manually, run the following command:

npm install --save-dev eslint-config-standard eslint-plugin-promise eslint-plugin-import eslint-plugin-n

Then, add this to your .eslintrc file:

{
  "extends": "standard"
}

Note: We omitted the eslint-config- prefix since it is automatically assumed by ESLint.

You can override settings from the shareable config by adding them directly into your .eslintrc file.

View on Github

4 - XO: Shareable config for XO.

ESlint-config-xo

ESLint shareable config for XO

Install

$ npm install --save-dev eslint-config-xo

Usage

Add some ESLint config to your package.json:

{
	"name": "my-awesome-project",
	"eslintConfig": {
		"extends": "xo"
	}
}

Or to .eslintrc:

{
	"extends": "xo"
}

This package also exposes xo/browser if you're in the browser:

{
	"extends": "xo/browser"
}

View on Github

Thank you for following this article. 

#javascript #configuration #eslint 

4 Trending Prominent Configuration on Github

5 Best Configs By Well-Known Companies/Organizations

In today's post we will learn about 5 Best Configs by Well-Known Companies/Organizations.

Table of contents:

  1. Airbnb - Shareable config for Airbnb's style guide.
  2. Airbnb-babel - Airbnb's ESLint config with Babel Support.
  3. Airbnb-typescript - Airbnb's ESLint config with TypeScript support.
  4. Alloy - Progressive ESLint config for your React/Vue/TypeScript projects.
  5. ESLint - Contains the ESLint configuration used for projects maintained by the ESLint team.

What is a Config file?

Configuration files (configs) are text files containing commands the console will execute when you run said config. It is basically an easier way of having to re-enter commands every time you launch the game.
A configuration file, often shortened to config file, defines the parameters, options, settings and preferences applied to operating systems (OSes), infrastructure devices and applications in an IT context. Software and hardware devices can be profoundly complex, supporting myriad options and parameters.

1 - Airbnb: Shareable config for Airbnb's style guide.

ESlint-config-airbnb

This package provides Airbnb's .eslintrc as an extensible shared config.

Usage

We export three ESLint configurations for your usage.

eslint-config-airbnb

Our default export contains most of our ESLint rules, including ECMAScript 6+ and React. It requires eslint, eslint-plugin-import, eslint-plugin-react, eslint-plugin-react-hooks, and eslint-plugin-jsx-a11y. Note that it does not enable our React Hooks rules. To enable those, see the eslint-config-airbnb/hooks section.

If you don't need React, see eslint-config-airbnb-base.

Install the correct versions of each package, which are listed by the command:

npm info "eslint-config-airbnb@latest" peerDependencies

If using npm 5+, use this shortcut

npx install-peerdeps --dev eslint-config-airbnb

If using yarn, you can also use the shortcut described above if you have npm 5+ installed on your machine, as the command will detect that you are using yarn and will act accordingly. Otherwise, run npm info "eslint-config-airbnb@latest" peerDependencies to list the peer dependencies and versions, then run yarn add --dev <dependency>@<version> for each listed peer dependency.

View on Github

2 - Airbnb-babel: Airbnb's ESLint config with Babel Support.

ESlint-config-airbnb-babel

Babel support for Airbnb's ESLint config

Install

npm install eslint-config-airbnb-babel --save-dev

Configure

This configuration must be placed after which ever version of the AirBnB rules you are using in your .eslintrc file:

{
  "extends": ["airbnb", "airbnb-babel"]
}

View on Github

3 - Airbnb-typescript: Airbnb's ESLint config with TypeScript support.

ESlint-config-airbnb-typescript

Enhances Airbnb's ESLint config with TypeScript support

Setup

1) Setup regular Airbnb config

Make sure you have the regular Airbnb config setup. If you are using React, use eslint-config-airbnb, or if you aren't using React, use eslint-config-airbnb-base.

2) Install dependencies (and peer dependencies)

npm install eslint-config-airbnb-typescript \
            @typescript-eslint/eslint-plugin@^5.13.0 \
            @typescript-eslint/parser@^5.0.0 \
            --save-dev

3) Configure ESLint

Within your ESLint config file:

extends: [
  'airbnb',
+ 'airbnb-typescript'
]

If you don't need React support:

extends: [
  'airbnb-base',
+ 'airbnb-typescript/base'
]

View on Github

4 - Alloy: Progressive ESLint config for your React/Vue/TypeScript projects.

ESlint-config-alloy

Progressive ESLint config for your React/Vue/TypeScript projects

Usage

Built-in

npm install --save-dev eslint @babel/core @babel/eslint-parser eslint-config-alloy

Create an .eslintrc.js in the root directory of your project, then copy the following content into it:

module.exports = {
  extends: [
    'alloy',
  ],
  env: {
    // Your environments (which contains several predefined global variables)
    //
    // browser: true,
    // node: true,
    // mocha: true,
    // jest: true,
    // jquery: true
  },
  globals: {
    // Your global variables (setting to false means it's not allowed to be reassigned)
    //
    // myGlobal: false
  },
  rules: {
    // Customize your rules
  },
};

React

npm install --save-dev eslint @babel/core @babel/eslint-parser @babel/preset-react@latest eslint-plugin-react eslint-config-alloy

Create an .eslintrc.js in the root directory of your project, then copy the following content into it:

module.exports = {
  extends: [
    'alloy',
    'alloy/react',
  ],
  env: {
    // Your environments (which contains several predefined global variables)
    //
    // browser: true,
    // node: true,
    // mocha: true,
    // jest: true,
    // jquery: true
  },
  globals: {
    // Your global variables (setting to false means it's not allowed to be reassigned)
    //
    // myGlobal: false
  },
  rules: {
    // Customize your rules
  },
};

View on Github

5 - ESLint: Contains the ESLint configuration used for projects maintained by the ESLint team.

ESLint Configuration

Contains the ESLint configuration used for projects maintained by the ESLint team.

Installation

You can install ESLint using npm:

npm install eslint --save-dev

Then install this configuration:

npm install eslint-config-eslint --save-dev

Usage

In your .eslintrc file, add:

{
    "extends": "eslint"
}

View on Github

Thank you for following this article. 

#javascript #eslint #configuration 

5 Best Configs By Well-Known Companies/Organizations

How to Set up Node.js Backend Projects

In this video we will learn how to set up Node.js backend projects. Configured with Typescript, ESLint, Prettier, Jest, Nodemon, environment variables, and debugging.

0:00 Intro & Initialize Project
6:25 Typescript Install
7:58 ESLint Install
13:19 Prettier Install
16:45 ESLint Config
24:39 Typescript Config
29:10 Testing Project Configurations
34:50 nodemon install and config
38:28 dotenv-safe install and config
41:40 Debugging
43:05 Jest install and config
49:30 Exclude tests from build
50:45 End

TSConfig Options: https://www.typescriptlang.org/tsconfig 
ESLint Config Docs: https://eslint.org/docs/user-guide/configuring/ 
Prettier Options: https://prettier.io/docs/en/options.html 

Project Github repo link: https://github.com/leoroese/blog-tube/tree/main/packages/node-ts-backend 

Subscribe: https://www.youtube.com/c/LeoRoese/featured 

#nodejs #typescript #eslint #javascript 

How to Set up Node.js Backend Projects
Lawrence  Lesch

Lawrence Lesch

1662424980

ESLint Shareable Config for React/JSX Support in JavaScript

eslint-config-standard-react

An ESLint Shareable Config for React/JSX support in JavaScript Standard Style

Install

This module is for advanced users. You probably want to use standard instead :)

npm install eslint-config-standard-react

Usage

Shareable configs are designed to work with the extends feature of .eslintrc files. You can learn more about Shareable Configs on the official ESLint website.

This Shareable Config adds React and JSX to the baseline JavaScript Standard Style rules provided in eslint-config-standard.

Here's how to install everything you need:

npm install --save-dev babel-eslint eslint-config-standard eslint-config-standard-jsx eslint-config-standard-react eslint-plugin-promise eslint-plugin-import eslint-plugin-node eslint-plugin-react

Then, add this to your .eslintrc file:

{
  "parser": "babel-eslint",
  "extends": ["standard", "standard-jsx", "standard-react"]
}

Note: We omitted the eslint-config- prefix since it is automatically assumed by ESLint.

You can override settings from the shareable config by adding them directly into your .eslintrc file.

Looking for something easier than this?

The easiest way to use JavaScript Standard Style to check your code is to use the standard package. This comes with a global Node command line program (standard) that you can run or add to your npm test script to quickly check your style.

Badge

Use this in one of your projects? Include one of these badges in your readme to let people know that your code is using the standard style.

js-standard-style

[![js-standard-style](https://cdn.rawgit.com/standard/standard/master/badge.svg)](https://github.com/standard/standard)

js-standard-style

[![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg)](https://github.com/standard/standard)

Learn more

For the full listing of rules, editor plugins, FAQs, and more, visit the main JavaScript Standard Style repo.

Download Details:

Author: Standard
Source Code: https://github.com/standard/eslint-config-standard-react 
License: MIT license

#javascript #eslint #config #react #node 

ESLint Shareable Config for React/JSX Support in JavaScript
Lawrence  Lesch

Lawrence Lesch

1662420720

Linter-eslint: ESLint Plugin for Atom Linter

linter-eslint 

This linter plugin for Linter provides an interface to eslint versions 7 and below. It will be used with files that have the "JavaScript" syntax.

For linting in projects that use ESLint v8 and above, install linter-eslint-node.

Installation

apm install linter-eslint

linter-eslint will look for a version of eslint local to your project and use it if it's available. If none is found it will fall back to the version it ships with.

Let's say you depend on a specific version of eslint. Maybe it has unreleased features or maybe it's newer than what linter-eslint ships with. If your-project/node_modules/eslint exists linter-eslint will be used. This package requires an eslint of at least v1.0.0.

If you do not have the linter package installed, it will be installed for you. If you are using an alternative linter-* consumer, the linter package can be disabled.

If you wish to lint files in JavaScript-derivative languages (like Typescript, Flow) with ESLint, you must add the scope name for that grammar to the List of scopes to run ESLint on option in linter-eslint Settings. For example, to lint TypeScript files, add source.ts to the list.

Use with plugins

You have two options:

Install locally to your project eslint and the plugin

  • $ npm i --save-dev eslint [eslint-plugins]

Install globally eslint and plugins

  • $ npm i -g eslint [eslint-plugins]
  • Activate Use Global Eslint package option
  • (Optional) Set Global Node Path with $ npm config get prefix

Using ESLint

Note that recent versions of ESLint do not use any rules by default. This means you have to specify a configuration file for your project!

To do this in a straightforward way run this:

eslint --init

Alternatively you can create the .eslintrc file by yourself. It is a good idea to have a look at the ESLint documentation, including the list of rules.

A Note About Settings

If Use Global is on, Atom will use the global ESLint. The path to it is figured out by running npm get prefix. If this fails for any reason, you can set the global path manually in Global Node Installation Path.

If Use Global is off, Atom will try to find a local installation in the project folder, look if there's ESLint in ${PROJECT_ROOT}/node_modules and use it if found.

The path to the local node_modules folder can be a path relative to the project or an absolute path and should end in /node_modules/. This path is used if the other methods of discovery have failed.

If there is no local installation Atom will use the built-in ESLint in the linter-eslint package itself.

Contributing

See the contributing guidelines to get started.

Download Details:

Author: AtomLinter
Source Code: https://github.com/AtomLinter/linter-eslint 

#javascript #eslint #linter 

Linter-eslint: ESLint Plugin for Atom Linter
Joseph  Murray

Joseph Murray

1662062160

A Modern Front-end Boilerplate for Svelte

Modern Web Boilerplate

This is a modern front-end boilerplate which is partially based on islands architecture with focus on improved DX (Developer Experience).

Modern Features

FeatureAdvantage
Dynamic ImportsReduced initial load times
Bundle SplittingReducing the loading and execution time
Tree ShakingDead code removal
Auto PrefixingSupports more browsers
SPAImproved UX with routing
PWANative app like performance
Image OptimizationReduces Image size
Special RoutingLightweight SPA
Rough AnnotationsModern site decorators
Type CheckingReduced Bugs
LintingMaintain Code Standards
Git HooksImproved DX (Developer Experience)
HMRQuick response on code change
WorkflowsAutomated github workflows

Technologies Used

TechnologyWhy?
SvelteDX, no Virtual DOM, build time compilation, reactivity and ease of use
ViteBlazing fast, DX, HMR, Extensible plugins and framework agnostic
TypeScriptType Checking, DX, Code Auto Completion and Superset of JavaScript
EsLintCode Linting and Maintains Standards
PrettierCode Formatting and Maintaining standards
CommitizenLints git commit messages
HuskyGit Hooks before and after git commit
TinroLightweight Routing
TerserJavaScript minification, mangling and tangling
PostCSSCSS transformations
AutoPrefixerPrefixes the CSS to support more browsers
GitHub ActionsBuilding and Deploying the Code in Github Pages
DependabotAutomatic Dependency Updates
CodeQLDiscover vulnerabilities across a codebase with semantic code analysis engine
PWAApp like installation and Offline capabilities
RollupAggressive Bundle Optimizations and TreeShaking
EsBuildUltra fast dependency pre bundling
Conventional CommitsGit commit messages standards
Release PleaseAutomated versioning and releasing packages based on commits
Image SharpImage optimizations out-of-the-box

Automation Scripts

yarn dev

Runs

vite

yarn build

  • Compiles the svelte code to highly optimized and bundled HTML, CSS and JavaScript in dist/ folder
  • Optimizes images using Sharp and downloads custom fonts from google and bundles it up
  • Produces the production code to be hosted

Runs

vite build

yarn preview

  • Starts a simple server with builded production site

Runs

vite preview

yarn lint

  • Lints the code with src directory and tries to fix the issues to ensure the code quality and standards across the entire codebase

Runs

eslint --ext .js,.ts,.svelte --ignore-path .gitignore --fix src

yarn format

  • Formats the entire project with prettier to make the code base more clean which improves the the readability and thus makes the project more maintainable

Runs

prettier --write . '!**/dist'

yarn check

  • TypeChecks the svelte files with TypeScript to reduce runtime bugs

Runs

svelte-check --tsconfig tsconfig.json

yarn prepare

  • Setup Husky Git Hooks for various automation

Runs

husky install

yarn commit

  • Runs commitizen and lints the commit messages to make release-please workflow to work well

Runs

cz

Automation Workflows

Husky Git Hooks

Pre Commit

  • Runs all necessary linting, formatting and build workflows ensures code standards and makes sure that everything works fine before committing

Hook at: pre-commit

Runs following commands

yarn lint #eslint linting
yarn format #prettier formatting
yarn build #vite-rollup building

Post Commit

  • Runs commit message linting to make sure the commit message needs all Conventional Commits standards which will be later used for automated versioning and release system by google's release please

Hook at: prepare-commit-msg

Runs following command

exec < /dev/tty && yarn commit --hook || true #lints commit with interactive prompts

GitHub Actions

DependaBot

  • Automated dependencies update including critical security updates
  • Maintained by GitHub and used by top projects and organizations all over the world

Workflow in: dependabot.yaml

CodeQL

  • Analyzes Code Quality to make sure the code is not bad and does static analysis to find out common security vulnerabilities

Workflow in: codeql-analysis.yaml

Release Please

  • Automated semantic versioning and releases based on the commits with automatic changelog generation and version bumps.
  • Created by Google to use for their products

Workflow in: release-please.yaml

Deploy

  • Automated build system which deploys the optimized compiled version of the site to gh-pages branch for GitHub Pages hosting

Workflow in: deploy.yaml

Download details:

Author: Rajaniraiyn
Source code: https://github.com/Rajaniraiyn/modern-web-boilerplate 
License: MIT license

#svelte #javascript

A Modern Front-end Boilerplate for Svelte

Lint-staged: Run Linters on Git Staged Files

🚫💩 lint-staged

Run linters against staged git files and don't let :poop: slip into your code base!

npm install --save-dev lint-staged # requires further setup
$ git commit

✔ Preparing lint-staged...
❯ Running tasks for staged files...
  ❯ packages/frontend/.lintstagedrc.json — 1 file
    ↓ *.js — no files [SKIPPED]
    ❯ *.{json,md} — 1 file
      ⠹ prettier --write
  ↓ packages/backend/.lintstagedrc.json — 2 files
    ❯ *.js — 2 files
      ⠼ eslint --fix
    ↓ *.{json,md} — no files [SKIPPED]
◼ Applying modifications from tasks...
◼ Cleaning up temporary files...

See asciinema video

asciicast

Why

Linting makes more sense when run before committing your code. By doing so you can ensure no errors go into the repository and enforce code style. But running a lint process on a whole project is slow, and linting results can be irrelevant. Ultimately you only want to lint files that will be committed.

This project contains a script that will run arbitrary shell tasks with a list of staged files as an argument, filtered by a specified glob pattern.

Related blog posts and talks

If you've written one, please submit a PR with the link to it!

Installation and setup

To install lint-staged in the recommended way, you need to:

  1. Install lint-staged itself:
    • npm install --save-dev lint-staged
  2. Set up the pre-commit git hook to run lint-staged
    • Husky is a popular choice for configuring git hooks
    • Read more about git hooks here
  3. Install some linters, like ESLint or Prettier
  4. Configure lint-staged to run linters and other tasks:
    • for example: { "*.js": "eslint" } to run ESLint for all staged JS files
    • See Configuration for more info

Don't forget to commit changes to package.json and .husky to share this setup with your team!

Now change a few files, git add or git add --patch some of them to your commit, and try to git commit them.

See examples and configuration for more information.

Changelog

See Releases.

Migration

v13

  • Since v13.0.0 lint-staged no longer supports Node.js 12. Please upgrade your Node.js version to at least 14.13.1, or 16.0.0 onward.

v12

  • Since v12.0.0 lint-staged is a pure ESM module, so make sure your Node.js version is at least 12.20.0, 14.13.1, or 16.0.0. Read more about ESM modules from the official Node.js Documentation site here.

v10

  • From v10.0.0 onwards any new modifications to originally staged files will be automatically added to the commit. If your task previously contained a git add step, please remove this. The automatic behaviour ensures there are less race-conditions, since trying to run multiple git operations at the same time usually results in an error.
  • From v10.0.0 onwards, lint-staged uses git stashes to improve speed and provide backups while running. Since git stashes require at least an initial commit, you shouldn't run lint-staged in an empty repo.
  • From v10.0.0 onwards, lint-staged requires Node.js version 10.13.0 or later.
  • From v10.0.0 onwards, lint-staged will abort the commit if linter tasks undo all staged changes. To allow creating an empty commit, please use the --allow-empty option.

Command line flags

❯ npx lint-staged --help
Usage: lint-staged [options]

Options:
  -V, --version                      output the version number
  --allow-empty                      allow empty commits when tasks revert all staged changes (default: false)
  -p, --concurrent <number|boolean>  the number of tasks to run concurrently, or false for serial (default: true)
  -c, --config [path]                path to configuration file, or - to read from stdin
  --cwd [path]                       run all tasks in specific directory, instead of the current
  -d, --debug                        print additional debug information (default: false)
  --diff [string]                    override the default "--staged" flag of "git diff" to get list of files. Implies
                                     "--no-stash".
  --diff-filter [string]             override the default "--diff-filter=ACMR" flag of "git diff" to get list of files
  --max-arg-length [number]          maximum length of the command-line argument string (default: 0)
  --no-stash                         disable the backup stash, and do not revert in case of errors
  -q, --quiet                        disable lint-staged’s own console output (default: false)
  -r, --relative                     pass relative filepaths to tasks (default: false)
  -x, --shell [path]                 skip parsing of tasks for better shell support (default: false)
  -v, --verbose                      show task output even when tasks succeed; by default only failed output is shown
                                     (default: false)
  -h, --help                         display help for command
  • --allow-empty: By default, when linter tasks undo all staged changes, lint-staged will exit with an error and abort the commit. Use this flag to allow creating empty git commits.
  • --concurrent [number|boolean]: Controls the concurrency of tasks being run by lint-staged. NOTE: This does NOT affect the concurrency of subtasks (they will always be run sequentially). Possible values are:
    • false: Run all tasks serially
    • true (default) : Infinite concurrency. Runs as many tasks in parallel as possible.
    • {number}: Run the specified number of tasks in parallel, where 1 is equivalent to false.
  • --config [path]: Manually specify a path to a config file or npm package name. Note: when used, lint-staged won't perform the config file search and will print an error if the specified file cannot be found. If '-' is provided as the filename then the config will be read from stdin, allowing piping in the config like cat my-config.json | npx lint-staged --config -.
  • --cwd [path]: By default tasks run in the current working directory. Use the --cwd some/directory to override this. The path can be absolute or relative to the current working directory.
  • --debug: Run in debug mode. When set, it does the following:
    • uses debug internally to log additional information about staged files, commands being executed, location of binaries, etc. Debug logs, which are automatically enabled by passing the flag, can also be enabled by setting the environment variable $DEBUG to lint-staged*.
    • uses verbose renderer for listr; this causes serial, uncoloured output to the terminal, instead of the default (beautified, dynamic) output.
  • --diff: By default linters are filtered against all files staged in git, generated from git diff --staged. This option allows you to override the --staged flag with arbitrary revisions. For example to get a list of changed files between two branches, use --diff="branch1...branch2". You can also read more from about git diff and gitrevisions.
  • --diff-filter: By default only files that are added, copied, modified, or renamed are included. Use this flag to override the default ACMR value with something else: added (A), copied (C), deleted (D), modified (M), renamed (R), type changed (T), unmerged (U), unknown (X), or pairing broken (B). See also the git diff docs for --diff-filter.
  • --max-arg-length: long commands (a lot of files) are automatically split into multiple chunks when it detects the current shell cannot handle them. Use this flag to override the maximum length of the generated command string.
  • --no-stash: By default a backup stash will be created before running the tasks, and all task modifications will be reverted in case of an error. This option will disable creating the stash, and instead leave all modifications in the index when aborting the commit.
  • --quiet: Supress all CLI output, except from tasks.
  • --relative: Pass filepaths relative to process.cwd() (where lint-staged runs) to tasks. Default is false.
  • --shell: By default linter commands will be parsed for speed and security. This has the side-effect that regular shell scripts might not work as expected. You can skip parsing of commands with this option. To use a specific shell, use a path like --shell "/bin/bash".
  • --verbose: Show task output even when tasks succeed. By default only failed output is shown.

Configuration

Lint-staged can be configured in many ways:

  • lint-staged object in your package.json
  • .lintstagedrc file in JSON or YML format, or you can be explicit with the file extension:
    • .lintstagedrc.json
    • .lintstagedrc.yaml
    • .lintstagedrc.yml
  • .lintstagedrc.mjs or lint-staged.config.mjs file in ESM format
    • the default export value should be a configuration: export default { ... }
  • .lintstagedrc.cjs or lint-staged.config.cjs file in CommonJS format
    • the exports value should be a configuration: module.exports = { ... }
  • lint-staged.config.js or .lintstagedrc.js in either ESM or CommonJS format, depending on whether your project's package.json contains the "type": "module" option or not.
  • Pass a configuration file using the --config or -c flag

Configuration should be an object where each value is a command to run and its key is a glob pattern to use for this command. This package uses micromatch for glob patterns. JavaScript files can also export advanced configuration as a function. See Using JS configuration files for more info.

You can also place multiple configuration files in different directories inside a project. For a given staged file, the closest configuration file will always be used. See "How to use lint-staged in a multi-package monorepo?" for more info and an example.

package.json example:

{
  "lint-staged": {
    "*": "your-cmd"
  }
}

.lintstagedrc example

{
  "*": "your-cmd"
}

This config will execute your-cmd with the list of currently staged files passed as arguments.

So, considering you did git add file1.ext file2.ext, lint-staged will run the following command:

your-cmd file1.ext file2.ext

Task concurrency

By default lint-staged will run configured tasks concurrently. This means that for every glob, all the commands will be started at the same time. With the following config, both eslint and prettier will run at the same time:

{
  "*.ts": "eslint",
  "*.md": "prettier --list-different"
}

This is typically not a problem since the globs do not overlap, and the commands do not make changes to the files, but only report possible errors (aborting the git commit). If you want to run multiple commands for the same set of files, you can use the array syntax to make sure commands are run in order. In the following example, prettier will run for both globs, and in addition eslint will run for *.ts files after it. Both sets of commands (for each glob) are still started at the same time (but do not overlap).

{
  "*.ts": ["prettier --list-different", "eslint"],
  "*.md": "prettier --list-different"
}

Pay extra attention when the configured globs overlap, and tasks make edits to files. For example, in this configuration prettier and eslint might try to make changes to the same *.ts file at the same time, causing a race condition:

{
  "*": "prettier --write",
  "*.ts": "eslint --fix"
}

If necessary, you can limit the concurrency using --concurrent <number> or disable it entirely with --concurrent false.

Filtering files

Linter commands work on a subset of all staged files, defined by a glob pattern. lint-staged uses micromatch for matching files with the following rules:

  • If the glob pattern contains no slashes (/), micromatch's matchBase option will enabled, so globs match a file's basename regardless of directory:
    • "*.js" will match all JS files, like /test.js and /foo/bar/test.js
    • "!(*test).js". will match all JS files, except those ending in test.js, so foo.js but not foo.test.js
  • If the glob pattern does contain a slash (/), it will match for paths as well:
    • "./*.js" will match all JS files in the git repo root, so /test.js but not /foo/bar/test.js
    • "foo/**/\*.js" will match all JS files inside the/foodirectory, so/foo/bar/test.jsbut not/test.js

When matching, lint-staged will do the following

  • Resolve the git root automatically, no configuration needed.
  • Pick the staged files which are present inside the project directory.
  • Filter them using the specified glob patterns.
  • Pass absolute paths to the linters as arguments.

NOTE: lint-staged will pass absolute paths to the linters to avoid any confusion in case they're executed in a different working directory (i.e. when your .git directory isn't the same as your package.json directory).

Also see How to use lint-staged in a multi-package monorepo?

Ignoring files

The concept of lint-staged is to run configured linter tasks (or other tasks) on files that are staged in git. lint-staged will always pass a list of all staged files to the task, and ignoring any files should be configured in the task itself.

Consider a project that uses prettier to keep code format consistent across all files. The project also stores minified 3rd-party vendor libraries in the vendor/ directory. To keep prettier from throwing errors on these files, the vendor directory should be added to prettier's ignore configuration, the .prettierignore file. Running npx prettier . will ignore the entire vendor directory, throwing no errors. When lint-staged is added to the project and configured to run prettier, all modified and staged files in the vendor directory will be ignored by prettier, even though it receives them as input.

In advanced scenarios, where it is impossible to configure the linter task itself to ignore files, but some staged files should still be ignored by lint-staged, it is possible to filter filepaths before passing them to tasks by using the function syntax. See Example: Ignore files from match.

What commands are supported?

Supported are any executables installed locally or globally via npm as well as any executable from your $PATH.

Using globally installed scripts is discouraged, since lint-staged may not work for someone who doesn't have it installed.

lint-staged uses execa to locate locally installed scripts. So in your .lintstagedrc you can write:

{
  "*.js": "eslint --fix"
}

Pass arguments to your commands separated by space as you would do in the shell. See examples below.

Running multiple commands in a sequence

You can run multiple commands in a sequence on every glob. To do so, pass an array of commands instead of a single one. This is useful for running autoformatting tools like eslint --fix or stylefmt but can be used for any arbitrary sequences.

For example:

{
  "*.js": ["eslint", "prettier --write"]
}

going to execute eslint and if it exits with 0 code, it will execute prettier --write on all staged *.js files.

Using JS configuration files

Writing the configuration file in JavaScript is the most powerful way to configure lint-staged (lint-staged.config.js, similar, or passed via --config). From the configuration file, you can export either a single function or an object.

If the exports value is a function, it will receive an array of all staged filenames. You can then build your own matchers for the files and return a command string or an array of command strings. These strings are considered complete and should include the filename arguments, if wanted.

If the exports value is an object, its keys should be glob matches (like in the normal non-js config format). The values can either be like in the normal config or individual functions like described above. Instead of receiving all matched files, the functions in the exported object will only receive the staged files matching the corresponding glob key.

Function signature

The function can also be async:

(filenames: string[]) => string | string[] | Promise<string | string[]>

Example: Export a function to build your own matchers

Click to expand

// lint-staged.config.js
import micromatch from 'micromatch'

export default (allStagedFiles) => {
  const shFiles = micromatch(allStagedFiles, ['**/src/**/*.sh'])
  if (shFiles.length) {
    return `printf '%s\n' "Script files aren't allowed in src directory" >&2`
  }
  const codeFiles = micromatch(allStagedFiles, ['**/*.js', '**/*.ts'])
  const docFiles = micromatch(allStagedFiles, ['**/*.md'])
  return [`eslint ${codeFiles.join(' ')}`, `mdl ${docFiles.join(' ')}`]
}

Example: Wrap filenames in single quotes and run once per file

Click to expand

// .lintstagedrc.js
export default {
  '**/*.js?(x)': (filenames) => filenames.map((filename) => `prettier --write '${filename}'`),
}

Example: Run tsc on changes to TypeScript files, but do not pass any filename arguments

Click to expand

// lint-staged.config.js
export default {
  '**/*.ts?(x)': () => 'tsc -p tsconfig.json --noEmit',
}

Example: Run ESLint on entire repo if more than 10 staged files

Click to expand

// .lintstagedrc.js
export default {
  '**/*.js?(x)': (filenames) =>
    filenames.length > 10 ? 'eslint .' : `eslint ${filenames.join(' ')}`,
}

Example: Use your own globs

Click to expand

It's better to use the function-based configuration (seen above), if your use case is this.

// lint-staged.config.js
import micromatch from 'micromatch'

export default {
  '*': (allFiles) => {
    const codeFiles = micromatch(allFiles, ['**/*.js', '**/*.ts'])
    const docFiles = micromatch(allFiles, ['**/*.md'])
    return [`eslint ${codeFiles.join(' ')}`, `mdl ${docFiles.join(' ')}`]
  },
}

Example: Ignore files from match

Click to expand

If for some reason you want to ignore files from the glob match, you can use micromatch.not():

// lint-staged.config.js
import micromatch from 'micromatch'

export default {
  '*.js': (files) => {
    // from `files` filter those _NOT_ matching `*test.js`
    const match = micromatch.not(files, '*test.js')
    return `eslint ${match.join(' ')}`
  },
}

Please note that for most cases, globs can achieve the same effect. For the above example, a matching glob would be !(*test).js.

Example: Use relative paths for commands

Click to expand

import path from 'path'

export default {
  '*.ts': (absolutePaths) => {
    const cwd = process.cwd()
    const relativePaths = absolutePaths.map((file) => path.relative(cwd, file))
    return `ng lint myProjectName --files ${relativePaths.join(' ')}`
  },
}

Reformatting the code

Tools like Prettier, ESLint/TSLint, or stylelint can reformat your code according to an appropriate config by running prettier --write/eslint --fix/tslint --fix/stylelint --fix. Lint-staged will automatically add any modifications to the commit as long as there are no errors.

{
  "*.js": "prettier --write"
}

Prior to version 10, tasks had to manually include git add as the final step. This behavior has been integrated into lint-staged itself in order to prevent race conditions with multiple tasks editing the same files. If lint-staged detects git add in task configurations, it will show a warning in the console. Please remove git add from your configuration after upgrading.

Examples

All examples assume you've already set up lint-staged in the package.json file and husky in its own config file.

{
  "name": "My project",
  "version": "0.1.0",
  "scripts": {
    "my-custom-script": "linter --arg1 --arg2"
  },
  "lint-staged": {}
}

In .husky/pre-commit

#!/usr/bin/env sh
. "$(dirname "$0")/_/husky.sh"

npx lint-staged

Note: we don't pass a path as an argument for the runners. This is important since lint-staged will do this for you.

ESLint with default parameters for *.js and *.jsx running as a pre-commit hook

Click to expand

{
  "*.{js,jsx}": "eslint"
}

Automatically fix code style with --fix and add to commit

Click to expand

{
  "*.js": "eslint --fix"
}

This will run eslint --fix and automatically add changes to the commit.

Reuse npm script

Click to expand

If you wish to reuse a npm script defined in your package.json:

{
  "*.js": "npm run my-custom-script --"
}

The following is equivalent:

{
  "*.js": "linter --arg1 --arg2"
}

Use environment variables with linting commands

Click to expand

Linting commands do not support the shell convention of expanding environment variables. To enable the convention yourself, use a tool like cross-env.

For example, here is jest running on all .js files with the NODE_ENV variable being set to "test":

{
  "*.js": ["cross-env NODE_ENV=test jest --bail --findRelatedTests"]
}

Automatically fix code style with prettier for any format Prettier supports

Click to expand

{
  "*": "prettier --ignore-unknown --write"
}

Automatically fix code style with prettier for JavaScript, TypeScript, Markdown, HTML, or CSS

Click to expand

{
  "*.{js,jsx,ts,tsx,md,html,css}": "prettier --write"
}

Stylelint for CSS with defaults and for SCSS with SCSS syntax

Click to expand

{
  "*.css": "stylelint",
  "*.scss": "stylelint --syntax=scss"
}

Run PostCSS sorting and Stylelint to check

Click to expand

{
  "*.scss": ["postcss --config path/to/your/config --replace", "stylelint"]
}

Minify the images

Click to expand

{
  "*.{png,jpeg,jpg,gif,svg}": "imagemin-lint-staged"
}

More about imagemin-lint-staged

imagemin-lint-staged is a CLI tool designed for lint-staged usage with sensible defaults.

See more on this blog post for benefits of this approach.

Typecheck your staged files with flow

Click to expand

{
  "*.{js,jsx}": "flow focus-check"
}

Frequently Asked Questions

Can I use lint-staged via node?

Click to expand

Yes!

import lintStaged from 'lint-staged'

try {
  const success = await lintStaged()
  console.log(success ? 'Linting was successful!' : 'Linting failed!')
} catch (e) {
  // Failed to load configuration
  console.error(e)
}

Parameters to lintStaged are equivalent to their CLI counterparts:

const success = await lintStaged({
  allowEmpty: false,
  concurrent: true,
  configPath: './path/to/configuration/file',
  cwd: process.cwd(),
  debug: false,
  maxArgLength: null,
  quiet: false,
  relative: false,
  shell: false,
  stash: true,
  verbose: false,
})

You can also pass config directly with config option:

const success = await lintStaged({
  allowEmpty: false,
  concurrent: true,
  config: { '*.js': 'eslint --fix' },
  cwd: process.cwd(),
  debug: false,
  maxArgLength: null,
  quiet: false,
  relative: false,
  shell: false,
  stash: true,
  verbose: false,
})

The maxArgLength option configures chunking of tasks into multiple parts that are run one after the other. This is to avoid issues on Windows platforms where the maximum length of the command line argument string is limited to 8192 characters. Lint-staged might generate a very long argument string when there are many staged files. This option is set automatically from the cli, but not via the Node.js API by default.

Using with JetBrains IDEs (WebStorm, PyCharm, IntelliJ IDEA, RubyMine, etc.)

Click to expand

Update: The latest version of JetBrains IDEs now support running hooks as you would expect.

When using the IDE's GUI to commit changes with the precommit hook, you might see inconsistencies in the IDE and command line. This is known issue at JetBrains so if you want this fixed, please vote for it on YouTrack.

Until the issue is resolved in the IDE, you can use the following config to work around it:

husky v1.x

{
  "husky": {
    "hooks": {
      "pre-commit": "lint-staged",
      "post-commit": "git update-index --again"
    }
  }
}

husky v0.x

{
  "scripts": {
    "precommit": "lint-staged",
    "postcommit": "git update-index --again"
  }
}

Thanks to this comment for the fix!

How to use lint-staged in a multi-package monorepo?

Click to expand

Install lint-staged on the monorepo root level, and add separate configuration files in each package. When running, lint-staged will always use the configuration closest to a staged file, so having separate configuration files makes sure linters do not "leak" into other packages.

For example, in a monorepo with packages/frontend/.lintstagedrc.json and packages/backend/.lintstagedrc.json, a staged file inside packages/frontend/ will only match that configuration, and not the one in packages/backend/.

Note: lint-staged discovers the closest configuration to each staged file, even if that configuration doesn't include any matching globs. Given these example configurations:

// ./.lintstagedrc.json
{ "*.md": "prettier --write" }
// ./packages/frontend/.lintstagedrc.json
{ "*.js": "eslint --fix" }

When committing ./packages/frontend/README.md, it will not run prettier, because the configuration in the frontend/ directory is closer to the file and doesn't include it. You should treat all lint-staged configuration files as isolated and separated from each other. You can always use JS files to "extend" configurations, for example:

import baseConfig from '../.lintstagedrc.js'

export default {
  ...baseConfig,
  '*.js': 'eslint --fix',
}

Can I lint files outside of the current project folder?

Click to expand

tl;dr: Yes, but the pattern should start with ../.

By default, lint-staged executes linters only on the files present inside the project folder(where lint-staged is installed and run from). So this question is relevant only when the project folder is a child folder inside the git repo. In certain project setups, it might be desirable to bypass this restriction. See #425, #487 for more context.

lint-staged provides an escape hatch for the same(>= v7.3.0). For patterns that start with ../, all the staged files are allowed to match against the pattern. Note that patterns like *.js, **/*.js will still only match the project files and not any of the files in parent or sibling directories.

Example repo: sudo-suhas/lint-staged-django-react-demo.

Can I run lint-staged in CI, or when there are no staged files?

Click to expand

Lint-staged will by default run against files staged in git, and should be run during the git pre-commit hook, for example. It's also possible to override this default behaviour and run against files in a specific diff, for example all changed files between two different branches. If you want to run lint-staged in the CI, maybe you can set it up to compare the branch in a Pull Request/Merge Request to the target branch.

Try out the git diff command until you are satisfied with the result, for example:

git diff --diff-filter=ACMR --name-only master...my-branch

This will print a list of added, changed, modified, and renamed files between master and my-branch.

You can then run lint-staged against the same files with:

npx lint-staged --diff="master...my-branch"

Can I use lint-staged with ng lint

Click to expand

You should not use ng lint through lint-staged, because it's designed to lint an entire project. Instead, you can add ng lint to your git pre-commit hook the same way as you would run lint-staged.

See issue !951 for more details and possible workarounds.

How can I ignore files from .eslintignore?

Click to expand

ESLint throws out warning File ignored because of a matching ignore pattern. Use "--no-ignore" to override warnings that breaks the linting process ( if you used --max-warnings=0 which is recommended ).

ESLint < 7

Click to expand

Based on the discussion from this issue, it was decided that using the outlined script is the best route to fix this.

So you can setup a .lintstagedrc.js config file to do this:

import { CLIEngine } from 'eslint'

export default {
  '*.js': (files) => {
    const cli = new CLIEngine({})
    return 'eslint --max-warnings=0 ' + files.filter((file) => !cli.isPathIgnored(file)).join(' ')
  },
}

ESLint >= 7

Click to expand

In versions of ESLint > 7, isPathIgnored is an async function and now returns a promise. The code below can be used to reinstate the above functionality.

Since 10.5.3, any errors due to a bad ESLint config will come through to the console.

import { ESLint } from 'eslint'

const removeIgnoredFiles = async (files) => {
  const eslint = new ESLint()
  const isIgnored = await Promise.all(
    files.map((file) => {
      return eslint.isPathIgnored(file)
    })
  )
  const filteredFiles = files.filter((_, i) => !isIgnored[i])
  return filteredFiles.join(' ')
}

export default {
  '**/*.{ts,tsx,js,jsx}': async (files) => {
    const filesToLint = await removeIgnoredFiles(files)
    return [`eslint --max-warnings=0 ${filesToLint}`]
  },
}

Download Details:

Author: okonet
Source Code: https://github.com/okonet/lint-staged 
License: MIT license

#javascript #git #workflow #eslint 

Lint-staged: Run Linters on Git Staged Files
Rui  Silva

Rui Silva

1660786200

12 Regras Essenciais De ESLint Para React

O ESLint tem um conjunto abrangente de regras para código JavaScript que abrange escolhas estilísticas e evita bugs comuns. Usar o ESLint sozinho dará um impulso ao seu projeto, mas existem plugins ESLint disponíveis para adicionar regras específicas do React que ajudarão você a escrever aplicativos React sólidos.

Neste post, veremos essas regras e plugins do ESLint, inclusive como eles se aplicam aos Hooks. Aqui estão alguns links rápidos para você pular:

  • Regras do React Hooks ( eslint-plugin-react-hooks)
    • react-hooks/rules-of-hooks
    • react-hooks/exhaustive-deps
  • Regras de reação ( eslint-plugin-react)
    • react/button-has-type
    • react/prop-types
    • react/require-default-props
    • react/no-array-index-key
    • react/react-in-jsx-scope
    • react/jsx-uses-react
    • react/display-name
    • react/no-danger-with-children
    • react/jsx-no-bind

Regras do React Hooks ( eslint-plugin-react-hooks)

Este plugin contém apenas duas regras, mas elas são críticas para evitar armadilhas comuns ao escrever componentes de função com Hooks.

ganchos de reação/regras de ganchos

Esta regra impõe que os componentes sigam as Regras de Ganchos ao usar Ganchos. As regras são discutidas em detalhes na documentação do React , mas existem duas regras que devem ser seguidas ao usar Hooks:

  1. Hooks só devem ser chamados a partir do código de nível superior do seu componente. O que isso realmente significa é que os Hooks não devem ser chamados condicionalmente - eles devem ser chamados em cada renderização, na mesma ordem, para evitar problemas e bugs sutis
  2. Hooks só devem ser chamados de um componente de função ou de outro Hook
    1. Hooks personalizados geralmente compõem o comportamento em conjunto a partir de Hooks embutidos ou até mesmo de outros Hooks personalizados

Na configuração padrão, as violações desta regra causarão um erro, fazendo com que a verificação do lint falhe.

react-hooks/exhaustive-deps

Essa regra impõe certas regras sobre o conteúdo da matriz de dependência que é passada para Hooks, como useEffect, useCallback, e useMemo. Em geral, qualquer valor referenciado no cálculo de efeito, retorno de chamada ou valor memorizado deve ser incluído na matriz de dependência. Se isso não for feito corretamente, podem ocorrer problemas como dados de estado desatualizados ou loops de renderização infinitos .

Essa regra é boa para encontrar possíveis bugs relacionados à dependência, mas existem algumas limitações:

  • Ganchos personalizados com matrizes de dependência não serão verificados com esta regra. Aplica-se apenas aos ganchos embutidos
  • A regra só pode verificar as dependências corretamente se for uma matriz estática de valores. Se uma referência a outro array for usada, ou outro array for espalhado nele, a regra emitirá um aviso de que não pode determinar as dependências

Esta regra tem sido um tanto controversa; existem vários tópicos de problemas longos no GitHub , mas a equipe do React tem sido boa em solicitar e incorporar feedback. Na configuração padrão, as violações dessa regra são tratadas como avisos.

Os detalhes desta regra podem ocupar um artigo inteiro por conta própria. Para um mergulho mais profundo sobre essa regra e como usá-la corretamente, consulte o artigo Understanding the React complete-deps linting warning , aqui no blog LogRocket.

Regras de reação ( eslint-plugin-react)

Este plugin contém muito mais regras (100 regras no momento da escrita) que são específicas para o núcleo do React. A maioria das regras cobre práticas gerais do React, e outras cobrem questões relacionadas à sintaxe JSX. Vamos dar uma olhada em alguns dos mais úteis.

reagir/botão-tem-tipo

Por motivos de acessibilidade, a maioria dos elementos clicáveis ​​em um componente que não são links simples para outro URL devem ser implementados como botões . Um erro comum é omitir o typeatributo desses botões quando eles não estão sendo usados ​​para enviar um formulário.

Quando não typeé especificado, um botão assume como padrão um tipo de submit. Isso pode causar problemas para botões que descem de um formelemento. Clicar nesse botão dentro de um formulário causará um envio de formulário potencialmente indesejado.

Os botões de ação que não se destinam a enviar um formulário devem ter um typeatributo de button.

Esta regra impõe que todos os botões tenham explicitamente um typeatributo — mesmo aqueles que se destinam a botões Enviar . Por ser explícito, as submissões não intencionais são evitadas e a intenção do código é clara.

tipos de reação/prop

Requer que todos os componentes do React tenham suas props descritas em uma PropTypesdeclaração. Essas verificações apenas lançam erros no modo de desenvolvimento, mas podem ajudar a detectar bugs decorrentes de props erradas sendo passadas para um componente.

Se o seu projeto usa TypeScript, essa regra também é satisfeita adicionando uma anotação de tipo às props do componente que os descreve.

Essas duas abordagens são abordadas em detalhes em Comparando TypeScript e PropTypes em aplicativos React por Dillion Megida.

react/require-default-props

Dependendo do componente, alguns adereços podem ser necessários, enquanto outros são opcionais. Se um prop opcional não for passado para um componente, ele será undefined. Isso pode ser esperado, mas pode introduzir bugs se o valor não for verificado.

Esta regra requer que cada prop opcional receba um valor padrão dentro de uma defaultPropsdeclaração para o componente. Esse valor padrão pode ser definido explicitamente como nullou undefinedse é isso que o componente espera.

Com componentes de função, existem duas estratégias diferentes que podem ser usadas para verificar props padrão:

padrãoProps

Essa estratégia espera que o componente de função tenha um defaultPropsobjeto com os padrões.

const MyComponent = ({ action }) => { ... }

MyComponent.propTypes = {
  Action: PropTypes.string;
};

MyComponent.defaultProps = {
  action: 'init'
};

Argumentos padrão

Essa estratégia espera que os padrões sejam especificados na declaração da função, usando a sintaxe de valores padrão embutida do JavaScript.

const MyComponent = ({ action = 'init' }) => { ... }

MyComponent.propTypes = {
  Action: PropTypes.string;
};

Se você usar a defaultArgumentsestratégia, não deve haver um defaultPropsobjeto. Se houver, esta regra falhará.

react/no-array-index-key

Ao renderizar uma lista de itens no React, normalmente chamamos mapum array e a função de mapeamento retorna um componente. Para acompanhar cada item da lista, o React precisa que esses componentes tenham um keyprop.

Uma armadilha comum com listas de renderização é usar o índice de matriz como chave. Isso pode causar renderizações desnecessárias ou até incorretas. A documentação do React desaconselha esta prática devido aos problemas que ela pode causar (há também uma discussão mais detalhada sobre como as chaves são usadas ). Espera-se que uma chave seja um identificador exclusivo para esse item, dentro da lista, que não muda, como o valor da chave primária em uma linha do banco de dados.

Essa regra garante que o índice do array não seja usado como chave.

react/react-in-jsx-scope

Considere este simples componente React:

const Greeter = ({ name }) => <div>Hello {name}!</div>;

O Reactobjeto não é referenciado. No entanto, Reactainda precisa ser importado ou você encontrará um erro. Isso se deve ao processo de transpilação do JSX. Os navegadores não entendem JSX, portanto, durante o processo de compilação (geralmente com uma ferramenta como Babel ou TypeScript), os elementos JSX são transformados em JavaScript válido.

Esse código JavaScript gerado chama React.createElementno lugar de elementos JSX. O componente acima pode ser transpilado para algo assim:

const Greeter = ({ name }) => React.createElement("div", null, "Hello ", name, "!");

As referências Reactaqui são porque Reactainda devem ser importadas. Essa regra garante que todos os arquivos com marcação JSX (não necessariamente um componente React) tenham Reactescopo (normalmente por meio de uma chamada importou require).

react/jsx-uses-react

Sempre importar o React é necessário para uma transpilação adequada, mas quando o ESLint olha para o arquivo, ele ainda é JSX, então não será Reactreferenciado em nenhum lugar. Se o projeto estiver usando a no-unused-varsregra, isso resultará em um erro, pois Reacté importado, mas não usado em nenhum lugar.

Essa regra captura essa situação e evita no-unused-varsfalhas na Reactimportação.

react/nome de exibição

Para saída de depuração adequada, todos os componentes React devem ter um nome de exibição. Em muitos casos, isso não exigirá nenhum código extra. Se um componente for uma função nomeada, o nome de exibição será o nome da função. Nos exemplos abaixo, o nome de exibição do componente será MyComponent.

  • const MyComponent = () => { … }
  • const MyComponent = function() { return …; }
  • export default function MyComponent() { return …; }

Há alguns casos em que o nome de exibição automático é perdido. Isso ocorre normalmente quando a declaração do componente é encapsulada por outra função ou componente de ordem superior, como nos dois exemplos abaixo:

  • const MyComponent = React.memo(() => { … });
  • const MyComponent = React.forwardRef((props, ref) => { … });

O MyComponentnome está vinculado ao novo componente “externo” retornado por memoe forwardRef. O próprio componente agora não tem nome de exibição, o que fará com que essa regra falhe.

Quando esses casos surgem, um nome de exibição pode ser especificado manualmente por meio da displayNamepropriedade para atender à regra:

const MyComponent = React.memo(() => { ... });
MyComponent.displayName = 'MyComponent';

react/no-children-prop

Os componentes do React aceitam uma prop especial chamada children. O valor desta prop será qualquer conteúdo que esteja dentro das tags de abertura e fechamento do elemento. Considere este MyListcomponente simples:

const MyList = ({ children }) => {
  return <ul>{children}</ul>;
};

Isso renderizará o elemento externo ul, e quaisquer filhos que colocarmos dentro do elemento serão renderizados dentro dele.

<MyList>
  <li>item1</li>
  <li>item2</li>
</MyList>

Este é o padrão preferido com componentes React. É possível, embora não recomendado, passar children como um prop child explícito:

<MyList children={<li>item1</li><li>item2</li>} />

O uso acima na verdade causará um erro porque as expressões JSX, como a passada como a prop child explícita, devem ter um único elemento raiz. Isso requer que os filhos sejam agrupados em um fragmento:

<MyList children={<><li>item1</li><li>item2</li></>} />

Conforme mostrado no primeiro exemplo, os filhos são passados ​​como elementos filhos diretamente para o componente, portanto, o componente é o elemento raiz da expressão. Nenhum fragmento ou outro elemento envolvente é necessário aqui.

Isso é principalmente uma escolha/padrão estilístico, mas impede a passagem inadvertida childrende elementos prop e filho explícitos:

<MyList children={<><li>item1</li><li>item2</li></>}>
  <li>item3</li>
  <li>item4</li>
</MyList>

Nesse caso, os elementos filho ( item3e item4) seriam exibidos, mas item1e item2não. Essa regra garante que os filhos sejam passados ​​apenas de maneira idiomática, como elementos JSX filhos.

reagir/sem-perigo-com-crianças

A prop do React dangerouslySetInnerHTMLpermite que uma marcação arbitrária seja definida como innerHTMLpropriedade de um elemento. Isso geralmente não é recomendado, pois pode expor seu aplicativo a um ataque de script entre sites (XSS). No entanto, se você souber que pode confiar na entrada e o caso de uso exigir, essa abordagem pode se tornar necessária.

O prop espera um objeto com uma __htmlpropriedade, cujo valor é uma string HTML bruta. Essa string será definida como o innerHTML.

Como isso substitui qualquer conteúdo filho existente, não faz sentido usar isso em combinação com um childrenprop. Na verdade, o React lançará um erro se você tentar fazer isso. Ao contrário de alguns erros que aparecem apenas no modo de desenvolvimento (como PropTypeserros de validação), esse erro travará seu aplicativo.

Esta regra impõe a mesma regra. Se dangerouslySetInnerHTMLfor usado com filhos, a regra de lint falhará. É muito melhor detectar esses erros durante o linting ou em tempo de compilação, em vez de serem relatados pelos usuários após a implantação do aplicativo!

react/jsx-no-bind

Toda vez que um componente React é renderizado, ele tem um custo de desempenho. Muitas vezes, certos padrões ou práticas podem fazer com que um componente se renderize desnecessariamente. Existem muitas causas para esse comportamento, e essa regra ajuda a evitar uma delas.

Quando qualquer função é definida dentro do componente, ela será um novo objeto de função em cada renderização. Isso significa que sempre que o componente é renderizado novamente, o prop é considerado alterado. Mesmo com React.memo, o componente será renderizado novamente.

Se o componente filho tiver alguma useEffectchamada que leve essa função como uma dependência, isso pode fazer com que o efeito seja executado novamente, criando a possibilidade de um loop infinito que provavelmente congelará o navegador.

Com esta regra habilitada, qualquer função que for passada como prop será sinalizada.

Há duas maneiras de abordar isso. Se a função não depende de mais nada dentro do componente, ela pode ser movida para fora do componente, onde é apenas uma função simples que sempre será a mesma referência de memória. Isso garante que a mesma função seja passada para o prop a cada vez.

Para casos em que a função depende do componente de alguma forma, a correção usual para isso é memoizá-la com o useCallbackHook. Quaisquer propriedades referenciadas na função terão que ser incluídas na useCallbackmatriz de dependências; às vezes isso requer vários níveis de memorização de valores ou funções.

Isso adiciona alguma complexidade, mas tem o benefício de ajudar a reduzir renderizações extras e evitar loops infinitos.

Empacotando

As regras abordadas aqui são apenas algumas das fornecidas pelo eslint-plugin-reactplugin. Algumas regras podem ser opinativas ou exageradas, mas a maioria também tem opções de configuração para torná-las menos rígidas.

Há também outro plugin ESLint muito útil centrado em JSX e práticas de acessibilidade: eslint-plugin-jsx-a11y. As regras deste plug-in verificam sua marcação JSX para garantir que as boas práticas de acessibilidade HTML estejam sendo seguidas.

Esses plugins React ESLint podem ser úteis para evitar armadilhas comuns, especialmente se você ainda é novo no React. Você pode até escrever suas próprias regras e plugins para cobrir outras situações!

Fonte: https://blog.logrocket.com/12-essential-eslint-rules-react/

#react #eslint 

12 Regras Essenciais De ESLint Para React
坂本  篤司

坂本 篤司

1660786080

React の 12 の必須 ESLint ルール

ESLint には、スタイルの選択をカバーし、一般的なバグを防ぐ JavaScript コードの包括的なルール セットがあります。ESLint を単独で使用するとプロジェクトが促進されますが、確実な React アプリケーションを作成するのに役立つ React 固有のルールを追加するために利用できる ESLint プラグインがあります。

この投稿では、これらの ESLint ルールとプラグインについて、フックに適用されるものも含めて説明します。ジャンプするための簡単なリンクを次に示します。

  • React Hooks ルール ( eslint-plugin-react-hooks)
    • react-hooks/rules-of-hooks
    • react-hooks/exhaustive-deps
  • React ルール ( eslint-plugin-react)
    • react/button-has-type
    • react/prop-types
    • react/require-default-props
    • react/no-array-index-key
    • react/react-in-jsx-scope
    • react/jsx-uses-react
    • react/display-name
    • react/no-danger-with-children
    • react/jsx-no-bind

React Hooks ルール ( eslint-plugin-react-hooks)

このプラグインには 2 つのルールしか含まれていませんが、フックを使用して関数コンポーネントを作成する際によくある落とし穴を回避するために重要です。

反応フック/フックのルール

このルールは、フックを使用するときに、コンポーネントがフックのルールに従うことを強制します。ルールはReact のドキュメントで詳しく説明されていますが、フックを使用する際に従う必要がある 2 つのルールがあります。

  1. フックは、コンポーネントの最上位コードからのみ呼び出す必要があります。これが実際に意味することは、フックを条件付きで呼び出すべきではないということです — 代わりに、問題や微妙なバグを避けるために、すべてのレンダリングで同じ順序で呼び出す必要があります
  2. フックは、関数コンポーネントまたは別のフックからのみ呼び出す必要があります
    1. カスタム フックは、多くの場合、組み込みのフックや他のカスタム フックから動作を構成します。

デフォルトの構成では、このルールに違反するとエラーが発生し、lint チェックが失敗します。

react-hooks/exhaustive-deps

この規則は、フックに渡される依存配列の内容に関する特定の規則useEffect( 、useCallback、など) を適用しuseMemoます。一般に、エフェクト、コールバック、またはメモ化された値の計算で参照される値は、依存配列に含まれている必要があります。これが適切に行われないと、古い状態データや無限のレンダリング ループなどの問題が発生する可能性があります。

このルールは、依存関係に関連する潜在的なバグを見つけるのに適していますが、いくつかの制限があります。

  • 依存配列を持つカスタム フックは、このルールではチェックされません。組み込みのフックにのみ適用されます
  • 値の静的配列である場合、ルールは依存関係のみを適切にチェックできます。別の配列への参照が使用されている場合、または別の配列がその中に分散されている場合、ルールは依存関係を判断できないという警告を発します。

このルールはやや物議を醸しています。GitHub には長いイシュー スレッドがいくつかありますが、React チームはフィードバックを募り、取り入れることに長けています。デフォルトの構成では、このルールの違反は警告として扱われます。

このルールの詳細は、それだけで記事全体を占める可能性があります。このルールの詳細と適切な使用方法については、こちらの LogRocket ブログで、React の徹底的な deps リンティング警告の記事を理解するを参照してください。

React ルール ( eslint-plugin-react)

このプラグインには、React のコアに固有のさらに多くのルール (執筆時点で 100 ルール) が含まれています。ほとんどのルールは一般的な React プラクティスをカバーしており、その他のルールは JSX 構文に関連する問題をカバーしています。より便利なものをいくつか見てみましょう。

反応/ボタンの種類

アクセシビリティ上の理由から、別の URL への単純なリンクではない、コンポーネント内のほとんどのクリック可能な要素は、ボタンとして実装する必要がありますtypeよくある間違いは、フォームの送信に使用されていないときに、これらのボタンから属性を省略してしまうことです。

notypeを指定すると、ボタンのデフォルトのタイプは になりsubmitます。formこれにより、要素から派生したボタンで問題が発生する可能性があります。フォーム内でこのようなボタンをクリックすると、不要なフォーム送信が行われる可能性があります。

フォームを送信するためのものではないアクション ボタンには、 のtype属性が必要ですbutton

このルールは、送信typeボタンとして意図されたものであっても、すべてのボタンが明示的に属性を持つことを強制します。明示的であることにより、意図しない送信が回避され、コードの意図が明確になります。

反応/小道具タイプ

すべての React コンポーネントの props がPropTypes宣言で記述されている必要があります。これらのチェックは、開発モードでのみエラーをスローしますが、コンポーネントに渡された間違った props から生じるバグをキャッチするのに役立ちます。

プロジェクトで TypeScript を使用している場合、この規則は、それらを記述するコンポーネント props に型注釈を追加することによっても満たされます。

これら 2 つのアプローチについては、Dillion Megida による React アプリケーションでの TypeScript と PropTypes の比較で詳しく説明されています。

反応/require-default-props

コンポーネントによっては、必須の props とオプションの props があります。オプションの prop がコンポーネントに渡されない場合、それは になりますundefined。これは予期されることですが、値がチェックされていないとバグが発生する可能性があります。

defaultPropsこのルールでは、すべてのオプションの propに、コンポーネントの宣言内でデフォルト値を指定する必要があります。このデフォルト値は、コンポーネントが期待するものである場合、nullまたはに明示的に設定できます。undefined

関数コンポーネントでは、デフォルトの props をチェックするために使用できる 2 つの異なる戦略があります。

defaultProps

この戦略は、関数コンポーネントがdefaultPropsデフォルトのオブジェクトを持つことを期待しています。

const MyComponent = ({ action }) => { ... }

MyComponent.propTypes = {
  Action: PropTypes.string;
};

MyComponent.defaultProps = {
  action: 'init'
};

デフォルト引数

この戦略は、JavaScript の組み込みのデフォルト値構文を使用して、関数宣言でデフォルトが指定されることを想定しています。

const MyComponent = ({ action = 'init' }) => { ... }

MyComponent.propTypes = {
  Action: PropTypes.string;
};

戦略を使用する場合、オブジェクトdefaultArgumentsは存在しないはずです。defaultProps存在する場合、このルールは失敗します。

反応/no-array-index-key

React でアイテムのリストをレンダリングする場合、通常はmap配列を呼び出し、マッピング関数はコンポーネントを返します。リスト内の各項目を追跡するために、React はこれらのコンポーネントにkeyprop を持たせる必要があります。

レンダリング リストのよくある落とし穴は、配列インデックスをキーとして使用することです。これにより、不要なレンダリングや不適切なレンダリングが発生する可能性があります。React のドキュメントでは、問題が発生する可能性があるため、この方法は使用しないようにアドバイスしています (キーの使用方法については、より詳細な説明もあります)。キーは、データベース行の主キー値のように、リスト内の変更されないアイテムの一意の識別子であることが期待されます。

この規則により、配列インデックスがキーとして使用されないことが保証されます。

反応/反応-jsx-スコープ

次の単純な React コンポーネントについて考えてみましょう。

const Greeter = ({ name }) => <div>Hello {name}!</div>;

Reactオブジェクトはまったく参照されていません。ただし、Reactインポートする必要があります。そうしないと、エラーが発生します。これは、JSX の変換プロセスによるものです。ブラウザーは JSX を認識しないため、ビルド プロセス中に (通常は Babel や TypeScript などのツールを使用して)、JSX 要素は有効な JavaScript に変換されます。

React.createElementこれにより、JSX 要素の代わりにJavaScript コード呼び出しが生成されました。上記のコンポーネントは、次のようにトランスパイルされる可能性があります。

const Greeter = ({ name }) => React.createElement("div", null, "Hello ", name, "!");

ここへの参照は、まだインポートする必要Reactがある理由です。Reactこのルールにより、JSX マークアップを含むすべてのファイル (必ずしも React コンポーネントであるとは限りません) がReactスコープ内にあることが保証されます (通常はimportorrequire呼び出しを介して)。

反応/jsx-uses-react

適切なトランスパイルのためには常に React をインポートする必要がありますが、ESLint がファイルを見ると、まだ JSX であるため、Reactどこにも参照されていません。プロジェクトがルールを使用している場合、はインポートされているがどこにも使用されていないno-unused-varsため、エラーが発生します。React

このルールはこの状況をキャッチし、インポートno-unused-varsの失敗を防ぎます。React

反応/表示名

適切なデバッグ出力を得るには、すべての React コンポーネントに表示名が必要です。多くの場合、これには追加のコードは必要ありません。コンポーネントが名前付き関数の場合、表示名は関数の名前になります。以下の例では、コンポーネントの表示名は になりますMyComponent

  • const MyComponent = () => { … }
  • const MyComponent = function() { return …; }
  • export default function MyComponent() { return …; }

自動表示名が失われる場合があります。これは通常、次の 2 つの例のように、コンポーネント宣言が別の関数または高次コンポーネントによってラップされている場合です。

  • const MyComponent = React.memo(() => { … });
  • const MyComponent = React.forwardRef((props, ref) => { … });

名前は、およびMyComponentによって返される新しい「外部」コンポーネントにバインドされます。コンポーネント自体には表示名がないため、このルールは失敗します。memoforwardRef

displayNameこれらのケースが発生した場合、ルールを満たすためにプロパティを介して表示名を手動で指定できます。

const MyComponent = React.memo(() => { ... });
MyComponent.displayName = 'MyComponent';

反応/子供のない小道具

React コンポーネントは、 と呼ばれる特別な props を受け入れchildrenます。この prop の値は、要素の開始タグと終了タグ内にあるコンテンツになります。MyList次の単純なコンポーネントを検討してください。

const MyList = ({ children }) => {
  return <ul>{children}</ul>;
};

これにより、外側ulの要素がレンダリングされ、要素内に配置されたすべての子がその内部でレンダリングされます。

<MyList>
  <li>item1</li>
  <li>item2</li>
</MyList>

これは、React コンポーネントで推奨されるパターンです。推奨されませんが、明示的な children プロパティとして子を渡すことは可能です:

<MyList children={<li>item1</li><li>item2</li>} />

明示的な children プロパティとして渡されるような JSX 式は単一のルート要素を持つ必要があるため、上記の使用法は実際にはエラーを引き起こします。これには、子をフラグメントでラップする必要があります。

<MyList children={<><li>item1</li><li>item2</li></>} />

最初の例に示すように、子は子要素としてコンポーネントに直接渡されるため、コンポーネントは式のルート要素になります。ここでは、フラグメントやその他の囲み要素は必要ありません。

これは主にスタイル上の選択/パターンですが、明示的なchildrenprop 要素と子要素の両方を誤って渡すことを防ぎます。

<MyList children={<><li>item1</li><li>item2</li></>}>
  <li>item3</li>
  <li>item4</li>
</MyList>

この場合、子要素 ( item3and item4) は表示されますが、item1andは表示されitem2ません。このルールにより、子は子 JSX 要素として慣用的な方法でのみ渡されることが保証されます。

反応/子供との危険なし

React のdangerouslySetInnerHTMLprop により、任意のマークアップをinnerHTML要素のプロパティとして設定できます。これは、アプリケーションがクロスサイト スクリプティング (XSS) 攻撃にさらされる可能性があるため、一般的にはお勧めできません。ただし、入力を信頼できることがわかっていて、ユース ケースでそれが必要な場合は、このアプローチが必要になることがあります。

__htmlprop は、値が生の HTML 文字列であるプロパティを持つオブジェクトを想定しています。この文字列は として設定されますinnerHTML

childrenこれは既存の子コンテンツを置き換えるため、これをpropと組み合わせて使用​​しても意味がありません。実際、これを行おうとすると、React はエラーをスローします。PropTypes開発モードでのみ表示される一部のエラー (検証エラーなど) とは異なり、このエラーはアプリをクラッシュさせます。

このルールは同じルールを適用します。を子で使用するdangerouslySetInnerHTMLと、lint ルールは失敗します。これらのエラーは、アプリのデプロイ後にユーザーから報告されるよりも、lint 時またはビルド時にキャッチする方がはるかに優れています。

反応/jsx-no-bind

React コンポーネントがレンダリングされるたびに、パフォーマンス コストが発生します。多くの場合、特定のパターンや慣行により、コンポーネントが不必要に再レンダリングされることがあります。この動作には多くの原因があり、このルールはそれらの 1 つを防ぐのに役立ちます。

コンポーネント内で関数が定義されると、レンダリングごとに新しい関数オブジェクトになります。これは、コンポーネントが再レンダリングされるたびに、小道具が変更されたと見なされることを意味します。であってもReact.memo、コンポーネントは再レンダリングされます。

子コンポーネントにuseEffectその関数を依存関係として取る呼び出しがある場合、これによりエフェクトが再度実行され、無限ループが発生してブラウザーがフリーズする可能性があります。

このルールを有効にすると、prop として渡されるすべての関数にフラグが付けられます。

これには 2 つの方法があります。関数がコンポーネント内の他のものに依存していない場合は、コンポーネントの外に移動できます。コンポーネントの外では、常に同じメモリ参照になる単純な関数になります。これにより、毎回同じ関数が prop に渡されることが保証されます。

関数何らかの形でコンポーネントに依存している場合、これに対する通常の修正はuseCallbackフックでメモ化することです。関数で参照されるすべてのプロパティは、useCallback依存配列に含める必要があります。場合によっては、値または関数の複数レベルのメモ化が必要になることがあります。

これにより複雑さが増しますが、余分なレンダリングを減らし、無限ループを防ぐのに役立つという利点があります。

まとめ

eslint-plugin-reactここで説明するルールは、プラグインによって提供されるルールのほんの一部です。一部のルールは独断的または過度に熱心である可能性がありますが、ほとんどの場合、ルールを緩和するための構成オプションもあります。

また、JSX とアクセシビリティ プラクティスを中心とした、非常に役立つ ESLint プラグインがもう 1 つありますeslint-plugin-jsx-a11y。このプラグインのルールは、JSX マークアップをチェックして、適切な HTML アクセシビリティ プラクティスに従っていることを確認します。

これらの React ESLint プラグインは、特に React を初めて使用する場合に、よくある落とし穴を回避するのに役立ちます。独自のルールとプラグインを作成して、他の状況をカバーすることもできます!

ソース: https://blog.logrocket.com/12-essential-eslint-rules-react/

#react #eslint 

React の 12 の必須 ESLint ルール

12 Règles ESLint Essentielles Pour React

ESLint dispose d'un ensemble complet de règles pour le code JavaScript qui couvrent les choix stylistiques et empêchent les bogues courants. Utiliser ESLint seul donnera un coup de pouce à votre projet, mais il existe des plugins ESLint disponibles pour ajouter des règles spécifiques à React qui vous aideront à écrire des applications React solides.

Dans cet article, nous passerons en revue ces règles et plugins ESLint, y compris ceux qui s'appliquent aux crochets. Voici quelques liens rapides pour vous déplacer :

  • Règles React Hooks ( eslint-plugin-react-hooks)
    • react-hooks/rules-of-hooks
    • react-hooks/exhaustive-deps
  • Règles de réaction ( eslint-plugin-react)
    • react/button-has-type
    • react/prop-types
    • react/require-default-props
    • react/no-array-index-key
    • react/react-in-jsx-scope
    • react/jsx-uses-react
    • react/display-name
    • react/no-danger-with-children
    • react/jsx-no-bind

Règles React Hooks ( eslint-plugin-react-hooks)

Ce plugin ne contient que deux règles, mais elles sont essentielles pour éviter les pièges courants lors de l'écriture de composants de fonction avec des crochets.

réagir-crochets/règles-de-crochets

Cette règle impose que les composants suivent les règles des crochets lors de l'utilisation des crochets. Les règles sont décrites en détail dans la documentation React , mais il y a deux règles qui doivent être suivies lors de l'utilisation de Hooks :

  1. Les crochets ne doivent être appelés qu'à partir du code de niveau supérieur de votre composant. Ce que cela signifie vraiment, c'est que les crochets ne doivent pas être appelés de manière conditionnelle - ils doivent plutôt être appelés à chaque rendu, dans le même ordre, pour éviter les problèmes et les bugs subtils.
  2. Les crochets ne doivent être appelés qu'à partir d'un composant de fonction ou d'un autre crochet
    1. Les crochets personnalisés composent souvent le comportement à partir de crochets intégrés, ou même d'autres crochets personnalisés.

Dans la configuration par défaut, les violations de cette règle entraîneront une erreur, entraînant l'échec de la vérification des peluches.

React-hooks/exhaustive-deps

Cette règle applique certaines règles concernant le contenu du tableau de dépendances qui est transmis à Hooks, telles que useEffect, useCallbacket useMemo. En général, toute valeur référencée dans le calcul de l'effet, du rappel ou de la valeur mémorisée doit être incluse dans le tableau de dépendance. Si cela n'est pas fait correctement, des problèmes tels que des données d'état obsolètes ou des boucles de rendu infinies peuvent en résulter.

Cette règle est efficace pour détecter les bogues potentiels liés aux dépendances, mais il existe certaines limitations :

  • Les hooks personnalisés avec des tableaux de dépendances ne seront pas vérifiés avec cette règle. Cela ne s'applique qu'aux crochets intégrés
  • La règle ne peut vérifier correctement les dépendances que s'il s'agit d'un tableau statique de valeurs. Si une référence à un autre tableau est utilisée, ou si un autre tableau y est étendu, la règle émettra un avertissement indiquant qu'elle ne peut pas déterminer les dépendances

Cette règle a été quelque peu controversée; il existe plusieurs longs fils de discussion sur GitHub , mais l'équipe React a été douée pour solliciter et intégrer des commentaires. Dans la configuration par défaut, les violations de cette règle sont traitées comme des avertissements.

Les détails de cette règle pourraient occuper à eux seuls un article entier. Pour une plongée plus approfondie sur cette règle et comment l'utiliser correctement, consultez l' article Comprendre l'avertissement de peluchage exhaustif de React , ici sur le blog LogRocket.

Règles de réaction ( eslint-plugin-react)

Ce plugin contient beaucoup plus de règles (100 règles au moment de la rédaction) qui sont spécifiques au cœur de React. La plupart des règles couvrent les pratiques générales de React, et d'autres couvrent les problèmes liés à la syntaxe JSX. Jetons un coup d'œil à certains des plus utiles.

réagir/bouton-a-type

Pour des raisons d'accessibilité, la plupart des éléments cliquables d'un composant qui ne sont pas de simples liens vers une autre URL doivent être implémentés sous forme de boutons . Une erreur courante consiste à omettre l' typeattribut de ces boutons lorsqu'ils ne sont pas utilisés pour soumettre un formulaire.

Lorsque no typeest spécifié, un bouton prend par défaut le type submit. Cela peut entraîner des problèmes pour les boutons qui descendent d'un formélément. Cliquer sur un tel bouton à l'intérieur d'un formulaire entraînera une soumission de formulaire potentiellement indésirable.

Les boutons d'action qui ne sont pas destinés à soumettre un formulaire doivent avoir un typeattribut de button.

Cette règle impose que tous les boutons aient explicitement un typeattribut, même ceux qui sont destinés à être des boutons Soumettre . En étant explicite, les soumissions involontaires sont évitées et l'intention du code est claire.

réagir/prop-types

Nécessite que tous les composants React aient leurs accessoires décrits dans une PropTypesdéclaration. Ces vérifications ne génèrent des erreurs qu'en mode développement, mais peuvent aider à détecter les bogues résultant de la transmission de mauvais accessoires à un composant.

Si votre projet utilise TypeScript, cette règle est également satisfaite en ajoutant une annotation de type aux accessoires du composant qui les décrit.

Ces deux approches sont décrites en détail dans Comparing TypeScript and PropTypes in React applications by Dillion Megida.

réagir/require-default-props

Selon le composant, certains accessoires peuvent être nécessaires tandis que d'autres sont facultatifs. Si un accessoire optionnel n'est pas passé à un composant, ce sera undefined. Cela peut être attendu mais peut introduire des bogues si la valeur n'est pas cochée.

Cette règle exige que chaque accessoire facultatif reçoive une valeur par défaut dans une defaultPropsdéclaration pour le composant. Cette valeur par défaut peut être explicitement définie sur nullou undefinedsi c'est ce que le composant attend.

Avec les composants de fonction, il existe deux stratégies différentes qui peuvent être utilisées pour vérifier les accessoires par défaut :

defaultProps

Cette stratégie s'attend à ce que le composant fonction ait un defaultPropsobjet avec les valeurs par défaut.

const MyComponent = ({ action }) => { ... }

MyComponent.propTypes = {
  Action: PropTypes.string;
};

MyComponent.defaultProps = {
  action: 'init'
};

defaultArguments

Cette stratégie s'attend à ce que les valeurs par défaut soient spécifiées dans la déclaration de la fonction, en utilisant la syntaxe des valeurs par défaut intégrée de JavaScript.

const MyComponent = ({ action = 'init' }) => { ... }

MyComponent.propTypes = {
  Action: PropTypes.string;
};

Si vous utilisez la defaultArgumentsstratégie, il ne devrait pas y avoir d' defaultPropsobjet. Si c'est le cas, cette règle échouera.

réagir / pas de clé d'index de tableau

Lors du rendu d'une liste d'éléments dans React, nous appelons généralement mapun tableau et la fonction de mappage renvoie un composant. Pour garder une trace de chaque élément de la liste, React a besoin que ces composants aient un keyaccessoire.

Un écueil courant avec les listes de rendu consiste à utiliser l'index du tableau comme clé. Cela peut entraîner des rendus inutiles, voire incorrects. La documentation React déconseille cette pratique en raison des problèmes qu'elle peut causer (il y a aussi une discussion plus détaillée sur la façon dont les clés sont utilisées ). Une clé est censée être un identifiant unique pour cet élément, dans la liste, qui ne change pas, comme la valeur de la clé primaire dans une ligne de base de données.

Cette règle garantit que l'index du tableau n'est pas utilisé comme clé.

réagir/réagir-dans-jsx-scope

Considérez ce composant React simple :

const Greeter = ({ name }) => <div>Hello {name}!</div>;

L' Reactobjet n'est pas du tout référencé. Cependant, Reactil doit encore être importé, sinon vous rencontrerez une erreur. Cela est dû au processus de transpilation de JSX. Les navigateurs ne comprennent pas JSX, donc pendant le processus de construction (généralement avec un outil tel que Babel ou TypeScript), les éléments JSX sont transformés en JavaScript valide.

Cela a généré des appels de code JavaScript React.createElementà la place des éléments JSX. Le composant ci-dessus peut être transpilé en quelque chose comme ceci :

const Greeter = ({ name }) => React.createElement("div", null, "Hello ", name, "!");

Les références à Reactici sont pourquoi Reactdoivent encore être importées. Cette règle garantit que tous les fichiers avec un balisage JSX (pas nécessairement même un composant React) ont une Reactportée (généralement via un appel importou require).

réagir/jsx-utilise-réagir

Il est toujours nécessaire d'importer React pour une transpilation correcte, mais lorsque ESLint regarde le fichier, il s'agit toujours de JSX, il ne sera donc Reactréférencé nulle part. Si le projet utilise la no-unused-varsrègle, cela entraîne une erreur car Reactest importé mais n'est utilisé nulle part.

Cette règle détecte cette situation et empêche no-unused-varsl'échec de l' Reactimportation.

réagir/nom d'affichage

Pour une sortie de débogage appropriée, tous les composants React doivent avoir un nom d'affichage. Dans de nombreux cas, cela ne nécessitera aucun code supplémentaire. Si un composant est une fonction nommée, le nom d'affichage sera le nom de la fonction. Dans les exemples ci-dessous, le nom d'affichage du composant sera MyComponent.

  • const MyComponent = () => { … }
  • const MyComponent = function() { return …; }
  • export default function MyComponent() { return …; }

Dans certains cas, le nom d'affichage automatique est perdu. C'est généralement lorsque la déclaration du composant est enveloppée par une autre fonction ou un composant d'ordre supérieur, comme dans les deux exemples ci-dessous :

  • const MyComponent = React.memo(() => { … });
  • const MyComponent = React.forwardRef((props, ref) => { … });

Le MyComponentnom est lié au nouveau composant "externe" renvoyé par memoet forwardRef. Le composant lui-même n'a plus de nom d'affichage, ce qui entraînera l'échec de cette règle.

Lorsque ces cas se présentent, un nom d'affichage peut être spécifié manuellement via la displayNamepropriété pour satisfaire la règle :

const MyComponent = React.memo(() => { ... });
MyComponent.displayName = 'MyComponent';

réagir/sans-enfants-prop

Les composants React acceptent un accessoire spécial appelé children. La valeur de cet accessoire sera le contenu contenu dans les balises d'ouverture et de fermeture de l'élément. Considérez ce MyListcomposant simple :

const MyList = ({ children }) => {
  return <ul>{children}</ul>;
};

Cela rendra l' ulélément extérieur, et tous les enfants que nous mettons à l'intérieur de l'élément seront rendus à l'intérieur de celui-ci.

<MyList>
  <li>item1</li>
  <li>item2</li>
</MyList>

C'est le modèle préféré avec les composants React. Il est possible, bien que déconseillé, de passer children comme prop children explicite :

<MyList children={<li>item1</li><li>item2</li>} />

L'utilisation ci-dessus provoquera en fait une erreur car les expressions JSX, comme celle transmise en tant que prop enfants explicite, doivent avoir un seul élément racine. Cela nécessite que les enfants soient enveloppés dans un fragment :

<MyList children={<><li>item1</li><li>item2</li></>} />

Comme indiqué dans le premier exemple, les enfants sont passés en tant qu'éléments enfants directement au composant, de sorte que le composant est l'élément racine de l'expression. Aucun fragment ou autre élément englobant n'est nécessaire ici.

Il s'agit principalement d'un choix/motif stylistique, mais cela empêche de passer par inadvertance à la fois un childrenaccessoire explicite et des éléments enfants :

<MyList children={<><li>item1</li><li>item2</li></>}>
  <li>item3</li>
  <li>item4</li>
</MyList>

Dans ce cas, les éléments enfants ( item3et item4) seraient affichés, mais pas item1et item2. Cette règle garantit que les enfants ne sont transmis que de manière idiomatique, en tant qu'éléments JSX enfants.

réagir/pas-de-danger-avec-les-enfants

La prop de React dangerouslySetInnerHTMLpermet de définir un balisage arbitraire comme innerHTMLpropriété d'un élément. Ceci n'est généralement pas recommandé, car cela peut exposer votre application à une attaque de script intersite (XSS). Cependant, si vous savez que vous pouvez faire confiance à l'entrée et que le cas d'utilisation l'exige, cette approche peut devenir nécessaire.

Le prop attend un objet avec une __htmlpropriété, dont la valeur est une chaîne HTML brute. Cette chaîne sera définie comme innerHTML.

Étant donné que cela remplace tout contenu enfant existant, il n'est pas logique de l'utiliser en combinaison avec un childrenaccessoire. En fait, React générera une erreur si vous essayez de le faire. Contrairement à certaines erreurs qui n'apparaissent qu'en mode développement (comme PropTypesles erreurs de validation), cette erreur plantera votre application.

Cette règle applique la même règle. Si dangerouslySetInnerHTMLest utilisé avec des enfants, la règle de charpie échouera. Il est bien préférable d'attraper ces erreurs lors du linting, ou au moment de la construction, plutôt que signalées par les utilisateurs une fois l'application déployée !

réagir/jsx-no-bind

Chaque fois qu'un composant React est rendu, cela a un coût de performance. Souvent, certains modèles ou pratiques peuvent entraîner un nouveau rendu inutile d'un composant. Il existe de nombreuses causes à ce comportement, et cette règle permet d'éviter l'une d'entre elles.

Lorsqu'une fonction est définie à l'intérieur du composant, ce sera un nouvel objet de fonction à chaque rendu. Cela signifie que chaque fois que le composant est rendu à nouveau, l'accessoire est considéré comme modifié. Même avec React.memo, le composant restituera.

Si le composant enfant a des useEffectappels qui prennent cette fonction en tant que dépendance, cela peut entraîner la réexécution de l'effet, créant ainsi la possibilité d'une boucle infinie qui gèlera probablement le navigateur.

Lorsque cette règle est activée, toute fonction transmise en tant que prop sera signalée.

Il y a deux façons d'aborder ce problème. Si la fonction ne dépend de rien d'autre à l'intérieur du composant, elle peut être déplacée à l'extérieur du composant, où il s'agit simplement d'une simple fonction qui sera toujours la même référence mémoire. Cela garantit que la même fonction est transmise à la prop à chaque fois.

Dans les cas où la fonction dépend du composant d'une manière ou d'une autre, la solution habituelle consiste à la mémoriser avec le useCallbackcrochet. Toutes les propriétés référencées dans la fonction devront être incluses dans le useCallbacktableau de dépendances ; cela nécessite parfois plusieurs niveaux de mémorisation de valeurs ou de fonctions.

Cela ajoute une certaine complexité, mais a l'avantage d'aider à réduire les rendus supplémentaires et à éviter les boucles infinies.

Emballer

Les règles couvertes ici ne sont que quelques-unes de celles fournies par le eslint-plugin-reactplugin. Certaines règles peuvent être opiniâtres ou trop zélées, mais la plupart ont également des options de configuration pour les rendre moins strictes.

Il existe également un autre plugin ESLint très utile centré sur JSX et les pratiques d'accessibilité : eslint-plugin-jsx-a11y. Les règles de ce plugin vérifient votre balisage JSX pour s'assurer que les bonnes pratiques d'accessibilité HTML sont suivies.

Ces plugins React ESLint peuvent être utiles pour éviter les pièges courants, surtout si vous êtes encore nouveau sur React. Vous pouvez même écrire vos propres règles et plugins pour couvrir d'autres situations !

Source : https://blog.logrocket.com/12-essential-eslint-rules-react/

#react #eslint 

12 Règles ESLint Essentielles Pour React

12 Reglas Esenciales De ESLint Para React

ESLint tiene un conjunto completo de reglas para el código JavaScript que cubre opciones estilísticas y evita errores comunes. Usar ESLint solo le dará un impulso a su proyecto, pero hay complementos de ESLint disponibles para agregar reglas específicas de React que lo ayudarán a escribir aplicaciones sólidas de React.

En esta publicación, repasaremos estas reglas y complementos de ESLint, incluso si se aplican a Hooks. Aquí hay algunos enlaces rápidos para que pueda saltar:

  • Reglas de ganchos de reacción ( eslint-plugin-react-hooks)
    • react-hooks/rules-of-hooks
    • react-hooks/exhaustive-deps
  • Reglas de reacción ( eslint-plugin-react)
    • react/button-has-type
    • react/prop-types
    • react/require-default-props
    • react/no-array-index-key
    • react/react-in-jsx-scope
    • react/jsx-uses-react
    • react/display-name
    • react/no-danger-with-children
    • react/jsx-no-bind

Reglas de ganchos de reacción ( eslint-plugin-react-hooks)

Este complemento solo contiene dos reglas, pero son fundamentales para evitar errores comunes al escribir componentes de funciones con Hooks.

ganchos de reacción/reglas de ganchos

Esta regla impone que los componentes sigan las Reglas de Hooks cuando usan Hooks. Las reglas se analizan en detalle en la documentación de React , pero hay dos reglas que deben seguirse al usar Hooks:

  1. Los ganchos solo deben llamarse desde el código de nivel superior de su componente. Lo que esto realmente significa es que los ganchos no deben llamarse condicionalmente; en su lugar, deben llamarse en cada renderizado, en el mismo orden, para evitar problemas y errores sutiles.
  2. Los ganchos solo deben llamarse desde un componente de función u otro gancho
    1. Los ganchos personalizados a menudo componen el comportamiento a partir de ganchos incorporados o incluso otros ganchos personalizados.

En la configuración predeterminada, las infracciones de esta regla provocarán un error, lo que hará que falle la comprobación de pelusa.

ganchos de reacción / profundidades exhaustivas

Esta regla aplica ciertas reglas sobre el contenido de la matriz de dependencia que se pasa a los Hooks, como useEffect, useCallbacky useMemo. En general, cualquier valor al que se haga referencia en el efecto, la devolución de llamada o el cálculo del valor memorizado debe incluirse en la matriz de dependencia. Si esto no se hace correctamente, pueden surgir problemas como datos de estado desactualizados o bucles de representación infinitos .

Esta regla es buena para encontrar posibles errores relacionados con la dependencia, pero tiene algunas limitaciones:

  • Los ganchos personalizados con matrices de dependencia no se verificarán con esta regla. Solo se aplica a los ganchos incorporados.
  • La regla solo puede comprobar correctamente las dependencias si se trata de una matriz estática de valores. Si se usa una referencia a otra matriz, o se distribuye otra matriz, la regla emitirá una advertencia de que no puede determinar las dependencias.

Esta regla ha sido algo controvertida; hay varios hilos de problemas largos en GitHub , pero el equipo de React ha sido bueno solicitando e incorporando comentarios. En la configuración predeterminada, las violaciones de esta regla se tratan como advertencias.

Los detalles de esta regla podrían ocupar un artículo completo por sí solos. Para una inmersión más profunda en esta regla y cómo usarla correctamente, consulte el artículo Comprensión de la advertencia de pelusa de profundidad exhaustiva de React , aquí en el blog de LogRocket.

Reglas de reacción ( eslint-plugin-react)

Este complemento contiene muchas más reglas (100 reglas en el momento de escribir este artículo) que son específicas del núcleo de React. La mayoría de las reglas cubren las prácticas generales de React y otras cubren problemas relacionados con la sintaxis JSX. Echemos un vistazo a algunos de los más útiles.

reaccionar/botón-tiene-tipo

Por razones de accesibilidad, la mayoría de los elementos en los que se puede hacer clic en un componente que no son simples enlaces a otra URL deben implementarse como botones . Un error común es omitir el typeatributo de estos botones cuando no se usan para enviar un formulario.

Cuando no typese especifica, un botón tiene por defecto un tipo de submit. Esto puede causar problemas con los botones que descienden de un formelemento. Hacer clic en dicho botón dentro de un formulario provocará un envío de formulario potencialmente no deseado.

Los botones de acción que no están destinados a enviar un formulario deben tener un typeatributo de button.

Esta regla exige que todos los botones tengan explícitamente un typeatributo, incluso los que están destinados a ser botones Enviar . Al ser explícito, se evitan envíos no intencionales y la intención del código es clara.

reaccionar/tipos de apoyo

Requiere que todos los componentes de React tengan sus accesorios descritos en una PropTypesdeclaración. Estas comprobaciones solo arrojan errores en el modo de desarrollo, pero pueden ayudar a detectar errores que surjan de los accesorios incorrectos que se pasan a un componente.

Si su proyecto usa TypeScript, esta regla también se cumple agregando una anotación de tipo a los accesorios del componente que los describe.

Estos dos enfoques se tratan en detalle en Comparación de TypeScript y PropTypes en aplicaciones React de Dillion Megida.

reaccionar/requerir-predeterminado-propiedades

Según el componente, es posible que se requieran algunos accesorios mientras que otros son opcionales. Si no se pasa una propiedad opcional a un componente, será undefined. Esto puede esperarse, pero puede introducir errores si no se comprueba el valor.

Esta regla requiere que cada accesorio opcional reciba un valor predeterminado dentro de una defaultPropsdeclaración para el componente. Este valor predeterminado se puede establecer explícitamente en nullo undefinedsi eso es lo que espera el componente.

Con los componentes de función, hay dos estrategias diferentes que se pueden usar para verificar los accesorios predeterminados:

accesorios predeterminados

Esta estrategia espera que el componente de la función tenga un defaultPropsobjeto con los valores predeterminados.

const MyComponent = ({ action }) => { ... }

MyComponent.propTypes = {
  Action: PropTypes.string;
};

MyComponent.defaultProps = {
  action: 'init'
};

argumentos predeterminados

Esta estrategia espera que los valores predeterminados se especifiquen en la declaración de la función, utilizando la sintaxis de valores predeterminados incorporada de JavaScript.

const MyComponent = ({ action = 'init' }) => { ... }

MyComponent.propTypes = {
  Action: PropTypes.string;
};

Si usa la defaultArgumentsestrategia, no debería haber un defaultPropsobjeto. Si lo hay, esta regla fallará.

reaccionar/ninguna-matriz-índice-clave

Cuando representamos una lista de elementos en React, normalmente llamamos mapa una matriz y la función de mapeo devuelve un componente. Para realizar un seguimiento de cada elemento de la lista, React necesita que estos componentes tengan un keyaccesorio.

Un error común con las listas de representación es usar el índice de la matriz como clave. Esto puede causar renderizaciones innecesarias o incluso incorrectas. La documentación de React desaconseja esta práctica debido a los problemas que puede causar (también hay una discusión más detallada sobre cómo se usan las claves ). Se espera que una clave sea un identificador único para ese elemento, dentro de la lista, que no cambia, como el valor de la clave principal en una fila de la base de datos.

Esta regla garantiza que el índice de la matriz no se utilice como clave.

reaccionar/reaccionar-en-jsx-scope

Considere este simple componente React:

const Greeter = ({ name }) => <div>Hello {name}!</div>;

No Reactse hace referencia al objeto en absoluto. Sin embargo, Reactaún debe importarse o, de lo contrario, encontrará un error. Esto se debe al proceso de transpilación de JSX. Los navegadores no entienden JSX, por lo que durante el proceso de compilación (generalmente con una herramienta como Babel o TypeScript), los elementos JSX se transforman en JavaScript válido.

Esto generó llamadas de código JavaScript React.createElementen lugar de elementos JSX. El componente anterior podría traducirse a algo como esto:

const Greeter = ({ name }) => React.createElement("div", null, "Hello ", name, "!");

Las referencias a Reactaquí son por qué Reactaún deben importarse. Esta regla garantiza que todos los archivos con marcado JSX (no necesariamente incluso un componente React) tengan Reactalcance (normalmente a través de una llamada importo require).

reaccionar/jsx-usos-reaccionar

Importar siempre React es necesario para una transpilación adecuada, pero cuando ESLint mira el archivo, sigue siendo JSX, por lo que no aparecerá Reactreferenciado en ninguna parte. Si el proyecto está usando la no-unused-varsregla, esto genera un error ya Reactque se importa pero no se usa en ninguna parte.

Esta regla detecta esta situación y evita que no-unused-varsfalle la Reactimportación.

reaccionar / mostrar-nombre

Para una salida de depuración adecuada, todos los componentes de React deben tener un nombre para mostrar. En muchos casos, esto no requerirá ningún código adicional. Si un componente es una función con nombre, el nombre para mostrar será el nombre de la función. En los siguientes ejemplos, el nombre para mostrar del componente será MyComponent.

  • const MyComponent = () => { … }
  • const MyComponent = function() { return …; }
  • export default function MyComponent() { return …; }

Hay algunos casos en los que se pierde el nombre para mostrar automático. Esto suele ocurrir cuando la declaración del componente está envuelta por otra función o componente de orden superior, como en los dos ejemplos a continuación:

  • const MyComponent = React.memo(() => { … });
  • const MyComponent = React.forwardRef((props, ref) => { … });

El MyComponentnombre está vinculado al nuevo componente "externo" devuelto por memoy forwardRef. El componente en sí ahora no tiene un nombre para mostrar, lo que hará que esta regla falle.

Cuando surgen estos casos, se puede especificar manualmente un nombre para mostrar a través de la displayNamepropiedad para cumplir con la regla:

const MyComponent = React.memo(() => { ... });
MyComponent.displayName = 'MyComponent';

reaccionar/no-niños-prop

Los componentes de React aceptan una propiedad especial llamada children. El valor de esta propiedad será cualquier contenido que esté dentro de las etiquetas de apertura y cierre del elemento. Considere este MyListcomponente simple:

const MyList = ({ children }) => {
  return <ul>{children}</ul>;
};

Esto renderizará el elemento exterior ul, y cualquier elemento secundario que coloquemos dentro del elemento se renderizará dentro de él.

<MyList>
  <li>item1</li>
  <li>item2</li>
</MyList>

Este es el patrón preferido con los componentes de React. Es posible, aunque no recomendado, pasar niños como un accesorio de niños explícito:

<MyList children={<li>item1</li><li>item2</li>} />

El uso anterior en realidad causará un error porque las expresiones JSX, como la que se pasa como elemento secundario explícito, deben tener un solo elemento raíz. Esto requiere que los niños estén envueltos en un fragmento:

<MyList children={<><li>item1</li><li>item2</li></>} />

Como se muestra en el primer ejemplo, los elementos secundarios se pasan directamente al componente como elementos secundarios, por lo que el componente es el elemento raíz de la expresión. Aquí no se necesita ningún fragmento u otro elemento envolvente.

Esta es principalmente una elección/patrón estilístico, pero evita pasar inadvertidamente tanto un childrenaccesorio explícito como elementos secundarios:

<MyList children={<><li>item1</li><li>item2</li></>}>
  <li>item3</li>
  <li>item4</li>
</MyList>

En este caso, los elementos secundarios ( item3y item4) se mostrarían, pero item1y item2no. Esta regla garantiza que los elementos secundarios solo se pasen de forma idiomática, como elementos JSX secundarios.

reaccionar/sin-peligro-con-niños

La prop de React dangerouslySetInnerHTMLpermite establecer un marcado arbitrario como innerHTMLpropiedad de un elemento. Por lo general, esto no se recomienda, ya que puede exponer su aplicación a un ataque de secuencias de comandos entre sitios (XSS). Sin embargo, si sabe que puede confiar en la entrada y el caso de uso lo requiere, este enfoque puede ser necesario.

La propiedad espera un objeto con una __htmlpropiedad, cuyo valor es una cadena HTML sin procesar. Esta cadena se establecerá como innerHTML.

Debido a que esto reemplaza cualquier contenido secundario existente, no tiene sentido usarlo en combinación con un childrenaccesorio. De hecho, React arrojará un error si intenta hacer esto. A diferencia de algunos errores que solo aparecen en el modo de desarrollo (como los PropTypeserrores de validación), este error bloqueará su aplicación.

Esta regla aplica la misma regla. Si dangerouslySetInnerHTMLse usa con niños, la regla de pelusa fallará. ¡Es mucho mejor detectar estos errores al aplicar linting o en el momento de la compilación, en lugar de que los usuarios los informen una vez que se implementa la aplicación!

reaccionar/jsx-sin enlace

Cada vez que se procesa un componente de React, se produce un costo de rendimiento. A menudo, ciertos patrones o prácticas pueden hacer que un componente se vuelva a renderizar innecesariamente. Hay muchas causas para este comportamiento y esta regla ayuda a prevenir una de ellas.

Cuando se define cualquier función dentro del componente, será un nuevo objeto de función en cada renderizado. Esto significa que cada vez que se vuelve a renderizar el componente, se considera que la propiedad ha cambiado. Incluso con React.memo, el componente se volverá a renderizar.

Si el componente secundario tiene useEffectllamadas que toman esa función como una dependencia, esto puede hacer que el efecto se ejecute nuevamente, creando la posibilidad de un bucle infinito que probablemente congelará el navegador.

Con esta regla habilitada, se marcará cualquier función que se pase como accesorio.

Hay dos maneras de abordar esto. Si la función no depende de nada más dentro del componente, se puede mover fuera del componente, donde es simplemente una función simple que siempre será la misma referencia de memoria. Esto asegura que se pase la misma función al prop cada vez.

Para los casos en los que la función depende del componente de alguna manera, la solución habitual para esto es memorizarlo con el useCallbackHook. Cualquier propiedad a la que se haga referencia en la función deberá incluirse en la useCallbackmatriz de dependencia; a veces esto requiere múltiples niveles de memorización de valores o funciones.

Esto agrega algo de complejidad, pero tiene la ventaja de ayudar a reducir los renderizados adicionales y evitar bucles infinitos.

Terminando

Las reglas cubiertas aquí son solo algunas de las proporcionadas por el eslint-plugin-reactcomplemento. Algunas reglas pueden ser obstinadas o demasiado entusiastas, pero la mayoría también tiene opciones de configuración para hacerlas menos estrictas.

También hay otro complemento ESLint muy útil centrado en JSX y prácticas de accesibilidad: eslint-plugin-jsx-a11y. Las reglas en este complemento verifican su marcado JSX para asegurarse de que se sigan las buenas prácticas de accesibilidad de HTML.

Estos complementos de React ESLint pueden ser útiles para evitar errores comunes, especialmente si aún es nuevo en React. ¡Incluso puede escribir sus propias reglas y complementos para cubrir otras situaciones!

Fuente: https://blog.logrocket.com/12-essential-eslint-rules-react/

#react #eslint 

12 Reglas Esenciales De ESLint Para React
Hoang  Ha

Hoang Ha

1660779000

12 Quy Tắc ESLint Cần Thiết Cho React

ESLint có một bộ quy tắc toàn diện cho mã JavaScript bao gồm các lựa chọn phong cách và ngăn chặn các lỗi phổ biến. Chỉ sử dụng ESLint sẽ giúp dự án của bạn tăng lên, nhưng có các plugin ESLint có sẵn để thêm các quy tắc dành riêng cho React sẽ giúp bạn viết các ứng dụng React vững chắc.

Trong bài đăng này, chúng ta sẽ xem xét các quy tắc và plugin ESLint này, bao gồm cả khi chúng áp dụng cho Hooks. Dưới đây là một số liên kết nhanh để bạn có thể tham khảo:

  • Quy tắc React Hooks ( eslint-plugin-react-hooks)
    • react-hooks/rules-of-hooks
    • react-hooks/exhaustive-deps
  • Quy tắc phản ứng ( eslint-plugin-react)
    • react/button-has-type
    • react/prop-types
    • react/require-default-props
    • react/no-array-index-key
    • react/react-in-jsx-scope
    • react/jsx-uses-react
    • react/display-name
    • react/no-danger-with-children
    • react/jsx-no-bind

Quy tắc React Hooks ( eslint-plugin-react-hooks)

Plugin này chỉ chứa hai quy tắc, nhưng chúng rất quan trọng để tránh các cạm bẫy thường gặp khi viết các thành phần hàm với Hooks.

react-hooks / rules-of-hooks

Quy tắc này bắt buộc các thành phần tuân theo Quy tắc của Hook khi sử dụng Hook. Các quy tắc được thảo luận chi tiết trong tài liệu React , nhưng có hai quy tắc phải tuân theo khi sử dụng Hooks:

  1. Các móc chỉ nên được gọi từ mã cấp cao nhất của thành phần của bạn. Điều này thực sự có nghĩa là các Hook không nên được gọi theo điều kiện - thay vào đó, chúng nên được gọi trên mọi kết xuất, theo cùng một thứ tự, để tránh các vấn đề và lỗi nhỏ.
  2. Hook chỉ nên được gọi từ một thành phần hàm hoặc một Hook khác
    1. Các móc tùy chỉnh thường kết hợp hành vi với nhau từ các Móc có sẵn hoặc thậm chí là các Móc tùy chỉnh khác

Trong cấu hình mặc định, vi phạm quy tắc này sẽ gây ra lỗi, khiến việc kiểm tra xơ vải không thành công.

react-hooks / expustive-deps

Quy tắc này thực thi các quy tắc nhất định về nội dung của mảng phụ thuộc được chuyển đến Hooks, chẳng hạn như useEffect, useCallbackuseMemo. Nói chung, bất kỳ giá trị nào được tham chiếu trong phép tính giá trị hiệu ứng, gọi lại hoặc ghi nhớ phải được đưa vào mảng phụ thuộc. Nếu điều này không được thực hiện đúng cách, có thể dẫn đến các vấn đề như dữ liệu trạng thái lỗi thời hoặc vòng lặp kết xuất vô hạn .

Quy tắc này rất tốt trong việc tìm ra các lỗi tiềm ẩn liên quan đến sự phụ thuộc, nhưng có một số hạn chế:

  • Các móc tùy chỉnh với các mảng phụ thuộc sẽ không được kiểm tra với quy tắc này. Nó chỉ áp dụng cho Hooks có sẵn
  • Quy tắc chỉ có thể kiểm tra chính xác các phần phụ thuộc nếu nó là một mảng giá trị tĩnh. Nếu một tham chiếu đến một mảng khác được sử dụng hoặc một mảng khác được trải rộng vào nó, quy tắc sẽ phát ra cảnh báo rằng nó không thể xác định các phần phụ thuộc

Quy tắc này đã gây tranh cãi đôi chút; Có một số chủ đề vấn đề dài trên GitHub , nhưng nhóm React đã rất giỏi trong việc thu hút và kết hợp phản hồi. Trong cấu hình mặc định, vi phạm quy tắc này được coi là cảnh báo.

Các chi tiết của quy tắc này có thể chiếm toàn bộ một bài báo của riêng họ. Để tìm hiểu sâu hơn về quy tắc này và cách sử dụng nó đúng cách, hãy xem bài viết về Hiểu rõ ràng về React expustive-deps linting cảnh báo, tại đây trên blog LogRocket.

Quy tắc phản ứng ( eslint-plugin-react)

Plugin này chứa nhiều quy tắc hơn (100 quy tắc tại thời điểm viết bài) dành riêng cho cốt lõi của React. Hầu hết các quy tắc bao gồm các thực hành React chung và những quy tắc khác bao gồm các vấn đề liên quan đến cú pháp JSX. Chúng ta hãy xem xét một số trong những cái hữu ích hơn.

react / button-has-type

Vì lý do trợ năng, hầu hết các phần tử có thể nhấp trong một thành phần không phải là liên kết đơn giản đến một URL khác nên được triển khai dưới dạng các nút . Một lỗi phổ biến là bỏ qua typethuộc tính khỏi các nút này khi chúng không được sử dụng để gửi biểu mẫu.

Khi không typeđược chỉ định, một nút mặc định là một loại submit. Điều này có thể gây ra sự cố cho các nút đi xuống từ một formphần tử. Việc nhấp vào một nút như vậy bên trong biểu mẫu sẽ gây ra việc gửi biểu mẫu không mong muốn.

Các nút hành động không nhằm mục đích gửi biểu mẫu phải có typethuộc tính là button.

Quy tắc này bắt buộc tất cả các nút phải có một typethuộc tính rõ ràng - ngay cả những nút được dùng làm nút Gửi . Bằng cách rõ ràng, việc đệ trình không chủ ý sẽ tránh được và mục đích của mã là rõ ràng.

phản ứng / chống lại các loại

Yêu cầu tất cả các thành phần React phải có các đạo cụ của chúng được mô tả trong một PropTypeskhai báo. Những kiểm tra này chỉ ném ra lỗi trong chế độ phát triển nhưng có thể giúp bắt lỗi phát sinh từ việc chuyển nhầm đạo cụ cho một thành phần.

Nếu dự án của bạn sử dụng TypeScript, quy tắc này cũng được thỏa mãn bằng cách thêm chú thích kiểu vào các đạo cụ thành phần mô tả chúng.

Hai cách tiếp cận này được đề cập chi tiết trong So sánh TypeScript và PropTypes trong các ứng dụng React của Dillion Megida.

phản ứng / yêu cầu-mặc định-đạo cụ

Tùy thuộc vào thành phần, một số đạo cụ có thể được yêu cầu trong khi những đạo cụ khác là tùy chọn. Nếu một chỗ dựa tùy chọn không được chuyển cho một thành phần, nó sẽ như vậy undefined. Điều này có thể được mong đợi nhưng có thể tạo ra lỗi nếu giá trị không được kiểm tra.

Quy tắc này yêu cầu rằng mọi hỗ trợ tùy chọn phải được cung cấp một giá trị mặc định bên trong một defaultPropskhai báo cho thành phần. Giá trị mặc định này có thể được đặt rõ ràng thành nullhoặc undefinednếu đó là những gì thành phần mong đợi.

Với các thành phần chức năng, có hai chiến lược khác nhau có thể được sử dụng để kiểm tra các đạo cụ mặc định:

defaultProps

Chiến lược này mong đợi thành phần chức năng có một defaultPropsđối tượng với các giá trị mặc định.

const MyComponent = ({ action }) => { ... }

MyComponent.propTypes = {
  Action: PropTypes.string;
};

MyComponent.defaultProps = {
  action: 'init'
};

defaultArguments

Chiến lược này mong đợi các giá trị mặc định được chỉ định trong khai báo hàm, sử dụng cú pháp giá trị mặc định có sẵn của JavaScript.

const MyComponent = ({ action = 'init' }) => { ... }

MyComponent.propTypes = {
  Action: PropTypes.string;
};

Nếu bạn sử dụng defaultArgumentschiến lược, không nên có một defaultPropsđối tượng. Nếu có, quy tắc này sẽ không thành công.

react / no-array-index-key

Khi hiển thị danh sách các mục trong React, chúng ta thường gọi mapmột mảng và hàm ánh xạ trả về một thành phần. Để theo dõi từng mục trong danh sách, React cần những thành phần này có chỗ dựa key.

Một lỗi phổ biến với danh sách hiển thị là sử dụng chỉ số mảng làm chìa khóa. Điều này có thể gây ra kết xuất không cần thiết hoặc thậm chí không chính xác. Tài liệu React khuyên bạn không nên thực hiện phương pháp này do các vấn đề mà nó có thể gây ra (cũng có một cuộc thảo luận chi tiết hơn về cách sử dụng các khóa ). Một khóa được mong đợi là số nhận dạng duy nhất cho mục đó, trong danh sách, không thay đổi, giống như giá trị khóa chính trong một hàng cơ sở dữ liệu.

Quy tắc này đảm bảo rằng chỉ số mảng không được sử dụng làm khóa.

phạm vi phản ứng / phản ứng trong jsx

Hãy xem xét thành phần React đơn giản này:

const Greeter = ({ name }) => <div>Hello {name}!</div>;

Đối Reacttượng hoàn toàn không được tham chiếu. Tuy nhiên, Reactvẫn cần được nhập nếu không bạn sẽ gặp lỗi. Điều này là do quá trình chuyển đổi của JSX. Các trình duyệt không hiểu JSX, vì vậy trong quá trình xây dựng (thường là với một công cụ như Babel hoặc TypeScript), các phần tử JSX được chuyển đổi thành JavaScript hợp lệ.

Mã JavaScript được tạo này gọi React.createElementthay cho các phần tử JSX. Thành phần trên có thể được chuyển thành một cái gì đó như thế này:

const Greeter = ({ name }) => React.createElement("div", null, "Hello ", name, "!");

Các tham chiếu đến Reactđây là lý do tại sao Reactvẫn phải nhập. Quy tắc này đảm bảo rằng tất cả các tệp có đánh dấu JSX (không nhất thiết ngay cả một thành phần React) đều có Reacttrong phạm vi (thường thông qua một importhoặc requirecuộc gọi).

react / jsx-using-react

Luôn nhập React là cần thiết để chuyển đổi thích hợp, nhưng khi ESLint xem tệp, nó vẫn là JSX, vì vậy nó sẽ không thấy được Reacttham chiếu ở bất kỳ đâu. Nếu dự án đang sử dụng no-unused-varsquy tắc, điều này dẫn đến lỗi vì Reactđược nhập nhưng không được sử dụng ở bất kỳ đâu.

Quy tắc này nắm bắt được tình huống này và ngăn chặn việc nhập no-unused-varskhông thành công React.

react / display-name

Để có đầu ra gỡ lỗi thích hợp, tất cả các thành phần React phải có tên hiển thị. Trong nhiều trường hợp, điều này sẽ không yêu cầu bất kỳ mã bổ sung nào. Nếu một thành phần là một hàm được đặt tên, tên hiển thị sẽ là tên của hàm. Trong các ví dụ dưới đây, tên hiển thị của thành phần sẽ là MyComponent.

  • const MyComponent = () => { … }
  • const MyComponent = function() { return …; }
  • export default function MyComponent() { return …; }

Có một số trường hợp tên hiển thị tự động bị mất. Điều này thường xảy ra khi khai báo thành phần được bao bọc bởi một hàm khác hoặc thành phần bậc cao hơn, như trong hai ví dụ dưới đây:

  • const MyComponent = React.memo(() => { … });
  • const MyComponent = React.forwardRef((props, ref) => { … });

Tên MyComponentđược liên kết với thành phần “bên ngoài” mới được trả về bởi memoforwardRef. Bản thân thành phần bây giờ không có tên hiển thị, điều này sẽ khiến quy tắc này không thành công.

Khi những trường hợp này phát sinh, tên hiển thị có thể được chỉ định theo cách thủ công thông qua thuộc displayNametính để đáp ứng quy tắc:

const MyComponent = React.memo(() => { ... });
MyComponent.displayName = 'MyComponent';

phản ứng / không có trẻ em-chống đỡ

Các thành phần phản ứng chấp nhận một hỗ trợ đặc biệt được gọi children. Giá trị của phần tử hỗ trợ này sẽ là bất kỳ nội dung nào bên trong thẻ mở và thẻ đóng của phần tử. Hãy xem xét thành phần đơn giản này MyList:

const MyList = ({ children }) => {
  return <ul>{children}</ul>;
};

Điều này sẽ hiển thị ulphần tử bên ngoài và bất kỳ phần tử con nào chúng ta đặt bên trong phần tử sẽ được hiển thị bên trong nó.

<MyList>
  <li>item1</li>
  <li>item2</li>
</MyList>

Đây là mẫu ưa thích với các thành phần React. Mặc dù không được khuyến khích, có thể chuyển trẻ em làm chỗ dựa rõ ràng cho trẻ em:

<MyList children={<li>item1</li><li>item2</li>} />

Việc sử dụng ở trên thực sự sẽ gây ra lỗi vì các biểu thức JSX, giống như biểu thức được truyền dưới dạng prop con rõ ràng, phải có một phần tử gốc duy nhất. Điều này đòi hỏi các trẻ em phải được bao bọc trong một mảnh:

<MyList children={<><li>item1</li><li>item2</li></>} />

Như thể hiện trong ví dụ đầu tiên, các phần tử con được truyền trực tiếp dưới dạng phần tử con cho thành phần, vì vậy thành phần là phần tử gốc của biểu thức. Không cần phân đoạn hoặc phần tử bao quanh khác ở đây.

Đây chủ yếu là một lựa chọn / mẫu theo phong cách, nhưng nó ngăn việc vô tình chuyển cả phần tử hỗ trợ rõ ràng childrenvà phần tử con:

<MyList children={<><li>item1</li><li>item2</li></>}>
  <li>item3</li>
  <li>item4</li>
</MyList>

Trong trường hợp này, các phần tử con ( item3và ) sẽ được hiển thị , item4nhưng sẽ không hiển thị. Quy tắc này đảm bảo rằng các phần tử con chỉ được truyền theo cách thành ngữ, dưới dạng các phần tử JSX con.item1item2

phản ứng / không nguy hiểm với trẻ em

Phần mềm hỗ trợ của React dangerouslySetInnerHTMLcho phép đặt đánh dấu tùy ý làm thuộc innerHTMLtính của một phần tử. Điều này thường không được khuyến khích, vì nó có thể khiến ứng dụng của bạn bị tấn công tập lệnh trên nhiều trang web (XSS). Tuy nhiên, nếu bạn biết bạn có thể tin tưởng đầu vào và trường hợp sử dụng yêu cầu nó, thì cách tiếp cận này có thể trở nên cần thiết.

Phần hỗ trợ mong đợi một đối tượng có __htmlthuộc tính, có giá trị là một chuỗi HTML thô. Chuỗi này sẽ được đặt là innerHTML.

Bởi vì điều này thay thế bất kỳ nội dung con nào hiện có, nên sẽ không hợp lý nếu sử dụng nó kết hợp với một phần childrenmềm hỗ trợ. Trên thực tế, React sẽ xuất hiện một lỗi nếu bạn cố gắng thực hiện việc này. Không giống như một số lỗi chỉ xuất hiện trong chế độ phát triển (như PropTypeslỗi xác thực), lỗi này sẽ làm hỏng ứng dụng của bạn.

Quy tắc này thực thi cùng một quy tắc. Nếu dangerouslySetInnerHTMLđược sử dụng với trẻ em, quy tắc lint sẽ không thành công. Tốt hơn là bạn nên bắt những lỗi này khi linting hoặc tại thời điểm xây dựng, hơn là do người dùng báo cáo sau khi ứng dụng được triển khai!

react / jsx-no-bind

Mỗi khi một thành phần React được hiển thị, nó sẽ phải trả giá bằng hiệu suất. Thông thường, một số mẫu hoặc thông lệ nhất định có thể khiến một thành phần tự hiển thị lại một cách không cần thiết. Có nhiều nguyên nhân dẫn đến hành vi này và quy tắc này giúp ngăn chặn một trong số chúng.

Khi bất kỳ chức năng nào được xác định bên trong thành phần, nó sẽ là một đối tượng chức năng mới trên mỗi lần hiển thị. Điều này có nghĩa là bất cứ khi nào thành phần được kết xuất lại, phần hỗ trợ được coi là đã thay đổi. Ngay cả với React.memo, thành phần sẽ hiển thị lại.

Nếu thành phần con có bất kỳ useEffectlệnh gọi nào sử dụng hàm đó làm phụ thuộc, điều này có thể khiến hiệu ứng chạy lại, tạo ra khả năng xảy ra một vòng lặp vô hạn có khả năng đóng băng trình duyệt.

Với quy tắc này được kích hoạt, bất kỳ chức năng nào được chuyển làm phần hỗ trợ sẽ được gắn cờ.

Có hai cách để giải quyết vấn đề này. Nếu hàm không phụ thuộc vào bất kỳ thứ gì khác bên trong thành phần, nó có thể được di chuyển ra bên ngoài thành phần, nơi nó chỉ là một hàm thuần túy sẽ luôn là cùng một tham chiếu bộ nhớ. Điều này đảm bảo rằng cùng một chức năng được chuyển đến prop mỗi lần.

Đối với trường hợp hàm phụ thuộc vào thành phần theo một cách nào đó, cách khắc phục thông thường cho điều này là ghi nhớ nó bằng useCallbackHook. Bất kỳ thuộc tính nào được tham chiếu trong hàm sẽ phải được đưa vào useCallbackmảng phụ thuộc; đôi khi điều này đòi hỏi nhiều cấp độ ghi nhớ các giá trị hoặc chức năng.

Điều này làm tăng thêm một số phức tạp, nhưng có lợi ích là giúp giảm hiển thị thêm và ngăn chặn các vòng lặp vô hạn.

Kết thúc

Các quy tắc được đề cập ở đây chỉ là một vài trong số những quy tắc được cung cấp bởi eslint-plugin-reactplugin. Một số quy tắc có thể cố chấp hoặc quá mức, nhưng hầu hết đều có các tùy chọn cấu hình để làm cho chúng bớt nghiêm ngặt hơn.

Ngoài ra còn có một plugin ESLint rất hữu ích khác tập trung vào JSX và các phương pháp trợ năng eslint-plugin-jsx-a11y:. Các quy tắc trong plugin này kiểm tra đánh dấu JSX của bạn để đảm bảo rằng các phương pháp hỗ trợ tiếp cận HTML tốt đang được tuân thủ.

Các plugin React ESLint này có thể hữu ích để tránh những cạm bẫy thường gặp, đặc biệt nếu bạn vẫn chưa quen với React. Bạn thậm chí có thể viết các quy tắc và plugin của riêng mình để bao gồm các tình huống khác!

Nguồn: https://blog.logrocket.com/12-essential-eslint-rules-react/

#react #eslint 

12 Quy Tắc ESLint Cần Thiết Cho React
曾 俊

曾 俊

1660777200

React 的 12 条基本 ESLint 规则

ESLint 有一套全面的 JavaScript 代码规则,涵盖风格选择并防止常见错误。单独使用 ESLint 可以提升你的项目,但是有一些 ESLint 插件可用于添加特定于 React 的规则,这将帮助你编写可靠的 React 应用程序。

在这篇文章中,我们将讨论这些 ESLint 规则和插件,包括它们适用于 Hooks 的情况。这里有一些快速链接供您跳转:

  • React Hooks 规则 ( eslint-plugin-react-hooks)
    • react-hooks/rules-of-hooks
    • react-hooks/exhaustive-deps
  • 反应规则 ( eslint-plugin-react)
    • react/button-has-type
    • react/prop-types
    • react/require-default-props
    • react/no-array-index-key
    • react/react-in-jsx-scope
    • react/jsx-uses-react
    • react/display-name
    • react/no-danger-with-children
    • react/jsx-no-bind

React Hooks 规则 ( eslint-plugin-react-hooks)

这个插件只包含两个规则,但它们对于避免使用 Hooks编写函数组件时的常见陷阱至关重要。

反应钩子/钩子规则

此规则强制组件在使用 Hooks 时遵循Hooks 规则。这些规则在React 文档中有详细讨论,但是在使用 Hooks 时必须遵循两个规则:

  1. 钩子只能从组件的顶级代码中调用。这真正意味着 Hooks 不应该被有条件地调用——它们应该在每次渲染时以相同的顺序被调用,以避免问题和细微的错误
  2. 只能从函数组件或另一个 Hook 调用 Hook
    1. 自定义 Hooks 通常将来自内置的甚至其他自定义 Hooks 的行为组合在一起

在默认配置中,违反此规则将导致错误,导致 lint 检查失败。

反应钩子/详尽的deps

此规则强制执行有关传递给 Hooks 的依赖数组内容的某些规则,例如useEffectuseCallbackuseMemo。一般来说,效果、回调或记忆值计算中引用的任何值都必须包含在依赖数组中。如果未正确完成,可能会导致状态数据过时或无限渲染循环等问题。

这条规则善于发现潜在的依赖相关的 bug,但也有一些限制:

  • 此规则不会检查具有依赖关系数组的自定义 Hook。它仅适用于内置 Hooks
  • 只有当它是一个静态值数组时,该规则才能正确检查依赖关系。如果使用了对另一个数组的引用,或者将另一个数组散布到其中,则规则将发出无法确定依赖关系的警告

这条规则有些争议。GitHub 上有几个很长的问题线程,但 React 团队在征求和整合反馈方面做得很好。在默认配置中,违反此规则将被视为警告。

这条规则的细节可以单独占据整篇文章。要深入了解此规则以及如何正确使用它,请参阅 LogRocket 博客上的了解 React 详尽的 linting 警告文章。

反应规则 ( eslint-plugin-react)

该插件包含更多特定于 React 核心的规则(撰写本文时为 100 条规则)。大多数规则涵盖一般的 React 实践,而其他规则则涵盖与 JSX 语法相关的问题。让我们来看看一些更有用的。

反应/按钮有类型

出于可访问性的原因,组件中的大多数不是指向另一个 URL 的简单链接的可点击元素都应该实现为按钮type一个常见的错误是在这些按钮不用于提交表单时忽略这些按钮的属性。

指定no 时type,按钮默认为submit. 这可能会导致从form元素下降的按钮出现问题。单击表单内的此类按钮将导致可能不需要的表单提交。

不打算提交表单的操作按钮应type具有button.

该规则强制要求所有按钮都明确地具有一个type属性——即使是那些打算用作提交按钮的按钮。通过明确,可以避免无意的提交,并且代码的意图是明确的。

反应/道具类型

要求所有 React 组件都在PropTypes声明中描述其 props。这些检查只会在开发模式下抛出错误,但可以帮助捕获由错误的 props 传递给组件引起的错误。

如果您的项目使用 TypeScript,则通过在描述它们的组件 props 中添加类型注释也可以满足此规则。

Dillion Megida 的比较 React 应用程序中的 TypeScript 和 PropTypes 详细介绍了这两种方法。

反应/要求默认道具

根据组件的不同,一些道具可能是必需的,而另一些则是可选的。如果一个可选的 prop 没有传递给组件,它将是undefined. 这可能是意料之中的,但如果未检查该值,则可能会引入错误。

此规则要求defaultProps在组件的声明中为每个可选 prop 赋予一个默认值。此默认值可以显式设置为,null或者undefined如果这是组件所期望的。

对于函数组件,可以使用两种不同的策略来检查默认道具:

默认道具

此策略期望函数组件具有具有defaultProps默认值的对象。

const MyComponent = ({ action }) => { ... }

MyComponent.propTypes = {
  Action: PropTypes.string;
};

MyComponent.defaultProps = {
  action: 'init'
};

默认参数

此策略期望在函数声明中指定默认值,使用 JavaScript 的内置默认值语法。

const MyComponent = ({ action = 'init' }) => { ... }

MyComponent.propTypes = {
  Action: PropTypes.string;
};

如果您使用该defaultArguments策略,则不应该有defaultProps对象。如果有,则此规则将失败。

反应/无数组索引键

在 React 中渲染项目列表时,我们通常调用map一个数组,映射函数返回一个组件。为了跟踪列表中的每个项目,React 需要这些组件有一个keyprop。

渲染列表的一个常见缺陷是使用数组索引作为键。这可能会导致不必要的甚至不正确的渲染。React 文档不建议这种做法,因为它可能导致问题(还有关于如何使用密钥的更详细的讨论)。键应该是列表中该项目的唯一标识符,不会更改,例如数据库行中的主键值。

此规则确保不将数组索引用作键。

react/react-in-jsx-scope

考虑这个简单的 React 组件:

const Greeter = ({ name }) => <div>Hello {name}!</div>;

React对象根本没有被引用。但是,React仍然需要导入,否则会遇到错误。这是由于 JSX 的转译过程。浏览器不理解 JSX,因此在构建过程中(通常使用 Babel 或 TypeScript 等工具),JSX 元素被转换为有效的 JavaScript。

这会生成 JavaScript 代码调用React.createElement来代替 JSX 元素。上面的组件可能会被转译成这样的东西:

const Greeter = ({ name }) => React.createElement("div", null, "Hello ", name, "!");

对这里的引用React是为什么React仍然必须导入。此规则确保所有带有 JSX 标记的文件(甚至不一定是 React 组件)都React在范围内(通常通过importorrequire调用)。

反应/jsx 使用反应

始终导入 React 是正确编译所必需的,但是当 ESLint 查看文件时,它仍然是 JSX,所以它不会React在任何地方看到引用。如果项目正在使用该no-unused-vars规则,则会导致错误,因为React已导入但未在任何地方使用。

此规则捕获这种情况并防止导入no-unused-vars失败。React

反应/显示名称

为了正确的调试输出,所有 React 组件都应该有一个显示名称。在许多情况下,这不需要任何额外的代码。如果组件是命名函数,则显示名称将是函数的名称。在以下示例中,组件的显示名称将为MyComponent.

  • const MyComponent = () => { … }
  • const MyComponent = function() { return …; }
  • export default function MyComponent() { return …; }

在某些情况下,自动显示名称会丢失。这通常是当组件声明被另一个函数或更高阶组件包装时,如下面的两个示例:

  • const MyComponent = React.memo(() => { … });
  • const MyComponent = React.forwardRef((props, ref) => { … });

该名称绑定到andMyComponent返回的新“外部”组件。组件本身现在没有显示名称,这将导致此规则失败。memoforwardRef

当出现这些情况时,可以通过displayName属性手动指定显示名称以满足规则:

const MyComponent = React.memo(() => { ... });
MyComponent.displayName = 'MyComponent';

反应/无儿童道具

React 组件接受一个名为children. 该道具的值将是元素的开始和结束标记内的任何内容。考虑这个简单的MyList组件:

const MyList = ({ children }) => {
  return <ul>{children}</ul>;
};

这将渲染外部ul元素,我们放置在元素内的任何子元素都将在其中渲染。

<MyList>
  <li>item1</li>
  <li>item2</li>
</MyList>

这是 React 组件的首选模式。尽管不推荐,但可以将 children 作为显式的 children 属性传递:

<MyList children={<li>item1</li><li>item2</li>} />

上述用法实际上会导致错误,因为 JSX 表达式,就像作为显式 children 属性传递的表达式一样,必须有一个根元素。这需要将孩子包裹在一个片段中:

<MyList children={<><li>item1</li><li>item2</li></>} />

如第一个示例所示,children 作为子元素直接传递给组件,因此组件是表达式的根元素。这里不需要片段或其他封闭元素。

这主要是一种风格选择/模式,但它确实可以防止无意中传递显式childrenprop 和子元素:

<MyList children={<><li>item1</li><li>item2</li></>}>
  <li>item3</li>
  <li>item4</li>
</MyList>

在这种情况下,将显示子元素 (item3和) ,item4但不会显示。此规则确保子元素仅以惯用方式作为子 JSX 元素传递。item1item2

对孩子做出反应/没有危险

React 的dangerouslySetInnerHTMLprop 允许将任意标记设置为innerHTML元素的属性。通常不建议这样做,因为它会使您的应用程序暴露于跨站点脚本 (XSS) 攻击。但是,如果您知道您可以信任输入并且用例需要它,那么这种方法可能变得必要。

prop 需要一个具有__html属性的对象,其值为原始 HTML 字符串。该字符串将设置为innerHTML.

children因为这会替换任何现有的子内容,所以将它与道具结合使用是没有意义的。事实上,如果你尝试这样做,React 会抛出一个错误。与仅在开发模式中出现的一些错误(如PropTypes验证错误)不同,此错误会使您的应用程序崩溃。

该规则执行相同的规则。如果dangerouslySetInnerHTML与孩子一起使用,lint 规则将失败。最好在 linting 或构建时捕获这些错误,而不是在应用程序部署后由用户报告!

反应/jsx-no-bind

每次渲染 React 组件时,都会付出性能代价。通常,某些模式或实践会导致组件不必要地重新渲染自身。这种行为的原因有很多,这条规则有助于防止其中之一。

当组件内部定义了任何函数时,它将在每次渲染时都是一个新的函数对象。这意味着无论何时重新渲染组件,都会认为 prop 发生了变化。即使使用React.memo,组件也会重新渲染。

如果子组件有任何useEffect将该函数作为依赖项的调用,这可能会导致效果再次运行,从而产生可能导致浏览器冻结的无限循环的可能性。

启用此规则后,任何作为道具传递的函数都将被标记。

有两种方法可以解决这个问题。如果该函数不依赖于组件内部的任何其他内容,则可以将其移到组件之外,它只是一个普通函数,始终是相同的内存引用。这样可以确保每次都将相同的函数传递给 prop。

对于函数确实以某种方式依赖于组件的情况,通常的解决方法是使用useCallbackHook 来记忆它。函数中引用的任何属性都必须包含在useCallback依赖数组中;有时这需要对值或函数进行多级记忆。

这增加了一些复杂性,但有助于减少额外的渲染并防止无限循环。

包起来

这里涵盖的规则只是eslint-plugin-react插件提供的一些规则。一些规则可能是固执己见或过分热心,但大多数还具有配置选项以使其不那么严格。

还有另一个以 JSX 和可访问性实践为中心的非常有用的 ESLint 插件:eslint-plugin-jsx-a11y. 此插件中的规则检查您的 JSX 标记,以确保遵循良好的 HTML 可访问性实践。

这些 React ESLint 插件有助于避免常见的陷阱,特别是如果你还是 React 的新手。您甚至可以编写自己的规则和插件来涵盖其他情况!

来源:https ://blog.logrocket.com/12-essential-eslint-rules-react/

#react #eslint 

React 的 12 条基本 ESLint 规则
Gordon  Taylor

Gordon Taylor

1660768020

ESlint-plugin-node: Additional ESLint's Rules for Node.js

eslint-plugin-node

Additional ESLint's rules for Node.js

💿 Install & Usage

$ npm install --save-dev eslint eslint-plugin-node
  • Requires Node.js >=8.10.0
  • Requires ESLint >=5.16.0

Note: It recommends a use of the "engines" field of package.json. The "engines" field is used by node/no-unsupported-features/* rules.

.eslintrc.json (An example)

{
    "extends": [
        "eslint:recommended",
        "plugin:node/recommended"
    ],
    "parserOptions": {
        // Only ESLint 6.2.0 and later support ES2020.
        "ecmaVersion": 2020
    },
    "rules": {
        "node/exports-style": ["error", "module.exports"],
        "node/file-extension-in-import": ["error", "always"],
        "node/prefer-global/buffer": ["error", "always"],
        "node/prefer-global/console": ["error", "always"],
        "node/prefer-global/process": ["error", "always"],
        "node/prefer-global/url-search-params": ["error", "always"],
        "node/prefer-global/url": ["error", "always"],
        "node/prefer-promises/dns": "error",
        "node/prefer-promises/fs": "error"
    }
}

package.json (An example)

{
    "name": "your-module",
    "version": "1.0.0",
    "type": "commonjs",
    "engines": {
        "node": ">=8.10.0"
    }
}

📖 Rules

  • ⭐️ - the mark of recommended rules.
  • ✒️ - the mark of fixable rules.

Possible Errors

Rule IDDescription 
node/handle-callback-errrequire error handling in callbacks 
node/no-callback-literalensure Node.js-style error-first callback pattern is followed 
node/no-exports-assigndisallow the assignment to exports⭐️
node/no-extraneous-importdisallow import declarations which import extraneous modules⭐️
node/no-extraneous-requiredisallow require() expressions which import extraneous modules⭐️
node/no-missing-importdisallow import declarations which import non-existence modules⭐️
node/no-missing-requiredisallow require() expressions which import non-existence modules⭐️
node/no-new-requiredisallow new operators with calls to require 
node/no-path-concatdisallow string concatenation with __dirname and __filename 
node/no-process-exitdisallow the use of process.exit() 
node/no-unpublished-bindisallow bin files that npm ignores⭐️
node/no-unpublished-importdisallow import declarations which import private modules⭐️
node/no-unpublished-requiredisallow require() expressions which import private modules⭐️
node/no-unsupported-features/es-builtinsdisallow unsupported ECMAScript built-ins on the specified version⭐️
node/no-unsupported-features/es-syntaxdisallow unsupported ECMAScript syntax on the specified version⭐️
node/no-unsupported-features/node-builtinsdisallow unsupported Node.js built-in APIs on the specified version⭐️
node/process-exit-as-throwmake process.exit() expressions the same code path as throw⭐️
node/shebangsuggest correct usage of shebang⭐️✒️

Best Practices

Rule IDDescription 
node/no-deprecated-apidisallow deprecated APIs⭐️

Stylistic Issues

Rule IDDescription 
node/callback-returnrequire return statements after callbacks 
node/exports-styleenforce either module.exports or exports 
node/file-extension-in-importenforce the style of file extensions in import declarations✒️
node/global-requirerequire require() calls to be placed at top-level module scope 
node/no-mixed-requiresdisallow require calls to be mixed with regular variable declarations 
node/no-process-envdisallow the use of process.env 
node/no-restricted-importdisallow specified modules when loaded by import declarations 
node/no-restricted-requiredisallow specified modules when loaded by require 
node/no-syncdisallow synchronous methods 
node/prefer-global/bufferenforce either Buffer or require("buffer").Buffer 
node/prefer-global/consoleenforce either console or require("console") 
node/prefer-global/processenforce either process or require("process") 
node/prefer-global/text-decoderenforce either TextDecoder or require("util").TextDecoder 
node/prefer-global/text-encoderenforce either TextEncoder or require("util").TextEncoder 
node/prefer-global/url-search-paramsenforce either URLSearchParams or require("url").URLSearchParams 
node/prefer-global/urlenforce either URL or require("url").URL 
node/prefer-promises/dnsenforce require("dns").promises 
node/prefer-promises/fsenforce require("fs").promises 

Deprecated rules

These rules have been deprecated in accordance with the deprecation policy, and replaced by newer rules:

Rule IDReplaced by
node/no-hide-core-modules(nothing)
node/no-unsupported-featuresnode/no-unsupported-features/es-syntax and node/no-unsupported-features/es-builtins

🔧 Configs

This plugin provides three configs:

  • plugin:node/recommended considers both CommonJS and ES Modules. If "type":"module" field existed in package.json then it considers files as ES Modules. Otherwise it considers files as CommonJS. In addition, it considers *.mjs files as ES Modules and *.cjs files as CommonJS.
  • plugin:node/recommended-module considers all files as ES Modules.
  • plugin:node/recommended-script considers all files as CommonJS.

Those preset config:

  • enable no-process-exit rule because the official document does not recommend a use of process.exit().
  • enable plugin rules which are given :star: in the above table.
  • add {ecmaVersion: 2019} and etc into parserOptions.
  • add proper globals into globals.
  • add this plugin into plugins.

👫 FAQ

🚥 Semantic Versioning Policy

eslint-plugin-node follows semantic versioning and ESLint's Semantic Versioning Policy.

  • Patch release (intended to not break your lint build)
    • A bug fix in a rule that results in it reporting fewer errors.
    • Improvements to documentation.
    • Non-user-facing changes such as refactoring code, adding, deleting, or modifying tests, and increasing test coverage.
    • Re-releasing after a failed release (i.e., publishing a release that doesn't work for anyone).
  • Minor release (might break your lint build)
    • A bug fix in a rule that results in it reporting more errors.
    • A new rule is created.
    • A new option to an existing rule is created.
    • An existing rule is deprecated.
  • Major release (likely to break your lint build)
    • A support for old Node version is dropped.
    • A support for old ESLint version is dropped.
    • An existing rule is changed in it reporting more errors.
    • An existing rule is removed.
    • An existing option of a rule is removed.
    • An existing config is updated.

📰 Changelog

❤️ Contributing

Welcome contributing!

Please use GitHub's Issues/PRs.

Development Tools

  • npm test runs tests and measures coverage.
  • npm run coverage shows the coverage result of npm test command.
  • npm run clean removes the coverage result of npm test command.

Download Details:

Author: Mysticatea
Source Code: https://github.com/mysticatea/eslint-plugin-node 
License: MIT license

#javascript #node #eslint 

ESlint-plugin-node: Additional ESLint's Rules for Node.js