【问题标题】:Matching root route in webpack-dev-server's historyApiFallback`匹配 webpack-dev-server historyApiFallback 中的根路由
【发布时间】:2018-04-26 15:58:55
【问题描述】:

Sample repo demonstrating the issue is here.

我正在尝试设置 webpack 开发服务器,以便:

  1. / 的请求由 public/landing.html(静态登录页面)处理
  2. 我的 React 应用会处理对其他任何内容的请求

使用create-react-app 和based on webpack-dev-server's options,我将webpackDevServer.config.js 设置如下:

historyApiFallback: { // Paths with dots should still use the history fallback. // See https://github.com/facebookincubator/create-react-app/issues/387. disableDotRule: true, rewrites: [ // shows views/landing.html as the landing page { from: /^\/$/, to: 'landing.html' }, // shows views/subpage.html for all routes starting with /subpage { from: /^\/subpage/, to: 'subpage.html' }, // shows views/404.html on all other pages { from: /./, to: '404.html' }, ], },

当我启动 webpack 时,我看到的是:

  • 对/subpage 的请求被正确路由到subpage.html
  • 对/foo 的请求被正确路由到404.html。最终,这些将由我的 React 应用处理。
  • 对/ 的请求被错误地路由到我的 React 应用程序。

如何让landing.html 回复/ 的请求?

【问题讨论】:

    标签: reactjs webpack webpack-dev-server create-react-app webpack-dev-middleware


    【解决方案1】:

    想到两个想法:

    1. Webpack Dev Server 无法实现您想要做的事情(据我所知)
    2. 而且,一旦 npm run build 运行并部署,部署的应用程序将不会遵循 Webpack 开发服务器中配置的相同规则

    即使我在#1 上弄错了,如果您打算部署应用程序,#2 似乎也是一个更大的问题。这导致我推荐一种替代设置,该设置适用于开发 和 生产(或部署在任何地方)。

    几个选项:

    • 将应用设置为单页应用 (SPA) 并使用 React Router 提供静态路由(/ 和 /subpage)和通配符(其他一切)
    • 设置节点(或其他服务器)以提供静态路由(/ 和 /subpage)和通配符(其他所有内容)

    一次尝试

    在尝试设置路线时,我能够实现此设置:

    • 在请求/ 时显示landing.html
    • 在请求/subpage 时显示subpage.html
    • 在特定路径显示 React App,如app.html

    为此,请进行以下更改:

    1. 将/public/index.html 移动到/public/app.html

      mv ./public/index.html ./public/app.html
      
    2. 在/config/webpackDevServer.config.js 中,将historyApiFallback 更新为:

      historyApiFallback: {
        // Paths with dots should still use the history fallback.
        // See https://github.com/facebookincubator/create-react-app/issues/387.
        disableDotRule: true,
        rewrites: [
          // shows views/landing.html as the landing page
          { from: /^\/$/, to: "landing.html" },
          // shows views/subpage.html for all routes starting with /subpage
          { from: /^\/subpage/, to: "subpage.html" },
          // shows views/app.html on all other pages
          // but doesn't work for routes other than app.html
          { from: /./, to: "app.html" }
        ]
      }
      
    3. 在/config/paths.js 中将appHTML 更新为:

      appHtml: resolveApp("public/app.html")
      
    4. 在/config/webpack.config.dev.js, updateplugins` 中包含:

      new HtmlWebpackPlugin({
        filename: "app.html",
        inject: true,
        template: paths.appHtml
      })
      

    请求一个随机 URL,如 localhost:3000/foo 将返回一个空白页面,但包含来自 app.html 页面的 HTML,没有注入捆绑的 <script> 标签。所以也许你可以找到解决这个最后障碍的办法。

    【讨论】:

    • 感谢您的回复!目前我们有一个团队构建的静态页面,以及另一个团队构建的 react 应用程序。最终我们将把静态页面拉到 react 中,但现在我们只是将它们并排提供服务,并且没有足够的带宽来重构它们(还)。就生产而言,我们目前将 nginx 设置为为 / 路由返回 index.html,并将 app.html 作为一个包罗万象(其中 app.html 是我们的反应应用程序),我们正在尝试在本地复制该范例, 没有成功。
    • 令我困惑的是,webpack 文档似乎表明在/^\/$/ 提供替换路由是可能的(又名landing.html),但是当我尝试在本地复制它时,它没有不行。
    • 提供index.html 以外的页面是可能的,我能够让它工作。但它只适用于特定路线,不能作为通配符。它很接近,但不会替换 PUBLIC_URL 变量,也不会注入脚本。
    • 例如,我可以让landing.html 在/ 提供服务,subpage.html 在/subpage 以及使用定义模板的所有其他路线,如app.html,但脚本不会被注入来运行 React 应用程序。
    • 我实际上不需要通配符路由工作 - 只需匹配 /。介意分享一个 repo 或你用来让它工作的配置吗?
    【解决方案2】:

    我以webpack-dev-middleware 结束了opening a bug request,发现这不是错误,而是配置失败。

    具体来说,问题在于使用HtmlWebpackPlugin 和historyApiFallback。我相信插件是在正则匹配之前处理的,HtmlWebpackPlugin的默认文件输出是index.html;这意味着开箱即用,/ 将始终路由到HtmlWebpackPlugin 输出文件。

    解决方法是在HtmlWebpackPlugin 中设置一个自定义文件名,这样您就可以再次控制匹配。 Here's a sample repo demonstrating the fix 这是 webpack 配置:

    module.exports = {
      context: __dirname,
      entry: [
        './app.js',
      ],
      output: {
        path: __dirname + "/dist",
        filename: "bundle.js"
      },
      devServer: {
        publicPath: "/",
        // contentBase: "./public",
        // hot: true,
        historyApiFallback: {
          // disableDotRule: true,
          rewrites: [
            { from: /^\/$/, to: '/public/index.html' },
            { from: /^\/foo/, to: '/public/foo.html' },
            { from: /(.*)/, to: '/test.html' },
          ],
        }
      },
      plugins: [
        new HtmlWebpackPlugin({
          title: "Html Webpack html",
          hash: true,
          filename: 'test.html',
          template: 'public/plugin.html',
        }),
      ],
    };
    

    【讨论】:

      猜你喜欢
      • 2020-09-28
      • 1970-01-01
      • 2017-01-14
      • 1970-01-01
      • 2019-04-22
      • 2018-08-20
      • 2018-05-21
      • 2019-01-01
      • 1970-01-01
      相关资源
      最近更新 更多