How to create a React App without create-react-app

How to create a React App without create-react-app

In this blog we will learn how to create React app , from scratch by using the HTML, CSS and JAVASCRIPT.

Here are some Prerequisites you should know about it :

  • npm : The package manager for Node.js. (They don't say what it stands for.) It also has all the packages in the front end scene. npm makes a command line tool, called npm as well. npm allows you to bring in code from the npm registry which is a bunch of open source modules that people have written so you can use them in your project.
  • Prettier : Prettier is a really fancy pretty printer. It takes the code you write, breaks it down into an abstract syntax tree (AST) which is just a representation of your code. It then takes that AST, throws away all of your code style you made and prints it back out using a predefined style.
  • EsLint: On top of Prettier which takes care of all the formatting, you may want to enforce some code styles which pertain more to usage: for example you may want to force people to never use with which is valid JS but ill advised to use. ESLint comes into play here. It will lint for this problems.
  • Parcel : Parcel is a great bundler for JavaScript projects. Parcel is an amazing tool with zero-config. It works with everything we want to do out of the box. Since this is a class on React and not build processes, this allows us to focus more on React.

So for a pretty minimal setup, you’d want to :

Initialize a folder

  • mkdir PetAdoptionApp
  • create "src" folder
  • create index.html
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <link rel="stylesheet" href="./style.css">
  <title>Adopt Me</title>
</head>

<body>
  <div id="root">not rendered</div>
  <script src="https://unpkg.com/react@17.0.2/umd/react.development.js"></script>
  <script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.development.js"></script>
    <script src="./App.js"></script>
</body>

</html>
  • In script tag first, we have the React library. This library provides the interface for interacting with React; all methods (except one) will be accessed through it. The API doesn't render itself; it's just the API.
  • The second library is the rendering layer. React DOM is used since we're rendering to the browser.

As this is react , we won’t be focusing on the css Create a new file called src/style.css

* {
    box-sizing: border-box;
    color: #333;
  }

  body {
    background-color: #81a69b;
    background-image: url(http://pets-images.dev-apis.com/pets/wallpaperB.jpg);
    margin: 0;
    font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
  }

  .search-params {
    width: 1100px;
    margin: 0 auto;
  }

  .search-params form {
    border-radius: 6px;
    background: #faeff0;
    box-shadow: 0px 0px 12px #aaa, -0px -0px 12px #fff;
    width: 360px;
    margin: 0px 25px 0px 0px;
    padding: 35px 15px 15px 15px;
    float: left;
  }

  .search {
    border-radius: 6px;
    background: #faeff0;
    box-shadow: 0px 0px 12px #aaa, -0px -0px 12px #fff;
    width: 715px;
    padding: 15px;
    float: left;
    margin-bottom: 25px;
  }

  .details {
    width: 1100px;
    margin: 0 auto;
    padding: 15px;
    margin-bottom: 25px;
    border-radius: 6px;
    background: #faeff0;
    box-shadow: 0px 0px 12px #aaa, -0px -0px 12px #fff;
  }

  .pet {
    width: 100%;
    height: 130px;
    display: block;
    overflow: hidden;
    margin: 25px 0;
    border-bottom: #333 2px solid;
  }

  .pet img {
    width: 100px;
    min-height: 100px;
  }

  .info {
    float: left;
    width: 80%;
    height: 100px;
    padding-top: 10px;
    flex-direction: column;
    justify-content: space-around;
  }

  .image-container {
    clip-path: circle(50% at 50% 50%);
    width: 100px;
    height: 100px;
    float: left;
    margin: 0px 20px 0px 10px;
  }

  .pet h1 {
    white-space: nowrap;
    font-weight: normal;
    font-size: 30px;
    color: #333;
    width: 95%;
    overflow: hidden;
    margin: 0;
    text-overflow: ellipsis;
  }

  header > a,
  #root > div > h1 {
    display: inline-block;
    background-image: url(http://static.frontendmasters.com/resources/2019-05-02-complete-intro-react-v5/image-logo.png);
    filter: brightness(150%);
    width: 279px;
    height: 76px;
    overflow: hidden;
    text-indent: -9999px;
    margin: 20px 0;
  }

  .pet h2 {
    white-space: nowrap;
    font-weight: normal;
    font-size: 20px;
    margin: 0;
    text-overflow: ellipsis;
  }

  header a {
    color: #333;
    font-size: 3px;
    text-decoration: none;
    font-weight: bold;
    display: block;
    padding-bottom: 10px;
  }

  header {
    display: flex;
    align-content: center;
    justify-content: center;
    width: 1100px;
    margin: 0 auto;
    padding: 20px 0px 0px 0px;
  }

  .details p {
    line-height: 1.5;
    padding: 0px 15px;
  }

  .details h1 {
    text-align: center;
    color: #333;
    font-size: 60px;
    margin: 5px 0px;
  }

  .details h2 {
    text-align: center;
    margin: 5px 0px 20px 0px;
  }

  .carousel {
    display: flex;
    justify-content: space-around;
    align-items: center;
    height: 400px;
    margin-top: 8px;
  }

  .carousel > img {
    max-width: 45%;
    max-height: 400px;
  }

  .carousel-smaller {
    width: 50%;
  }

  .carousel-smaller > img {
    width: 100px;
    height: 100px;
    border-radius: 50%;
    display: inline-block;
    margin: 15px;
    cursor: pointer;
    border: 2px solid #333;
  }

  .carousel-smaller > img.active {
    border-color: #333;
    opacity: 0.6;
  }

  .search-params label {
    display: block;
    width: 60px;
  }

  .search-params input,
  .search-params select {
    margin-bottom: 30px;
    font-size: 18px;
    height: 30px;
    width: 325px;
  }

  .search-params button,
  #modal button,
  #modal a,
  .details button {
    background-color: #ad343e;
    padding: 5px 25px;
    color: white;
    font-size: 18px;
    border: #333 1px solid;
    border-radius: 5px;
    display: block;
    margin: 0 auto;
    cursor: pointer;
  }

  #modal a {
    display: inline-block;
    margin-right: 15px;
    text-decoration: none;
  }

  .search-params button:hover {
    background-color: #122622;
  }

  .search-params button:active {
    background-color: #5f1d22;
  }

  .search-params button:focus {
    border: 1px solid cornflowerblue;
  }

  #modal {
    background-color: rgba(0, 0, 0, 0.9);
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    top: 0;
    z-index: 10;
    display: flex;
    justify-content: center;
    align-items: center;
  }

  #modal:empty {
    display: none;
  }

  #modal > div {
    background-color: white;
    max-width: 500px;
    padding: 15px;
    text-align: center;
    border-radius: 30px;
    background: #faeff0;
  }

  #modal .buttons button {
    display: inline-block;
    margin-right: 15px;
  }

  @media only screen and (max-width: 1129px) {
    header {
      display: flex;
      align-content: center;
      justify-content: center;
      width: 95%;
      margin: 0 auto;
      padding: 20px 0px 0px 0px;
    }

    .search-params {
      width: 95%;
    }

    .search-params form {
      margin-bottom: 20px;
    }

    .search {
      width: 55%;
      padding: 15px;
      border-radius: 9px;
      float: left;
      margin-bottom: 25px;
    }

    .details {
      width: 95%;
      margin: 0 auto;
      padding: 15px;
      border-radius: 9px;
      margin-bottom: 25px;
    }

    .info {
      width: 65%;
    }

    .info h1 {
      width: 100%;
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
    }

    .info h2 {
      width: 100%;
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
    }
  }

  @media only screen and (max-width: 945px) {
    .search-params {
      width: 95%;
    }

    .search {
      width: 100%;
    }
  }

  @media only screen and (max-width: 600px) {
    .pet {
      height: 200px;
    }

    .info {
      width: 100%;
      text-align: center;
    }

    .image-container {
      margin: 0 auto;
      float: none;
    }
    .carousel-smaller > img {
      width: 60px;
      height: 60px;
    }
  }
  • Create a new file called src/App.js
    const App = () => {
    return React.createElement(
     "div",
     {},
     React.createElement("h1", {}, "Adopt Me!")
    );
    };
    ReactDOM.render(React.createElement(App), document.getElementById("root"));
    
    • React.createElement creates an instance of a component. DOM tags will be created with the string you pass as the argument. We used h1 and div, those tags are output to the DOM. If we put x-custom-date-picker, it'll output that (so web components are possible too.)

