Running Gatsby with TypeScript + ESLint + Prettier — 2020 Fall version

Ryosuke Iwanaga
4 min readNov 24, 2020

--

Photo by Martin Shreder on Unsplash

tl;dr — I’ve successfully migrated gatsby-starter-blog to full TypeScript compatible with ESLint + Prettier. See the repository below:

Introduction

I had been looking for the best practice to make my (not finished yet) Gatsby site to full TypeScript. I had tried multiple times in last one year but every time the best practice was different and it was too hard to accomplish the goal by a novice in Gatsby or TypeScript or React or any modern JavaScript ecosystem, like me.

My acceptance criteria for this work were below:

  1. All code are written in TypeScript (except gatsby-*.js).
  2. All code are typed and checked by IDE (WebStorm) automatically.
  3. All code are formatted/linted automatically by IDE and commit hook.

Since I’m a newbie to the modern JS world (disclaimer: I’m a pure backend/server-side engineer who are operationally inclined), I’d like to use better tooling as much as possible from the beginning so that I can avoid unnecessary mistakes, I thought. However, the tooling in this world is just chaos due to the volume of ecosystem and velocity of the developments. I don’t want to refresh my learning of its history here, but I’d like to give you a few examples:

  • Prettier becomes a kind of de facto of formatter but ESLint has ability to format as well.
  • TSLint was the de facto linter but it’s now ESLint.
  • Gatsby required to add TypeScript plugin explicitly, but now it’s included out-of-the-box.
  • However, the plugin doesn’t use tsc and there is no type checking.
  • npm vs yarn vs yarn2. Gatsby is not ready for yarn2 yet.

Also, you can find tons of similar information about “Gatsby + TypeScript” in the Internet but all (including this post) are just snapshot at the moment when written. So, you need to understand each step and apply the best practice by yourself at the time you’re doing. This post was written in November 2020.

Key items

To achieve my acceptance criteria, these were the key items I accomplished:

  1. Automatic type generation of GraphQL result by gatsby-plugin-typegen and overriding gatsby-node.js by TypeScript using ts-node.
  2. Using tsconfig.json for type checking. Built-in TypeScript support by WebStorm.
  3. eslint-config-prettier to resolve conflicts between ESLint and Prettier, husky+lint-staged for pre-commit hook, built-in ESLint and Prettier support by WebStorm.

Acknowledgments

My work was mostly just cloned from two Japanese entries. The former one gave me 95% of the steps I did. The latter provides me the history and all information around ESLint and Prettier. A huge thanks to them.

Implementations

Let’s walk through each step.

Add lint-staged and husky by mrm: The easiest way to setup the pre-commit hook for Prettier. I also enabled WebStorm feature to run Prettier at saving the file. (Note: There was a bug that it was not working with Vim plugin but now fixed.) I did this as a first step so that every single file changed afterward were automatically formatted by Prettier.

Add typescript and tsconfig.json: I used tsc --init to generate tsconfig.json since it’s just enough. tsc isn’t used for transpiling, so--noEmit. --jsx preserve has no meaning for type checking but jsx parameter is required to check JSX/TSX files.

Add eslint and .eslintrc.js: I also used eslint --init to generate config and install packages. The input of its wizard is recorded in the commit message. (Note: eslint --init won’t support yarn so that I decided not to use yarn.)

Add eslint-config-prettier to avoid conflicts: Simply I added eslint-config-prettier and configs to extends . I also checked the conflicts by npx eslint --print-config src/pages/using-typescript.tsx | npx eslint-config-prettier-check

Add .graphqlconfig for WebStorm: This is not required to achieve the goal, but helps GraphQL query itself typed. The boilerplate of config was generated by WebStorm. See also this post (even it is in Japanese, its screenshots must be helpful.)

Add gatsby-plugin-typegen and migrate to TypeScript!: Now, I just added gatsby-plugin-typegen and migrated pages and components to TypeScript! Thanks to WebStorm with TypeScript / ESLint / Prettier, this step was pretty easy and had no ambiguity. Sweet.

Add ts-node and migrate gatsby-node.js and templates to TypeScript: This is tricky because Gatsby doesn’t support TypeScript with gatsby-*.js yet. Also, gatsby-plugin-typegen seems not generating types for GraphQL query here.

Add npm tasks and enable ESLint in pre-commit: Since now our codes are all ESLint-certified, I enabled ESLint in pre-commit hook delegated to lint-staged. (Note: tsc is not supporting single file with tsconfig.json so that I can’t add it to pre-commit since it runs per file. I rely on WebStorm.)

Workaround a bug of gatsby-plugin-typegen: The last commit is just a workaround for a bug of gatsby-plugn-typegen.

Conclusion

Although there are still some gaps like ts-node is needed or gatsby-plugin-typegen doesn’t generate all types yet (and a bug), the repository has clean but all type checked and formatted code which are perfectly working with WebStorm.

Finally I can start learning TypeScript! It was long Yak Shaving, but worth to go thorough since I’m now confident about modern JavaScript ecosystem a little:)

If there is anything wrong (I believe there is), feel free to comment here or ping me.

--

--

Ryosuke Iwanaga
Ryosuke Iwanaga

Written by Ryosuke Iwanaga

Software Engineer / ex-AWS / #FTTB / Anime / Canada -- Posts are my own, not endorsed by any org. Request 1on1 here: http://calendly.com/riywo/1on1

No responses yet