Based on https://www.youtube.com/watch?v=wftux-8hqQA (Create a Modern React App From Scratch | Webpack 5 | 2021 by CyberWolve)
This setup is not a tutorial, but more of an aid-memoire to myself in setting up webpack for an application requiring react and translation. Use at your own risk.
TL;DR: Download or
git clone https://github.com/gwynsoft/webpack-react.git
Start by initialising a folder:
npm init -y
npm i -D @babel/core @babel/preset-env @babel/preset-react babel-loader css-loader mini-css-extract-plugin html-webpack-plugin style-loader webpack webpack-cli webpack-dev-server
style-loader injects css files directly into app bundle
mini-css-extract-plugin creates css resources separate from the app bundle
npm i react react-dom
mkdir public
Create public/index.html with:
> type ! + enter to get html skeleton:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="/main.css" class="css" />
<title>[Your Title]</title>
</head>
<body>
<div id="root"></div>
<script src="/bundle.js"></script>
</body>
</html>
mkdir src
Create src/App.js containing:
import React from "react";
const App = () => {
return <h1>Hello World</h1>;
};
export default App;
Create src/index.css containing:
h1 {
color: red
}
Create src/index.js containing:
import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
ReactDOM.render(<App />, document.getElementById("root"));
create webpack.config.js containing:
const path = require("path"); // built-in module needed to resolve paths
const HtmlWebpackPlugin = require("html-webpack-plugin"); // Generates a html file in dist with all components included
module.exports = {
output: {
path: path.resolve(__dirname, "./dist"), // Where to put the generated files
filename: "bundle.js", // Name of generated file
clean: true, // Clears the dist directory before writing new files
publicPath: "/", // for routing
},
devtool: "source-map", // Allows us to see errors with the correct file &line number
devServer: {
port: 3000,
watchFiles: ["src/*/*", "public/*/*"], // was watchContentBase
historyApiFallback: true, // **** essential for proper routing ****
open: true, // Opens a browser automatically
hot: true, // Enable hot reloading
},
module: {
rules: [
{
// Javascript and JSX files
test: /\.(js|jsx)$/,
exclude: /nodeModules/,
use: {
loader: "babel-loader",
options: { presets: [ "@babel/preset-env", ["@babel/preset-react", { runtime: "automatic" }], ], },
},
},
{
// CSS files
test: /\.css$/,
use: ["style-loader", "css-loader"],
},
],
},
plugins: [new HtmlWebpackPlugin({ template: "./public/index.html" })],
};
In package.json add:
"scripts">
"start": "webpack serve --mode development",
"build": "webpack --mode production"
Add a favicon to /public
test with npm start
Add ESLint and Prettier Support
See How To Lint and Format Code with ESLint in Visual Studio Code (Corrected for new dependencies as at 30 Sep 21
First, add ESLint and Prettier extensions to VSCode. Then install the following dev dependencies:
npm i -D prettier eslint eslint-config-prettier @babel/eslint-parser eslint-plugin-react eslint-plugin-react-hooks eslint-plugin-jsx-a11y eslint-plugin-import
Create .prettierrc with an empty object:
{}
Create .eslintrc with:
{ "extends": [ "eslint:recommended", "plugin:import/errors", "plugin:react/recommended", "plugin:jsx-a11y/recommended", "prettier" ], "rules": { "react/prop-types": 0, "no-console": 1, "react-hooks/rules-of-hooks": 2, "react-hooks/exhaustive-reps": 0, "no-unused-vars": 1 }, "plugins": ["import", "react", "jsx-a11y", "react-hooks"], "parserOptions": { "ecmaVersion": 2018, "sourceType": "module", "ecmaFeatures": { "jsx": true } }, "env": { "es6": true, "browser": true, "node": true, "commonjs": true }, "settings": { "react": { "version": "detect" } } }
Add SASS functionality
npm i -D sass sass-loader
In webpack.config.js change css test to:
// CSS files
test: /\.s?css$/,
use: ["style-loader", "css-loader", "sass-loader"],
Create folder /src/styles/base, containing _global.scss, _variables.scss and _mixins.scss
Create folder /src/styles/modules
Change src/index.css to index.scss
Create _variables.scss containing:
:root {
--text: orange;
}
$bg: lightgreen;
Create styles/_global.scss containing:
@use 'variables';
body {
margin: 0;
background-color: variables.$bg; /* SASS variable */
color: var(--text); /* CSS variable */
}
Add @use './styles/base/global'; to index.scss
Change index.css in index.js to index.scss
Add postcss and MiniCssExtractPlugin
npm i -D postcss postcss-preset-env postcss-loader
In webpack.config.js change css use rule to:
use: [
MiniCssExtractPlugin.loader,
"css-loader",
{
loader: "postcss-loader",
options: {
postcssOptions: {
plugins: [
[
"postcss-preset-env",
{
// Options
},
],
],
},
},
},
"sass-loader",
],
The order of loaders is important!!
Add
const MiniCssExtractPlugin = require("mini-css-extract-plugin"); after const HtmlWebpackPlugin at top of file and
(dist/main.css should contain:
:root{--text: orange}body{margin:0;background-color:#90ee90;color:var(--text)}
/*# sourceMappingURL=main.css.map*/
)
Set Up Translation
npm i flag-icon-css i18next i18next-browser-languagedetector i18next-http-backend js-cookie react-i18next react-router-dom
{jcomments on}