Categories
Programming

React App without create-react-app

When creating new react application, create-react-app is very handy command. Following commands can create and start a basic react app.

npx create-react-app my-app
cd my-app
npm start

Although simple, for a beginner it is difficult to understand what is running behind the scene. For getting better understanding of how our react app is working we can make it from scratch.

First create a new directory in your system using command:

mkdir myReactApp

Go to the ‘myReactApp‘ directory:

cd myReactApp

Create package.json file:

npm init -y

Now, install react and react-dom:

 npm install react react-dom

This adds react and react-dom under dependencies in package.json file and also it creates node_modules directory with all nested dependencies.

Create .gitignore file in ‘myReactApp’ to avoid pushing unnecessary code to git. Add node_modules/ and dist in .gitignore file.

node_modules/
dist

Next step is to create new ‘app‘ folder in ‘myReactApp’. Also create three files in ‘app’ folder index.js, index.html and index.css. Add following lines to each file.

<!DOCTYPE html>
<html>
    <head><title>
        my-app
    </title></head>
    <body>
        <div id="app"></div>
    </body>
</html>
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';

class App extends React.Component{
    render(){
        return(
            <div>Welcome to React World!</div>
        )
    }
}

ReactDOM.render(<App />, document.getElementById('app'))

In render method, this code is using JSX format. To show that correctly in browser, it needs to be transpiled to regular JavaScript. To address this, we need babel and webpack. To install these dependencies run following command.

Also notice that, these are not runtime dependencies, so we are using npm flag –save-dev.

npm install --save-dev @babel/core @babel/preset-env @babel/preset-react webpack webpack-cli babel-loader css-loader style-loader html-webpack-plugin

Next part is setting up Webpack. It bundles all JavaScript files and creates one bundle file. For webpack configuration create webpack.config.js file.

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

module.exports = {
    entry : './app/index.js',
    output : {
        path : path.resolve(__dirname , 'dist'),
        filename: 'index_bundle.js'
    },
    module : {
        rules : [
            {test : /\.(js)$/, use:'babel-loader'},
            {test : /\.css$/, use:['style-loader', 'css-loader']}
        ]
    },
    mode:'development',
    plugins : [
        new HtmlWebpackPlugin ({
            template : 'app/index.html'
        })
    ]

}

Now add babel and webpack to package.json file. This is complete package.json file after adding babel and script properties.

{
  "name": "myReactApp",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "babel": {
    "presets": [
      "@babel/preset-env",
      "@babel/preset-react"
    ]
  },
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "create": "webpack"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "react": "^16.13.1",
    "react-dom": "^16.13.1"
  },
  "devDependencies": {
    "@babel/core": "^7.12.3",
    "@babel/preset-env": "^7.12.1",
    "@babel/preset-react": "^7.12.1",
    "babel-loader": "^8.1.0",
    "css-loader": "^5.0.0",
    "htm": "^3.0.4",
    "html-webpack-plugin": "^4.5.0",
    "style-loader": "^2.0.0",
    "webpack": "^5.2.0",
    "webpack-cli": "^4.1.0"
  }
}

Following command runs the webpack and builds bundle in /dist.

npm run create

After generating the /dist, open ~/myReactApp/dist/index.html in browser. It should show the output message from App.js.

GitHub link: https://github.com/lochloch/myReactApp.