npm package: @hannohealth/eslint-config
Description: A shareable ESLint config with safe defaults and some opinionated rules
Author: Hanno
Latest version: 1.4.2
Deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.

# @hannohealth/eslint-config

A global [ESLint](https://eslint.org/) and [Prettier](https://prettier.io/) configuration with opinionated defaults for [Hanno](https://hanno.co/)'s JavaScript projects.

In addition to our base ESLint configuration, we also include variants for our **Node**, **React** and **React Native** projects.

_This repository is private, but the package itself is published on [npm](https://www.npmjs.com/package/@hannohealth/eslint-config) and includes this README._

## Installation

1. Install the main package:
   ```
   yarn add -D @hannohealth/eslint-config
   ```
2. Install the peer dependencies:
   ```
   yarn add -D @babel/core eslint prettier
   ```

## Prettier

In your `prettier.config.js` file, add the following:

```
module.exports = require('@hannohealth/eslint-config/prettier.config');
```

## ESLint

### Base

The [`base`](/base.js) configuration provides a baseline set of rules that are mainly drawn from `eslint:recommended`, with a few modifications.

Add the following to your `.eslintrc.js` file:

```
module.exports = {
  extends: ['@hannohealth'],
};
```

It introduces the following plugins:

- [`@babel/eslint-plugin`](https://github.com/babel/babel/tree/main/eslint/babel-eslint-plugin)
- [`eslint-plugin-jest`](https://github.com/jest-community/eslint-plugin-jest)
- [`eslint-plugin-jest-formatting`](https://github.com/dangreenisrael/eslint-plugin-jest-formatting)
- [`eslint-plugin-import`](https://github.com/benmosher/eslint-plugin-import)
- [`eslint-plugin-flowtype`](https://github.com/gajus/eslint-plugin-flowtype)
- [`eslint-plugin-promise`](https://github.com/xjamundx/eslint-plugin-promise)
- [`eslint-plugin-eslint-comments`](https://github.com/mysticatea/eslint-plugin-eslint-comments)
- [`eslint-plugin-sonarjs`](https://github.com/SonarSource/eslint-plugin-sonarjs)

We also include `eslint-config-prettier` for Prettier compatibility and `eslint-plugin-prettier` to notify any Prettier errors as ESLint errors in ESLint.

#### Defensive programming rules

These rules are designed to enforce [defensive programming](https://hanno.atlassian.net/wiki/spaces/PM/pages/6182797407/Defensive+programming), but there's still room for improvement. The following scenarios haven't been covered yet, but might be re-considered in the future:

- Enforce else clauses: https://stackoverflow.com/questions/35053371/what-is-the-benefit-of-terminating-if-else-if-constructs-with-an-else-clause/35055736#35055736. Since there doesn't seem to be a rule yet that enforces this, we may have to building a custom one in the future
- Magic numbers: avoiding them is desirable, but should be restricted to user-facing values. Right now, this would require a huge amount of changes in our repositories, so we've left it out for now: https://eslint.org/docs/rules/no-magic-numbers
- Reduce function complexity: using https://eslint.org/docs/rules/max-lines-per-function and https://github.com/SonarSource/eslint-plugin-sonarjs/blob/master/docs/rules/cognitive-complexity.md would allow us to enforce this. Right now, they have been set to a relatively high threshold, but we may reduce this over time to restrict functions to a lower number of lines. The corresponding rules are marked with `TODO-complexity`
- Stricter typing: Flow types can help us increase the level of type safety, but enforcing some of these stricter rules would lead to 100+ changes across our repositories, so they remain disabled for now. But we may consider reenabling them in the future. The corresponding rules are marked with `TODO-typing`.

### Node

The [`node`](/node.js) configuration extends `base`, but is otherwise a relatively minimal configuration which sets the environment to Node and allows us to use console logs.

To integrate, add the following to your `.eslintrc.js` file:

```
module.exports = {
  extends: ['@hannohealth/eslint-config/node'],
};
```

### React

The [`react`](/react.js) configuration extends `base` with some rules specific to React.

To integrate, add the following to your `.eslintrc.js` file:

```
module.exports = {
  extends: ['@hannohealth/eslint-config/react'],
};
```

It introduces the following plugins:

- [`eslint-plugin-react`](https://github.com/yannickcr/eslint-plugin-react)
- [`eslint-plugin-react-hooks`](https://github.com/facebook/react/tree/master/packages/eslint-plugin-react-hooks)
- [`eslint-plugin-cypress`](https://github.com/cypress-io/eslint-plugin-cypress)

### React Native

The [`react-native`](/react-native.js) configuration extends `base` with some rules specific to React Native. Among other things, this enables the React Native globals and allows us to properly use the module resolver in a React Native codebase.

To integrate, add the following to your `.eslintrc.js` file:

```
module.exports = {
  extends: ['@hannohealth/eslint-config/react-native'],
};
```

It introduces the following plugins:

- [`eslint-config-react-native`](https://github.com/Intellicode/eslint-plugin-react-native)
- [`eslint-config-react-native-a11y`](https://github.com/FormidableLabs/eslint-plugin-react-native-a11y)
- [`eslint-config-detox`](https://github.com/hammadj/eslint-plugin-detox)

Even though this configuration inherits the `eslint-plugin-cypress` from our React configuration, which is not suited for React Native, this shouldn't interfere with the React Native setup.

## Editors

### Visual Studio Code

If you're VS Code user, you may find adding this config to your `.vscode/settings.json` helpful when you integrate the configuration into your project. This will ensure that linting happens on save and applies the appropriate settings:

```json
{
  "eslint.format.enable": true,
  "editor.formatOnSave": true
}
```

## Development

To set up the project for development:

1. Clone the repository.
2. Run `asdf install nodejs` (assuming you are using [asdf](https://asdf-vm.com/) to manage your node version)
3. Run `npm install --global yarn`
4. Run `yarn` to install dependencies.

When modifying this package, we suggest the following workflow, to test the package locally, and also in a more complex project which makes more extensive use of the rules:

1. Make local changes.
2. Run `yarn` to update dependencies.
3. Run `yarn lint:all` to perform initial checks.
4. Publish the package locally with `npx yalc publish`.
5. Test the changes in a standalone project with `npx yalc add @hannohealth/eslint-config`, then `yarn` to install updated dependencies.
6. Push changes in this package to the new project with `npx yalc publish --push`, then `yarn` in the new project to install updated dependencies.