本文针对热模块更换的哪些方面?

Posted

技术标签:

【中文标题】本文针对热模块更换的哪些方面?【英文标题】:What aspect of Hot Module Replacement is this article for? 【发布时间】:2016-08-29 05:44:51 【问题描述】:

我正在学习 Webpack,遇到了this article。 我大致了解什么是热模块更换 (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' 

        ]
    


我的问题是this article 的哪个方面试图解释 Webpack 热模块替换?我在哪里可以使用该页面上提供的示例代码?

简而言之,我的问题是this 到底是什么?

【问题讨论】:

【参考方案1】:

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

但是,这只有在代码提供特殊挂钩来删除以前的代码、撤消所有副作用并注入新代码的情况下才有可能。典型的副作用:注册事件监听器、在对象中存储数据、修改全局状态。

例如,在应用程序运行时替换 CSS 是一件容易的事,因为 CSS 根据定义是无副作用的。为了了解HMR的内部,我们来看看style-loader:

样式加载器附加 this special code 来处理 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();
    );

if (module.hot) 检查是否启用了 HMR module.hot.accept(&lt;module identifier&gt;, handler) 注册一个处理程序以注入新代码 module.hot.dispose(handler) 注册一个处理程序来处理旧代码

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

React 中的 HMR 稍微复杂一些,并且在过去几个月中经历了一些严重的重构。但基本原则是每个导出的组件都包装在代理中。代理是一个像另一个对象一样工作的对象。这可以通过将所有功能转发到“真实”对象或使用ES2015 proxies(显然更强大)来实现。这样,原始对象可以很容易地被换出,而无需更新任何其他组件。我在another SO answer 中对此进行了更详细的描述。


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

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

您需要客户端和服务器上的一些基础设施来建立 WebSockets 连接,将新代码推送到客户端并通知所有过时的模块来处理更新。实现这一点的最简单方法是使用带有webpack-dev-server --hot --inline 的 webpack-dev-server。不需要其他代码。特别是不要将 HMR 插件或任何 webpack-dev-server 的东西添加到 webpack.config.js 中——它们都将通过 --hot --inline 启用。有更多的方法来配置它——这实际上可能是需要的,具体取决于您的设置。这就是为什么这部分经常让新手感到困惑的原因。

Webpack 需要在监视模式下运行,因为我们只想处理更改的文件。当您使用webpack-dev-serverwebpack-dev-middleware 时,您不需要在配置中添加任何内容,它已经放置了webpack compiler into watch-mode(当然,仅在lazy: false 的情况下)。

【讨论】:

我注意到 webpack-dev-server --hot --inline ,即使我省略了 --hot ,HMR 仍然有效。你能帮我理解为什么吗? 您的webpack.config.js 中是否也应用了HMR 插件。您应该添加插件使用--hot 调用它

以上是关于本文针对热模块更换的哪些方面?的主要内容,如果未能解决你的问题,请参考以下文章

搞懂RTOS 需要哪些方面的知识储备

实时重载、热重载和热模块更换之间的概念区别是啥?

AspectJ:如何限制目标的哪些方面

针对android 都有哪些关于访问访问方面的权限

Laravel 5 Vue 热模块更换(HMR)

热模块更换 - 更新但不重新渲染