I've been looking for a way to create a new typescript react project from the scratch. I came across a few relevant articles and open source github projects that I thought I could use to get started but couldn't get them to work properly because they were outdated. I started on this journey to setup a new webpack project with typescript and react and wanted to share my journey with others.
Here's a link to the boiler plate code created using steps enlisted below:
🚀 Welcome to your new awesome project!
This project has been created using webpack-cli, you can now run
npm run build
or
yarn build
to bundle your application
Create new project root directory
% mkdir react-ts-webpack-template; cd react-ts-webpack-template
Install webpack-cli packages
% npm install -D webpack-cli
% npm install -D @webpack-cli/generators
Generate new webpack project
- Run webpack init command.
% npx webpack init
- Go through the webpack setup process.
You should see a list of options to be selected go ahead make the same selections.
- Folder structure created should look like this -
Note: typescript and ts-loader packages are automatically installed as part as part of the webpack init command.
- Check webpack project can be run and served without issues
% npm run build
% npm run serve
Web dev server should be launched as seen below
Install react packages
% npm install react react-dom
% npm install --save-dev @types/react @types/react-dom
Setup Babel
- install babel packages using npm
npm install --save-dev @babel/core @babel/preset-env @babel/preset-typescript @babel/cli @babel/preset-react
- add a .babelrc file
{
"presets": [
"@babel/preset-env",
"@babel/preset-typescript",
"@babel/preset-react"
]
}
- add script below in package.json to enable command line invocation of babel.
"babel": "babel src --out-file dist/main.js --extensions .ts,.js,.tsx,.jsx,.cjs,.mjs --presets=@babel/preset-typescript,@babel/preset-env,@babel/preset-react"
- check babel setup works as expected
npm run babel
check for creation of dist/ directory with main.js which is the code that babel transpiled and webpack bundled it under main.js
Update tsconfig.json
{
"compilerOptions": {
"allowSyntheticDefaultImports": true,
"noImplicitAny": true,
"module": "es6",
"target": "es5",
"allowJs": true,
"jsx": "react-jsx", //tells ts compiler to compile react jsx
"moduleResolution": "node"
},
"include": ["src/**/*"],
"exclude": ["**/*.spec.ts"]
}
compilerOptions.jsx property when set to "react-jsx" lets typescript compiler know that it needs to handle react jsx code.
include and exclude tell the typescript compiler which files to include and exclude from compilation.
Update webpack config
Make the following changes to web pack
update the entry point to be "./src/index.tsx" instead of "./src/index.ts"
add rules for babel-loader and file-loaders
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: ["babel-loader"],
},
{
test: /\.(jpg|jpeg|png|gif|mp3|svg)$/,
use: ["file-loader"],
},
Create sample ts react component and related files required to be rendered into the index.html page
- create new files index.tsx, App.tsx and App.css in src/ dir
% touch src/index.tsx src/App.tsx src/App.css
- add the sample code below into App.tsx to create a new functional react component
import { FC } from "react";
interface MessageProps {
greeting: string;
user: string;
projectTitle: string;
}
const App: FC<MessageProps> = (props: MessageProps) => {
return (
<div className="app-id">
<h1 className="greeting-id">{props.greeting}</h1>
<h1 className="user-id">{props.user} </h1>
<h2 className="title-id">{props.projectTitle}</h2>
</div>
);
};
export default App;
- update index.html to add inside the body tag. this refers to the node where we will be injecting and rendering the new react component App.
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<title>Welcome to React TypeScript Project Boilerplate</title>
</head>
<body>
<!-- This is the DOM node -->
<div id="root"></div>
</body>
</html>
-
make following updates to index.tsx.
- import the sample react component defined in App.jsx
- get a reference to the browser DOM node(div tag with root id) from index.html
- call createRoot pass in reference to browser DOM node that will serve as the root for rendering react components.
- invoke render method of root object created passing in JSX markup where we use the imported sample App component.
import { createRoot } from "react-dom/client";
import "./App.css";
import App from "./App";
import React from "react";
const root = createRoot(document.getElementById("root"));
root.render(
<App
greeting={"Hello"}
user={"Swetha"}
projectTitle={
"Welcome to the journey of setting up your own typescript react project from scratch"
}
/>
);
- update App.css with simple rules
h1.user-id,
h1.greeting-id {
color: red;
display: inline-block;
margin-right: 15px;
}
h2.title-id {
background-color: aqua;
}
- Run npm build and serve
% npm run build
% npm run serve
Top comments (0)