├── .gitignore
├── src
├── assets
│ └── icons
│ │ └── favicon.png
├── app.styles.scss
├── index.js
├── index.scss
└── App.js
├── public
└── index.html
├── config
├── paths.js
├── webpack.dev.js
├── webpack.prod.js
└── webpack.common.js
├── .babelrc
├── .eslintrc.js
├── package.json
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | dist
3 | stats.json
4 | .DS_Store
--------------------------------------------------------------------------------
/src/assets/icons/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/miami78/webpack5-react-boilerplate/HEAD/src/assets/icons/favicon.png
--------------------------------------------------------------------------------
/src/app.styles.scss:
--------------------------------------------------------------------------------
1 | .app-container {
2 | color: white;
3 | background-color: black;
4 | text-align: center;
5 | height: 100%;
6 | width: 100%;
7 | }
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import ReactDOM from "react-dom";
3 | import App from "./App";
4 | import "./index.scss";
5 |
6 | ReactDOM.render(, document.getElementById("root"));
7 |
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Webpack 5 boilerplate for react
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/src/index.scss:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
5 | sans-serif;
6 | -webkit-font-smoothing: antialiased;
7 | -moz-osx-font-smoothing: grayscale;
8 | }
--------------------------------------------------------------------------------
/config/paths.js:
--------------------------------------------------------------------------------
1 | const path = require("path");
2 |
3 | module.exports = {
4 | // Source files
5 | src: path.resolve(__dirname, "../src"),
6 |
7 | // Production build files
8 | build: path.resolve(__dirname, "../dist"),
9 |
10 | // Static files that get copied to build folder
11 | public: path.resolve(__dirname, "../public"),
12 | };
13 |
--------------------------------------------------------------------------------
/src/App.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | import "./app.styles.scss";
4 |
5 | class App extends React.Component {
6 | render() {
7 | return (
8 |
9 | Webpack 5 boilerplate for react using babel, sass, with a hot dev server
10 | and an optimized production build.
11 |
12 | );
13 | }
14 | }
15 | export default App;
16 |
--------------------------------------------------------------------------------
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | [ "@babel/preset-env", {
4 | "modules": false,
5 | "targets": {
6 | "browsers": [
7 | "last 2 Chrome versions",
8 | "last 2 Firefox versions",
9 | "last 2 Safari versions",
10 | "last 2 iOS versions",
11 | "last 1 Android version",
12 | "last 1 ChromeAndroid version",
13 | "ie 11"
14 | ]
15 | }
16 | } ],
17 | "@babel/preset-react"
18 | ],
19 | "plugins": [ "@babel/plugin-proposal-class-properties" ]
20 | }
--------------------------------------------------------------------------------
/config/webpack.dev.js:
--------------------------------------------------------------------------------
1 | const paths = require("./paths");
2 |
3 | const webpack = require("webpack");
4 | const { merge } = require("webpack-merge");
5 | const common = require("./webpack.common.js");
6 |
7 | module.exports = merge(common, {
8 | // Set the mode to development or production
9 | mode: "development",
10 |
11 | // Control how source maps are generated
12 | devtool: "inline-source-map",
13 |
14 | // Spin up a server for quick development
15 | devServer: {
16 | historyApiFallback: true,
17 | contentBase: paths.build,
18 | open: true,
19 | compress: true,
20 | hot: true,
21 | port: 8080,
22 | },
23 |
24 | plugins: [
25 | // Only update what has changed on hot reload
26 | new webpack.HotModuleReplacementPlugin(),
27 | ],
28 | });
29 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | env: {
3 | browser: true,
4 | es6: true,
5 | node: true,
6 | },
7 | parser: "babel-eslint",
8 | extends: [
9 | "eslint:recommended",
10 | "plugin:react/recommended",
11 | "prettier",
12 | "prettier/react",
13 | ],
14 | parserOptions: {
15 | ecmaVersion: "2017",
16 | ecmaFeatures: {
17 | experimentalObjectRestSpread: true,
18 | jsx: true,
19 | },
20 | sourceType: "module",
21 | },
22 | plugins: ["babel", "react", "import", "prettier"],
23 | rules: {
24 | "import/no-duplicates": "error",
25 | "import/no-unresolved": "error",
26 | "import/named": "error",
27 | "prettier/prettier": "error",
28 | "react/no-typos": "error",
29 | "react/no-unused-state": "error",
30 | "react/jsx-no-bind": "error",
31 | "array-callback-return": "error",
32 | "consistent-return": "error",
33 | "babel/no-invalid-this": "error",
34 | "no-unused-vars": ["error", { argsIgnorePattern: "^_" }],
35 | },
36 | settings: {
37 | react: {
38 | pragma: "React",
39 | version: "15.0",
40 | flowVersion: "0.63.1",
41 | },
42 | },
43 | };
44 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "namup-ke",
3 | "version": "1.0.0",
4 | "description": "National Missing and Unidentified Persons Kenya",
5 | "main": "index.js",
6 | "scripts": {
7 | "start": "cross-env NODE_ENV=development webpack serve --config config/webpack.dev.js",
8 | "build": "cross-env NODE_ENV=production webpack --config config/webpack.prod.js",
9 | "lint": "eslint src --ext .jsx --ext .js",
10 | "predeploy": "npm run build",
11 | "deploy": "gh-pages -d dist"
12 | },
13 | "keywords": [],
14 | "author": "Larry Miami",
15 | "license": "ISC",
16 | "devDependencies": {
17 | "@babel/core": "^7.12.1",
18 | "@babel/plugin-proposal-class-properties": "^7.12.1",
19 | "@babel/preset-env": "^7.12.1",
20 | "@babel/preset-react": "^7.12.1",
21 | "babel-eslint": "^10.1.0",
22 | "babel-loader": "^8.1.0",
23 | "clean-webpack-plugin": "^3.0.0",
24 | "copy-webpack-plugin": "^6.2.1",
25 | "cross-env": "^7.0.2",
26 | "css-loader": "^5.0.0",
27 | "css-minimizer-webpack-plugin": "^1.1.5",
28 | "eslint": "^7.11.0",
29 | "eslint-config-prettier": "^6.12.0",
30 | "eslint-import-resolver-alias": "^1.1.2",
31 | "eslint-plugin-babel": "^5.3.1",
32 | "eslint-plugin-import": "^2.22.1",
33 | "eslint-plugin-prettier": "^3.1.4",
34 | "eslint-plugin-react": "^7.21.2",
35 | "html-webpack-plugin": "^4.5.0",
36 | "node-sass": "^4.14.1",
37 | "optimize-css-assets-webpack-plugin": "^5.0.4",
38 | "prettier": "^2.1.2",
39 | "sass-loader": "^10.0.3",
40 | "style-loader": "^2.0.0",
41 | "terser-webpack-plugin": "^4.2.3",
42 | "webpack": "^5.1.2",
43 | "webpack-cli": "^4.0.0",
44 | "webpack-dev-server": "^3.11.0",
45 | "webpack-merge": "^5.2.0"
46 | },
47 | "dependencies": {
48 | "react": "^16.14.0",
49 | "react-dom": "^16.14.0"
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/config/webpack.prod.js:
--------------------------------------------------------------------------------
1 | const paths = require("./paths");
2 | const { merge } = require("webpack-merge");
3 | const common = require("./webpack.common.js");
4 |
5 | const MiniCssExtractPlugin = require("mini-css-extract-plugin");
6 | const OptimizeCssAssetsPlugin = require("optimize-css-assets-webpack-plugin");
7 | const TerserPlugin = require("terser-webpack-plugin");
8 |
9 | module.exports = merge(common, {
10 | mode: "production",
11 | devtool: false,
12 | output: {
13 | path: paths.build,
14 | publicPath: "/",
15 | filename: "js/[name].[contenthash].bundle.js",
16 | },
17 | plugins: [
18 | // Extracts CSS into separate files
19 | // Note: style-loader is for development, MiniCssExtractPlugin is for production
20 | new MiniCssExtractPlugin({
21 | filename: "styles/[name].[contenthash].css",
22 | chunkFilename: "[id].css",
23 | }),
24 | ],
25 | module: {
26 | rules: [
27 | {
28 | test: /\.(scss|css)$/,
29 | use: [
30 | MiniCssExtractPlugin.loader,
31 | {
32 | loader: "css-loader",
33 | options: {
34 | importLoaders: 2,
35 | sourceMap: false,
36 | },
37 | },
38 | "sass-loader",
39 | ],
40 | },
41 | ],
42 | },
43 | optimization: {
44 | minimize: true,
45 | minimizer: [new OptimizeCssAssetsPlugin(), new TerserPlugin()],
46 | // Once your build outputs multiple chunks, this option will ensure they share the webpack runtime
47 | // instead of having their own. This also helps with long-term caching, since the chunks will only
48 | // change when actual code changes, not the webpack runtime.
49 | runtimeChunk: {
50 | name: "runtime",
51 | },
52 | },
53 | performance: {
54 | hints: false,
55 | maxEntrypointSize: 512000,
56 | maxAssetSize: 512000,
57 | },
58 | });
59 |
--------------------------------------------------------------------------------
/config/webpack.common.js:
--------------------------------------------------------------------------------
1 | const paths = require("./paths");
2 |
3 | const { CleanWebpackPlugin } = require("clean-webpack-plugin");
4 | const CopyWebpackPlugin = require("copy-webpack-plugin");
5 | const HtmlWebpackPlugin = require("html-webpack-plugin");
6 |
7 | module.exports = {
8 | // Where webpack looks to start building the bundle
9 | entry: [paths.src + "/index.js"],
10 |
11 | // Where webpack outputs the assets and bundles
12 | output: {
13 | path: paths.build,
14 | filename: "[name].bundle.js",
15 | publicPath: "/",
16 | },
17 |
18 | // Customize the webpack build process
19 | plugins: [
20 | // Removes/cleans build folders and unused assets when rebuilding
21 | new CleanWebpackPlugin(),
22 |
23 | // Copies files from target to destination folder
24 | new CopyWebpackPlugin({
25 | patterns: [
26 | {
27 | from: paths.src + "/assets",
28 | to: "assets",
29 | globOptions: {
30 | ignore: ["*.DS_Store"],
31 | },
32 | },
33 | ],
34 | }),
35 |
36 | // Generates an HTML file from a template
37 | // Generates deprecation warning: https://github.com/jantimon/html-webpack-plugin/issues/1501
38 | new HtmlWebpackPlugin({
39 | title: "National Missing and Unidentified Persons Kenya",
40 | favicon: paths.src + "/assets/icons/favicon.png",
41 | template: paths.public + "/index.html", // template file
42 | filename: "index.html", // output file
43 | }),
44 | ],
45 |
46 | // Determine how modules within the project are treated
47 | module: {
48 | rules: [
49 | // JavaScript: Use Babel to transpile JavaScript files
50 | { test: /\.(js|jsx)$/, exclude: /node_modules/, use: ["babel-loader"] },
51 |
52 | // Styles: Inject CSS into the head with source maps
53 | {
54 | test: /\.(scss|css)$/,
55 | use: [
56 | "style-loader",
57 | {
58 | loader: "css-loader",
59 | options: { sourceMap: true, importLoaders: 1 },
60 | },
61 | { loader: "sass-loader", options: { sourceMap: true } },
62 | ],
63 | },
64 |
65 | // Images: Copy image files to build folder
66 | { test: /\.(?:ico|gif|png|jpg|jpeg)$/i, type: "asset/resource" },
67 |
68 | // Fonts and SVGs: Inline files
69 | { test: /\.(woff(2)?|eot|ttf|otf|svg|)$/, type: "asset/inline" },
70 | ],
71 | },
72 | };
73 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # webpack5-react-boilerplate
2 |
3 | Webpack 5 boilerplate for react using babel, sass, with a hot dev server and an optimized production build.Configured with eslint rules.
4 |
5 | ## Installation
6 |
7 | ```
8 | git clone https://github.com/miami78/webpack5-react-boilerplate.git
9 | cd webpack5-react-boilerplate
10 | yarn / npm i
11 | ```
12 |
13 | ## Usage
14 |
15 | ### Development server
16 |
17 | ```bash
18 | yarn start / npm start
19 | ```
20 |
21 | You can view the development server at `localhost:8080`.
22 |
23 | ### Production build
24 |
25 | ```bash
26 | yarn build / npm run build
27 | ```
28 |
29 | ## Features
30 |
31 | - [webpack](https://webpack.js.org/)
32 | - [Babel](https://babeljs.io/)
33 | - [Sass](https://sass-lang.com/)
34 | - [Eslint](https://eslint.org/)
35 |
36 | ## Dependencies
37 |
38 | ### webpack
39 |
40 | - [`webpack`](https://github.com/webpack/webpack) - Module and asset bundler.
41 | - [`webpack-cli`](https://github.com/webpack/webpack-cli) - Command line interface for webpack
42 | - [`webpack-dev-server`](https://github.com/webpack/webpack-dev-server) - Development server for webpack
43 | - [`webpack-merge`](https://github.com/survivejs/webpack-merge) - Simplify development/production configuration
44 | - [`cross-env`](https://github.com/kentcdodds/cross-env) - Cross platform configuration
45 |
46 | ### Babel
47 |
48 | - [`@babel/core`](https://www.npmjs.com/package/@babel/core) - Transpile ES6+ to backwards compatible JavaScript
49 | - [`@babel/plugin-proposal-class-properties`](https://babeljs.io/docs/en/babel-plugin-proposal-class-properties) - Use properties directly on a class (an example Babel config)
50 | - [`@babel/preset-env`](https://babeljs.io/docs/en/babel-preset-env) - Smart defaults for Babel
51 |
52 | ### Loaders
53 |
54 | - [`babel-loader`](https://webpack.js.org/loaders/babel-loader/) - Transpile files with Babel and webpack
55 | - [`sass-loader`](https://webpack.js.org/loaders/sass-loader/) - Load SCSS and compile to CSS
56 | - [`node-sass`](https://github.com/sass/node-sass) - Node Sass
57 | - [`css-loader`](https://webpack.js.org/loaders/css-loader/) - Resolve CSS imports
58 | - [`style-loader`](https://webpack.js.org/loaders/style-loader/) - Inject CSS into the DOM
59 |
60 | ### Eslint
61 | - [`eslint-config-prettier`](https://www.npmjs.com/package/eslint-config-prettier) - Turns off all rules that are unnecessary or might conflict with Prettier.
62 | - [`eslint-import-resolver-alias`](https://www.npmjs.com/package/eslint-import-resolver-alias) - a simple Node behavior import resolution plugin for eslint-plugin-import, supporting module alias.
63 | - [`eslint-plugin-babel`](https://www.npmjs.com/package/eslint-plugin-babel) - an eslint rule plugin companion to babel-eslint.
64 | - [`eslint-plugin-import`](https://www.npmjs.com/package/eslint-plugin-import) - This plugin intends to support linting of ES2015+ (ES6+) import/export syntax, and prevent issues with misspelling of file paths and import names.
65 | - [`eslint-plugin-prettier`](https://www.npmjs.com/package/eslint-plugin-prettier) - Runs prettier as an eslint rule.
66 | - [`eslint-plugin-react`](https://www.npmjs.com/package/eslint-plugin-react) - React specific linting rules for ESLint.
67 |
68 |
69 | ### Plugins
70 |
71 | - [`clean-webpack-plugin`](https://github.com/johnagan/clean-webpack-plugin) - Remove/clean build folders
72 | - [`copy-webpack-plugin`](https://github.com/webpack-contrib/copy-webpack-plugin) - Copy files to build directory
73 | - [`html-webpack-plugin`](https://github.com/jantimon/html-webpack-plugin) - Generate HTML files from template
74 | - [`mini-css-extract-plugin`](https://github.com/webpack-contrib/mini-css-extract-plugin) - Extract CSS into separate files
75 | - [`optimize-css-assets-webpack-plugin`](https://github.com/NMFR/optimize-css-assets-webpack-plugin) - Optimize and minimize CSS assets
76 | - [`terser-webpack-plugin`](https://github.com/webpack-contrib/terser-webpack-plugin) - Optimize and minimize JavaScript
--------------------------------------------------------------------------------