How to setup gatsby with TypeScript and ESLint + prettier
Tags: typescript, gatsby, vscode, javascript
Published: 2020-03-30 17:29:37

Gatsbyjs starters are perfect for jumpstarting a new project. As all boilerplates, it lacks some tools to optimize our development experience.
Fortunately for us, Gatsbyjs is highly customizable.

## TypeScript

Typescript is the easiest of them and the most impactful. [Install the TS package](https://www.gatsbyjs.org/packages/gatsby-plugin-typescript/), add it to the `gatsby-config.js` file, and create a `tsconfig.json` file.

```json
// basic gatsbyjs tsconfig.json
{
  "compilerOptions": {
    "module": "commonjs",
    "target": "esnext",
    "jsx": "preserve",
    "lib": ["dom", "esnext"],
    "strict": true,
    "noEmit": true,
    "isolatedModules": true,
    "esModuleInterop": true,
    "noUnusedLocals": false
  },
  "exclude": ["node_modules", "public", ".cache"]
}
```

You can now start converting JS files to TS. Remember to add the `@types/` packages, as by default they are not included.

As a bonus, install `typescript` and add a type check script to your `package.json`.

```json
"type-check": "./node_modules/typescript/bin/tsc --noEmit --skipLibCheck"
```

Gatsby and `gatsby-plugin-typescript` use babel, so type checking will not stop the build. Use the script either manually or as a pre-commit hook to run it automatically.

## Prettier

Like TypeScript, prettier is pretty straight-forward. One of the most used starters, [gatsby-starter-blog](https://www.gatsbyjs.org/starters/gatsbyjs/gatsby-starter-blog/) already includes it. Let's see how to add it from scratch.

We have to install prettier as dev dependency `npm i -D prettier`. After that, a simple `.prettierrc` file will suffice.

```json
// .prettierrc
{
  "endOfLine": "lf",
  "semi": true,
  "singleQuote": false,
  "tabWidth": 2,
  "trailingComma": "es5"
}
```

[Install the prettier plugin on vscode](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode) and enable it on your personal `settings.json` file. View -> command palette -> search for "> preferences: open settings (JSON)".

```json
// settings.json rules for prettier
{
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "[javascript]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode",
    "editor.formatOnSave": false
  },
  "[javascriptreact]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode",
    "editor.formatOnSave": false
  },
  "[typescript]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode",
    "editor.formatOnSave": false
  },
  "[typescriptreact]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode",
    "editor.formatOnSave": false
  }
}
```

## ESLint

ESLint requires a bit more than the other two. First, we need to install all the dev deps needed to run it.
We will need `eslint`, `eslint-loader`, and `gatsby-plugin-eslint` for the initial config.
`eslint-plugin-react` for react, `eslint-plugin-prettier` and `eslint-config-prettier` for prettier. `@typescript-eslint/eslint-plugin` and `@typescript-eslint/parser` for TypeScript compatibility.

`$ npm i -D eslint eslint-loader gatsby-plugin-eslint eslint-plugin-react eslint-plugin-prettier eslint-config-prettier @typescript-eslint/eslint-plugin @typescript-eslint/parser`

Open `gatsby-config.js` and add the ESLint config to make it work. We need to allow TS extensions and optimize a couple of options.

```js
// gatsby-config.js with eslint for both JS and TS files
{
  ...
  plugins: [
    ...,
    {
      resolve: "gatsby-plugin-eslint",
      options: {
        test: /\.js$|\.jsx$|\.ts$|\.tsx$/,
        exclude: /(node_modules|.cache|public)/,
        stages: ["develop"],
        options: {
          emitWarning: true,
          failOnError: false,
        },
      },
    },
  ]
}
```

Then we need to set up a basic `.eslintrc.js` file. Here's where we will have to tell ESLint to be nice to react, prettier, and TypeScript.

```js
// basic .eslintrc.js compatible with react prettier and typescript
module.exports = {
  // Specifies the ESLint parser for TypeScript
  parser: "@typescript-eslint/parser",
  extends: [
    "plugin:react/recommended",
    "plugin:@typescript-eslint/recommended",
    "prettier/@typescript-eslint",
    "plugin:prettier/recommended",
  ],
  settings: {
    react: {
      version: "detect",
    },
  },
  env: {
    browser: true,
    node: true,
    es6: true,
  },
  plugins: ["@typescript-eslint", "react", "prettier"],
  parserOptions: {
    ecmaFeatures: {
      jsx: true,
    },
    // Allows for the parsing of modern ECMAScript features
    ecmaVersion: 2018,
    // Allows for the use of imports
    sourceType: "module",
  },
  rules: {
    // Disable prop-types as we use TypeScript for type checking
    "react/prop-types": "off",
    "@typescript-eslint/explicit-function-return-type": "off",
    // Enable prettier rules
    "prettier/prettier": "error",
    // interface start with capital I
    "@typescript-eslint/interface-name-prefix": "off",
    // allow "any" as type
    "@typescript-eslint/no-explicit-any": "off",
    // allow @ts-ignore for testing purposes
    "@typescript-eslint/ban-ts-ignore": "off",
  },
};
```

Last this we need to make sure vscode is actually working with us and understands all that we want. [Install the ESLint package for vscode](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) if you don't have it already. A few lines on the user's `settings.json` file will make it work (like we did for prettier).

```json
// settings.json rules for ESLint
{
  "eslint.autoFixOnSave": true,
  "eslint.validate": [
    "javascript",
    "javascriptreact",
    {
      "language": "typescript",
      "autoFix": true
    },
    {
      "language": "typescriptreact",
      "autoFix": true
    }
  ]
}
```

Your Gatsbyjs template with TypeScript, prettier and ESLint enabled is ready.\
The initial time it costs to set it up is dwarfed by the advantages that these technologies can provide. Have fun coding!

---

originally posted on [decodenatura](https://decodenatura.com/how-to-set-up-gatsby-typescript-eslint-prettier/)