在 Browsersync 中手动重写对特定 URL 的请求
Manually rewrite requests to specific URLs in Browsersync
我在一个有点奇怪的设置中使用 BrowserSync,我在其中代理我的 Web 服务器(Docker 容器中的 Apache),但也从 Webpack 开发服务器提供热模块替换 (HMR) .
在我的本地开发环境中,设置如下所示:
https://mytestsite.localhost
– Docker 容器中的 Apache 服务
https://localhost:8888
– Webpack 开发服务器,服务于 HMR
https://localhost:3000
– BrowserSync`
对于硬重新加载,这一切都很好——webpack 开发服务器似乎传递了需要重新加载的消息,一切正常。
我遇到的问题是热重载。 BS 代理服务的文档应该读取 webpack-dev-server 服务的 hotupdate.json
。在收到热更新时,页面会尝试加载 /hotupdate.json
(我相信这会告诉它要选择哪段代码),但是,因为它是相对的 URL,浏览器会尝试 GET https://localhost:3000/hotupdate.json
,这是 404s,因为这个 hotupdate.json
实际上是由 Webpack 服务器提供的,例如https://localhost:8888/hotupdate.json
.
因为我知道这个资源的绝对 URL,所以我想强制 BrowserSync 将任何请求重定向到 /hotupdate.json
到 https://localhost:8888/hotupdate.json
。我以为我可以用一些中间件来做到这一点,但我很挣扎,可能是因为我从来没有完全理解 Express 风格的中间件。
我试过类似的方法,但没有用!
browserSync({
proxy: {
target: `https://${process.env.APP_HOST_PATH}`,
middleware: [
dontProxyHotUpdate,
require('webpack-dev-middleware')(bundler, {
noInfo: true,
publicPath: webpackConfig.output.path
}),
]
},
files: [
'app/css/*.css',
'app/*.html'
]
});
function dontProxyHotUpdate (req, res, next){
if(req.url === '/hotupdate.json'){
req.url = 'https://127.0.0.1:8888/hotupdate.json';
}
next();
}
它肯定会尽我所能加载中间件,比如 console.log(req.url)
,但我无法重写请求 URL。我想可能的解决方案是重写请求 URL,或者直接覆盖响应。
N.B。有人可能会问为什么我不直接使用 webpack-dev-server,因为它自己很好地服务于 HMR。它确实如此,但它也不允许很好地重写页面中的锚元素,例如将 https://mytestsite.localhost/link
更改为 https://localhost:3000/link
。这对于在开发过程中浏览站点显然很重要(这很好,但不是必需的),但对于重写资产链接更为重要——特别是 SVG,除非路径、主机和端口都匹配,否则不会加载.
嗯,最后我解决了自己的问题!
我最终使用 http-proxy-middlware
编写了自己的中间件 - 就像这样。
var proxy = require('http-proxy-middleware');
browserSync({
proxy: {
target: `https://${process.env.APP_HOST_PATH}`,
middleware: [
dontProxyHotUpdate,
require('webpack-dev-middleware')(bundler, {
noInfo: true,
publicPath: webpackConfig.output.path
}),
// require("webpack-hot-middleware")(bundler) // I don't think that we want this here as it can be handled by the webpack dev server
],
},
// no need to watch '*.js' here, webpack will take care of it for us,
// including full page reloads if HMR won't work
files: [
path.join(source, '**/*.php'),
path.join(source, 'style.css')
]
});
var dontProxyHotUpdate = proxy('/hotupdate*', {
target: 'https://127.0.0.1:8888/',
changeOrigin: true, // for vhosted sites, changes host header to match to target's host
logLevel: 'debug',
secure: false
});
我在一个有点奇怪的设置中使用 BrowserSync,我在其中代理我的 Web 服务器(Docker 容器中的 Apache),但也从 Webpack 开发服务器提供热模块替换 (HMR) .
在我的本地开发环境中,设置如下所示:
https://mytestsite.localhost
– Docker 容器中的 Apache 服务
https://localhost:8888
– Webpack 开发服务器,服务于 HMR
https://localhost:3000
– BrowserSync`
对于硬重新加载,这一切都很好——webpack 开发服务器似乎传递了需要重新加载的消息,一切正常。
我遇到的问题是热重载。 BS 代理服务的文档应该读取 webpack-dev-server 服务的 hotupdate.json
。在收到热更新时,页面会尝试加载 /hotupdate.json
(我相信这会告诉它要选择哪段代码),但是,因为它是相对的 URL,浏览器会尝试 GET https://localhost:3000/hotupdate.json
,这是 404s,因为这个 hotupdate.json
实际上是由 Webpack 服务器提供的,例如https://localhost:8888/hotupdate.json
.
因为我知道这个资源的绝对 URL,所以我想强制 BrowserSync 将任何请求重定向到 /hotupdate.json
到 https://localhost:8888/hotupdate.json
。我以为我可以用一些中间件来做到这一点,但我很挣扎,可能是因为我从来没有完全理解 Express 风格的中间件。
我试过类似的方法,但没有用!
browserSync({
proxy: {
target: `https://${process.env.APP_HOST_PATH}`,
middleware: [
dontProxyHotUpdate,
require('webpack-dev-middleware')(bundler, {
noInfo: true,
publicPath: webpackConfig.output.path
}),
]
},
files: [
'app/css/*.css',
'app/*.html'
]
});
function dontProxyHotUpdate (req, res, next){
if(req.url === '/hotupdate.json'){
req.url = 'https://127.0.0.1:8888/hotupdate.json';
}
next();
}
它肯定会尽我所能加载中间件,比如 console.log(req.url)
,但我无法重写请求 URL。我想可能的解决方案是重写请求 URL,或者直接覆盖响应。
N.B。有人可能会问为什么我不直接使用 webpack-dev-server,因为它自己很好地服务于 HMR。它确实如此,但它也不允许很好地重写页面中的锚元素,例如将 https://mytestsite.localhost/link
更改为 https://localhost:3000/link
。这对于在开发过程中浏览站点显然很重要(这很好,但不是必需的),但对于重写资产链接更为重要——特别是 SVG,除非路径、主机和端口都匹配,否则不会加载.
嗯,最后我解决了自己的问题!
我最终使用 http-proxy-middlware
编写了自己的中间件 - 就像这样。
var proxy = require('http-proxy-middleware');
browserSync({
proxy: {
target: `https://${process.env.APP_HOST_PATH}`,
middleware: [
dontProxyHotUpdate,
require('webpack-dev-middleware')(bundler, {
noInfo: true,
publicPath: webpackConfig.output.path
}),
// require("webpack-hot-middleware")(bundler) // I don't think that we want this here as it can be handled by the webpack dev server
],
},
// no need to watch '*.js' here, webpack will take care of it for us,
// including full page reloads if HMR won't work
files: [
path.join(source, '**/*.php'),
path.join(source, 'style.css')
]
});
var dontProxyHotUpdate = proxy('/hotupdate*', {
target: 'https://127.0.0.1:8888/',
changeOrigin: true, // for vhosted sites, changes host header to match to target's host
logLevel: 'debug',
secure: false
});