webpack 快速构建 React 学习环境(2)-- 热更新

简介: 上一篇文章 《webpack 快速构建 React 学习环境(1)》中介绍了构建一个最简单开发环境,这里接着完善这个开发环境,让它用起来更加的趁手。

上一篇文章 《webpack 快速构建 React 学习环境(1)》中介绍了构建一个最简单开发环境,这里接着完善这个开发环境,让它用起来更加的趁手。

看着篇文章前请先看 《webpack 快速构建 React 学习环境(1)》

本小结内容对应构建的项目源码:github.com/wewin11235/…,仓库的 stage2 分支

文章同步发布在个人博客站点

上一篇中构建的开发环境存在的问题

上一节搭建的开发环境不能热加载,每次文件改动后都需要重新编译,手动刷新页面。虽然使用 webpack --watch 命令在文件变化后能重新编译,但是仍需要手动刷新页面。webpack --watch 的方式还有个缺点,每次都是重新编译生成新的文件到 build 目录下, 文件多的时候这个编译过程就会慢。

webpack-dev-server 配合 HRM 可以构建一个完美的开发环境,改动保存后自动编译,无需手动刷新页面。

使用 webpack-dev-server

webpack-dev-server 主要是启动了一个使用 express 的 Http 服务器。它的作用主要是用来伺服资源文件。此外这个Http服务器和client使用了websocket通讯协议,原始文件作出改动后,webpack-dev-server 会实时的编译. webpack-dev-server 的时时编译并不会输出到 webpack.config.js 中指定的出口,编译生成的文件在内存中,也有效的提高了编译效率。

安装与配置:

npm in webpack-dev-server -D
复制代码

安装完成后: ./node_modules/.bin/webpack-dev-server 便可启动 server


ℹ 「wds」: Project is running at http://localhost:8081/
ℹ 「wds」: webpack output is served from /./
 「wdm」: Hash: b2af4145bdae26f19266
复制代码

dev server 被启动在了 8081 端口, server 会默认找项目主目录下的 index.html 文件作为服务的根页面。 由于我们编译后的服务入口文件 index.html 放在 build 目录下,所以要对 webpack-dev-server 做一下配置:

webpack.config.js 增加如下配置:

devServer: {
    contentBase: path.join(__dirname, 'build')
}
复制代码

此时 webpack.config.js :

const path = require('path');
var HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: './src/index.js',
  output: {
    path: path.resolve(__dirname, 'build'),
    filename: '[name].[hash:8].js',
    publicPath: '/',
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /(node_modules)/,
        use: {
          loader: 'babel-loader'
        },
      },
    ],
  },
  plugins: [new HtmlWebpackPlugin({
    filename: 'index.html',
    template: 'src/index.html'
  })],
  devServer: {
    contentBase: path.join(__dirname, 'build'),
  }
};
复制代码

这样就可以访问 http://localhost:8081 查看启动的服务。

此时 dev server 虽然启动,但尝试修改 index.js 内容可以发现页面并不能自动刷新,webpack dever server 的自动刷新有两种模式 Iframe 和 inline 两种模式,这里用 inline 模式,修改配置如下:

const path = require('path');
var HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: './src/index.js',
  output: {
    path: path.resolve(__dirname, 'build'),
    filename: '[name].[hash:8].js',
    publicPath: '/',
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /(node_modules)/,
        use: {
          loader: 'babel-loader'
        },
      },
    ],
  },
  plugins: [
    new HtmlWebpackPlugin({
      filename: 'index.html',
      template: 'src/index.html'
    })
  ],
  devServer: {
    contentBase: path.join(__dirname, 'build'),
    port: 9000,   // 指定服务启动在 9000 端口
     inline: true,  // inline 模式启动
     open: true  // 执行webpack-dev-server 后自动打开浏览器
  }
};
复制代码

