cli: pass websocket host and port explicitly in configuration

When configuring the ReactRefreshPlugin and the
WebpackDevServer, we previously inferred the host
and port from the browser location. This is no
longer sufficient, since dynamic plugin containers
may be served from separate dev servers.

https://webpack.js.org/configuration/dev-server/#websocketurl
https://github.com/pmmmwh/react-refresh-webpack-plugin/blob/main/docs/API.md#sockhost

Signed-off-by: MT Lewis <mtlewis@users.noreply.github.com>
This commit is contained in:
MT Lewis
2024-07-17 18:12:16 +01:00
parent 94ab20ebfa
commit b7709255e8
3 changed files with 34 additions and 19 deletions
+30
View File
@@ -29,6 +29,7 @@ import { ModuleFederationPlugin } from '@module-federation/enhanced/webpack';
import { LinkedPackageResolvePlugin } from './LinkedPackageResolvePlugin';
import ModuleScopePlugin from 'react-dev-utils/ModuleScopePlugin';
import { RunScriptWebpackPlugin } from 'run-script-webpack-plugin';
import ReactRefreshPlugin from '@pmmmwh/react-refresh-webpack-plugin';
import { paths as cliPaths } from '../../lib/paths';
import fs from 'fs-extra';
import { getPackages } from '@manypkg/get-packages';
@@ -54,6 +55,21 @@ export function resolveBaseUrl(config: Config): URL {
}
}
export function resolveEndpoint(config: Config): {
host: string;
port: number;
} {
const url = resolveBaseUrl(config);
return {
host: config.getOptionalString('app.listen.host') ?? url.hostname,
port:
config.getOptionalNumber('app.listen.port') ??
Number(url.port) ??
(url.protocol === 'https:' ? 443 : 80),
};
}
async function readBuildInfo() {
const timestamp = Date.now();
@@ -108,6 +124,20 @@ export async function createConfig(
publicPath = `${publicPath}${publicSubPath}`.replace('//', '/');
}
if (isDev) {
const { host, port } = resolveEndpoint(options.frontendConfig);
plugins.push(
new ReactRefreshPlugin({
overlay: {
sockProtocol: 'ws',
sockHost: host,
sockPort: port,
},
}),
);
}
if (checksEnabled) {
plugins.push(
new ForkTsCheckerWebpackPlugin({
+3 -9
View File
@@ -30,7 +30,7 @@ import {
import { paths as libPaths } from '../../lib/paths';
import { loadCliConfig } from '../config';
import { Lockfile } from '../versioning';
import { createConfig, resolveBaseUrl } from './config';
import { createConfig, resolveBaseUrl, resolveEndpoint } from './config';
import { createDetectedModulesEntryPoint } from './packageDetection';
import { resolveBundlingPaths, resolveOptionalBundlingPaths } from './paths';
import { ServeOptions } from './types';
@@ -131,13 +131,7 @@ DEPRECATION WARNING: React Router Beta is deprecated and support for it will be
const { frontendConfig, fullConfig } = cliConfig;
const url = resolveBaseUrl(frontendConfig);
const host =
frontendConfig.getOptionalString('app.listen.host') || url.hostname;
const port =
frontendConfig.getOptionalNumber('app.listen.port') ||
Number(url.port) ||
(url.protocol === 'https:' ? 443 : 80);
const { host, port } = resolveEndpoint(frontendConfig);
const detectedModulesEntryPoint = await createDetectedModulesEntryPoint({
config: fullConfig,
@@ -257,7 +251,7 @@ DEPRECATION WARNING: React Router Beta is deprecated and support for it will be
// When the dev server is behind a proxy, the host and public hostname differ
allowedHosts: [url.hostname],
client: {
webSocketURL: 'auto://0.0.0.0:0/ws',
webSocketURL: { hostname: host, port },
},
},
compiler,
+1 -10
View File
@@ -17,7 +17,6 @@
import { ModuleOptions, WebpackPluginInstance } from 'webpack';
import MiniCssExtractPlugin from 'mini-css-extract-plugin';
import { svgrTemplate } from '../svgrTemplate';
import ReactRefreshPlugin from '@pmmmwh/react-refresh-webpack-plugin';
type Transforms = {
loaders: ModuleOptions['rules'];
@@ -193,15 +192,7 @@ export const transforms = (options: TransformOptions): Transforms => {
const plugins = new Array<WebpackPluginInstance>();
if (isDev) {
if (!isBackend) {
plugins.push(
new ReactRefreshPlugin({
overlay: { sockProtocol: 'ws' },
}),
);
}
} else {
if (!isDev) {
plugins.push(
new MiniCssExtractPlugin({
filename: 'static/[name].[contenthash:8].css',