神奇的HMR

作者: snow_in | 来源:发表于2018-12-05 19:33 被阅读0次

模块热替换(Hot Module Replacement 简称HMR),就是当对代码做了修改并保存后,修改结果会直接反应在应用中而不用刷新浏览器。这个过程包括了两个步骤,一是保存后webpack重新打包;二是浏览器进行新老模块的替换,将新的结果反应在浏览器上。

两个过程对应着两个webpack插件的使用:webpack-dev-middleware和 webpack-hot-middleware,我们就来看一下如何利用这两个插件实现HMR。

假设已经创建了webpack.dev.conf.js配置文件.
build/setup-dev-server.js:

const path = require('path');
const webpack = require('webpack');
const webpackConfig = require('./webpack.dev.conf');
const DevMiddleware = require('webpack-dev-middleware');
const hotMiddleware = require('webpack-hot-middleware');

module.exports = function setupDevServer (app, opts) {
  webpackConfig.entry.app = ['webpack-hot-middleware/client', webpackConfig.entry.app]; // 入口文件添加'webpack-hot-middleware/client',服务端能够和客户端通信的关键
  webpackConfig.output.filename = '[name].js';
  webpackConfig.plugins.push(
    new webpack.HotModuleReplacementPlugin(),
    new webpack.NoEmitOnErrorsPlugin()
  );

  const compiler = webpack(webpackConfig); // 以webpack.dev.conf.js文件为基础,创建一个用来传给webpack-dev-middleware的对象
  const devMiddleware = DevMiddleware(compiler, {
    publicPath: webpackConfig.output.publicPath, // 必传参数,和webpack.dev.conf.js文件里面的publicPath一致
    stats: { colors: true, chunks: false }
  });
  app.use(devMiddleware); // 添加中间件,告诉express使用webpack-dev-middleware插件

  compiler.plugin('done', () => { // 钩子函数被调用时客户端检查模块更新
    const fs = devMiddleware.fileSystem;
    const filePath = path.join(webpackConfig.output.path, 'index.html');
    if (fs.existsSync(filePath)) {
      const template = fs.readFileSync(filePath, 'utf-8');
      opts.templateUpdated(template);
    }
  });
  app.use(hotMiddleware(compiler));
}

server.js:

const express = require('express');
const app = express();

const noDevelop = process.env.NODE_ENV !== 'develop';
const resolve = file => path.resolve(__dirname, file);
let tempHTML;

//...其他代码

if (!noDevelop) {
  const setupDevServer = require('./build/setup-dev-server');
  setupDevServer(app, {
    templateUpdated: (template) => {
      tempHTML = template;
    }
  });
} else {
  tempHTML = fs.readFileSync(resolve('./dist/index.html'));
}

app.get('*', (req, res, next) => {
  res.end(tempHTML);
  next();
})

app.listen('7777', function () {
  
});

然后在package.json的scripts添加一条命令:

"dev": "cross-env NODE_ENV=develop node server.js"

执行npm run dev就可以运行了。

相关文章

  • 神奇的HMR

    模块热替换(Hot Module Replacement 简称HMR),就是当对代码做了修改并保存后,修改结果会直...

  • 从这十几个方面优化你的 Webpack 配置

    开发环境性能优化 优化打包构建速度 HMR 优化代码调试 source-map HMR 概念:「HMR:」 hot...

  • HMR

    描述 HMR 全称 Hot Module Replacement,即模块热更新。 当代码变更时,局部替换掉部分模块...

  • webpack之热更新/替换

    模块热替换(HMR)什么是模块热替换HMR(Hot Module Replacement),在应用程序运行过程中,...

  • webpack2搭建开发环境

    开发环境 本文主要介绍使用webpack2进行前端开发以及编译发布文件,主要涉及: HMR - React HMR...

  • Angular hmr

    先决条件 angular cli 至少 1.0.0-beta.22 以上版本 创建项目 使用Angular CLI...

  • react-hot-loader fixbug

    [HMR] Update check failed: Error: Failed to execute 'open...

  • webpack 之 hot module replacement

    hot module replacement (HMR): It allows all kinds of modu...

  • Angular7 热更新

    说明 1、HMR的好处是:开发的时候不需要每次都整体刷新浏览器,只替换被修改过的模块2、不要把HMR在生产环境里面...

  • webpack实践(5)-- 模块热替换

    模块热替换(HMR) 这个功能允许在运行时更新所有类型的模块,而不是完全刷新。但是HMR不适合生产环境,也就是说它...

网友评论

    本文标题:神奇的HMR

    本文链接:https://www.haomeiwen.com/subject/tyowcqtx.html