DEV Community

Cover image for How to setup gatsby with TypeScript and ESLint + prettier
Francesco Agnoletto
Francesco Agnoletto

Posted on • Updated on • Originally published at decodenatura.com

How to setup gatsby with TypeScript and ESLint + prettier

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, add it to the gatsby-config.js file, and create a tsconfig.json file.

// 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.

"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 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.

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

Install the prettier plugin on vscode and enable it on your personal settings.json file. View -> command palette -> search for "> preferences: open settings (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.

// 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.

// 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 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).

// 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

Discussion (3)

Collapse
sweethuman profile image
Gheorghe Avram

I'm running gatsby@v4 and with the latest gatsby-plugin-eslint and the configed in the article didn't work for me, but this did:

{
      resolve: 'gatsby-plugin-eslint',
      options: {
        rulePaths: [gatsbyRequiredRules],
        extensions: ['js', 'jsx', 'ts', 'tsx'],
        exclude: ['node_modules', 'bower_components', '.cache', 'public'],
        stages: ['develop'],
        emitWarning: true,
        failOnError: false,
      },
    }
Enter fullscreen mode Exit fullscreen mode
Collapse
sweethuman profile image
Gheorghe Avram

I discovered somehow this breaks shadowing for Gatsby plugins. I haven't investigated further. After removing the gatsby-plugin-eslint, shadowing works again.

Collapse
sweethuman profile image
Gheorghe Avram

Also, don't need to install and use prettier/@typescript-eslint already included in prettier.