Webpack 4 Quickly

Paul Allies
3 min readJan 12, 2019

--

We are going to create a React Web Application in the following way:

  • Create Project
  • Install Dev Dependencies
  • Install Dependencies
  • Configure Babel
  • Style App
  • State Management
  • Create index.js
  • Create app.js
  • Configure Webpack
  • Add npm Scripts
  • Dev, Build and Serve Production

Create Project

$> mkdir webpackquickly
$> cd webpackquickly
webpackquickly $> npm init -y

Install Dev Dependencies

webpackquickly $> npm i -D webpack webpack-cli style-loader css-loader file-loader html-webpack-plugin clean-webpack-plugin webpack-dev-server http-server @babel/core babel-loader @babel/preset-env @babel/preset-react

Install Dependencies

webpackquickly $> npm i -S react react-dom

Configure Babel

Add .babelrc file

{
"presets": [
"@babel/preset-env",
"@babel/preset-react"
]
}

Styling

We can implement css styling with css file. Let’s create a style.css file.

src/style.css

.hello {
color: red;
}

State Management

Let’s use React Context to manage application state, the application displays a message and we’ll change the message with a button.
Let’s create the Application Context.

src/Context.js

import React, { Component } from 'react';
var MainContext = React.createContext();
export const withContext = Component => (props) => (
<MainContext.Consumer>
{
value => (
<Component {...value} {...props} />
)
}
</MainContext.Consumer>
)
export class MainProvider extends Component {
constructor(props) {
super(props);
this.state = {
name: ""
};
}
render() {
return (
<MainContext.Provider
value={{
contextState: this.state,
changeName: (name) => this.setState({ name }) //action
}}
>
{this.props.children}
</MainContext.Provider >
);
}
}

“withContext” is a higher order function to easily make a child component or function aware of the application state and actions. “MainProvider” is the parent App Container. to make all children aware of the app state and actions. Let’s apply this to the index.js file

App Entry

src/index.js

import React from 'react';
import ReactDOM from 'react-dom';
import App from './app';
import './style.css';
import { MainProvider } from './Context';
var rootElem = document.getElementById("app");
ReactDOM.render(<MainProvider><App /></MainProvider>, rootElem);
//to be used with web dev server
if (module.hot) {
module.hot.accept('./app', function () {
ReactDOM.render(<MainProvider><App /></MainProvider>, rootElem);
});
}

Main App

src/app.js

import React from "react";
import { withContext } from './Context'
function App({ changeName, contextState }) {
return (
<div>
<div className="hello">{contextState.name}</div>
<button onClick={() => changeName("Paul")}>Change</button>
</div>
);
};
export default withContext(App);

Configure Webpack

webpack.config.js

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const webpack = require("webpack");
module.exports = {
mode: 'development',
entry: {
app: './src/index.js',
},
devtool: 'inline-source-map',
devServer: {
contentBase: './dist',
hot: true
},
module: {
rules: [{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
}]
},
plugins: [
new CleanWebpackPlugin(['dist']),
new HtmlWebpackPlugin({
filename: 'index.html',
template: 'src/assets/index.html'
}),
new webpack.HotModuleReplacementPlugin(),
],
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist')
}
};

Create NPM Scripts

"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack",
"serve": "http-server dist",
"start": "webpack-dev-server --open"
}

Run Dev App

$> npm start

Run Build

$> npm run build

Serve Production Build

$> npm run serve

--

--