webpack热更新原理(面试大概率会问)

2022-10-10 19:35:45 浏览数 (1)

搭建webpack环境

创建一个项目
代码语言:javascript复制
mkdir dev-erver && cd dev-server
npm init -y // 快速创建一个项目配置
npm i webpack webpack-dev-server webpack-cli --save-dev
mkdir src // 创建资源目录
mkdir dist // 输出目录
touch webpack.dev.js // 因为是在开发环境需要热更新,所以直接创建dev配置文件
目录结构
image.pngimage.png
webpack版本

这里说明一下,webpack4和webpack5的配置信息或者显示信息可能有点区别

代码语言:javascript复制
  "devDependencies": {
    "webpack": "^5.74.0",
    "webpack-cli": "^4.10.0",
    "webpack-dev-server": "^4.9.3"
  }
编写配置文件
代码语言:javascript复制
// webpack.dev.js

'use strict';

const path = require('path');

module.exports = {
    entry: './src/index.js', // 入口文件
    output: {
        path: path.resolve(__dirname, 'dist'), // 输出到哪个文件夹
        filename: 'output.js' // 输出的文件名
    },
    mode: 'development', // 开发模式
    devServer: {
        // contentBase: path.resolve(__dirname, 'dist')  // contentBase是用来指定被访问html页面所在目录的;
        //但是我本地报错了,使用下面的语句
    static: path.resolve(__dirname, "dist")

    }
};
新建文件
代码语言:javascript复制
// src/index.js

'use strict' 

document.write('hello world~')
package.json添加一条命令
代码语言:javascript复制
  "scripts": {
    "test": "echo "Error: no test specified" && exit 1",
    "dev": "webpack-dev-server --config webpack.dev.js --open"
  },

npm run dev 运行

image.pngimage.png

我们看到文件已经打包完成了,但是在dist目录里并没有看到文件,这是因为WDS是把编译好的文件放在缓存中,没有放在磁盘上,但是我们是可以访问到的,

output.js 对应你在webpack配置文件中的输出文件,配置的是什么就访问什么

http://localhost:8080/output.js

显然我们想看效果而不是打包后的代码,所以我们在dist目录里创建一个html文件引入即可,参考webpack视频讲解:进入学习

代码语言:javascript复制
<script src="./output.js"></script>

感受webpack的热更新

内容出来了,我们接下来修改index.js文件,来看下是否可以自动刷新

代码语言:javascript复制
'use strict' 

document.write('hello world~byebye world')

这确实是热更新,但是这种是每一次修改会重新刷新整个页面,大家可以打开控制台查看。webpack-dev-server 提供了实时重加载的功能,但是不能局部刷新。必须配合后两步的配置才能实现局部刷新,这两步的背后其实是借助了HotModuleReplacementPlugin。

webpack-dev-server搭配HotModuleReplacementPlugin 实现热更新

我们需要的是,更新修改的模块,但是不要刷新页面。这个时候就需要用到模块热替换。

模块热替换(Hot Module ReplacementHMR)是 webpack 提供的最有用的功能之一。它允许在运行时更新各种模块,而无需进行完全刷新。

特性

模块热替换(HMR - Hot Module Replacement)功能会在应用程序运行过程中替换、添加或删除模块,而无需重新加载整个页面。主要是通过以下几种方式,来显著加快开发速度:

  • 保留在完全重新加载页面时丢失的应用程序状态。
  • 只更新变更内容,以节省宝贵的开发时间。
  • 调整样式更加快速 - 几乎相当于在浏览器调试器中更改样式。
启用
代码语言:javascript复制
// webpack.dev.js

const path = require('path');
const webpack = require('webpack'); // 主要多了这一行

module.exports = {
    entry: './src/index.js', // 入口文件
    output: {
        path: path.resolve(__dirname, 'dist'), // 输出到哪个文件夹
        filename: 'output.js' // 输出的文件名
    },
    mode: 'development', // 开发模式
    devServer: {
        // contentBase: path.resolve(__dirname, 'dist')  // contentBase是用来指定被访问html页面所在目录的;但是我本地报错了,使用下面的语句
        static: path.resolve(__dirname, "dist"),
        hot: true // 主要多了这一行

    },
    plugins: [ //  主要多了这一行
        new webpack.HotModuleReplacementPlugin()
    ]
};

我们修改一下文件,形成引用关系

代码语言:javascript复制
//index.js

import { test } from './page1.js' 

document.write('hello world~1234')

test()
代码语言:javascript复制
//page1.js

module.exports = {
  test: function () {
    console.log(11111)
  }
}

在入口页index.js面再添加一段

代码语言:javascript复制
if (module.hot) {
    module.hot.accept();
}

思考

0 人点赞