DEV Community

Alex Adam
Alex Adam

Posted on • Edited on • Originally published at alexadam.dev

3

Create a React project from scratch, with TypeScript and Webpack

A step by step guide on how to create a React project from scratch, with TypeScript and Webpack 5.

You can find the full source code here: https://github.com/alexadam/project-templates/tree/master/projects/react-app

Setup

Prerequisites:

  • node
  • yarn

Create the project's folder:

mkdir react-app
cd react-app
Enter fullscreen mode Exit fullscreen mode

Generate a default package.json file with yarn:

yarn init -y
Enter fullscreen mode Exit fullscreen mode

Install React, TypeScript and Webpack:

yarn add react react-dom

yarn add --dev @types/react \
        @types/react-dom \
        awesome-typescript-loader \
        css-loader \
        html-webpack-plugin \
        node-sass \
        sass-loader \
        style-loader \
        typescript \
        webpack \
        webpack-cli \
        webpack-dev-server
Enter fullscreen mode Exit fullscreen mode

Add build, dev & clean scripts in the package.json file:

 ....
  },
  "scripts": {
    "clean": "rm -rf dist/*",
    "build": "webpack",
    "dev": "webpack serve"
  }
Enter fullscreen mode Exit fullscreen mode

Configure TypeScript by creating the file tsconfig.json with:

{
  "compilerOptions": {
    "incremental": true,
    "target": "es5",
    "module": "commonjs",
    "lib": ["dom", "dom.iterable", "es6"],
    "allowJs": true,
    "jsx": "react",
    "sourceMap": true,
    "outDir": "./dist/",
    "rootDir": ".",
    "removeComments": true,
    "strict": true,
    "moduleResolution": "node",            
    "allowSyntheticDefaultImports": true,
    "esModuleInterop": true,
    "experimentalDecorators": true
  },
  "include": [
    "client"
  ],
  "exclude": [
    "node_modules",
    "build",
    "dist"
  ]
}
Enter fullscreen mode Exit fullscreen mode

To configure Webpack, make a file webpack.config.js containing:

const path = require("path");

const app_dir = __dirname + '/client';

const HtmlWebpackPlugin = require('html-webpack-plugin');
const HTMLWebpackPluginConfig = new HtmlWebpackPlugin({
  template: app_dir + '/index.html',
  filename: 'index.html',
  inject: 'body'
});

const config = {
  mode: 'development',
  entry: app_dir + '/app.tsx',
  output: {
    path: __dirname + '/dist',
    filename: 'app.js',
    publicPath: '/'
  },
  module: {
    rules: [{
        test: /\.s?css$/,
        use: [
          'style-loader',
          'css-loader',
          'sass-loader'
        ]
      }, {
        test: /\.tsx?$/,
        loader: "awesome-typescript-loader",
        exclude: /(node_modules|bower_components)/
      },
      {
        test: /\.(woff|woff2|ttf|eot)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
        exclude: [/node_modules/],
        loader: "file-loader"
      },
      {
        test: /\.(jpe?g|png|gif|svg)$/i,
        exclude: [/node_modules/],
        loader: "file-loader"
      },
      {
        test: /\.(pdf)$/i,
        exclude: [/node_modules/],
        loader: "file-loader",
        options: {
          name: '[name].[ext]',
        },
      },
    ]
  },
  plugins: [HTMLWebpackPluginConfig],
  resolve: {
    extensions: [".ts", ".tsx", ".js", ".jsx"]
  },
  optimization: {
    removeAvailableModules: false,
    removeEmptyChunks: false,
    splitChunks: false,
  },
  devServer: {
    port: 8080,
    // open: true,
    hot: true,
    inline: true,
    historyApiFallback: true,
  },
};
module.exports = config;
Enter fullscreen mode Exit fullscreen mode

Example App

Create a folder named client (in the project's folder):

mkdir client
cd client
Enter fullscreen mode Exit fullscreen mode

Make a simple React component, in the file numbers.tsx:

import React, {useState} from 'react';

interface INumberProps {
  initValue: number
}

const Numbers = (props: INumberProps) => {
  const [value, setValue] = useState(props.initValue)

  const onIncrement = () => {
    setValue(value + 1)
  }

  const onDecrement = () => {
    setValue(value - 1)
  }

  return (
    <div>
      Number is {value}
        <div>
          <button onClick={onIncrement}>+</button>
          <button onClick={onDecrement}>-</button>
        </div>
    </div>
  )
}
export default Numbers
Enter fullscreen mode Exit fullscreen mode

Create the main React component (the entry point), in the file app.tsx:

import * as React from 'react';
import * as ReactDOM from 'react-dom';
import Numbers from './numbers';

ReactDOM.render(
    <Numbers initValue={42} />,
    document.getElementById('app') as HTMLElement
  );
Enter fullscreen mode Exit fullscreen mode

Next, add the index.html:

<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>React TypeScript</title>
</head>

<body>
  <div id="app"></div>
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

Then, run yarn dev and open http://localhost:8080/ in a browser.

Use this project as a template

You can save the Setup steps as a shell script:

#!/bin/sh

rm -rf node_modules
rm package.json

yarn init --yes

yarn add react react-dom

yarn add --dev @types/react \
        @types/react-dom \
        awesome-typescript-loader \
        css-loader \
        html-webpack-plugin \
        node-sass \
        sass-loader \
        style-loader \
        typescript \
        webpack \
        webpack-cli \
        webpack-dev-server

# Remove the last line
sed -i.bak '$ d' package.json && rm package.json.bak

# append the scripts commads
cat <<EOT >> package.json
   ,"scripts": {
      "clean": "rm -rf dist/*",
      "build": "webpack",
      "dev": "webpack serve"
   }
}
Enter fullscreen mode Exit fullscreen mode

Delete the node-modules folder and, when you want to start a new project, you can copy the contents of react-app to the new location:

mkdir new-project
cd new-project

# copy the react-app folder content to the new project
rsync -rtv /path/to/../react-app/ .

./init.sh
Enter fullscreen mode Exit fullscreen mode

Heroku

Build apps, not infrastructure.

Dealing with servers, hardware, and infrastructure can take up your valuable time. Discover the benefits of Heroku, the PaaS of choice for developers since 2007.

Visit Site

Top comments (0)

SurveyJS custom survey software

JavaScript Form Builder UI Component

Generate dynamic JSON-driven forms directly in your JavaScript app (Angular, React, Vue.js, jQuery) with a fully customizable drag-and-drop form builder. Easily integrate with any backend system and retain full ownership over your data, with no user or form submission limits.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay