Lately, I've been working on polishing my JS skills, specifically, React and TypeScript has been on my radar for a while so I thought it'd be a great idea to work on an app to incorporate both.
Let's go through a quick recap of React and touch base on what TypeScript.
React and TypeScript walk into a bar...
React is a front-end JavaScript developed by Facebook. It follows a component-based approach which helps us to build reusable UI components. It also uses a virtual DOM instead of the real DOM, this helps us re-render just certain parts of the app instead of the whole thing.
TypeScript essentially is a strict, typed superset of JS. TypeScript compiles to readable, standards-based JS. The main thing about TypeScript is that it allows us to add static types to our JS code and doing so helps us catch errors earlier in the debugging process.
Less time debugging AND clearer code? Sign ๐ me ๐ up ๐.
Setup
Thankfully, there's a Create-React-App template that already does the heavy lifting for us that includes TypeScript.
npx create-react-app my-app-name --template typescript
Next stop, setting up our linters because we're all about that clean code.
We're going to be using ESLint and Prettier. Let's set up our local env running:
npm install --save-dev eslint@6.8.x @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint-plugin-react prettier eslint-config-prettier eslint-plugin-prettier --dev
We're also going to need to set up their configuration files. On the root of your project, create .eslintrc.js
and use this configuration:
module.exports = {
parser: "@typescript-eslint/parser", // Specifies the ESLint parser
parserOptions: {
ecmaVersion: 2020, // Allows for the parsing of modern ECMAScript features
sourceType: "module", // Allows for the use of imports
ecmaFeatures: {
jsx: true // Allows for the parsing of JSX
}
},
settings: {
react: {
version: "detect" // Tells eslint-plugin-react to automatically detect the version of React to use
}
},
extends: [
"plugin:react/recommended", // Uses the recommended rules from @eslint-plugin-react
"plugin:@typescript-eslint/recommended", // Uses the recommended rules from @typescript-eslint/eslint-plugin
"prettier/@typescript-eslint", // Uses eslint-config-prettier to disable ESLint rules from @typescript-eslint/eslint-plugin that would conflict with prettier
"plugin:prettier/recommended" // Enables eslint-plugin-prettier and eslint-config-prettier. This will display prettier errors as ESLint errors. Make sure this is always the last configuration in the extends array.
],
rules: {
// Place to specify ESLint rules. Can be used to overwrite rules specified from the extended configs
// e.g. "@typescript-eslint/explicit-function-return-type": "off",
},
};
For Prettier we need to create also in the root, a file called .prettierc.js
with the following code:
module.exports = {
semi: true,
trailingComma: "all",
singleQuote: true,
printWidth: 120,
tabWidth: 4
};
And to tie it all together and make it even easier for us, add the following line to your package.json
:
"lint": "eslint '*/**/*.{js,ts,tsx}' --quiet --fix"
That way we can simply run ยดnpm run lintยด and have everything working for us.
We're also going to be including Github Actions to make sure that even if we forget to run the interest, our code is going to be checked.
At root level, add .github/workflows
and in it, create a file called linters.yml
with the following:
name: Linters
on: pull_request
env:
FORCE_COLOR: 1
jobs:
eslint:
name: ESLint
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
with:
node-version: "12.x"
- name: Setup ESLint
run: |
npm install --save-dev eslint@6.8.x @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint-plugin-react --dev
[ -f .eslintrc.js ]
- name: ESLint Report
run: npx eslint .
When you open a PR, you should see the linters working.
Optional
Since we're setting up everything, I want to make time to also set up our styling dependencies. I usually use Semantic UI, but this time I'm going to be using Tailwind CSS.
Tailwind is a utility-first CSS framework for custom interfaces. It gives us a lot of functionality out of the box.
Depending on what you need, there are two types of setup: the basic one and the production one. I used this great resource by Dave Ceddia.
That's it for our setup process. In our next installment, we'll talk about writing our first TypeScript component.
I hope you found this helpful, stay safe and please remember to take a break.
Got something to add? Please feel free to reach out for any question, comment, meme or dog photos swap.
Top comments (1)
Nice writeup! I do something pretty similar for backend stuff and CDK. Isn't it weird in this day and age of excellent developer tooling there isn't a TypeScript/eslint setup that can be done in fewer steps? Would make a great side project (but alas, I already have so many).
Of course CRA includes eslint, but I found operating the built-in one kind of challenging, so I would definitely do something like what you're doing here.