粥里有勺糖

vuePress-theme-reco 粥里有勺糖    2018 - 2023
粥里有勺糖 粥里有勺糖

Choose mode

  • dark
  • auto
  • light
关于我
备战春秋
  • 心得总结
  • 校招考点汇总
  • 面经汇总
  • 复习自查
技术笔记
  • 技术教程
  • 模板工程
  • 源码学习
  • 技术概念
  • 个人作品
  • 学习笔记
计算机基础
  • 算法与数据结构
  • 操作系统
  • 计算机网络
  • 设计模式
  • 剑指offer
大前端
  • javascript
  • vue
  • html
  • css
  • 🌏浏览器专题
  • Web性能优化
  • regexp
  • node
面试
  • 问解
  • javascript
  • css
  • 手撕代码
  • 性能优化
  • 综合问题
  • 面经汇总
  • 小程序
手撕代码
  • 数据结构与算法
  • javascript
  • css
个人站点
  • GitHub (opens new window)
  • 博客园 (opens new window)
  • 掘金 (opens new window)
线上作品
  • 轻取(文件收集) (opens new window)
  • 个人图床 (opens new window)
  • 考勤小程序 (opens new window)
  • 时光恋人 (opens new window)
  • 在线简历生成 (opens new window)
留言板
Github (opens new window)
author-avatar

粥里有勺糖

285

文章

40

标签

关于我
备战春秋
  • 心得总结
  • 校招考点汇总
  • 面经汇总
  • 复习自查
技术笔记
  • 技术教程
  • 模板工程
  • 源码学习
  • 技术概念
  • 个人作品
  • 学习笔记
计算机基础
  • 算法与数据结构
  • 操作系统
  • 计算机网络
  • 设计模式
  • 剑指offer
大前端
  • javascript
  • vue
  • html
  • css
  • 🌏浏览器专题
  • Web性能优化
  • regexp
  • node
面试
  • 问解
  • javascript
  • css
  • 手撕代码
  • 性能优化
  • 综合问题
  • 面经汇总
  • 小程序
手撕代码
  • 数据结构与算法
  • javascript
  • css
个人站点
  • GitHub (opens new window)
  • 博客园 (opens new window)
  • 掘金 (opens new window)
线上作品
  • 轻取(文件收集) (opens new window)
  • 个人图床 (opens new window)
  • 考勤小程序 (opens new window)
  • 时光恋人 (opens new window)
  • 在线简历生成 (opens new window)
留言板
Github (opens new window)
  • devlearn

    • 开发教程
    • 实践:利用ArrayBuffer实现预览指定目录下的所有文件的内容
    • 在linux-deepin上使用deepin-wine5完美运行腾讯会议/QQ/微信等此类应用
    • eslint插件开发教程
    • ServerLess之云函数实践-天气API
    • 移动端阻止弹窗下层页面被滑动
    • 小技巧:for of中获取index
    • Git常用的一些基本操作
    • 向页面注入js实现为图片和文字元素添加透明蒙层
    • 实践:使用jsencrypt配合axios实现非对称加密传输的数据
    • 封装dotenv库实现类似Vite加载环境变量的行为
    • 30行代码实现合并指定目录下的所有文件的内容
    • 马上中秋了,把鼠标指针变为小玉兔
    • Node中require与fs.readFile读取JSON文件的对比
    • 使用免费的七牛云OSS(10G)搭建个人的在线图床
    • 分享封装的一些七牛云OSS操作方法
    • 本地配置SSH免密远程登录服务器
    • 工具方法汇总
    • 腾讯云Serverless实践-Node.js服务部署
    • 腾讯云Serverless实践-静态网站托管
    • 为什么'\x1B'.length === 1?\x与\u知识延伸
    • Vite插件开发纪实:vite-plugin-monitor(上)
    • Vite插件开发纪实:vite-plugin-monitor(中)
    • Vite插件开发纪实:vite-plugin-monitor(下)
    • 解决Vite-React项目中js使用jsx语法报错的问题
    • webpack 项目接入Vite的通用方案介绍
    • webpack 项目接入Vite的通用方案介绍-草稿
    • 优雅的处理挂载window上的函数可能不存在的情况
    • Mac上抓包秒通关羊了个羊