上面的配置,当文件有更新,你会发现浏览器刷新了,配置 HMR 可以实现局部热替换,不用整个浏览器刷新。HMR 的配置请参考 [hot-module-replacement] (https://webpack.docschina.org/guides/hot-module-replacement)。 react 框架下还需要用到 react-hot-loader

开启 HotModuleReplace

改动有以下几处: 添加 src/print.js 文件

export default function printMe() {
  console.log("Updating print.js...");
}
复制代码

修改 webpack.config.js 文件,添加 hot 配置:

const path = require('path');
const webpack = require("webpack");
var HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: './src/index.js',
  output: {
    path: path.resolve(__dirname, 'build'),
    filename: '[name].[hash:8].js',
    publicPath: '/',
  },
  mode: 'development',
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /(node_modules)/,
        use: {
          loader: 'babel-loader'
        },
      },
    ],
  },
  plugins: [
    new HtmlWebpackPlugin({
      filename: 'index.html',
      template: 'src/index.html'
    }),
    new webpack.NamedModulesPlugin(),
    new webpack.HotModuleReplacementPlugin()
  ],
  devServer: {
    contentBase: path.join(__dirname, 'build'),
    port: 9000,
    open: true,  // HMR 支持
    hot: true
  }
};
复制代码

src/index.js 文件如下:

import React from 'react';
import ReactDOM from 'react-dom';
import { hot } from 'react-hot-loader'

class HelloReact extends React.Component{
  constructor(props) {
    super(props);
  }

  render(){
    return( <div>Hello  React</div>);
  }
}

export default hot(module)(HelloReact);

ReactDOM.render(<HelloReact />, document.getElementById('root'));

if (module.hot) {
  module.hot.accept('./print.js', function(){
      console.log("Accepting the updated printMe module!");
      printMe();
  })
}
复制代码

React 框架下热更新支持(react-hot-loader)

安装 react-hot-loader

npm i react-hot-loader -D
复制代码

修改 .babelrc 如下

{
  "presets": [
    ["@babel/preset-env", {
      "targets": {
        "node": "current"
      }
    }],
    "@babel/preset-react"
  ],
  "plugins": ["react-hot-loader/babel"]  //添加 ‘react-hot-loader/babel’ 这个插件支持
}
复制代码

在使用的时候改变下 React 组件的 export 的方式,如我们的 src/index.js 文件修改为如下:

import React from 'react';
import ReactDOM from 'react-dom';
import { hot } from 'react-hot-loader';  // 引入 hot 模块

class HelloReact extends React.Component{
  constructor(props) {
    super(props);
  }

  render(){
    return( <div>Hello  React</div>);
  }
}

export default hot(module)(HelloReact);  //修改 export 时候的方式

ReactDOM.render(<HelloReact />, document.getElementById('root'));

if (module.hot) {
  module.hot.accept('./print.js', function(){
      console.log("Accepting the updated printMe module!");
      printMe();
  })
}
复制代码

此时运行 ./node_modules/.bin/webpack-dev-server --mode=development ,再尝试修改 index.js 内容你会发现页面更新了,但是浏览器并没有刷新。

这样我们就构建了一个自动编译,自动更新的 React 的开发环境。

重构示例 react-demo

这个重构和开发环境搭建无关,只是在引入了 react-hot-loader 后,会发现现在的 src/index.js 此时显得很不优雅,这给因为 ReactHello 作为一个组件本就应该抽取为一个独立的文件:

新建文件:src/ReactHello.js:

import React from 'react';
import { hot } from 'react-hot-loader'

class HelloReact extends React.Component{
  constructor(props) {
    super(props);
  }

  render(){
    return( <div>Hello React</div>);
  }
}

export default hot(module)(HelloReact);
复制代码

调整 src/index.js:

import React from 'react';
import ReactDOM from 'react-dom';
import HelloReact from './HelloReact.js';

ReactDOM.render(<HelloReact />, document.getElementById('root'));

if (module.hot) {
  module.hot.accept('./print.js', function(){
      console.log("Accepting the updated printMe module!");
      printMe();
  })
}
复制代码

这样看着就舒服多了。

文章配合使用的 Demo 地址:github.com/wewin11235/… 仓库的 stage2 分支



原文发布时间为:2018年06月29日

作者:蚂蚁哈哈哈

