热门模块更换的哪个方面是本文的目的?

Nic*_*.Xu 3 webpack webpack-dev-server

我正在学习Webpack并遇到这篇文章.我对什么是热模块替换(HMR)有一般的了解.我可以通过以下示例代码配置webpack HMR插件:

var plugins = [ new webpack.HotModuleReplacementPlugin(), // using HMR plugin
            new HtmlWebpackPlugin({template: './index.html'})
        ]; 

module.exports = {
    // webpack config object
    context: entryBasePath,
    entry:{
        app: ['webpack/hot/dev-server', './bootstrap.js']
    },
    output: {
        path: outputBasePath,
        filename: './bundle.js',
        sourceMapFilename: '[file].map' // set source map output name rule
    },
    devtool: 'source-map', // enable source map
    plugins: plugins, 
    module: {
        loaders: [
            { test: /\.scss$/, loader: 'style!css!sass'}, 
            { test: /\.tpl$/,  loader: 'raw' }, 
            {
        test: /\.woff2?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
        loader: 'url?limit=10000'
      },
      {
        test: /\.(ttf|eot|svg)(\?[\s\S]+)?$/,
        loader: 'file'
      },
      { test: /bootstrap-sass\/assets\/javascripts\//, loader: 'imports?jQuery=jquery' }

        ]
    }

}
Run Code Online (Sandbox Code Playgroud)

我的问题是本文的哪个方面试图解释Webpack Hot Module Replacement?我在哪里可以使用该页面上提供的示例代码?

总之,我的问题是什么(地狱)是这个呢?

Joh*_*ald 7

热模块替换(HMR)是在应用程序运行时交换代码的功能.它允许您在保留应用程序状态的同时编辑代码.这对样式特别有用,您通常只想在不重新加载浏览器的情况下更新样式.

但是,只有在代码提供了特殊的钩子来删除前面的代码,撤消所有副作用并注入新代码时,才能实现这一点.典型的副作用:注册事件侦听器,将数据存储在对象中,修改全局状态.

例如,在应用程序运行时替换CSS是一项简单的任务,因为CSS根据定义是无副作用的.为了理解HMR的内部结构,让我们来看看样式加载器:

样式加载器附加这个特殊代码来处理HMR(我删除了一些对这个例子来说不重要的代码):

if (module.hot) {
    // When the styles change, update the <style> tags
    module.hot.accept(loaderUtils.stringifyRequest(this, !!remainingRequest), function () {
        var newContent = require(loaderUtils.stringifyRequest(this, !!remainingRequest));
        update(newContent);
    });
    // When the module is disposed, remove the <style> tags
    module.hot.dispose(function () {
        update();
    });
}
Run Code Online (Sandbox Code Playgroud)
  • if (module.hot) { 检查,如果启用了HMR
  • module.hot.accept(<module identifier>, handler) 注册一个处理程序来注入新代码
  • module.hot.dispose(handler) 注册处理程序以处理旧代码

update函数很难阅读,但它基本上只是添加新的样式表document.head并删除未使用的样式表.

React中的HMR有点复杂,并且在过去几个月中经历了一些严重的重构.但基本原则是每个导出的组件都包含在代理中.代理是一个像另一个对象一样的对象.这可以通过将所有函数转发到"真实"对象或使用ES2015代理(显然更强大)来实现.这样,可以轻松地换出原始对象而无需更新任何其他组件.我在另一个SO答案中详细描述了这一点.


为了使HMR工作,需要满足一些要求:

  • 您的代码需要挂钩module.hot.acceptmodule.hot.dispose处理代码更新.这通常通过加载器(例如,样式加载器)或babel变换(例如,babel-preset-react-hmre预设)来实现.从技术上讲,你可以为每个模块编写这些钩子......也许这是开始学习内部的好方法.如果更新的模块不包含此代码或无法处理更新,则更新将被拒绝,webpack将重新加载浏览器窗口.这可能看起来像HMR,但实际上只是浏览器刷新.

  • 您需要在客户端和服务器上使用一些基础结构来建立WebSockets连接,将新代码推送到客户端并通知所有过时的模块来处理更新.实现这一目标的最简单方法是使用webpack-dev-server webpack-dev-server --hot --inline.不需要其他代码.特别是不要添加HMR插件或任何webpack-dev-server的东西webpack.config.js- 它将全部启用--hot --inline.有更多方法可以配置 - 根据您的设置,实际上可能需要这些方法.这通常是为什么这部分通常会让新人感到困惑的原因.

  • Webpack需要在监视模式下运行,因为我们只想处理更改的文件.当您使用webpack-dev-server或者webpack-dev-middleware它时,您不需要向配置添加任何内容,它已经将webpack编译器置于监视模式(lazy: false当然,仅在情况下).