handmade react
Tags: react, bundler, javascript, html
Published: 2020-08-04 07:51:49

In my mind react is a simple glue for create basic or complex application. The reactive state handling philosophy give power of really fast development, plus I can use any modern js solution, like arrow function, decoupling, rest operator, or even my favourite proposal __pipeline__ __operator__. But this article speak about handmade build system for react or even plain static HTML page.

### 1) *Instant save*
The crazy old development method is create local webserver and save your files, refresh the browser. 

```js
// pro
 - immediately result
 - true handmade way, you control everything
 - free from node_modules blackhole
// const
 - each 'build' need a restart
 - endless challenge: 'you vs. browsers'
 - hard to handle outer dependencies
 - straight to spaghetti code
``` 

CLI is your friend, so this is the most basic development method: (under windows [gitbash](https://gitforwindows.org/))
```bash
mkdir foo
cd foo
serve ./
# another terminal:
nano index.html
```

### 2) *Don't fight with build system: development online*
This way is great for learning any programming languages without know the selected language build system, for example: [rust playground](https://play.rust-lang.org/)

```js
// pro
 - zero start time
 - learn any programming languages
 - share you example
 - take look, try, fork other developers 'solutions'
// const
 - your code is public
 - mandatory use online IDE
 - hard to debug
 - different asset handling
 - don't fine for product ready code
``` 

### 3.1) *Handmade :: [parcel](https://parceljs.org/)*
Why I call this method handmade? Because this one is easy to learn from scratch. Just one line need to know for HTML/javascript: 
```bash
yarn add -D parcel-bundler
```

#### write our codes after create src folder:
> ./src/index.html
```html
<!DOCTYPE>
<html>
  <head><title>foo js app</title></head>
  <body>
   <script src="./index.js"></script>
  </body>
</html>
```
> ./src/index.js - any code
```javascript
window.onload = () => document.body.innerHTML="foo js app";
```

#### final touch: start your development
```bash
yarn parcel './src/index.html';
```

At this moment check your result: localhost:1234. When you edit your code, that is instant rebuilding and browser refreshing. 

### 3.2) *add Framework* :: [React](https://reactjs.org/)
One step further you can add react (or any other framework)
```bash
yarn add react react-dom
```

#### write some react code
>./src/index.js
```jsx
import React from 'react';
import {render} from 'react-dom';

const title = 'Foo application';

render(
  <pre>{title}<br/>{'-'.repeat(title.length)}</pre>
  , document.getElementById('foo')
);
```

> Start development same way as HTML
```bash
yarn parcel './src/index.html';
```
At this moment you can handle your own building setup without too much worry. Of course you have few todo left to product ready program into some repo, but that is another post.

```js
// pro
 - easy to use development setup
 - IDE independent
 - hot reload
 - blazing fast
 - work with plain HTML, react or any framework
 - automatic dependency install: css, scss, typescript, 
   glsl and much more without config.
// const
 - slightly hard to output PWA vs rollup or webpack
 - complex company build system choice: configurable bundlers 
``` 

#### add style
> ./src/dark-green.scss
```scss
body, html {
  background: black;
}
pre {
  color: rgb(47, 160, 47);
  font-size: 1.2em;
}
```

You can insert style into js code
> ./src/index.js 
```
import 'dark-green.scss';
```

This moment parcel bundler working to add dependency for scss

#### What going behind the scene?
Improve our react program, show our code:
```jsx
import React, {useState, useEffect} from 'react';
import {render} from 'react-dom';
import './dark-green.scss';

const FooApp = () => {
  const [myCode, readCode] = useState('');

  useEffect(() => {
    fetch('')
      .then( result => result.text() )
      .then( readCode )
  }, []);

  return <pre>{myCode}</pre>;
}

render(<FooApp />, document.getElementById('foo'));
```

> result ::
```HTML
<!DOCTYPE html>
<head>
  <title>foo< app/title>
</title><link rel="stylesheet" href="/src.e31bb0bc.css"></head>
<body>
  <div id="foo"></div>
  <script src="/src.e31bb0bc.js"></script>
</body>
```

Generated code in :: src.e31bb0bc.js, few line later:
```jsx
const readText = result => result.text();

const FooApp = () => {
  const [codeOfIndexJs, readCode] = useState('');

  useEffect(() => {
    fetch('')
      .then( readText )
      .then( txt =>  txt.match(/src="(.*)"/)[1] )
      .then( script => fetch(script) )
      .then( readText )
      .then( readCode )
  }, []);

  return <pre>{codeOfIndexJs}</pre>;
}
```

get the result. Don't afraid that is only development time generated code, if you would like see the minified builded one, then run build:
```bash
yarn parcel build ./src/index.html
serve ./dist
```

### 3.3) preparing TODO, touch the package.json
Before use yarn won't forget install [node.js](https://nodejs.org/en/) and [yarn](https://yarnpkg.com/). Create project directory.




#### time to insert few script to package.json
```bash
cat package.json
```

> result :: ```json
{
  "devDependencies": {
    "parcel-bundler": "^1.12.4",
  },
  "dependencies": {
    "react": "^16.13.1",
    "react-dom": "^16.13.1"
  }
}
```

Insert starting point helper:
```json
  "scripts": {
    "start": "parcel ./src/index.html",
    "build": "parcel build ./src/index.html",
  },
```

then you be fine:
```
yarn start
```

Thanks for reading! 
[photo: Robert Bye - unsplash](https://unsplash.com/@robertbye)