npm package: @fueled/eslint-config-frontend-web
Description: An opinionated set of conditions for frontend development at Fueled.
Author: Fueled Frontend Web Team
Latest version: 2.1.2-0

# Fueled Frontend ESLint Configuration

## Contents

* [Installation](#installation)
* [Usage](#usage)
  * [React](#react)
  * [Vue](#vue)
* [Common errors](#common-errors)
* [Gotchas](#gotchas)

## Installation

`eslint-config-frontend-web` is a private package in the `@fueled` organization. Before installing, ensure that you have authenticated any future requests by [logging in](https://npme.npmjs.com/docs/cli/configuration.html#logging-in) to NPM in the command line, and also that you are part of the `@fueled` organization. For help with either of these, reach out to one of the Leads in the Frontend Web team.

First, install the global eslint config and the shared peer dependencies:

```
npm install --save-dev @fueled/eslint-config-frontend-web eslint-config-esnext
```

## Usage

Create a `.eslintrc.js` file at the root of your directory (and ensure that `eslintConfig` is removed `package.json`) with the following:

```js
module.exports = {
  env: {
    'node': true,
  },
  extends: [
    '@fueled/frontend-web',
  ],
  'settings': {},
  'rules': {},
};

```

To run the linter on a directory of files:

```
$ eslint --ext .js ./path/to/src
```

If the project setup tool that was used (Vue CLI, Create React App _etc_) has an existing `npm run lint` rule, ensure that this is replaced with the command above.

### React

For React projects, swap `@fueled/frontend-web` for `@fueled/frontend-web/lib/react`, and run the same command to run the linter.

If Create React App is used to setup the project there will be a number of errors thrown against `~/src/serviceWorker.js` which can be ignored by adding `/* eslint-disable */` at the start of the file, and `// eslint-disable-line import/no-namespace` to the end of the line importing `* as serviceWorker` in `~/src/index.js`.

You will also need to install the React peer dependencies:

```
`npm install --save-dev eslint-plugin-react eslint-plugin-jsx-a11y`
```

### Vue

For Vue projects, swap `@fueled/frontend-web` for `@fueled/frontend-web/lib/vue`, and add `,.vue` to the file extensions when running the linter:

```
$ eslint --ext .js,.vue ./path/to/src
```

You will also need to install the Vue peer dependencies:

```
`npm install --save-dev eslint-plugin-vue eslint-plugin-vue-a11y`
```

## Common Errors

Because the Fueled Frontend linter is a little more aggressive than other defaults, there are a few rules that might break out of the box with Vue CLI or Create React App. Some are formatting changes that should be easily fixed by using the [Fueled Frontend Prettier Config](../prettier-config-frontend-web), however others require a bit more massaging:


### `no-console`

`console.log` is a developer's friend, but should only make it into production in rare circumstances – logging analytics calls for example. As such `no-console` is set to `error` where `process.env.NODE_ENV` is `production`, and `warn` everywhere else. This ensures that it doesn't slow down local development, but will still trigger linting errors when pushing PR builds or deploying to production.

For instances where it is necessary to keep the `console.log` use `/* eslint-disable-next-line no-console */`.

### `no-process-env`

Best practice for using `process.env` variables is to create a `config.js` file at the root of the application, and then export the necessary environment variables.

Here is an example `config.js` file (note the `eslint-disable` to allow the correct use of `process.env` in this file), and the necessary changes to `router/index.js` in a Vue CLI project:

```diff
+ /* eslint-disable no-process-env */
+ export const ENV_BASE_URL = process.env.BASE_URL;
```

```diff
+ import { ENV_BASE_URL } from '../config.js';

…

const router = new VueRouter({
  mode: 'history',
-  base: process.env.BASE_URL,
+  base: ENV_BASE_URL,
  routes,
});
```

## Gotchas

### Project-specific Rules

Wherever possible no amendments should be made to `@fueled/eslint-config-frontend-web`, however in rare edge cases (notably for legacy projects with existing configurations that differ from this standard) it is necessary to have overrides.

To add project-specific overrides, use `rules` as you would ordinarily to add new or change existing rule sets:

```js
module.exports = {
  // …
  rules: {
    quotes: [2, 'single', {
      'allowTemplateLiterals': true,
    }]
  },
};
```

### Webpack `import/no-unresolved` Error

For non-standard webpack configuration, it may be necessary to make use of [eslint-import-resolver-webpack](https://www.npmjs.com/package/eslint-import-resolver-webpack). An example being the use of `resourceQuery` to conditionally inline SVGs; this would trigger an error similar to:

```
error  Unable to resolve path to module './images/foo.svg?inline'  import/no-unresolved
```

To fix this, install [eslint-import-resolver-webpack](https://www.npmjs.com/package/eslint-import-resolver-webpack) and configure it within the `settings` object in `.eslintrc.js` using the path to the webpack configuration. For Vue CLI this needs to be resolved from `@vue/cli-service` – `config: require.resolve('@vue/cli-service/webpack.config.js')`.

You may also have require: an aditional `import/ignore` array to ensure that only the necessary files are linted:

```js
module.exports = {
  // …
  settings: {
    'import/ignore': [
      'node_modules/',
    ],
    'import/resolver': {
      webpack: {
        config: './path/to/webpack/config',
      },
    },
  },
  // …
};
```

### `vue-a11y`

1. `vue-a11y/click-events-have-key-events` is triggered on `<button>`, `<a>` etc. It should be ignored with `<!-- eslint-disable …` as per [the issue](https://github.com/maranran/eslint-plugin-vue-a11y/issues/10).