Обновление или ввод URL-адреса приводит к ошибке 404 при сборке веб-пакета в React.js.Как это исправить? - PullRequest
0 голосов
/ 23 апреля 2019

Я использую React Router v4 и Webpack для сборки проекта. Когда я создаю свое приложение в производственном режиме и обновляю страницу, я получаю ошибку 404. «Не удалось найти путь запроса» Но когда я использую «запуск пряжи», я не получил ошибку 404. Я видел, что добавило следующее предложение к index.html в качестве решения:

<script src='/static/js/bundle.js'></script>

Но я не могу найти файл "bundle.js" в моем проекте или в локальном файле браузера.

App.js

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 (
             <Switch>
                 <Route exact path="/home" component={Home}/>
                 <Route exact path="/about" component={About}/>
             </Switch>
        );
    }
}

export default withRouter(App);

Root.js

const Root = () => {
return (
    <Router history={history}>
        <Route path="/" component={App}/>
    </Router>
);
};

export default Root;

index.js

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(<Root/>, document.getElementById('root'));

serviceWorker.unregister();

webpack.config.prod.js

    '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) => {
      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: () => [
              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 =>
          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 => `.${ext}`)
          .filter(ext => 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 <script> 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 &&
          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) &&
          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,
    };

localhost: папка 5000

   --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

Спасибо за чтение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...