Skip to content

Commit 6cb1e4e

Browse files
authored
fix: show warning when hot is enabled with the HMR plugin in config (#3744)
* fix: show warning when `hot` is enabled with HMR plugin in config * test: for HMR warning
1 parent 8f20c3e commit 6cb1e4e

File tree

2 files changed

+79
-8
lines changed

2 files changed

+79
-8
lines changed

lib/Server.js

+12-8
Original file line numberDiff line numberDiff line change
@@ -1056,16 +1056,20 @@ class Server {
10561056
// TODO remove after drop webpack v4 support
10571057
compiler.options.plugins = compiler.options.plugins || [];
10581058

1059-
if (
1060-
this.options.hot &&
1061-
!compiler.options.plugins.find(
1059+
if (this.options.hot) {
1060+
const HMRPluginExists = compiler.options.plugins.find(
10621061
(p) => p.constructor === webpack.HotModuleReplacementPlugin
1063-
)
1064-
) {
1065-
// apply the HMR plugin, if it didn't exist before.
1066-
const plugin = new webpack.HotModuleReplacementPlugin();
1062+
);
10671063

1068-
plugin.apply(compiler);
1064+
if (HMRPluginExists) {
1065+
this.logger.warn(
1066+
`"hot: true" automatically applies HMR plugin, you don't have to add it manually to your webpack configuration.`
1067+
);
1068+
} else {
1069+
// apply the HMR plugin
1070+
const plugin = new webpack.HotModuleReplacementPlugin();
1071+
plugin.apply(compiler);
1072+
}
10691073
}
10701074
});
10711075

test/server/hot-option.test.js

+67
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,73 @@ describe("hot option", () => {
166166
});
167167
});
168168

169+
describe("simple config with already added HMR plugin", () => {
170+
let loggerWarnSpy;
171+
let getInfrastructureLoggerSpy;
172+
let compiler;
173+
174+
beforeEach(() => {
175+
compiler = webpack({
176+
...config,
177+
devServer: { hot: false },
178+
plugins: [...config.plugins, new webpack.HotModuleReplacementPlugin()],
179+
});
180+
181+
loggerWarnSpy = jest.fn();
182+
183+
getInfrastructureLoggerSpy = jest
184+
.spyOn(compiler, "getInfrastructureLogger")
185+
.mockImplementation(() => {
186+
return {
187+
warn: loggerWarnSpy,
188+
info: () => {},
189+
log: () => {},
190+
};
191+
});
192+
});
193+
194+
afterEach(() => {
195+
getInfrastructureLoggerSpy.mockRestore();
196+
loggerWarnSpy.mockRestore();
197+
});
198+
199+
it("should show warning with hot normalized as true", async () => {
200+
server = new Server({ port }, compiler);
201+
202+
await server.start();
203+
204+
expect(loggerWarnSpy).toHaveBeenCalledWith(
205+
`"hot: true" automatically applies HMR plugin, you don't have to add it manually to your webpack configuration.`
206+
);
207+
208+
await server.stop();
209+
});
210+
211+
it(`should show warning with "hot: true"`, async () => {
212+
server = new Server({ port, hot: true }, compiler);
213+
214+
await server.start();
215+
216+
expect(loggerWarnSpy).toHaveBeenCalledWith(
217+
`"hot: true" automatically applies HMR plugin, you don't have to add it manually to your webpack configuration.`
218+
);
219+
220+
await server.stop();
221+
});
222+
223+
it(`should show warning with "hot: false"`, async () => {
224+
server = new Server({ port, hot: false }, compiler);
225+
226+
await server.start();
227+
228+
expect(loggerWarnSpy).not.toHaveBeenCalledWith(
229+
`"hot: true" automatically applies HMR plugin, you don't have to add it manually to your webpack configuration.`
230+
);
231+
232+
await server.stop();
233+
});
234+
});
235+
169236
describe("multi compiler hot config HMR plugin", () => {
170237
it("should register the HMR plugin before compilation is complete", async () => {
171238
let pluginFound = false;

0 commit comments

Comments
 (0)