webpack-dev-server 内置支持了HMR
仅仅通过配置hot hotOnly来开启(或者使用命令行参数 并且命令行参数的优先级更高)
记得在webpack早期版本中开启HMR还是比较繁琐,混乱的,各种的配置方式,有时候也各种不生效。
目前webpack-dev-server@3.11.2版本的内置逻辑
不论是通过命令行启动或者是node api的形式启动webpack-dev-server,都最终初始化了这个类
class Server {
constructor(compiler, options = {}, _log) {
...
// 这里是添加HMR脚本的入口
updateCompiler(this.compiler, this.options);
...
}
}
updateCompiler
function updateCompiler() {
// 同时还支持了自动添加HotModuleReplacementPlugin 所以我们的配置中可以忽略
const findHMRPlugin = (config) => {
if (!config.plugins) {
return undefined;
}
return config.plugins.find(
(plugin) => plugin.constructor === webpack.HotModuleReplacementPlugin
);
};
// 真正执行 添加入口的逻辑
addEntries(webpackConfig, options);
}
addEntries(webpackConfig, options);
function addEntries() {
...
// client端连接到socket服务
const clientEntry = `${require.resolve(
'../../client/'
)}?${domain}${sockHost}${sockPath}${sockPort}`;
// client 负责HMR 或者 live-reload的逻辑
let hotEntry;
if (options.hotOnly) {
hotEntry = require.resolve('webpack/hot/only-dev-server');
} else if (options.hot) {
hotEntry = require.resolve('webpack/hot/dev-server');
}
//其中 下面的这个构建target 都会自动的注入 clientEntry
const webTarget = [
'web',
'webworker',
'electron-renderer',
'node-webkit',
undefined, // eslint-disable-line
null,
].includes(config.target);
/** @type {Entry} */
const additionalEntries = checkInject(
options.injectClient,
config,
webTarget
)
? [clientEntry]
: [];
// 如果开启hot 注入hotEntry
if (hotEntry && checkInject(options.injectHot, config, true)) {
additionalEntries.push(hotEntry);
}
...
}
注意点 target
参考官方文档:webpack.js.org/configurati…