Real world app setup with React, Webpack 4 and Redux (Part 1)
Objective
To create real world react application from the scratch with
- Webpack4
- SCSS styles
- Unit Testing with Jest
- Navigation with Router
- Redux
- Internationalisation (I18n)
Please note this is not a React tutorial, this is just steps to setup a real world application.
Install React, Webpack 4 and dependencies
Init
Create a project folder open the project folder in terminal and run
npm init
Install Webpack 4
npm i webpack webpack-cli -D
Add npm Scripts
Add the npm scripts to the package.json, with start we want to .
"scripts": {
"start": "webpack-dev-server --mode development --open",
"build-dev": "webpack --mode development",
"build-prod": "webpack --mode production",
"test": "echo \"Error: no test specified\" && exit 1"
},
Dependency Installation
Install the react and react-dom
npm i react react-dom -S
Then we install
- babel-core
- babel-loader
- babel-preset-env
- babel-preset-react
npm i babel-core babel-loader@7 babel-preset-env babel-preset-react -D
As of today on 28 Aug, 2018, babel-loader@8.x (latest) expects another dependency @babel/core which creates some problem for compiling. I would suggest to downgrade the babel-loader@7.x. Also if you are reading this in future please check if 8.x is compatible
Now we need to install html-webpack-plugin and use this in our webpack config file. This plugin generates an HTML file with <script> injected, writes this to dist/index.html, and minifies the file.
npm i html-webpack-plugin -D
Install html-webpack-plugin as a dev dependency:
npm i html-webpack-plugin -D
Create a config file for webpack webpack.config.js
const HtmlWebPackPlugin = require("html-webpack-plugin");const htmlPlugin = new HtmlWebPackPlugin({
template: "./src/index.html",
filename: "./index.html"
});module.exports = {
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
}
]
},
plugins: [htmlPlugin]
};
Create another file .babelrc for babel-loader for cleaner readability
{
"presets": ["env", "react"]
}
Change the src/index.js file
import React from "react";
import ReactDOM from "react-dom";const Index = () => {
return <div>Hello World!</div>;
};ReactDOM.render(<Index />, document.getElementById("index"));
Create src/index.html file
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>React and Webpack4</title>
</head>
<body>
<section id="index"></section>
</body>
</html>
Run the project
Run the project with npm start
This will compile the files into dist folder and launch and add a new tab to the browser.
You can refer the changes upto this point in commit here
I really like the way create-react-app
structures the files, so I’ll also follow similar approach, you can do it your own way from here. My app structure now looks like below.
Install and using SCSS
Install SCSS, dependencies
npm i style-loader css-loader sass-loader node-sass -D
Create a new file src/App.scss
body {
font-size: 13px;
div {
margin: auto;
padding: 20px;
}
}
Import the new scss file to src/index.js
import React from 'react';
import './App.scss' //Import the scss file
import ReactDOM from 'react-dom';
import App from './App';const render = () =>
ReactDOM.render(
<div>
<App/>
</div>,
document.getElementById('index'));render();
We also need to let webpack know that we are integrating with SCSS files. Add following code to webpack.config.js under module.rules array
{
test: /\.scss$/,
use: [
"style-loader",
"css-loader",
"sass-loader"
]
}
And that’s it! You should be able to see the css changes now in your application. Check the details in here to see the changes in detail
Unit Testing with Jest
Install Jest
npm install — save-dev jest
add test file src/App.test.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';it('renders without crashing', () => {
const div = document.createElement('div');
ReactDOM.render(<App />, div);
ReactDOM.unmountComponentAtNode(div);
});
add test script to package.json
"test": "jest"
you can now try running the tests
npm test
Check the changes for details here