Now run the Live Server , you will see the output:

Adopt Me!

Now Add some code to App.js :

const Pet = (props) => {
  return React.createElement("div", {}, [
    React.createElement("h1", {}, props.name),
    React.createElement("h2", {}, props.animal),
    React.createElement("h2", {}, props.breed),
  ]);
};

const App = () => {
  return React.createElement("div", {}, [
    React.createElement("h1", {}, "Adopt Me!"),
    React.createElement(Pet, {
      name: "Luna",
      animal: "Dog",
      breed: "Havanese",
    }),
    React.createElement(Pet, {
      name: "Pepper",
      animal: "Bird",
      breed: "Cockatiel",
    }),
    React.createElement(Pet, { name: "Doink", animal: "Cat", breed: "Mix" }),
  ]);
};
ReactDOM.render(React.createElement(App), document.getElementById("root"));

To create a multiple Pets we have used the array in the third parameter of createElement . By using the props property , we have assigned name, animal and breed to Pet component.

Giving the argument in App component it is rendered through ReactDOM.render( React.createElement(App) , //…..)). Here is the result of it :

98.png

  • Go to the outermost folder, i.e. Parent folder of src , in the command line type run npm init -yat the root of your project.
  • Next step, type this command on terminal npm install -D prettier@2.5.1. The reason we type is that all developers does not have the same IDE. Unlike VS Code, it provides the extension for it along with we have to do some setup . That’s why now it will be going to get installed on your local machine now . In short term, it is Code formatter. There are some changes you need to do in package.json for using it using CLI command.
    "scripts": {
      "format": "prettier --write \"src/**/*.{js,jsx}\""
    }
    

So that our tool can know this is a Prettier project, we're going to create a file called .prettierrc and put {} in it. This lets everyone know this is a Prettier project that uses the default configuration.

Run command:

npm run format

You may want to enforce some code styles that are related to usage on top of Prettier, which takes care of all the formatting: for instance, you may want to prevent the use of the which is valid JS, but not recommended. ESLint comes into play here. It will lint for this problems.

First of all, run npm install -D eslint@8.8.0 eslint-config-prettier@8.3.0 to install ESLint in your project development dependencies.

Create this file called .eslintrc.json.

{
  "extends": ["eslint:recommended", "prettier"],
  "plugins": [],
  "parserOptions": {
    "ecmaVersion": 2022,
    "sourceType": "module",
    "ecmaFeatures": {
      "jsx": true
    }
  },
  "env": {
    "es6": true,
    "browser": true,
    "node": true
  }
}

Now in package.json type this, to get rid of errors

"scripts": {
    "format": "prettier --write \"src/**/*.{js,jsx}\"",
    "lint": "eslint \"src/**/*.{js,jsx}\" --quiet"
  },

In this blog, we are goin to use the Parcel, is a "Blazing fast, zero configuration web application bundler." Install Parcel by doing npm install -D parcel@2.2.1

Now inside of your package.json put:

"scripts" {
  "dev": "parcel src/index.html"
}

Now open http://localhost:1234. You should see your site come up.

As a starting point, we have given index.html. Following that, it finds the two React files and the App.js file that we linked to in index.html. Due to its smartness, it doesn't do anything with those two React files since they are remote, but it reads App.js and compiles its dependencies since it is local. We need to fix its lack of dependencies.

The first thing we need to do is fix the React and ReactDOM dependencies. Currently, these come from unpkg. Unpkg is not intended to handle production traffic, nor do we want the burden of loading all of our future dependencies this way. Believe me, it would get messy quickly and we'd have to make a million requests to get all of them by the end (we'll install more later as we go.) Instead, it'd be better if we could pull our dependencies down from npm and include it in our bundle. Let's do that now.

Run npm install react@17.0.2 react-dom@17.0.2. This will pull React and ReactDOM down from npm and put it in your node_modules directory. Now instead of loading them from unpkg, we can tell Parcel to include them in your main bundle. Let's do that now.

Replace the App.js import with <script type="module" src="./App.js"></script>.

In your package.json, add a new top level field called browserslist(notice the s, browserslist):

{
  …
  "browserslist": [
    "last 2 Chrome versions"
  ]
}

This is how you create React App from the scratch. Please let me know if there are any missing points in it. Thank You for reading the Blog !

Photo Cover by Lautaro Andreani on Unsplash