These are the steps I take to start a basic React project on an ExpressJS server. Clone the finished boilerplate from here: https://github.com/jefferyshivers/React-Express-Boilerplate
mkdir reactexpress && cd $_
# the Express server file:
touch server.js
# Webpack configuration:
touch webpack.config.js
# React source directory and file
mkdir src && touch src/index.js
# Static files
mkdir dist && touch dist/index.html
Here is our project structure so far:
.
├── dist
│ └── index.html
├── server.js
├── src
│ └── index.js
└── webpack.config.js
For the React end, install React:
npm i -D react react-dom
Create your top-level React component:
# src/index.js
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
class App extends Component {
render() {
return (
<div>
Hello world.
</div>
)
}
}
ReactDOM.render(
<App />,
document.getElementById('root'));
We want to put that component in a div with the id "root" in the static index.html
file:
# dist/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>React Express Boilerplate</title>
</head>
<body>
<div id="root"></div>
<script src="./bundle.js"></script>
</body>
</html>
Notice the script tag loading the bundle.js
file; we will generate that file using Webpack. Since React uses a lot of stuff that
browsers can't simply compile right out of the box, Webpack will use Babel transpilers to break it down into browser-ready code.
Install Babel with npm:
npm i -D babel-core babel-loader babel-preset-env babel-preset-react
Install Webpack:
npm i -D webpack webpack-dev-server
Configure Webpack:
# webpack.config.js
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
filename: 'bundle.js',
publicPath: '/',
path: path.resolve(__dirname, 'dist')
},
module: {
rules: [
{
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
"presets" : ["env", "react"]
}
}
}
]
}
};
In the package.json
file in the root of project directory, add scripts to make running Express and Webpack easier:
"scripts": {
"start": "node index.js",
"start-dev": "./node_modules/.bin/webpack-dev-server --content-base dist/",
"build": "./node_modules/.bin/webpack"
},
Now running npm run build
or yarn build
should render dist/bundle.js
.
Lastly, install Express:
npm i -S express webpack-dev-middleware
And write the Express server:
# index.js
var express = require('express');
var app = express();
var path = require('path');
const webpack = require('webpack');
const config = require('./webpack.config');
const compiler = webpack(config);
app.use(require('webpack-dev-middleware')(compiler, {
publicPath: config.output.publicPath
}));
app.get('*', function(req, res) {
res.sendFile('dist/index.html', { root: __dirname });
});
app.listen(3000);
You can now serve your project locally with npm run start
or yarn start
. View localhost:3000
in a browser to see the project.
With the start-dev
script, we use webpack-dev-server to hot-reload the project in the browser as assets are updated. To update
the bundle.js
file anytime a change is made to the React source code, add --watch
to the build
command (note: you'll need two
tabs open to have this running in one while the Express server is running in another).