Step1: enable webpackage 4.0+ heat replacement

  1. Install NPM [email protected] [email protected] babel-loader @babel/[email protected] @babel/[email protected] [email protected] html-webpack-plugin -D

@babel/[email protected] @babel/[email protected], parse the JS file, Babel /preset-env advanced syntax into low-level syntax; Html-webpack-plugin parses template HTML files;

  1. Install react react- dom@babel /preset-react -D

React syntax

  1. Configuration webpack. Config. Js

Description: the most important thing is devServer: hot hotOnly (browser does not automatically refresh) and the webpack plug-in NamedModulesPlugin plugins, HotModuleReplacementPlugin;

const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const webpack = require("webpack");
module.exports = {
  devServer: {
    port: 3000.open: true.// Automatically open the browser,
    contentBase: path.resolve(__dirname, 'build'),
    hot: true.// Turn on heat switch
    hotOnly: true , // Even if the HMR is not in effect, the browser will not automatically update must be set
  },
  entry: './src/index.js'.mode: 'development'.output: {
    filename: 'build.js'.path: path.resolve(__dirname, 'build')},devtool: 'eval-source-map'.module: {
    rules: [{
      test: /\.js$/.exclude: /node_modules/.include: path.resolve(__dirname, 'src'),
      use: [{
        loader: 'babel-loader'.options: {
          presets: [
            '@babel/preset-env'.'@babel/preset-react']}}]}},plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html'.filename: 'index.html'
    }),
    new webpack.NamedModulesPlugin(), // Print out the path of those changed files
    new webpack.HotModuleReplacementPlugin(), // Hot replace component]}Copy the code

Step2: replace the root component with HMR

  1. To use HMR, code like this:
  // root.js
  import React from 'react';

  export default class Root extends React.Component{
    render(){
      return <div>Test</div>}}Copy the code
  import React from 'react';
  import {render} from 'react-dom';

  import RootContainer from './root.js';
  render(<RootContainer></RootContainer>.document.getElementById('root'));
Copy the code
  1. Add heat substitution, code like this
import React from 'react';
import ReactDOM from 'react-dom';

import RootContainer from './root.js';

const render = (App) = > {
  ReactDOM.render(<App />, document.getElementById('root')); } render(RootContainer) if(module.hot){module.hot.accept('./root.js', ()=>{console.log('root updates... '); // const NextRootContainer = require('./root.js').default; render(NextRootContainer) }); }Copy the code

Note: the red box the console log and webpack. NamedModulesPlugin () printed more xinwen a path; The figure is as follows:

  1. Create a Component Demo and import it in root.js
  // demo.js
  import React from 'react';
  export default class Demo extends React.Component{
    render(){
      return <div>Demo</div>}}Copy the code
  // root.js
  import React from 'react';
  import Demo from './demo.js';

  export default class Root extends React.Component{
    render(){
      return <div>
        <div>Test</div>
        <Demo></Demo>
      </div>}}Copy the code

Running results:

When you update root.js Test to Test1, the result shows that root.js has changed, and the Demo component update path is not displayed, as shown in the following figure:

Change demo.js Demo to Demo1, the root Demo is updated, because Demo is the root component, the root path is also displayed, as shown in the following figure:

note: Add state to root, code address, Test text to Test1, same thing Demo to Demo1, when we change aa to AAA, Test1 becomes Test Demo1 becomes Demo; State is not saved; The results are as follows:

Note: Without further steps, this is enough to hot-reload changes in response to components, but their internal component state will not be retained because a new copy of the component has been mounted and its state will be reinitialized. State stored outside of a state store, such as Redux, is obviously not lost.

Step3: Add React Hot Loader to save component status

  1. Install react-hot-loader NPM I react-hot-loader -d

  2. Modify webpack.config.js configurations

  // old
  {
    test: /\.js$/.exclude: /node_modules/.include: path.resolve(__dirname, 'src'),
    use: [{
      loader: 'babel-loader'.options: {
        presets: [
          '@babel/preset-env'.'@babel/preset-react']]}}}Copy the code
// new 
{
  test: /\.js$/.exclude: /node_modules/.include: path.resolve(__dirname, 'src'),
  use: [{
    loader: 'react-hot-loader/webpack'}, {loader: 'babel-loader'.options: {
      presets: [
        '@babel/preset-env'.'@babel/preset-react']."plugins": [ "react-hot-loader/babel"]]}}}Copy the code
  1. Update entry and modify index.js
entry: './src/index.js'.Copy the code

to

entry: ['react-hot-loader/patch'.'./src/index.js']
Copy the code
  // index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { AppContainer } from 'react-hot-loader';
import RootContainer from './root.js';

const render = (App) = > {
  ReactDOM.render(
    <AppContainer>
      <App />
    </AppContainer>.document.getElementById('root'));
} 

render(RootContainer)

if(module.hot){
  module.hot.accept('./root.js', () = > {console.log('Root' updated... '); // display in the browser
    const NextRootContainer = require('./root.js').default;
    render(NextRootContainer)
  });
}
Copy the code

Test1 Demo1 does not change