๐Project Setup
This guide is to help understand what goes on under the hood of CRA application, and to grasp how the tools like Webpack and Babel work in tandem with React and Typescript.
Motivation
I had fun with create-react-app,
with the no-worries setup it provides to dive right into the action of writing React components, but now it's time we get our hands dirty with the configuration that create-react-app
does for us under the hood. This is basically to understand the basic concepts of how tools like Webpack and Babel help us developers in writing better code, with the latest ECMAScript standards, while also ensuring that older browsers that do not support these latest standards, also work for the code that we write.
P.S. This is a really long article, stick till then end, it's going to be worth the effort! All the code for this guide is available on Github.
1. Base setup
Let's start by creating a folder and initializing git
and yarn
, plus we'll also add two folders, src
and public
, which will house our code.
React
dependencies
React
dependenciesLet's add the react
and react-dom
dependencies:
Typescript & others
Let's add the Typescript and other dev dependencies: [use the -D
flag to save as dev dependency]
With these dependencies added, we need to add a new file to the root directory of the app, called tsconfig.json
. This file will contain all the configuration required for Typescript in our app.
Babel & others
With the Typescript configuration in place, let's add babel and it's dev dependencies:
Create a new file in the root directory called .babelrc, which will contain the config options for babel.
Base Code
With this basic setup in place, we can now write Typescript JSX, i.e, TSX in our app! But keep in mind, we can only write it, currently it cannot be compiled and displayed on the browser, for which we will need Webpack!
2. Webpack
We need to inject our <script>
into the index.html
file. We do this by using webpack, which will transpile
and bundle
our React app into plain Javascript, and inject it into the HTML page in our app.
Webpack & others
Let's add webpack and it's dev dependencies! Also, I'll be using a really cool webpack dashboard to see the status of my compilation and bundling, it's called webpack-dashboard
, and is open sourced by FormidableLabs
.
With the above tools installed, we will need to create a new "script" in our package.json
file, which points to the webpack configuration of our app. But before we start with the webpack configuration, we need to add another package, called babel-loader
, which is required to transpile all the .tsx
and .jsx
files in out app!
Configuration
Let's configure webpack. For this, we need to create a new file called webpack.config.js
at the root level directory of our app.
With the configuration done, we need to add the script to the package.json
file:
We can finally test our app on the browser! Simply run yarn start
in the terminal to see the app working on localhost:3000
.
3. Prod and Dev Webpack Configs
It's usually a good idea to split out webpack configuration into different files. We usually 4 webpack config files:
webpack.dev.js : This contains the config for the webpack dev server
webpack.prod.js: This contains the config for building our app for production
webpack.common.js: This contains the configs that are common to both dev & prod
webpack.config.js: This 'merges' both dev OR prod config file AND the common config file
Let us setup this structure for our app! We'll create a webpack/
folder in the root directory of our app, and create 3 files in it, viz., webpack.common.js
, webpack.dev.js
and webpack.prod.js
. We would have to change the content of webpack.config.js (which is in the root directory, and not the webpack folder) as well. But first, we need to install a package that merges two webpack configuration files.
With this package installed, we are ready to configure our webpack configuration files!
4. Adding styles
Since there are many options out there to style a React app, we'll be focusing on really the basic tools for styling an app, i.e, CSS, CSS-modules and SASS. These are the most widely used styling tools used and are relatively easy to set up with webpack! We will add different rules for development and production modes.
Installing dev dependencies
Before we start adding rules to webpack config files for styling, we need to install a few loaders that can handle CSS and SASS:
Webpack Configs for Styling
Add typings.d.ts
typings.d.ts
With these configurations in place, we need to do one final thing, add a new file in the src/
folder called typings.d.ts
, which will have the modules declaration in it. Let's add some basic modules that we will declare in this file, and then move on to add configurations for using images and other stuff in our app with webpack!
5. Images and SVGs
All apps require images and SVGs in their code. To bundle such files in our app with webpack, we do not need to install any extra dependencies! Prior to webpack 5 & 4, we had to install the 'file-loader' dependency with other things to use images and SVGs in our app. Now, we need to just use the type
property set to asset/resource
or asset/inline
to use images or SVGs in our app respectively. Not only images and SVGs, we can also use other file with file-extenstions like .gif, .jpg, .jpeg, .woff, .eot, etc.
We will declate these configs in our common webpack config file:
6. Misc Webpack Dependencies
Here are a few common dependencies that are typically used in every production ready application. They are not absolutely necessary to install, but it's recommended that you do, since they are pretty useful!
React Refresh Webpack Plugin
This is a plugin that adds hot reloading to our app.
Dotenv Webpack Plugin
This plugin helps us use environment variables throughout our app, and utilizes the functionality of webpack.DefinePlugin
to declare global constants which can be declared at compile time, and therefore helps us hide important information for the source code and the end-user.
With this setup in place, we can define a .env
file in our app's root directory and declare global constants that we can define during runtime.
Update package.json
package.json
We need to add the scripts to the package.json
file from where we can run the webpack server for production or development. We'll add the rimraf
package as well, to delete all previous build folders, so as to start a clean build every time we build our app!
7. ESLint
The ESLint package helps use developers write code that is as accurate as possible by pointing our errors as we write our code. Pretty useful feature to have linting in our code to highlight errors and warnings that indicate problems with our code.
A prerequisite for this dependency is that we need to have the ESLint extension installed in VSCode. This extension can be found here.
Now, we have to define the configurations for ESLint in a new file at the app's root directory, called '.eslintrc.js
'.
Let's take it to the next level by adding a script to run eslint on our files:
8. Prettier
This is basically a style guide for our code, and helps maintain a standard for writing code for an application. Again, a prerequisite for this to work is we have the Prettier extensions installed on VSCode. This extension can be found here.
To configure prettier, a '.prettierrc.js
' file is required at the app's root directory.
We need to modify the .eslintrc.js
file a little bit as well:
Time to take it to the next level, by adding a script to run prettier on all our files:
We can also turn on the 'Format on Save' option in VSCode to true
, to format our files when we save them.
9. Husky & lint-staged
lint-staged
With Husky
and lint-staged
packages, we prevent linting and formatting errors to be committed to a common work repository for our app. This help maintain a code standard, and thus prevents accidental errors in our code or formatting of our code to be committed into the repository.
Define lint-staged
configs
lint-staged
configsDefine Husky configs
We define the husky config that tells husky
to run the lint-staged
configurations just before the code is being committed.
10. Nice-to-have(s)
Below are some other configurations for our React + Typescript app that are not necessarily required, but are good to have.
Babel & Runtime
These plugins let us us the async-await
features in our application.
We'll update the .babelrc
file to incorporate the plugins.
Copy Webpack Plugin
This plugin helps us copy static assets from a source to a destination, typically used to copy the contents of the source folder into the build folder, when the build command is run.
Bundle Analyzer Plugin
This plugin runs when we build our app for production. It loads a webpage that displays all the bundled files and their sizes. Pretty useful feature to use in an app that is being deployed.
Last updated