title: Refresh or typing URL gives 404 error on webpack production build in React.js. How to fix it?
body: <p>I'm using React Router v4 and Webpack for build project.
  When I build my application in production mode and refresh the page I'm getting 404 error. "The request path could not been found"
  But when I use "yarn start", I did not get a 404 error.
  I saw that added the following sentence to index.html as the solution:</p>
  
  <pre><code>&lt;script src='/static/js/bundle.js'&gt;&lt;/script&gt;
  </code></pre>
  
  <p>But I can't find "bundle.js" file in my project or browser's local file.</p>
  
  <p>App.js</p>
  
  <pre><code>import React, {Component} from 'react';
  import './App.css';
  import {Route, Switch} from "react-router-dom";
  import Homefrom "./page/Home";
  import About from "./page/About";
  
  class App extends Component {
      constructor(props) {
          super(props);
      }
  
      render() {
          return (
               &lt;Switch&gt;
                   &lt;Route exact path="/home" component={Home}/&gt;
                   &lt;Route exact path="/about" component={About}/&gt;
               &lt;/Switch&gt;
          );
      }
  }
  
  export default withRouter(App);
  </code></pre>
  
  <p>Root.js</p>
  
  <pre><code>const Root = () =&gt; {
  return (
      &lt;Router history={history}&gt;
          &lt;Route path="/" component={App}/&gt;
      &lt;/Router&gt;
  );
  };
  
  export default Root;
  </code></pre>
  
  <p>index.js</p>
  
  <pre><code>import React from 'react';
  import ReactDOM from 'react-dom'
  import 'core-js';
  import 'react-app-polyfill/ie11';
  import './index.css';
  import * as serviceWorker from './serviceWorker';
  import Root from "./Root";
  
  ReactDOM.render(&lt;Root/&gt;, document.getElementById('root'));
  
  serviceWorker.unregister();
  </code></pre>
  
  <p>webpack.config.prod.js</p>
  
  <pre><code>    'use strict';
  
      const fs = require('fs');
      const path = require('path');
      const webpack = require('webpack');
      const resolve = require('resolve');
      const PnpWebpackPlugin = require('pnp-webpack-plugin');
      const HtmlWebpackPlugin = require('html-webpack-plugin');
      const InlineChunkHtmlPlugin = require('react-dev-utils/InlineChunkHtmlPlugin');
      const TerserPlugin = require('terser-webpack-plugin');
      const MiniCssExtractPlugin = require('mini-css-extract-plugin');
      const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
      const safePostCssParser = require('postcss-safe-parser');
      const ManifestPlugin = require('webpack-manifest-plugin');
      const InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin');
      const WorkboxWebpackPlugin = require('workbox-webpack-plugin');
      const ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin');
      const getCSSModuleLocalIdent = require('react-dev-utils/getCSSModuleLocalIdent');
      const paths = require('./paths');
      const getClientEnvironment = require('./env');
      const ModuleNotFoundPlugin = require('react-dev-utils/ModuleNotFoundPlugin');
      const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin-alt');
      const typescriptFormatter = require('react-dev-utils/typescriptFormatter');
  
  
      const publicPath = paths.servedPath;
      const shouldUseRelativeAssetPaths = publicPath === './';
      const shouldUseSourceMap = process.env.GENERATE_SOURCEMAP !== 'false';
      const shouldInlineRuntimeChunk = process.env.INLINE_RUNTIME_CHUNK !== 'false';
      const publicUrl = publicPath.slice(0, -1);
      const env = getClientEnvironment(publicUrl);
  
      if (env.stringified['process.env'].NODE_ENV !== '"production"') {
        throw new Error('Production builds must have NODE_ENV=production.');
      }
  
      const useTypeScript = fs.existsSync(paths.appTsConfig);
  
      // style files regexes
      const cssRegex = /\.css$/;
      const cssModuleRegex = /\.module\.css$/;
      const sassRegex = /\.(scss|sass)$/;
      const sassModuleRegex = /\.module\.(scss|sass)$/;
  
      // common function to get style loaders
      const getStyleLoaders = (cssOptions, preProcessor) =&gt; {
        const loaders = [
          {
            loader: MiniCssExtractPlugin.loader,
            options: Object.assign(
              {},
              shouldUseRelativeAssetPaths ? { publicPath: '../../' } : undefined
            ),
          },
          {
            loader: require.resolve('css-loader'),
            options: cssOptions,
          },
          {
            loader: require.resolve('postcss-loader'),
            options: {
              ident: 'postcss',
              plugins: () =&gt; [
                require('postcss-flexbugs-fixes'),
                require('postcss-preset-env')({
                  autoprefixer: {
                    flexbox: 'no-2009',
                  },
                  stage: 3,
                }),
              ],
              sourceMap: shouldUseSourceMap,
            },
          },
        ];
        if (preProcessor) {
          loaders.push({
            loader: require.resolve(preProcessor),
            options: {
              sourceMap: shouldUseSourceMap,
            },
          });
        }
        return loaders;
      };
  
      module.exports = {
        mode: 'production',
        bail: true,
  results.
        devtool: shouldUseSourceMap ? 'source-map' : false,
        entry: [paths.appIndexJs],
        output: {
          path: paths.appBuild,
          filename: 'static/js/[name].[chunkhash:8].js',
          chunkFilename: 'static/js/[name].[chunkhash:8].chunk.js',
          publicPath: publicPath,
          // Point sourcemap entries to original disk location (format as URL on Windows)
          devtoolModuleFilenameTemplate: info =&gt;
            path
              .relative(paths.appSrc, info.absoluteResourcePath)
              .replace(/\\/g, '/'),
        },
        optimization: {
          minimizer: [
            new TerserPlugin({
              terserOptions: {
                parse: {
                  ecma: 8,
                },
                compress: {
                  ecma: 5,
                  warnings: false,
                  comparisons: false,
                  inline: 2,
                },
                mangle: {
                  safari10: true,
                },
                output: {
                  ecma: 5,
                  comments: false,
                  ascii_only: true,
                },
              },
              parallel: true,
              cache: true,
              sourceMap: shouldUseSourceMap,
            }),
            new OptimizeCSSAssetsPlugin({
              cssProcessorOptions: {
                parser: safePostCssParser,
                map: shouldUseSourceMap
                  ? {
                      inline: false,
                      annotation: true,
                    }
                  : false,
              },
            }),
          ],
          splitChunks: {
            chunks: 'all',
            name: false,
          },
          runtimeChunk: true,
        },
        resolve: {
          modules: ['node_modules'].concat(
            process.env.NODE_PATH.split(path.delimiter).filter(Boolean)
          ),
          extensions: paths.moduleFileExtensions
            .map(ext =&gt; `.${ext}`)
            .filter(ext =&gt; useTypeScript || !ext.includes('ts')),
          alias: {
            'react-native': 'react-native-web',
          },
          plugins: [
            new ModuleScopePlugin(paths.appSrc, [paths.appPackageJson]),
          ],
        },
        resolveLoader: {
          plugins: [
            PnpWebpackPlugin.moduleLoader(module),
          ],
        },
        module: {
          strictExportPresence: true,
          rules: [
            { parser: { requireEnsure: false } },
                {
              test: /\.(js|mjs|jsx)$/,
              enforce: 'pre',
              use: [
                {
                  options: {
                    formatter: require.resolve('react-dev-utils/eslintFormatter'),
                    eslintPath: require.resolve('eslint'),
  
                  },
                  loader: require.resolve('eslint-loader'),
                },
              ],
              include: paths.appSrc,
            },
            {
              oneOf: [
                {
                  test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/],
                  loader: require.resolve('url-loader'),
                  options: {
                    limit: 10000,
                    name: 'static/media/[name].[hash:8].[ext]',
                  },
                },
                {
                  test: /\.(js|mjs|jsx|ts|tsx)$/,
                  include: paths.appSrc,
  
                  loader: require.resolve('babel-loader'),
                  options: {
                    customize: require.resolve(
                      'babel-preset-react-app/webpack-overrides'
                    ),
  
                    plugins: [
                      [
                        require.resolve('babel-plugin-named-asset-import'),
                        {
                          loaderMap: {
                            svg: {
                              ReactComponent: '@svgr/webpack?-prettier,-svgo![path]',
                            },
                          },
                        },
                      ],
                    ],
                    cacheDirectory: true,
                    cacheCompression: true,
                    compact: true,
                  },
                },
                {
                  test: /\.(js|mjs)$/,
                  exclude: /@babel(?:\/|\\{1,2})runtime/,
                  loader: require.resolve('babel-loader'),
                  options: {
                    babelrc: false,
                    configFile: false,
                    compact: false,
                    presets: [
                      [
                        require.resolve('babel-preset-react-app/dependencies'),
                        { helpers: true },
                      ],
                    ],
                    cacheDirectory: true,
                    cacheCompression: true,
  
                    sourceMaps: false,
                  },
                },
                {
                  test: cssRegex,
                  exclude: cssModuleRegex,
                  loader: getStyleLoaders({
                    importLoaders: 1,
                    sourceMap: shouldUseSourceMap,
                  }),
                  sideEffects: true,
                },
                {
                  test: cssModuleRegex,
                  loader: getStyleLoaders({
                    importLoaders: 1,
                    sourceMap: shouldUseSourceMap,
                    modules: true,
                    getLocalIdent: getCSSModuleLocalIdent,
                  }),
                },
                {
                  test: sassRegex,
                  exclude: sassModuleRegex,
                  loader: getStyleLoaders(
                    {
                      importLoaders: 2,
                      sourceMap: shouldUseSourceMap,
                    },
                    'sass-loader'
                  ),
                  sideEffects: true,
                },
                {
                  test: sassModuleRegex,
                  loader: getStyleLoaders(
                    {
                      importLoaders: 2,
                      sourceMap: shouldUseSourceMap,
                      modules: true,
                      getLocalIdent: getCSSModuleLocalIdent,
                    },
                    'sass-loader'
                  ),
                },
                {
                  loader: require.resolve('file-loader'),
                  exclude: [/\.(js|mjs|jsx|ts|tsx)$/, /\.html$/, /\.json$/],
                  options: {
                    name: 'static/media/[name].[hash:8].[ext]',
                  },
                },
              ],
            },
          ],
        },
        plugins: [
          // Generates an `index.html` file with the &lt;script&gt; injected.
          new HtmlWebpackPlugin({
            inject: true,
            hash: true,
            template: paths.appHtml,
            minify: {
              removeComments: true,
              collapseWhitespace: true,
              removeRedundantAttributes: true,
              useShortDoctype: true,
              removeEmptyAttributes: true,
              removeStyleLinkTypeAttributes: true,
              keepClosingSlash: true,
              minifyJS: true,
              minifyCSS: true,
              minifyURLs: true,
            },
          }),
          shouldInlineRuntimeChunk &amp;&amp;
            new InlineChunkHtmlPlugin(HtmlWebpackPlugin, [/runtime~.+[.]js/]),
          new InterpolateHtmlPlugin(HtmlWebpackPlugin, env.raw),
          new ModuleNotFoundPlugin(paths.appPath),
          new webpack.DefinePlugin(env.stringified),
          new MiniCssExtractPlugin({
            filename: 'static/css/[name].[contenthash:8].css',
            chunkFilename: 'static/css/[name].[contenthash:8].chunk.css',
          }),
          new ManifestPlugin({
            fileName: 'asset-manifest.json',
            publicPath: publicPath,
          }),
          new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
          new WorkboxWebpackPlugin.GenerateSW({
            clientsClaim: true,
            exclude: [/\.map$/, /asset-manifest\.json$/],
            importWorkboxFrom: 'cdn',
            navigateFallback: publicUrl + '/index.html',
            navigateFallbackBlacklist: [
              new RegExp('^/_'),
              new RegExp('/[^/]+\\.[^/]+$'),
            ],
          }),
          // TypeScript type checking
          fs.existsSync(paths.appTsConfig) &amp;&amp;
            new ForkTsCheckerWebpackPlugin({
              typescript: resolve.sync('typescript', {
                basedir: paths.appNodeModules,
              }),
              async: false,
              checkSyntacticErrors: true,
              tsconfig: paths.appTsConfig,
              compilerOptions: {
                module: 'esnext',
                moduleResolution: 'node',
                resolveJsonModule: true,
                isolatedModules: true,
                noEmit: true,
                jsx: 'preserve',
              },
              reportFiles: [
                '**',
                '!**/*.json',
                '!**/__tests__/**',
                '!**/?(*.)(spec|test).*',
                '!src/setupProxy.js',
                '!src/setupTests.*',
              ],
              watch: paths.appSrc,
              silent: true,
              formatter: typescriptFormatter,
            }),
        ].filter(Boolean),
        node: {
          dgram: 'empty',
          fs: 'empty',
          net: 'empty',
          tls: 'empty',
          child_process: 'empty',
        },
        performance: false,
      };
  </code></pre>
  
  <p>localhost:5000's folder</p>
  
  <pre><code>   --static
        --js
           --1.841adf67.chunck.js?296dbda6ec241c2c7629
           --App.js
           --Root.js
           --history.js
           --index.js
           --main.83c8fdd1.chunck.js?296dbda6ec241c2c7629
           --runtime~main.229c360f.js?296dbda6ec241c2c7629
  </code></pre>
  
  <p>Thanks for reading.</p>