This article is part of a two part series on how to configure a React app from scratch with Webpack and Babel and eventually add TypeScript to it. To read the first article in this series, click on the below link.
So you stumbled upon TypeScript and loved how you will be able to add type safety along with a whole bunch of other things that it has to offer. So, let's modify last week's app and add TypeScript to it. In case you haven't read last week's article on how to setup a react app with webpack and babel, feel free to go through the below link and setup a basic react app to which we can add TypeScript.
To get the starter code click on this below link.
Link to the GitHub repo: react-with-webpack
Let's start with the required steps now.
-
Install the following packages typescript,
@types/react and @types/react-dom using the following command.You can also replace the --save-dev with a more subtle -D to install any package as a dev dependency.
npm install typescript npm install @types/react @types/react-dom --save-dev
**@types/react:** contains type definations for React.
**@types/react-dom:** contains type definations for React DOM.
2. We will need to let Babel know that we are including typescript in the project. So, let's go ahead and install the package **@babel/preset-typescript** as a dev dependency.
```
npm install @babel/preset-typescript --save-dev
-
Now we have a mean to let Babel know of the typescript files that we will be using. But we still need to load these files with webpack, right? For that we need another package named as ts-loader.
npm install -D ts-loader
Your **package.json** file should look something like this.
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1614875520420/ugOzSsHPE.png" alt="package.json" />
4. We have all the required packages now. It's time to make some changes in our *webpack.config.js* and *.babelrc* file.
Replace the below code with the one present in your **.babelrc** file.
```
{
"presets": [
"@babel/env",
"@babel/react",
"@babel/preset-typescript"
],
"plugins": [
"@babel/plugin-proposal-class-properties"
]
}
As you can see, we are adding a new preset which is the *@babel/preset-typescript* to our already existing set of presets.
Time to make changes to our **webpack.config.js** file now. Copy the below code and replace the existing code which is present in the file.
```
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
entry: "./src/index.tsx",
output: { path: path.join(__dirname, "build"), filename: "index.bundle.js" },
mode: process.env.NODE_ENV || "development",
resolve: {
extensions: [".tsx", ".ts", ".js"],
},
devServer: { contentBase: path.join(__dirname, "src") },
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: ["babel-loader"],
},
{
test: /\.(ts|tsx)$/,
exclude: /node_modules/,
use: ["ts-loader"],
},
{
test: /\.(css|scss)$/,
use: ["style-loader", "css-loader"],
},
{
test: /\.(jpg|jpeg|png|gif|mp3|svg)$/,
use: ["file-loader"],
},
],
},
plugins: [
new HtmlWebpackPlugin({
template: path.join(__dirname, "src", "index.html"),
}),
],
};
5. Time to use TypeScript. But wait, we need something to specify that this directory is a TypeScript project, right! We also need to provide the compiler options in which our TypeScript files will be compiled. For that we will need a new file named as **tsconfig.json**.
Let's go ahead and create that file.
```
touch tsconfig.json
For now, remove the existing code from the **tsconfig.json** file and replace it with the below code.
```
{
"compilerOptions": {
"target": "es5",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noFallthroughCasesInSwitch": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": false,
"jsx": "react-jsx"
},
"include": [
"src"
]
}
Let's go over the attributes now.
**"target": "es5" =>** will compile es6 or above code to es5 so that it is compatible with browsers.
**"include": [src]" =>** specifies that only the files in the *src* folder should be included.
**"sourceMap": true =>** Generates corresponding ‘.map’ file so that it can be used in the production code for debugging.
**"strict": true =>** enables a wide range of type checking behavior that results in stronger guarantees of program correctness.
**"allowJs": true =>** allows JavaScript files to be imported inside your project, instead of just .ts and .tsx files.
To learn more about the various attributes used in the file visit this [link](https://www.typescriptlang.org/tsconfig).
6. Last but not the least, its time to rename our JavaScript files (**.js**) to TypeScript - React (**.tsx**).
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1614876953079/38HnYETS7.png" alt="react-with-typescript" />
*renamed index.js & App.js to index.tsx & App.tsx respectively*
7. Go ahead and run the below command to start the app.
```
npm run start
The app will be served at **http://localhost:8080**.
Well, you have successfully added TypeScript to your project. Go ahead and make use of its functionalities to build great webapps.
Have a great day. Thanks for reading the entire thing.
Here's the link to the Github Repo in case you have faced some issue during the entire process. Feel free to make some tweaks if you find something breaking because of updates to any of the packages.
Cover Photo by Cristina G
Top comments (14)
Thanks for the article.
I have implemented webpack and babel to our reactjs ts project. However, on development, I cannot see codes as in writed in ts. I see all changed.
And I cannot found the way keep codes same while developing.
Maybe you could help me with a sample component and what issue you are facing! Would be happy to help you with that.
One quick question, what is the point of using babel-loader if we are using Typescript and ts-loader / tsconfig for compiling?
You can keep only ts-loader for compiling. I added typescript on top of my webpack JS repo, so it already had the babel-loader, which I might have forgotten to remove at that time.
Thanks, that helped a lot!
Great Article - Thanks!
Thank you!!! Great article!
Thank you for your feedback! 😄
Don't
babel-loader
withts-loader
(remove this one!) upon babel 7! I hope this will save someone debugging in the future! ReferenceThat's not entirely true for real-time type checking. If
ts-loader
is removed, type-checking must be done usingtsc
or similar. Babel will not run type checks (devblogs.microsoft.com/typescript/...). So yes, Babel understands TypeScript in Babel 7 now, which is great. But if someone is using the webpack dev server as in this post, they may want type-checking to happen upon every recompile.In my experience, the easiest way to do that is to simply use both loaders in the rule, like this:
nice tutorial, thank you
Thanks 😁
Great article! Thank you
Thanks 😁