DEV Community

Ravi Ojha
Ravi Ojha

Posted on • Edited on

Setting up React Project from Scratch

create-react-app is great tool to get started with react, it gives us everything we need initially for react learning, hacking some things together or even starting a new project.

But some times we do need to know what is going on behind the scene and most importantly what are all the libraries or tools that are being used under the table.

We will try to understand different tools involved to get up and running with react from scratch. We don't have to remember everything, it just gives us a feeling of knowing that makes us more confident.

So, Let's get started

First: Create project folder

Create a project directory, it can be anywhere we want. I personally like to keep everything in one place, for me it's ~/repos/....

mkdir react-from-scratch && cd $_
Enter fullscreen mode Exit fullscreen mode

Next: Initialize project with npm

npm init -y
Enter fullscreen mode Exit fullscreen mode
  • -y flag to create default package.json, If we don't provide this flag with npm init then it will open up a CLI questionnaire. We can read more about this here

Now we have a directory to hold code for our project.

Next: Install React and React-DOM

  • react: This only contains the functionality necessary to define React components. We can find more on this here
  • react-dom: This serves as the entry point to the DOM. We can find more on this here

Lets get them installed now:

npm install react react-dom -S
Enter fullscreen mode Exit fullscreen mode
  • -S (alternate as --save) to save it as dependencies. we don't need to provide this flag it's there by default. But it's good to know that it's there.

Next: Install babel and required plugins

Babel lets us try and use new JavaScript features (ES2015+). So Babel is basically JavaScript transpiler which enables us to write new/modern JavaScript that will be transpiled/converted into backwards compatibility version of JavaScript or widely supported ES5 JavaScript.

We usually customize Babel with preset, preset is a set of plugins used to support particular language. For us we will be using react-preset

We will also need to install babel core (@babel/core) which has the core functionality of Babel.

Lets get them installed now:

npm i -D @babel/preset-react @babel/core
Enter fullscreen mode Exit fullscreen mode
  • -D (alternate as --save-dev) to save it as dev dependencies.

NOTE: Do have a look at @babel/preset-env which allows us to use the latest JavaScript without needing to micromanage which syntax transforms are needed by our target environment(s). But for this demo we are not specifically targeting any environments, we should be good to proceed, and we don't need to install it. We can read more here

Next: Install Babel Loader

This allows transpiling JavaScript files using Babel and later webpack will be using it to transpile Modern JavaScript into the JavaScript code that browsers can understand.

npm i -D babel-loader
Enter fullscreen mode Exit fullscreen mode

Next: Configure Babel

In root folder of our directory, create a file called .babelrc and add the below content to it. Here we are basically telling Babel to use this configuration while transpiling.

{
  "presets":[
    "@babel/preset-react"
  ]
}
Enter fullscreen mode Exit fullscreen mode

Next: Install Webpack, Webpack cli (the tool used to run webpack on the command line) and Webpack Dev Server

  • webpack: It is JavaScript Module bundler. We can read more here
  • webpack-cli: is required to run the project from the terminal.
  • webpack-dev-server: This will be use to serve our content.

Lets get them installed now:

npm i -D webpack webpack-cli webpack-dev-server
Enter fullscreen mode Exit fullscreen mode

Next: Install HtmlWebpackPlugin

It simplifies creation of HTML files to serve our webpack bundles. We can either let the plugin generate an HTML file for us or supply our own template.

The plugin will generate an HTML5 file for us that includes all our webpack bundles in the body using script tags. We can read more about this here

npm i -D html-webpack-plugin
Enter fullscreen mode Exit fullscreen mode

Now, we still need to create webpack.config.js for webpack configuration. But to understand it more clearly first we will write our component and get our html out.

As of now, Our project's folder structure should look like this:

.
├── node_modules
├── package.json
├── .babelrc
Enter fullscreen mode Exit fullscreen mode

And, package.json should look like this:

{
  "name": "react-from-scratch",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1",
  },
  "keywords": [],
  "author": "Ravi Ojha",
  "license": "ISC",
  "dependencies": {
    "react": "^16.13.1",
    "react-dom": "^16.13.1"
  },
  "devDependencies": {
    "@babel/core": "^7.10.1",
    "@babel/preset-react": "^7.10.1",
    "babel-loader": "^8.1.0",
    "html-webpack-plugin": "^4.3.0",
    "webpack": "^4.43.0",
    "webpack-cli": "^3.3.11",
    "webpack-dev-server": "^3.11.0"
  }
}
Enter fullscreen mode Exit fullscreen mode

