Reading Time: 8 minutes
In this blog, we will see how to set up a React app from scratch using Typescript, Webpack, Babel, Eslint, and prettier. Although the setup given by create-react-app is great and optimized well, it’s good to know what is the job of each tool and how to configure them by yourself that way you can have full control and customize them according to your project need.
React app setup
Index
- Creating a git repo
- Initializing basic web project
- Adding npm
- Setting up babel
- Adding webpack
- Setting up eslint and prettier
Step 1: Creating an git repo
We will initialize a git repository. So inside the folder which will contain all your project run:
git init
Create a file called .gitignore and these two folder names, so they won’t be tracked.
buildnode_modules
Step 2: Initializing a basic web project
Create folders “src” and “build”. Inside the src folder create a file index.html. In the index.html file add an HTML starter template with this line inside the body. <div id=”root”></div>. And this div will contain all the react components that will be rendered. And this index.html will be out of our single-page web app.
src/index.html
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>React ts</title></head><body> <div id="root"></div></body></html>
Step 3 : Adding npm
To manage all the packages and dependencies we need to have a package.json file to run the command.
npm init -y
Note: we can change the meta info in package.json file like name, version description etc late
Now we will install the hero of the app. That’s right… React! So run command
npm i react react-dom
Note: at the time of writing this blog latest version was React 17.
No, since we will be going to use Typescript language to code our react components.
npm i -D typescript @types/react @types/react-dom
“typescript” is the core package that lets you use typescript.
“@types/react @types/react-dom” are the types for React and React-Dom functions.
Create a file “tsconfig.json” in the root directory to give the compiler options for type checking.
tsconfig.json
{ "compilerOptions": { "target": "ES5" /* Specify ECMAScript target version */, "module": "ESNext" /* Specify module code generation */, "moduleResolution": "node" /* Specify module resolution strategy */, "lib": [ "DOM", "ESNext" ] /* Specify library files to be included in the compilation. */, "jsx": "react-jsx" /* Specify JSX code generation */, "noEmit": true /* Do not emit outputs. */, "isolatedModules": true /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */, "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */, "strict": true /* Enable all strict type-checking options. */, "skipLibCheck": true /* Skip type checking of declaration files. */, "forceConsistentCasingInFileNames": true, "resolveJsonModule": true "allowJs": true /* Allow javascript files to be compiled */, "checkJs": true /* Report errors in .js files */, }, "include": ["src/**/*"] }
Important note
the compiler options are focused on type checking and not transpiling. We will use babel for that.
Create 2 files in “src” folder “index.tsx” and “App.tsx”
src/App.tsx
import React from 'react'export const App = () => { return ( <div> Hello, this is my React app. </div> )}
src/index.tsx
import ReactDOM from 'react-dom';import { App } from './App';ReactDOM.render(<App/>, document.getElementById('root'));
Step 4: Adding babel
This code cannot be understood by our browser as it. We need babel to covert ts and react to js code.
Babel is a Js compiler that is mainly used to convert ECMAScript 2015+ code into a backward compatible version of JavaScript in current and older browsers or environments.
If you have no idea about what is Babel, you can skim through its documentation quickly.
Run the following command
npm i -D @babel/core @babel/preset-env @babel/preset-react @babel/preset-typescript @babel/runtime @babel/transform-runtime-plugin
@babel/core => the core package of babel.
@babel/preset-env => allows you to use the latest JavaScript.
@babel/preset-typescript => for using typescript.
@babel/transform-runtime-plugin => helps you use some modern features of js like async/await.
Create a file in root “.babelrc” for configuring babel
{ "presets": [ "@babel/preset-env", [ "@babel/preset-react", { "runtime": "automatic" } ], "@babel/preset-typescript" ], "plugins": [ [ "@babel/plugin-transform-runtime", { "regenerator": true } ] ]}
Step 5: Adding webpack
Now, we will install add webpack to our project.
And why webpack or what is webpack ?
If you have written react code you would know that it requires writing a lot of javascript files and importing these files to other files. We do this using some sort of module system, the two most popular module systems are CommonJS’srequire()
and ESM’simport
. Unfortunately, there is no browser support for CommonJs, and support for ESM is not universal yet. So we need a tool that can take all the files that we have written and combine/bundle them into a single js file while keeping track of their dependencies. The tool that does this are called bundlers and webpack is one of the many javascript bundlers!
Learn more about webpack.
Let dive straight into setting up webpack
Let’s create together the config files and install packages step by step to understand them more clearly. Let’s start with the core packages.
npm i -D webpack webpack-cli webpack-dev-server html-webpack-plugin babel-loader
Create a folder in root named “webpack” and create the following files
webpack/|- webpack.common.js|- webpack.config.js|- webpack.development.js|- webpack.production.js
The common file will have the common config for both the dev and prod environment and each dev and prod file will have some environment-specific configurations. in the webpack.config.js file, we will merge the common and environment-specific configurations.
webpack/webpack.common.js
const path = require('path')const HtmlWebpackPlugin = require('html-webpack-plugin')module.exports = { entry: path.resolve(__dirname, '..', './src/index.tsx'), resolve: { extensions: ['.js', '.ts', '.tsx'], }, module: { rules: [ { // should use babel-loader for all ts js tsx and jsx files test: /\.(ts|js)x?$/, exclude: /node_modules/, use: [ { loader: 'babel-loader', }, ], }, ], , output: { path: path.resolve(__dirname, '..', './build'), filename: '[name].[chunkhash].js', }, plugins: [ new HtmlWebpackPlugin({ template: path.resolve(__dirname, "..", "./src/index.html") }) ],}
entry specifies from which file to webpack first look and start bundling
resolve here helps to import without extensions and looks for file in order i.e tsx -> ts -> js
module to define rules of how diff module should be loaded.
output to specify where the bundled code should be outputted. The path contains the path of the folder, in this case, build folder we created. And filename tells the name of the file of the bundled code, so it will take the name and the chuck reference of the file and combine them to create a filename for bundled output.
HtmlWebpackPlugin template tells the webpack to use index.html file as a template to add bundled js file to and add index.html to the build folder.
To load a file that is not javascript or typescript like CSS and fonts and images requires different loaders. So run the command to install
npm i -D style-loader css-loader
And add new rules in webpack.common.js.
module.export = { ... ... ... module: { rules: [ . . ., { { // should use style-loader and css-loader for all css files test: /\.css$/, use: ['style-loader', 'css-loader'], }, { // v5 supports image loaders out of box test: /\.(?:ico|gif|png|jpg|jpeg)$/i, type: 'asset/resource', }, { test: /\.(woff(2)?|eot|ttf|otf|svg|)$/, type: 'asset/inline', }, } ] },.........}
for image files and font files there is out-of-the-box support t from v5. but if you are on lower versions you look up specific loaders.
Also, a help full plugin that can copy assets into your build folder
npm i -D copy-webapck-plugin
const CopyWebpack = require('copy-webpack-plugin')module.export = {...plugins: [ ... new CopyWebpack({ patterns: [{ from: 'sourcefolder', to: 'destinationfolder' }], }), ],}
Now we have most of our webpack config in place. Let’s add the environment config for development and production mode.
webpack/webpack.development.js
const webpack = require('webpack')module.exports = { mode: "development", devtool: "cheap-module-source-map", plugins: [ new webpack.DefinePlugin({ 'process.env.name': JSON.stringify('dev') }) ],}
webpack/webpack.production.js
const webpack = require('webpack');module.exports = { mode: "production", devtool: "source-map", plugins: [ new webpack.DefinePlugin({ 'process.env.name': JSON.stringify('prod') }) ]}
So as you can see not much differs from a basic webpack setup.
mode sets the mode of app this will also set the environment variables in the node process.
devtool is used to set that how the js files will be minified. So for the dev environment, we use a less minified version so its easy to debug and source-map for prod which gives very optimized and lightweight build files.
In the webpack.DefinePlugin we modify the node process object which is very useful to do environment-specific variables and functionality in code. In this case, we are not doing much but you can use this to set API URLs. You can access this in any js/ts file by just using the process.env.name directly.
Now we will configure the webpack.config.js file which will merge the common config and one of the environment-specific configs depending on the environment.
npm i -D webpack-merge
webpack.config.js
const { merge } = require("webpack-merge");const commonConfig = require("./webpack.common.js");module.exports = (envVars) => { const { env } = envVars; const envConfig = require(`./webpack.${env}.js`); const config = merge(commonConfig, envConfig); return config;};
So this file takes the variable that we will pass from the scripts we will add in the package.json to run and build the app using webpack. Let’s see how.
package.json
"scripts": { ... , "start": "webpack serve --config webpack/webpack.config.js --env env=dev --open", "build": "webpack --config webpack/webpack.config.js --env env=prod", ... },
Add these two new scripts “start” and “build”. The “start” script serves the app locally to port localhost:8080 and we pass env=dev. The “build” script will be used for creating build folder of the app and we pass env=prod.
Note: we install webpack-cli earlier which gives us the ability to use the command webpack.
You can test our progress here by changing the App.tsx file to
import React from 'react'export const App = () => { return ( <div> Hello, this is {process.env.name} app </div> )}
run “npm start” and go to localhost:8080
to check the prod build run the command “npm run build”. You will see the files are added to the build folder and now if you wish you can serve this by using running “npx http-server ./build” whish will spin up a local server and server files.
Step 6: Adding eslint and prettier
Now we will set up eslint. Eslint is not required to run an app but it helps in writing quality code that is less prone to bugs and more readable. I would say must to have if you have a team of developers.
There can be an infinite number of ways you can set up eslint. It completely depends on you, which rules you wanna enforce to check for bugs. There are some already great blogs that you can search to setup eslint in a very strict manner. However, in this blog, I will add a basic one and you can take it from here.
Note: Install the eslint extension for whichever code editor your using.
Let’s install all the dependencies.
npm i -D eslint eslint-plugin-import eslint-plugin-jsx-a11y eslint-plugin-react eslint-plugin-react-hooks
create file .eslintrc.js
.eslintrc.js
module.exports = { parser: '@typescript-eslint/parser', parserOptions: { ecmaVersion: 2020, sourceType: 'module', }, settings: { react: { version: 'detect', }, }, extends: [ 'plugin:react/recommended', 'plugin:react-hooks/recommended', 'plugin:@typescript-eslint/recommended', 'plugin:import/errors', 'plugin:import/warnings', 'plugin:import/typescript', 'plugin:jsx-a11y/recommended', ], rules: { 'no-unused-vars': 'off', '@typescript-eslint/no-unused-vars': ['error'], '@typescript-eslint/no-var-requires': 'off', 'react/prop-types': 'off', 'react/jsx-uses-react': 'off', 'react/react-in-jsx-scope': 'off', '@typescript-eslint/explicit-module-boundary-types': 'off', indent: ['error', 2], '@typescript-eslint/indent': ['error', 2], 'max-len': ['error', { code: 120 }], },}
Now to help you format your code I recommend adding prettier to your project. Which is an opinionated code formatter.
Note: Add prettier extension in your code editor.
npm i -D prettier eslint-plugin-prettier eslint-config-prettier
create file .prettierrc.js
.prettierrc.js
module.exports = { semi: false, trailingComma: 'es5', singleQuote: true, jsxSingleQuote: false, printWidth: 80, tabWidth: 2, endOfLine: 'auto'}
Your code will be formatted automatically according to this config and you can prettier rules to eslint as well so there is no conflict. In the .eslintrc.js file in extends add :
.eslintrs.js
extends: [ ... , 'prettier', 'plugin:prettier/recommended',]
Now if you have any syntax or logical error according to your rules it will who error in your Code editor.
To help us make our life easy so we will add two scripts to check and possibly fix any fixable eslint error.
package.json
scripts: { ... , "lint": "eslint --fix \"./src/**/*.{js,jsx,ts,tsx,json}\"", "format": "prettier --write \"./src/**/*.{js,jsx,ts,tsx,json,css,scss,md}\"",}
Conclusion
Well done! You have successfully created a react app without create-react-app. Setting up an app from scratch is something developers can wear like a badge of honor. There is a lot more stuff you can change on optimizing but the aim of this blog was to give you a well basic enough setup. Hope you learned something new today.
References
FAQs
Does React need webpack and Babel? ›
React doesn't "need" babel or webpack but the library is built on the concept of using ES6 javascript syntax and JSX (essentially HTML in JS). React however can be used without ES6 and JSX which would remove the initial need for Babel but you would lose the potential benefits of ES6 and JSX.
Is Babel included in create React app? ›This package includes the Babel preset used by Create React App. Please refer to its documentation: Getting Started – How to create a new app. User Guide – How to develop apps bootstrapped with Create React App.
Is Babel still needed in 2022? ›Conclusion. Having Babel and TypeScript do part of the source transform seems unnecessarily complicated. So, if you are using both, it is better to use Babel for transpiling and the TypeScript compiler for type checking.
Is Babel necessary for webpack? ›Yes. That is why we have "webpack the bundler", and "Babel the compiler/transpiler", and babel-loader to connect the two together. Without babel-loader webpack would not be able to process files through Babel.
What is the difference between Babel and webpack? ›In the preceding section, you learned that webpack is a tool that brings together many loaders and plugins to create a single bundled code file. Babel is a library that does a single job: it compiles JavaScript. Babel is one of many loaders you can use with webpack.
Should I use Babel or webpack? ›"Modern Javascript works with all browsers", "Open source" and "Integration with lots of tools" are the key factors why developers consider Babel; whereas "Most powerful bundler", "Built-in dev server with livereload" and "Can handle all types of assets" are the primary reasons why Webpack is favored.
Should I use webpack or create react app? ›Create react app abstracts the configuration does not allow you change it unless you eject. Using webpack does require knowledge of webpack and does allow complete control over your environment.
Why webpack instead of create react app? ›Configuring webpack provides complete control over the development environment, while initializing with Create React App prevents any custom configuration by default.
What is webpack and Babel in react JS? ›What Are Webpack and Babel? Webpack and Babel are tools for developers that optimize JavaScript applications. Webpack is a module bundler we can use to minify multiple files in a JavaScript project and increase the overall efficiency. A module bundler takes in all the assets and comes up with a single output file.
Can React run without Babel? ›While React can be used without a build pipeline, we recommend setting it up so you can be more productive. A modern build pipeline typically consists of: A package manager, such as Yarn or npm. It lets you take advantage of a vast ecosystem of third-party packages, and easily install or update them.
Is Babel a frontend or backend? ›
Babel is a transpiler, used to convert more modern versions of JavaScript into older versions of JavaScript compatible with server side JavaScript in Node. js as well as browsers. While Babel is clearly very popular, it is used on both front and back end applications, so it's not a reliable proxy of front end usage.
What can I use instead of Babel? ›Webpack, TypeScript, CoffeeScript, ESLint, and rollup are the most popular alternatives and competitors to Babel.
What is better than Webpack? ›gulp, Babel, Parcel, Browserify, and Grunt are the most popular alternatives and competitors to Webpack.
What was the main problem with the Tower of Babel? ›According to Genesis, the Babylonians wanted to make a name for themselves by building a mighty city and a tower “with its top in the heavens.” God disrupted the work by so confusing the language of the workers that they could no longer understand one another.
Can I use webpack with create React app? ›Create React App is a great way to get started with a Webpack-React app using standard conventions. Therefore, we'll use it in all of our forthcoming Webpack-React apps.
Do people still use webpack? ›Loved by many, hated by some, known to all. And still the most popular bundler in 2021. With more than 15 million weekly downloads (at the time of writing this post), there's no doubt that Webpack is still the bundler par excellence in 2021.
Can webpack replace Babel? ›You can replace the compiler and continue using webpack, or you can use SWC's own bundler called spack, which can completely replace webpack, along with Babel.
What are four core concepts of webpack? ›There are four basic concepts in webpack: entry , output , modules and plug-ins . These configurations are added in webpack.
Does Babel improve performance? ›babel-loader caches its results in node_modules/. cache/babel-loader by default. After enabling caching with babel-loader we improved the build performance by another 26%. Although configurations vary among locales, most of the modules are the same.
Is Babel deprecated? ›Since @babel/polyfill was deprecated in 7.4.0, we recommend directly adding core-js and setting the version via the corejs option.
Do I need webpack with npm? ›
It is highly unlikely that you will not need it. Webpack is a module bundler. It is mostly used to manage JavaScript codebases, most often for usage in the browser, and requires Node.
Do I need Babel if I use TypeScript? ›If you need custom transformations, you'll need to use Babel. The good news is that most TypeScript tools allow you to both use TypeScript and then run the code through Babel afterwards, to get the best of both worlds. But this obviously comes with additional complexity in your build-chain.
Is Babel a compiler or transpiler? ›Babel is a JavaScript compiler.
What is the difference between react and webpack? ›Webpack is a module bundler whereas react-script is an npm package with dependencies a react-based project may need to quickly start a project like babel, and webpack in the list of react-script dependencies.
Is React overkill for small apps? ›Using React can be overkill if the requirements are too simplistic. For example, you need to make a few pages with no dynamic elements or customization. In cases like these, it might suffice to use simple HTML and a bit of JavaScript.
Why React is not SEO friendly? ›React gives you a SPA (Single Page Application) which requires Javascript to show the content on the page. The problem is that the Google crawl bot, that scans all the pages on the internet, isn't as good as understanding a page with javascript compared with a page that consists of regular HTML-code.
What is the best backend for React app? ›js is the best backend with React, as you can use it to create microservices and query builders to solve all database queries. The combination of React for the front end and Node for the back end is perfect for developing a web application that will handle multiple simultaneous requests.
Should I use webpack for small projects? ›Should I Use Webpack? If you're building a complex Front End™ application with many non-code static assets such as CSS, images, fonts, etc, then yes, Webpack will give you great benefits.
Should I learn webpack before React? ›You don't have to go that route. Your focus, first and foremost, should be on nailing that React thing. Forget about everything else — Webpack, Redux, and a bazillion of other fancy stuff. You'll get to these when the time comes.
What is Babel used for in React? ›Babel is a very famous transpiler that basically allows us to use future JavaScript in today's browsers. In simple words, it can convert the latest version of JavaScript code into the one that the browser understands.
What is the difference between JSX and Babel? ›
Babel : Babel is a JavaScript compiler that transform the latest JavaScript features, which are not understandable to every browser, into a backward compatible version of JavaScript in current and older browsers or environments. JSX : JSX is a syntactical extension to JavaScript.
Can you build an app with only React? ›It is efficient, flexible, and intuitive. As a result, React has become massively popular among developers worldwide. It supports the responsive layout for all modern devices, including smartphones, laptops, and desktops. Therefore, you can create your mobile app using React JS.
Can I get a job only with React? ›React is a JavaScript library, so you need to have the other fundamentals of front-end development, such as HTML, CSS, and JavaScript. Once you do, though, there are plenty of opportunities to put that skill set to use in the jobs market, even if you've never had a programming job before.
Can a beginner learn React without knowing JavaScript? ›You don't need to be a JavaScript expert to start your ReactJS journey, but just as knowledge of ingredients is a must for any chef hoping to master cooking, the same is true for learning ReactJS.
Do we still need Babel? ›In conclusion, Babel is not required for small projects which do not require older browser support or if the developer does not use Javascript syntax introduced after ES5.
Should I use Babel with Node? ›If you've been active as a Node. js developer, or even dabbled in front-end libraries like React or Vue. js, then there's no doubt that you've likely run across Babel.
Why is Babel necessary? ›What is Babel and what problem does it solve? Babel is a compiler that converts your modern JavaScript to run in older browsers. It can also perform other jobs such as converting JSX syntax, but it is not the only tool for that. As browsers evolve, new APIs and ECMAScript features are added.
Is webpack necessary for React? ›Well, we don't necessarily need webpack to work with React, other alternatives could be Browserify, Parsel, Brunch, etc, but honestly, I don't know how well they fit in with React. js. Webpack is the most widely used and an accepted module bundler and task runner throughout React. js community.
Do we need Babel with webpack? ›We need webpack to bundle our code and webpack-cli is a command-line tool that uses webpack to do the same. Also webpack requires babel-loader to transpile our ES6 code to ES5 before bundling (Remember, what I said about being responsible developers 😃).
Can I use Babel without webpack? ›If you just want to get started on React real quick and you don't mind using require or import in your code, then babel could be enough to jump start your React project. Say for example that all your javascript files are in the ./src folder, you can bundle them into one file with this command.
Should I use webpack or create React app? ›
Create react app abstracts the configuration does not allow you change it unless you eject. Using webpack does require knowledge of webpack and does allow complete control over your environment.
Is there something better than webpack? ›We've looked at three powerful alternatives for your JavaScript workflow: Vite, Parcel and Esbuild. All of these tools can provide big improvements over Webpack to your JavaScript development flow. If you haven't updated your JavaScript tooling for a while, now is a great time to do so!
Is Webpack really necessary? ›Should I Use Webpack? If you're building a complex Front End™ application with many non-code static assets such as CSS, images, fonts, etc, then yes, Webpack will give you great benefits.