匹配 webpack-dev-server historyApiFallback 中的根路由
Posted
技术标签:
【中文标题】匹配 webpack-dev-server historyApiFallback 中的根路由【英文标题】:Matching root route in webpack-dev-server's historyApiFallback` 【发布时间】:2018-04-26 15:58:55 【问题描述】:Sample repo demonstrating the issue is here.
我正在尝试设置 webpack 开发服务器,以便:
/
的请求由 public/landing.html
(静态登录页面)处理
我的 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
回复/
的请求?
【问题讨论】:
【参考方案1】:想到两个想法:
-
Webpack Dev Server 无法实现您想要做的事情(据我所知)
而且,一旦
npm run build
运行并部署,部署的应用程序将不会遵循 Webpack 开发服务器中配置的相同规则
即使我在#1 上弄错了,如果您打算部署应用程序,#2 似乎也是一个更大的问题。这导致我推荐一种替代设置,该设置适用于开发 和 生产(或部署在任何地方)。
几个选项:
将应用设置为单页应用 (SPA) 并使用 React Router 提供静态路由(/
和 /subpage
)和通配符(其他一切)
设置节点(或其他服务器)以提供静态路由(/
和 /subpage
)和通配符(其他所有内容)
一次尝试
在尝试设置路线时,我能够实现此设置:
在请求/
时显示landing.html
在请求/subpage
时显示subpage.html
在特定路径显示 React App,如app.html
为此,请进行以下更改:
将/public/index.html
移动到/public/app.html
mv ./public/index.html ./public/app.html
在/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"
]
在/config/paths.js
中将appHTML
更新为:
appHtml: resolveApp("public/app.html")
在/config/webpack.config.dev.js, update
plugins` 中包含:
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',
),
],
;
【讨论】:
以上是关于匹配 webpack-dev-server historyApiFallback 中的根路由的主要内容,如果未能解决你的问题,请参考以下文章