Next: Create Directory and Files for Project

In root of project folder create couple of files add the contents as given below:

mkdir src && cd $_
touch index.js App.js index.html
Enter fullscreen mode Exit fullscreen mode

Index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>React App From Scratch</title>
</head>
<body>
  <div id="root"></div>
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

Note:

  1. We don't have any <script> added into html, this html will be used later as a template for HtmlWebpackPlugin in webpack.config.js.
  2. We have div#root in out html, this is where react-dom will inject or attach our root level component.

App.js

import React from 'react';

const App = () => {
  return (
    <div>
      Hello!! This is React Session from Scratch
    </div>
  );
};

export default App;
Enter fullscreen mode Exit fullscreen mode

Note: This is App Component that will be Inserted into DOM

index.js

import React from 'react';
/**
  As suggested in comment the above line was missing,
  -- Thanks Ross.
*/
import ReactDOM from 'react-dom';
import App from './App';

ReactDOM.render(<APP/>, document.getElementById("root"))
Enter fullscreen mode Exit fullscreen mode

Note:

  1. Notice we are referring div#root to attach our Root Component.
  2. This will be our entry point for our application, same will be added in webpack.conf.js later.

Now, Lets take a pause and look at our project folder structure, it should be similar to this:

.
├── node_modules
├── src
        ├── App.js
        ├── index.html
        ├── index.js
├── package.json
├── .babelrc
Enter fullscreen mode Exit fullscreen mode

Note: Now lets create the webpack.config.js file.

Next: Create Webpack Configuration file

In root of our project create a file called webpack.config.js and add the below content to it:

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

module.exports = {
  entry: './src/index.js',
  output: {
    path: path.resolve(__dirname, '/dist'),
    filename: 'bundle.js',
  },
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        exclude: /node_modules/,
        use: 'babel-loader',
      },
    ],
  },
  plugins: [
    new HtmlWebpackPlugin({ template: './src/index.html' }),
  ],
};
Enter fullscreen mode Exit fullscreen mode
  • entry: An entry point indicates which module webpack should use to begin building out its internal dependency graph. For us it is src/index.js
  • output: The output property tells webpack where to emit the bundle file it creates and how to name these files.
  • module:rules[...]:use: We are specifying which loader to use to transpile our code. For us it will be babel-loader.
  • plugin: We will see multiple plugins to do multiple thing, here we have only used the html-webpack-plugin to generate our final html to be served.

Note: We are using the index.html we created earlier as a template, in here output:filename will be inserted as <script> tag in our final html to be served.

Next: Add script in package.json

Add the below content in script section in package.json like below:

"scripts": {
    "start:dev": "webpack server"
  },

/**
  As pointed in comment, With latest Webpack It has to be
  * "webpack server"
  Rather than just
  * "webpack-dev-server"
  -- Thanks Aakarshak
*/
Enter fullscreen mode Exit fullscreen mode

Next: Run the application

Run the below command from terminal

npm run start:dev
Enter fullscreen mode Exit fullscreen mode

Finally: This is what we will get!!

Alt Text

Alt Text

Alt Text

Happy Coding!! Thanks for reading.

Top comments (9)

Collapse
 
aakarshak profile image
Aakarshak Sthapak

Nice Post.
Just wanted to add the below code Will throw an error on Webpack v4.
"scripts": {
"start:dev": "webpack-dev-server"
},

you need to change it to:
"scripts": {
"start:dev": "webpack serve"
},

Collapse
 
raviojha profile image
Ravi Ojha

Corrected it Aakarshak.
Thanks a lot.

Collapse
 
raviojha profile image
Ravi Ojha

Thanks, Will check that.

Collapse
 
rossanodan profile image
Rossano D'Angelo • Edited

Hey man, amazing article!

I just noticed this error in the console (see below).
Error

Just add

import React from 'react;

at the top of your index.js file.

Collapse
 
raviojha profile image
Ravi Ojha

Hey Ross, Thanks for the tip
I have update the post.

Collapse
 
krishnakakade profile image
krishna kakade

Best way to create app and save time is
npx create-react-app example

Collapse
 
rossanodan profile image
Rossano D'Angelo

Yes but setting up a project from scratch allows you to understand what's inside the "box" :)

Collapse
 
krishnakakade profile image
krishna kakade

Best way to create app and save time is
npx create-react-app example

Collapse
 
ben profile image
Ben Halpern

Nice post