这里 css 热模块之所以生效,除了在 dev-server 中开启了 hmr,另一个是借助了 mini-css-extract-plugin 这个包;而借助 style-loader 使用模块热替换来加载 CSS 也这么简单。
html 使用 hmr没有开启热模块替换之前,修改 index.html 中的文字,浏览器页面会自动刷新;而开启之后,修改 html 中的文字,浏览器页面就不会自动刷新。
将 index.html 也配置到入口(entry)中:
// webpack.config.js module.exports = { - entry: './src/index.js', // 将 index.html 也作为入口文件 + entry: ['./src/index.js', './src/index.html'], }重启服务,再次修改 index.html,浏览器页面自动刷新,热模块替换对 html 没生效。
// index.html - <p>请查看控制台</p> + <p>请查看控制台2</p>Tip:热模块替换,就是一个模块发生了变化,只变更这一个,其他模块无需变化;而 index.html 不像 index.js 会有多个模块,index.html 只有一个模块,就是它自己,所以也就不需要热模块替换。
js 使用 hmr首先在 dev-server 中开启 hmr,然后创建一个 js 模块,接着在 index.js 中引入:
// a.js const i = 1; console.log(i); // index.js // 引入 a.js 模块 import './a';此刻,你若修改 i 的值(const i = 2;),则会发现浏览器页面会刷新。
要让热模块替换在 js 中生效,我们需要修改代码:
// index.js // 引入 a.js 模块 import './a'; if (module.hot) { module.hot.accept('./a', () => { console.log('Accepting the updated printMe module!'); }); }再次修改 i 的值,控制台会输出新的值,但浏览器页面不会再刷新。
此时,如果你尝试给入口文件(index.js)底部增加一条语句 console.log('a');,你会发现浏览器还是会刷新。
所以这种方式对入口文件无效,只能处理非入口 js。
注:如果一个 js 模块没有 HMR 处理函数,更新就会冒泡(bubble up)。
小结模块热替换比较难以掌握。
社区还提供许多其他 loader,使 HMR 与各种框架和库平滑地进行交互:
Vue Loader: 此 loader 支持 vue 组件的 HMR,提供开箱即用体验。
React Hot Loader: 实时调整 react 组件。
source mapsource map,提供一种源代码到构建后代码的映射,如果构建后代码出错了,通过映射可以方便的找到源代码出错的地方。
初步体验我们先故意弄一个语法错误,看浏览器的控制台如何提示:
// a.js const i = 1; // 下一行语法错误 console.log(i)(); // 控制台提示 a.js 第3行出错 Uncaught TypeError: console.log(...) is not a function a.js:3点击“a.js:3”,显示内容为:
var i = 1; // 下一行语法错误 console.log(i)();定位到了源码,很清晰。
假如换成 es6 的语法,点击进入的错误提示就没这么清晰了。请看示例:
// a.js class Dog { constructor(name) { this.name = name; } say() { console.log(this.name)(); } } new Dog('xiaole').say(); ... var Dog = /*#__PURE__*/function () { function Dog(name) { _classCallCheck(this, Dog); this.name = name; } _createClass(Dog, [{ key: "say", value: function say() { console.log(this.name)(); // {1} } }]); return Dog; }(); new Dog('xiaole').say();错误提示会定位了行{1},我们看到的不在是自己编写的源码,而是通过 babel 编译后的代码。
接下来我们通过配置 devtool,选择一种 source map 格式来增强调试过程。不同的值会明显影响到构建(build)和重新构建(rebuild)的速度。
Tip:Devtool 控制是否生成,以及如何生成 source map。
// webpack.config.js module.exports = { devtool: 'source-map' }