本文来源: 掘金  如需转载请联系原作者
相关文章
|
27天前
|
前端开发
配置 Webpack 实现热更新
【10月更文挑战第23天】还可以进一步深入探讨热更新的具体实现细节、不同场景下的应用案例,以及如何针对特定需求进行优化等方面的内容。通过全面、系统地了解 Webpack 热更新的配置方法,能够更好地利用这一功能,提升项目的开发效率和性能表现。同时,要不断关注 Webpack 及相关技术的发展动态,以便及时掌握最新的热更新技术和最佳实践。
|
2月前
|
JavaScript
webpack学习三:webpack初始化整合配置vue,一步一步的抽离代码块整合vue。
这篇文章是关于如何在webpack环境中配置Vue.js,包括安装Vue.js、解决报错、理解el与template的区别、使用SPA模式、抽离模板为对象、封装为单独的js文件、安装vue-loader时遇到的问题及解决方案,以及整个过程的总结。
72 2
webpack学习三:webpack初始化整合配置vue,一步一步的抽离代码块整合vue。
|
2月前
|
JavaScript
webpack学习五:webpack的配置文件webpack.config.js分离,分离成开发环境配置文件和生产环境配置文件
这篇文章介绍了如何将webpack的配置文件分离成开发环境和生产环境的配置文件,以提高打包效率。
48 1
webpack学习五:webpack的配置文件webpack.config.js分离,分离成开发环境配置文件和生产环境配置文件
|
2月前
|
JavaScript 前端开发 Java
webpack学习一:什么是模块化开发,什么是webpack,以及二者之间的关系。
这篇文章介绍了模块化开发的概念、历史和实现方式,以及webpack作为一个现代JavaScript应用的静态模块打包工具,它如何帮助我们将ES6等高级语法打包成浏览器可以识别的低级语法,并解释了npm在webpack安装和使用中的作用。
42 1
webpack学习一:什么是模块化开发,什么是webpack,以及二者之间的关系。
|
27天前
|
缓存 监控 算法
提高 Webpack 热更新的性能
【10月更文挑战第23天】还可以进一步深入探讨热更新性能优化的具体案例、不同场景下的优化策略,以及与其他相关技术的结合应用等方面的内容。通过全面、系统地了解热更新性能优化的方法和技巧,能够更好地利用这一功能,为项目的成功开发提供有力保障。同时,要不断关注技术的发展动态,以便及时掌握最新的热更新技术和最佳实践。
|
27天前
|
自然语言处理 前端开发 开发工具
webpack 热更新
【10月更文挑战第23天】Webpack 热更新是一项非常实用的技术,它为前端开发带来了极大的便利和效率提升。通过深入了解其原理和应用,开发者可以更好地利用热更新功能,提高开发质量和速度。
|
27天前
|
缓存 监控
webpack 提高构建速度的方式
【10月更文挑战第23天】需要根据项目的具体情况和需求,综合运用这些方法,不断进行优化和改进,以达到最佳的构建速度和效果。同时,随着项目的发展和变化,还需要持续关注和调整构建速度的相关措施,以适应不断变化的需求。
|
27天前
|
存储 缓存 前端开发
利用 Webpack 5 的持久化缓存来提高构建效率
【10月更文挑战第23天】利用 Webpack 5 的持久化缓存是提高构建效率的有效手段。通过合理的配置和管理,我们可以充分发挥缓存的优势,为项目的构建和开发带来更大的便利和效率提升。你可以根据项目的实际情况,结合以上步骤和方法,进一步优化和完善利用持久化缓存的策略,以达到最佳的构建效果。同时,不断探索和实践新的方法和技术,以适应不断变化的前端开发环境和需求。
|
2月前
|
移动开发 JavaScript 前端开发
webpack学习四:使用webpack配置plugin,来使用HtmlWebpackPlugin、uglifyjs-webpack-plugin、webpack-dev-server等插件简化开发
这篇文章主要介绍了如何通过配置Webpack的插件,如HtmlWebpackPlugin、uglifyjs-webpack-plugin和webpack-dev-server,来简化前端开发流程。
51 0
webpack学习四:使用webpack配置plugin,来使用HtmlWebpackPlugin、uglifyjs-webpack-plugin、webpack-dev-server等插件简化开发
|
6月前
|
缓存 JavaScript 前端开发
探讨如何通过一系列优化策略来提升TypeScript与Webpack的构建性能。
【6月更文挑战第11天】本文探讨了优化TypeScript与Webpack构建性能的策略。理解Webpack的解析、构建和生成阶段是关键。优化包括:调整tsconfig.json(如关闭不必要的类型检查)和webpack.config.js选项,启用Webpack缓存,实现增量构建,代码拆分和懒加载。通过这些方法,可以提升构建速度,提高开发效率。
79 0
下一篇
无影云桌面