Webpack 4 Quickly
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