【问题标题】:What is the correct webpack configuration for dealing with 404 refresh errors?处理 404 刷新错误的正确 webpack 配置是什么?
【发布时间】:2020-05-01 22:08:00
【问题描述】:

我目前正在开发一个包含路由的 React + Express Web 应用程序。当我转到不是我的主页的路线并刷新页面时,我收到 404 错误。有很多帖子可以解决这个问题,就像这里描述的那样:https://tylermcginnis.com/react-router-cannot-get-url-refresh/ 我已经尝试实现。这是我对问题的理解:

  1. 转到http://locahost:3000,它会加载 dist/index.html 和 dist/bundle.js(其中定义了所有必要的 React 路由)
  2. 转到http://localhost:3000/about,这是一条服务于 about.html 的预定义路由
  3. 刷新页面 - 您看到 404 错误,表示 index.html 未在 http://localhost:3000/about 中定义。我知道这是因为在http://localhost:3000/about,Web 应用程序尝试获取 index.html,但在dist/index.html 文件夹中找不到它。我相信这种情况正在发生,因为我的 dist/index.html 是从我的 webpack 配置中在内存中提供的,并且没有创建“真实的”dist/index.html 文件。

这是我的 webpack 配置文件:

const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');

module.exports = {
  entry: path.join(__dirname, './src/index.js'),
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist'),
  },
  module: {
    rules: [
      {
        // which files should babel be used on
        test: /\.(js|jsx)$/,
        exclude: /node_modules/,
        loader: ['babel-loader'],
      },
      {
        test: /\.css$/,
        use: [
          'style-loader', 'css-loader'
        ]
      }
    ]
  },
  plugins: [
    new webpack.HotModuleReplacementPlugin(),
    // copy the index.html file to the dist folder so that devServer can serve the static index.html file from dist folder
    new HtmlWebpackPlugin({
      template: './src/index.html'
    }),
    new CleanWebpackPlugin()
  ],
  // dist used to serve our application in browser
  devServer: {
    contentBase: path.join(__dirname, 'dist'),
    port: 3000,
    compress: true,
    hot: true,
    proxy: {
      '/**': {
        target: 'http://localhost:5000',
        secure: false
      }
    }
  }
};

还有我的 index.html 文件:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>App</title>
    </head>
    <body>
        <div id="app"></div>
    </body>
</html>

当结合使用webpack-dev-serverHtmlWebpackPlugin 时,根据我在网上阅读的内容,它需要一个我指定的模板index.html 文件并将其加载到内存中我的dist 文件夹中。它实际上并没有出现在那里 - 如果您转到http://localhost:3000/webpack-dev-server,您会看到 index.html 文件。它对我的bundle.js 文件也有同样的作用,该文件包含我的index.html 文件引用的所有 JS 代码我猜这一切都在内存中完成,因为除非你'将在需要静态提供文件的地方投入生产。

如果我的理解是正确的,我是否应该在我的 dist 文件夹中放置一个引用我的 bundle.js 开发文件的 index.html 文件?除了使用&lt;script&gt; 标签来引用bundle.js 之外,它与我上面的内容相同。在我的src 文件夹中拥有一个index.html 文件以及在我的dist 文件夹中仅用于“重新加载”,这对我来说似乎是违反直觉的。此外,为什么要使用HtmlWebpackPlugin呢?那么在内存中加载 index.html/bundle/js 有什么意义呢?

【问题讨论】:

    标签: webpack build react-router


    【解决方案1】:

    安装 HtmlWebpackPlugin(html-webpack-plugin) 并添加 index.html 解决我同样的问题

    这里是 webpack.config.js

    module.exports = {
        entry: './src/index.js',
        output: {
            path: path.resolve(__dirname, 'dist'),
            filename: "[name].[hash:8].bound.js",
            publicPath: '/',
        },
        devServer: {
            contentBase: './dist',
            hot: true,
        },
        plugins: [
            new HtmlWebpackPlugin({
                title: 'gsap-learning',
                template: path.resolve(__dirname, './src/index.html'),
            })
        ],
        resolve: {
            alias: {
                '@': path.resolve(__dirname, './src')
            }
        },
        module: {
            rules: [
                {
                    test: /\.css$/,
                    use: ['style-loader', 'css-loader'],
                },
                {
                    test: /\.less$/,
                    loader: 'less-loader'
                },
                {
                    test: /\.m?(js|jsx)$/,
                    exclude: /node_modules/,
                    use: {
                        loader: 'babel-loader',
                        options: {
                            presets: ['@babel/preset-env', '@babel/preset-react']
                        }
                    }
                }
            ]
        },
    };
    

    app.js

    function App() {
        return (
            <Router>
                <Header />
                <Switch>
                    <Route exact path="/" component={Home} />
                    {/*<Route path="/lesson/:id">*/}
                    {/*    <Lessons />*/}
                    {/*</Route>*/}
                </Switch>
            </Router>
        );
    }
    

    index.js

    import React from 'react';
    import ReactDOM from 'react-dom';
    import './index.css';
    import App from './App';
    
    ReactDOM.render(
        <React.StrictMode>
            <App />
        </React.StrictMode>,
        document.getElementById('root')
    );
    

    index.html

    <!doctype html>
    <html>
    <head>
        <meta charset="utf-8">
        <meta http-equiv="expires" content="0">
        <meta http-equiv="Pragma" content="no-cache">
        <meta http-equiv="Cache-Control" content="no-cache">
        <meta http-equiv="content-type" content="text/html; charset=UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
        <meta name="renderer" content="webkit">
        <meta name="viewport" content="width=device-width, maximum-scale=1, minimum-scale=1, initial-scale=1">
        <title>Gsap-learning</title>
    </head>
    <body>
    <div id="root"></div>
    </body>
    </html>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-02
      相关资源
      最近更新 更多