A new React project with Typescript, Eslint, and Prettier

elisealcala

Elizabeth Alcalá

Posted on March 14, 2020

A new React project with Typescript, Eslint, and Prettier

In almost every new project I start with React I always ask myself if I should use create-react-app. To small apps, this is a pretty good option but if you want to configure your app a little more and maybe change the babel and webpack configuration, you should start a project from scratch.

Let's create a new directory and initialize a default npm app.

# Make a new directory and move into it 
mkdir new-react-app && cd new-react-app

# Initialise a new npm project with defaults
npm init -y
Enter fullscreen mode Exit fullscreen mode

Now our application has a package.json file.

Let's start with webpack and babel setup.
   # Install webpack 
   npm install --save-dev webpack webpack-cli webpack-dev-server

   # Install the html webpack plugin
   npm install --save-dev html-webpack-plugin
Enter fullscreen mode Exit fullscreen mode
   # Install babel
   npm i --save-dev @babel/core babel-loader @babel/preset-env @babel/preset-react @babel/preset-typescript
Enter fullscreen mode Exit fullscreen mode
A babel preset it's a tool to add support for a certain language.
Enter fullscreen mode Exit fullscreen mode

@babel /preset-env, @babel /preset-react and @babel /preset-typescript : Allow us to add support for the latest features of javascript, react and typescript.

Let's create a webpack.config.js file on the root of our app.

   const path = require('path');
   const HtmlWebpackPlugin = require('html-webpack-plugin');

   module.exports = {
     entry: './src/app.tsx',
     resolve: {
       extensions: ['.ts', '.tsx', '.js'],
     },
     module: {
       rules: [
         {
           test: /\.(ts|tsx)$/,
           exclude: /node_modules/,
           use: {
             loader: 'babel-loader',
           },
         },
       ],
     },
     devServer: {
       contentBase: path.join(__dirname, 'build'),
       historyApiFallback: true,
       host: '0.0.0.0',
       compress: true,
       hot: true,
       port: 3000,
       publicPath: '/',
     },
     devtool: 'source-map',
     output: {
       filename: '[name].bundle.js',
       publicPath: '/',
       path: path.resolve(__dirname, 'build'),
     },
     plugins: [
       new HtmlWebpackPlugin({
         template: path.join(__dirname, 'index.html'),
       }),
     ],
   };

Enter fullscreen mode Exit fullscreen mode

This webpack configuration it's basic but it does the work.

Let's create an index.html file on the root.

   <!DOCTYPE html>
   <html>
     <head>
       <meta charset="utf-8" />
       <meta http-equiv="X-UA-Compatible" content="IE=edge">
       <title>My app with Typescript and React</title>
       <meta name="viewport" content="width=device-width, initial-scale=1">
     </head>
     <body>
       <div id="root"></div>
     </body>
   </html>
Enter fullscreen mode Exit fullscreen mode

Now let's create a babel.config.js file.

   module.exports = {
     presets: [
       '@babel/preset-env',
       '@babel/preset-react',
       '@babel/preset-typescript',
     ],
   };
Enter fullscreen mode Exit fullscreen mode

In our package.json file, we have to add some script to run our app, and to compile it in a build folder.

   // package.json

   {
     "scripts": {
       "start": "webpack-dev-server --mode development",
       "build": "webpack --mode production",
     },
   }

Enter fullscreen mode Exit fullscreen mode
Typescript and react.

Typescript is a programming language developed by Microsoft. It's a superset of javascript, which means it has some additional features, like static typing and support for object oriented programming options. Today is one of the most popular languages.

   # Install typescript
   npm install typescript

   #Install the react dependencies
   npm install react react-dom @types/react @types/react-dom
Enter fullscreen mode Exit fullscreen mode

@types/react y @types/react-dom: These packages add the types for react and react-dom.

Let's create a src folder on the root, and inside an app.tsx file.

   mkdir src
   cd src
   touch app.tsx
Enter fullscreen mode Exit fullscreen mode

Our app.tsx can be like this for now.

   import React from 'react';
   import ReactDom from 'react-dom';

   const App = () => <p>hello world</p>;

   ReactDom.render(<App />, document.getElementById('root') as HTMLElement);

Enter fullscreen mode Exit fullscreen mode

Now let's create a tsconfig.json file. This file has all the rules for typescript to work on our app. You can change it according to what you need. See the full list of options here, https://www.typescriptlang.org/docs/handbook/tsconfig-json.html.

   {
     "compilerOptions": {
       "allowSyntheticDefaultImports": true,
       "noImplicitAny": true,
       "moduleResolution": "node",
       "baseUrl": "./",
       "sourceMap": true,
       "module": "esnext",
       "target": "esnext",
       "jsx": "react",
       "allowJs": true,
       "noEmit": true,
       "noImplicitThis": true,
       "strictNullChecks": true,
       "lib": ["es6", "dom"],
     },
   }
Enter fullscreen mode Exit fullscreen mode
Better development experience with Eslint and Prettier.

Eslint is a linting tool for javascript. It analyzes our code, looking for syntax errors, saving us a lot of development time.

Prettier is a code formatter. It enforces a consistent style across our app.

   # Install eslint and prettier
   npm install --save-dev eslint prettier

   # Install plugin and presets needed for our app
   npm install --save-dev eslint-config-prettier eslint-plugin-prettier eslint-plugin-react @typescript-eslint/eslint-plugin @typescript-eslint/parser
Enter fullscreen mode Exit fullscreen mode

eslint-config-prettier: It's important to use this package to avoid conflicts between eslint and prettier rules.

@typescript-eslint/eslint-plugin y @typescript-eslint/parser: These plugins add support for typescript.

Let's create a configuration file for Eslint called .eslintrc.js on the root of our project. You can change these rules according to your needs.

Here is the list of supported rules for eslint-plugin-react: https://github.com/yannickcr/eslint-plugin-react

   module.exports =  {
     parser:  '@typescript-eslint/parser',
     extends:  [
       'plugin:react/recommended',
       'plugin:@typescript-eslint/recommended',
       'plugin:prettier/recommended',
     ],
     parserOptions:  {
       ecmaVersion:  2018,
       sourceType:  'module',
     },
     plugins: ["prettier"],
     rules: {
       "prettier/prettier": [
         "error",
         {
           singleQuote: true,
           trailingComma: 'all',
         }
       ],
       'react/prop-types': [
         1,
         {
           ignore: ['context', 'tracking'],
         },
       ],
     },
     settings: {
       "react": {
         "version": "detect",
       },
     },
     overrides: [
       {
         files: ['*.ts', '*.tsx'],
         rules: {
           'react/prop-types': 'off',
         },
       },
     ],
   };
Enter fullscreen mode Exit fullscreen mode

Now if we are using VS Code, we can enable the option to format our code on save.

Let's create a .vscode folder on the root, and create inside a settings.json file with this content.

   {
     "eslint.validate": [
       "javascript",
       "javascriptreact",
       "Babel Javascript",
       "typescript",
       "typescriptreact",
     ],
     "eslint.alwaysShowStatus": true,
     "editor.codeActionsOnSave": {
       "source.fixAll.eslint": true
     },
   }
Enter fullscreen mode Exit fullscreen mode

Now when we run npm start we should see our application run on localhost:3000.

💖 💪 🙅 🚩
elisealcala
Elizabeth Alcalá

Posted on March 14, 2020

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related