Setting up React Project with out using create-react-app

neotam Avatar

Setting Up React Project without create-react-app3
Posted on :

Tags :

The “Create react app” helps you avoid boilerplate code. But, to create react app by yourself manually will help you understand the how different compoents work together

Steps we take in create the react app are,

  • Install the Node and NPM
  • Create the NPM Project
  • Install: react, babel and webpack
  • Configure the webpack

Install Node and NPM

Download and install the latest node for appropriate platform from Download Node.

You can verify if node succesfully installed using command “node -v”

Creating Project

To create the npm project run the following command

npm init

You will be prompted to enter information, follow through. But, make sure you are in the project root directory when you run the command “npm init”. The command “npm init” will create the file named “package.json”

Install Dependencies

Let’s install the dependencies. Start with installing the react

npm i -S react react-dom

Install the webpack, which is responsible for bundeling and creating a build to deploy on server or production

npm install --save-dev webpack

To use webpack as command line application you will need “webpack-cli”

npm install --save-dev webpack-cli

Install the webpack-dev-server to help your development with live reloading

npm install --save-dev webpack-dev-server

Finally, you need to install the Babel. Babel is the JavaScript Transpiler and compiler, by using Babel you can use tomorrow javascript standards today even before they are mainstream. Let’s install babel and babel cli, where @babel/cli required to use babel from commandline

npm install --save-dev @babel/core @babel/cli

Babel comes with CLI which can be used to compile or transpile the javascript source files from command line.

We need to tell Babel what are sources files and rules to traspile the source into and by using which syntax. To do so, we can configuration files. Naming of configuration files is as follows

  • Project-wide configuration
    • babel.config.* files, with the following extensions: .json.js.cjs.mjs.cts.
  • File-relative configuration
    • .babelrc.* files, with the following extensions: .json.js.cjs.mjs.cts.
    • .babelrc file, with no extension.
    • package.json files, with a "babel" key.

Now we need to babel presets for react to help babel understand the JSX and ES2015+

npm install --save-dev @babel/preset-env

The preset ” @babel/preset-env” is the smart preset which enables you to use the latest javascript with out micromanaging the the version and syntax

Now install the most important preset to work with react JSX

npm install --save-dev @babel/preset-react

To make use of these presets, configure the “babel.config.json”

{
  "presets": ["@babel/preset-react", "@babel/preset-env"]
}

And to let webpack use the bable, we need to install the babel-loader.

npm i --save-dev babel-loader

Loaders are transformations that are applied to the source code of a module. They allow you to pre-process files as you import or “load” them

To help wepack put together the html files with bundled javascript, install the following plugin

npm i -S html-webpack-plugin

Sample React App Coding

Create a folder named public with “index.html” inside

Lets create the App.js inside the src file of project root directory and then import it inside the “index.js”

import React, { useState } from "react";


function FavSport() {
  const [sport, setSport] = useState("cricket");

  return (
    <>
      <h1>My Most favorite Sport:  <em>{sport}!</em> </h1>
      <button type="button"  onClick={() => setSport("Cricket")}>Cricket</button>
      <button type="button"  onClick={() => setSport("Fifa")} >Fifa</button>
      <button type="button"  onClick={() => setSport("Tennis")} >Tennis</button>
      <button type="button"  onClick={() => setSport("Boxing")} >Boxing</button>
      <button type="button"  onClick={() => setSport("Chess")} >Chess</button>

    </>
  );
}


const App = () =>  {
   return (
         <main> 
             <FavSport />
         </main> 
 )
}

export default App; 

Following is the index.js, in which we will import the above App.js

import ReactDOM from "react-dom/client";
import App from "./src/App"; 

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);

Configuring Webpack

Finally, we need to create and configure webpack. Start by creating file named “webpack.config.js” within the project root directory.

Here is sample , minimal configuration of webpack, which just takes care of creating dist

const path = require('path');

module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'main.js',
    path: path.resolve(__dirname, 'dist'),
  },
};

Here is the samle webpack.config.js with configured webpack-dev-server and build configuration

const HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path');

module.exports = {
  entry: './index.js',

  /** "mode"
     * the environment - development, production, none. tells webpack 
     * to use its built-in optimizations accordingly. default is production 
     */
  mode: 'development',
  output: {
    path: path.resolve(__dirname, './dist'),
    filename: 'bundle.js',
  },
  target: 'web',

  devServer: {
    port: '5059',
    static: {
      directory: path.join(__dirname, 'public')
    },
    open: true,
    hot: true,    // To enable HMR(Hot Module Replacement) to reload modules only without page refresh
    liveReload: true,   
  },

  resolve: {
    extensions: ['.js', '.jsx', '.json'],
  },

  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        exclude: /node_modules/,
        use: 'babel-loader',
      },
    ],
  },

  plugins: [

    // To inject the bundled js into html, if specified template html is used otherwise html file will be created
    new HtmlWebpackPlugin({
      template: path.join(__dirname, 'public', 'index.html')
    })
  ]
};

You can also use the VSCode extension webpack to help you assist in creating webpack configuration and startup templates

Let’s make sense of the above webpack configuration.

entry: './index.js',

  mode: 'development',
  output: {
    path: path.resolve(__dirname, './dist'),
    filename: 'bundle.js',
  },

We are telling the webpack to consider index.js as entry point to determine all dependencies and import. Then, apply rules according to to modules.rules to produce the output in a single file name bundle.js and place it dist folder

module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        exclude: /node_modules/,
        use: 'babel-loader',
      },
    ],
  },

modules provies the rules to resolve the .js and .jsx files by extension according to the regular expression provided in test property. For each resolved file, check if require() or import statements are used inside the script if so, use the babel-loader to transpile it before added into the bundle. Where, exclude prohibits the webpack from touching the node_modules directory

Running and Building

To run webpack when you execute command like “npm start” or “npm run build”. Configure the scripts property inside the package.json

 "scripts": {
    "start": "webpack-dev-server .",
    "build": "Webpack",
    "test": "test"
  },

To run the development server, run the command

npm start 

To create the build to deploy on server

npm run build 

Source Code

Here is the source code for this tutorial

Troubleshooting

Make sure React is imported in the index.js and App.js for build to be created properly. Otherwise, you might get an error “

Uncaught ReferenceError: React is not defined

Leave a Reply

Your email address will not be published. Required fields are marked *