Vite插件开发纪实:vite-plugin-monitor(中)

vuePress-theme-reco 粥里有勺糖    2018 - 2023

Vite插件开发纪实:vite-plugin-monitor(中)

粥里有勺糖 2021-09-27 技术笔记技术教程

# Vite插件开发纪实:vite-plugin-monitor(中)

# 前言

上一篇文章主要介绍了开发插件所需的准备工作,以及此次要开发的插件将要解决的问题

# 功能开发

有了前文的铺垫内容,下面就是功能开发

# 获取启动耗时

项目启动后会在终端中输出ready in xxms

图片

为此咱们使用Vs Code在源码 (opens new window)中搜一下这个关键字

图片

可以看到此部分代码在源码中如下

const info = server.config.logger.info

// @ts-ignore
if (global.__vite_start_time) {
  // @ts-ignore
  const startupDuration = performance.now() - global.__vite_start_time
  info(`\n  ${chalk.cyan(`ready in ${Math.ceil(startupDuration)}ms.`)}\n`)
}
1
2
3
4
5
6
7
8

这个performance.now()等同于Date.now()即当前时间,通过global.__vite_start_time就能获取到服务启动时间

我们就从这个info方法入手,给它重定义一下,通过configureServer钩子可以获取到server实例

index.ts

import type { Plugin } from 'vite';

export default function Monitor(): Plugin {
  const startTime = global.__vite_start_time

  return {
    name: 'vite-plugin-monitor',
    apply: 'serve',
    configureServer(server) {
      const { info } = server.config.logger;
      // 拦截info方法的调用
      server.config.logger.info = function _info(str) {
        // 调用原info方法
        info.apply(this, arguments);
        // 通过字符串内容进行一个简单的判断
        if (str.includes('ready in')) {
          console.log('startupDuration', Date.now() - startTime)
        }
      };
    },
  };
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

启动一个项目看看效果,成了。 图片

# HMR时间获取

热更新时,终端中会出现下面的日志

图片

同理源码里搜一搜,能够定位出如下内容

config.logger.info(
    updates
    .map(({ path }) => chalk.green(`hmr update `) + chalk.dim(path))
    .join('\n'),
  { clear: true, timestamp: true }
)
1
2
3
4
5
6

暂以打印这个日志的时间作为HMR开始的时间

let startTime = null
const { info } = server.config.logger;
server.config.logger.info = function _info(str) {
  info.apply(this, arguments);
  if (str.indexOf('hmr update') >= 0) {
    startTime = Date.now()
  }
};
1
2
3
4
5
6
7
8

触发HMR时,客户端会发出一个获取资源的请求,请求携带了一个import参数,我们通过这个参数来标识这个特定的请求

http://localhost:8080/src/pages/home/index.vue?import&t=1632924377207
1

钩子中的server实例包含middlewares属性可以向上添加自定义的中间件处理方法

  • 通过URL实例解析search参数,然后判断是否包含import&
  • 重定义end方法,在资源传回到客户端后打印耗时
server.middlewares.use(async (req, res, next) => {
  const { search } = new URL(req.url, `http://${req.headers.host}`);
  if (
    search.indexOf('import&') >= 0
  ) {
    const { end } = res;
    res.end = function _end() {
      // 在资源返回后打印耗时
      end.apply(this, arguments);
      console.log(Date.now() - startTime)
    };
  }
  next();
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14

事实上通过--debug启动服务,能看到在HMR时会打印4个时间

图片

目前方法仅仅得到了vite:hmr部分的时间,与实际耗时还有一丝丝差异

# 小结

更加详细的信息只能通过--debug看到,下一步的计划就是hack,模拟一下debug下的行为,将debug的打印的数据都拦截下来 由于时间关系,这部分hack还没完成。准备假期抽时间实现一下。下一篇文章将详细的介绍最终实现。

Edit this page (opens new window)
Last Updated: 2022/5/15 12:46:34