在 webpack-dev-server 的 historyApiFallback 中匹配根路由
Matching root route in webpack-dev-server's historyApiFallback`
Sample repo demonstrating the issue is here.
我正在尝试设置 webpack 开发服务器以便:
/
的请求由 public/landing.html
(静态登陆页面) 提供
- 对任何其他内容的请求都由我的 React 应用程序处理
使用 create-react-app
和 based on webpack-dev-server
's options, I've set up my 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
响应 /
的请求?
想到两个想法:
- Webpack Dev Server 无法实现您想做的事情(据我所知)
- 并且,一旦
npm run build
为 运行 并部署,部署的应用程序将不会遵循与 Webpack Dev Server 中配置的相同规则
即使我在 #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
将 return 一个空白页面,但包含来自 app.html
页面的 HTML 而没有捆绑 <script>
标签注入。所以也许你可以找到解决这个最后障碍的方法。
我以 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',
}),
],
};
Sample repo demonstrating the issue is here.
我正在尝试设置 webpack 开发服务器以便:
/
的请求由public/landing.html
(静态登陆页面) 提供
- 对任何其他内容的请求都由我的 React 应用程序处理
使用 create-react-app
和 based on webpack-dev-server
's options, I've set up my 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
响应 /
的请求?
想到两个想法:
- Webpack Dev Server 无法实现您想做的事情(据我所知)
- 并且,一旦
npm run build
为 运行 并部署,部署的应用程序将不会遵循与 Webpack Dev Server 中配置的相同规则
即使我在 #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
将 return 一个空白页面,但包含来自 app.html
页面的 HTML 而没有捆绑 <script>
标签注入。所以也许你可以找到解决这个最后障碍的方法。
我以 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',
}),
],
};