首页 > 其他分享 >热更新原理

热更新原理

时间:2023-11-17 17:34:58浏览次数:26  
标签:浏览器 dev server webpack 更新 模块 原理 js

(面试)说一下 webpack 的热更新原理?

webpack 通过 watch 可以监测代码的变化;webpack-dev-middleware 可以调用 webpack 暴露的 API 检测代码变化,并且告诉 webpack 将代码保存到内存中;webpack-dev-middleware 通过 sockjs 和 webpack-dev-server/client 建立 webSocket 长连接,将 webpack 打包阶段的各个状态告知浏览器端,最重要的是新模块的 hash 值。webpack-dev-server/client 通过 webpack/hot/dev-server 中的 HMR 去请求新的更新模块,HMR 主要借助 JSONP。先拿到 hash 的 json 文件,然后根据 hash 拼接出更新的文件 js,然后 HotModulePlugin 对比新旧模块和模块依赖完成更新。

搭建 webpack 环境

创建一个项目

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

webpack 版本

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

"devDependencies": {
  "webpack": "^5.74.0",
  "webpack-cli": "^4.10.0",
  "webpack-dev-server": "^4.9.3"
}

编写配置文件

// 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"),
  },
};

新建文件

// src/index.js
"use strict";
document.write("hello world~");

package.json 添加一条命令

"scripts": {
  "test": "echo \"Error: no test specified\" && exit 1",
  "dev": "webpack-dev-server --config webpack.dev.js --open"
},

npm run dev 运行
image

看到文件已经打包完成了,但是在 dist 目录里并没有看到文件,这是因为 WDS 是把编译好的文件放在缓存中,没有放在磁盘上,但是是可以访问到的,
output.js 对应在 webpack 配置文件中的输出文件,配置的是什么就访问什么
http://localhost:8080/output.js
显然想看效果而不是打包后的代码,所以在 dist 目录里创建一个 html 文件引入即可

<script src="./output.js"></script>

感受 webpack 的热更新

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

"use strict";
document.write("hello world~byebye world");

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

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

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

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

特性

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

保留在完全重新加载页面时丢失的应用程序状态。
只更新变更内容,以节省宝贵的开发时间。
调整样式更加快速 - 几乎相当于在浏览器调试器中更改样式。

启用

// 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(),
  ],
};

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

//index.js
import { test } from "./page1.js";
document.write("hello world~1234");
test();
//page1.js
module.exports = {
  test: function () {
    console.log(11111);
  },
};

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

if (module.hot) {
  module.hot.accept();
}

思考

标签:浏览器,dev,server,webpack,更新,模块,原理,js
From: https://www.cnblogs.com/wp-leonard/p/17839305.html

相关文章

  • # yyds干货盘点 # chrome老更新的话 driver怎么才能保持更新呢?
    大家好,我是皮皮。一、前言前几天在Python最强王者交流群【鶏啊鶏。】问了一个selenium驱动器的问题,一起来看看吧。问题描述:有没有selenium用的比较多的大佬 想问问一些selenium的定时任务 关于chrome老更新的话 driver怎么才能保持更新呢二、实现过程后来【瑜亮老师】给了一......
  • Babel原理及其使用
    Babel的包构成核心包babel-core:babel转译器本身,提供了babel的转译API,如babel.transform等,用于对代码进行转译。像webpack的babel-loader就是调用这些API来完成转译过程的。babylon:js的词法解析器babel-traverse:用于对AST(抽象语法树,想了解的请自行查询编译原理)......
  • chrome老更新的话 driver怎么才能保持更新呢?
    大家好,我是皮皮。一、前言前几天在Python最强王者交流群【鶏啊鶏。】问了一个selenium驱动器的问题,一起来看看吧。问题描述:有没有selenium用的比较多的大佬 想问问一些selenium的定时任务 关于chrome老更新的话 driver怎么才能保持更新呢二、实现过程后来【瑜亮老师】给......
  • Vue3 模板引用 ref 的实现原理
    什么是模板引用ref?有时候可以使用 ref attribute为子组件或HTML元素指定引用ID。<template><inputref="input"/></template><script>import{defineComponent,ref}from"vue";exportdefaultdefineComponent({setup(){......
  • Vue3 的 effect、 watch、watchEffect 的实现原理
    所谓watch,就是观测一个响应式数据或者监测一个副作用函数里面的响应式数据,当数据发生变化的时候通知并执行相应的回调函数。Vue3最新的watch实现是通过最底层的响应式类ReactiveEffect的实例化一个reactiveeffect对象来实现的。它的创建过程跟effectAPI的实现类似,所......
  • Vue插槽(Slot)的实现原理
    实现原理(简单文字)slot又名插槽,是Vue的内容分发机制,组件内部的模板引擎使用slot元素作为承载分发内容的出口。插槽slot是子组件的一个模板标签元素,而这一个标签元素是否显示,以及怎么显示是由父组件决定的。slot又分三类,默认插槽,具名插槽和作用域插槽实现原理:当子组件vm......
  • 微服务 Nacos 配置热更新
       ......
  • scoped实现原理及穿透方法
    何为scoped在vue文件中的style标签上,有一个特殊的属性:scoped。当一个style标签拥有scoped属性时,它的CSS样式就只能做用于当前的组件,也就是说,该样式只能适用于当前组件元素。经过该属性,可使得组件之间的样式不互相污染。若是一个项目中的全部style标签所有加上了sco......
  • Vue $nextTick原理
    作用:vue更新DOM是异步更新的,数据变化,DOM的更新不会马上完成,nextTick的回调是在下次DOM更新循环结束之后执行的延迟回调。实现原理:nextTick主要使用了宏任务和微任务。根据执行环境分别尝试采用Promise:可以将函数延迟到当前函数调用栈最末端MutationObserver:是H5新加......
  • vm.$set原理
    给对应和数组本身都增加了dep属性当给对象新增不存在的属性则触发对象依赖的watcher去更新当修改数组索引时,调用数组本身的splice去更新数组(数组的响应式原理就是重新了splice等方法,调用splice就会触发视图更新)splice();push();pop();shift();unshift();sort(......