Minimal Webpack configuration to get React app
Tags: react
Published: 2019-10-27 13:54:24

In this post, I will show you my implementation of Webpack, express, and babel to get react app working.
First, we are going to download everything we need. Let's start.
```javascript
npm i @babel/cli @babel/core @babel/preset-env @babel/preset-react babel-loader express file-loader react react-dom webpack webpack-cli webpack-node-externals
```
and
```javascript
npm i --save-dev nodemon
```
Your dependencies should look like the next picture:
![react dependencies](https://thepracticaldev.s3.amazonaws.com/i/88avd3ipfhnb0w7zq915.png)
After that, we are good to go.
My project structure will be as follows:
![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/j3l7dt3ucyscdi7z0u8v.png)
As you see we have an `index.js` file for the `app` component, another one for the `client` folder and another one for the `server` folder. Also, we have `.babelrc`, `wpclient.config.js` and `wpserver.config.js`. And last but not least we have an `index.html` file in the `public` folder. 
Let's see all of these files and how they relate to each other. Also, we will have to see the `scripts` field in the `package.json` file.
Let's start for the `index.js` file in the `app` folder.
```javascript
import React from 'react'

export default
()=>
<div>hello</div>
```
As you see is a simple component in react. Now let's see the content of the `index.js` file in `client` folder.
```javascript
import React from 'react'
import {render} from 'react-dom'
import App from './comps/app/index'
import './public/index.html'

render
(
  <App/>,
  document.getElementById('app')
)
``` 
As you see it `import`s the `index.html` file, so let's see its content too.
```javascript
<!DOCTYPE html>
<html>
 <head>
   <title>my app</title>
 </head>
 <body>
   <div id='app'></div>
   <script src='./bundle.js'></script>
 </body>
</html>
```
As you see we place a `script` tag which references to a file `./bundle.js`. That's the file `webpack` will make as the result of the bundle process and that will be placed in the `dist` folder under `root` project folder.
Last `index.js` file we see is the one in the `server` folder.
```javascript
import express from 'express'

const app = express()
app.use(express.static('dist'))
const port=3000
app.listen(port,()=>console.log('listening on port '+port))
```
As you can see it uses the content under `dist` folder, which is where `webpack` puts its output by default.
It rests us to see the `webpack` configuration files. The first one is `wpclient.config.js`.
```javascript
export default
{
  entry: './src/client/index.js',
  output:
  {
    filename: './bundle.js'
  },
  module:
  {
    rules:
    [
      {
        use: 'babel-loader',
        test: /\.js$/,
        exclude: /node_modules/
      },
      {
        test: /\.(html)$/,
        use:
        {
          loader: 'file-loader',
          options:
          {
            name: './index.html',
          }
        }
      }
    ]
  }
}
```
Its entry point is `./src/client/index.js` which we already have seen. Its output is in `./bundle.js` which means in `dist` folder (`webpack` creates it if not exists). Then it uses `babel-loader` to deal with ES6 syntax. And last it uses `file-loader` to put `index.html` file into the `dist` folder too (together with the `bundle.js` file). It is for that reason we imported that file in the `index.js` file definition under `client` folder.
Now let's see the content of `wpserver.config.js` file.
```javascript
import nodeExternals from 'webpack-node-externals'

export default
{
  target: 'node',
  externals: [nodeExternals()],
  entry: './src/server/index.js',
  output:
  {
    filename: '../index.js'
  },
  module:
  {
    rules:
    [
      {
        use: 'babel-loader',
        test: /\.js$/,
        exclude: /node_modules/
      }
    ]
  }
}
```
As you see it uses `nodeExternals` to tell not to use `node_modules` folder. It targets `node` and the entry point is of course `./src/server/index.js` which we already have seen. The output `../index.js` is relative to the `dist` folder under the root project, so it will create an `index.js` file under the root directory as output. That's the file the scripts in `package.json` will execute (that is, `node` and `nodemon`).
So we have seen all the files, it only rests us see `.babelrc` configuration file. Let's do that now.
```javascript
{
  "presets":
  [
    "@babel/preset-env",
    "@babel/preset-react"
  ]
}
```
Now we are ready to go. This means we must prepare the scripts to execute all those files. We do that in `package.json`. Let's see how.
```javascript
  "scripts":
  {
    "transpile-wpserver": "babel wpserver.config.js -d wp",
    "transpile-wpclient": "babel wpclient.config.js -d wp",
    "bundle-server": "npm run transpile-wpserver && webpack --config wp/wpserver.config.js",
    "bundle-client": "npm run transpile-wpclient && webpack --config wp/wpclient.config.js",
    "start": "npm run bundle-client&& npm run bundle-server&& node index.js",
    "bundle-server-w": "npm run transpile-wpserver && webpack -w --config wp/wpserver.config.js",
    "bundle-client-w": "npm run transpile-wpclient && webpack -w --config wp/wpclient.config.js",
    "dev": "npm run bundle-client-w & npm run bundle-server-w & nodemon"
  }
```
As you see what we do first is to `transpile` or compile webpack configuration files themselves before using (they are wrote using ES6 syntax). Those transpiled webpack configuration files will be kept under `wp` folder (which `babel` will create for us). Then we run `webpack` itself to produce the bundle. Finally we run `node` or `nodemon` (depending if we are developing or in production mode) to the `index.js` file which is the bundle produced by `webpack` in the case of the server file (the other one, the front end, will be under `dist` folder). As you see when running `nodemon` it is not necessary to specify the file because it defualts to `index.js` file under root directory, while when using `node` command it is necessary.

If you do all that you will have a React app up and running.
Thank you for reading.