Vite 太快了,烦死了,是时候该小睡一会了。

简介: 在知乎看参与 Vue Conf 2021 是怎样的体验?[1]这个问题的时候,偶然发现 Anthony Fu 的回答里提到了一个好玩的凡尔赛插件:vite-plugin-sleep[2]。

在知乎看参与 Vue Conf 2021 是怎样的体验?[1]这个问题的时候,偶然发现 Anthony Fu 的回答里提到了一个好玩的凡尔赛插件:vite-plugin-sleep[2]

先看看回答中 Anthony Fu 是怎么引出这个插件的:

关于 QA 环节中对于 Vite 快的意义的提问似乎引发了大家的一些讨论,借此机会说说自己的浅见。我们有两个词,UX 和 DX,分别对应用户体验(User Experience)和开发者体验(Developer Experience)。

的确某种程度上,作为开发者我们应该优先满足于终端用户的体验,但是随着开发者数量的增加,以及软件需求的越发复杂,开发者同样作为人的体验也十分重要。

如果开发者不能获得很好的 DX,便很难有足够好的效率去进行 UX 的改善。而性能的提升可以更好的让机器接受人的命令而不是浪费时间在等待机器完成工作。

当然,如果你是觉得工具太快影响休息的话,这里安利一下 @小炫 的插件,让你的 Vite 也休息一下 vite-plugin-sleep(被你发现了,其实抖这个机灵才是我的目的)

这充满凡尔赛气息的话语属实逗笑我了,Webpack 的构建之慢确实带给了我们一些美好的摸鱼时间,Vite 是夺走它们的罪魁祸首,这才是属于打工人的插件


介绍


先看看 vite-plugin-sleep 的「动机」章节:

In the old days with webpack, we had many times when we could compile with pay, and with vite it was so fast that we couldn't rest. Time to take a nap in the vite.

在 Webpack 陪伴的那些日子里,我们在编译的时候有很多的时间可以用来休息,但 Vite 太快了,夺走了这一切

是时候小睡一会了……


用法


yarn add vite-plugin-sleep
// vite.config.ts
import sleep from "vite-plugin-sleep";
/** @see {@link https://vitejs.dev/config/} */
export default defineConfig({
  plugins: [
    // ...other plugins
    sleep(/* options */),
  ],
});

就这么简单,安装然后引入,属于你的摸鱼时间又回来了。


原理


看看这个插件的源码是什么样的,顺便学习一下 Vite 插件的编写方式。

Vite 插件的通用形式一般是个函数,接受用户传入的一个 options 配置选项,返回 Vite 标准的插件格式,一个形如这样的对象:

{
  name: 'vite-plugin-sleep',
  config() { // 自定义 config 逻辑 }
  load() { // 自定义 load 逻辑 },
}

Vite 暴露了很多钩子函数给用户,让用户在适当的时机对源码内部的行为进行一些介入和更改。

在官网的 插件 API —— 钩子[3] 章节阅读文档,注意有一部分钩子是继承自 Rollup 的,所以需要去 Rollup 的官网来查看使用说明。

以官网中提到的例子来解释:

export default function myPlugin() {
  const virtualFileId = "@my-virtual-file";
  return {
    name: "my-plugin", // 必须的,将会显示在 warning 和 error 中
    resolveId(id) {
      if (id === virtualFileId) {
        return virtualFileId;
      }
    },
    load(id) {
      if (id === virtualFileId) {
        return `export const msg = "from virtual file"`;
      }
    },
  };
}

这个插件允许用户引入一个虚拟文件(在实际文件中不存在),通过 load 钩子来自定义读取文件的内容,用户就可以这样引入 "from virtual file" 这个字符串了。

import { msg } from "@my-virtual-file";
console.log(msg);

有了这些前置知识,我们来看下这个插件是怎么写的:

import type { Plugin } from "vite";
import type { UserOptions } from "./lib/options";
import { sleep } from "./lib/utils";
import { name } from "../package.json";
export default function sleepPlugin(userOptions: UserOptions = {}): Plugin {
  const options = {
    ...userOptions,
  };
  let firstStart = true;
  return {
    name,
    enforce: "pre",
    configureServer(server) {
      server.middlewares.use(async (req, __, next) => {
        // if not html, next it.
        // @ts-expect-error
        if (!req.url.endsWith(".html") && req.url !== "/") {
          return next();
        }
        if (firstStart) {
          await sleep(options.devServerStartDelay || 20000);
          firstStart = false;
        }
        next();
      });
    },
    async load() {
      await sleep(options.hmrDelay || 2000);
      return null;
    },
  };
}

其实很简单,configureServer[4] 钩子是 Vite 官方提供的独有钩子(也就是 Rollup 中不存在的钩子),是用于配置开发服务器的钩子,最常见的用例是添加一些自定义服务中间件。

load 钩子则是 Rollup 内置的,根据官网的说法,return null 代表这个文件交给其他插件或者由默认解析行为处理,也就是延迟两秒后啥都不干。

再回到插件的内容,先定义一个睡觉的函数:

export function sleep(delay: number) {
  return new Promise((resolve) => setTimeout(resolve, delay));
}

配合 await 语法,可以实现非常优雅的睡眠。

通过 enforce: 'pre' 来强制这个插件的钩子在最前面执行(其他插件别想阻止我摸鱼)。

configureServer 这个钩子里的代码也很简单,初次启动 Vite 开发服务器的时候,访问入口 HTML 文件时,sleep 沉睡用户传入的时间,默认 20 秒。(20 秒够干嘛?XD,请设置成 120 秒。)

官方给出的例子就是添加中间件,但尤老板万万没想到中间这段注释代码被摸鱼小能手填充之后,竟是用来做这种事!

之后是 load 钩子,读取每个文件的时候,默认沉睡 2 秒。

就这么简单,一个 Vite 摸鱼插件完成了。


总结


周末了,通过这个凡尔赛的插件图个乐子,顺便学习一下 Vite 插件的基础知识,美滋滋!


参考资料


[1]

参与 Vue Conf 2021 是怎样的体验?: https://www.zhihu.com/question/460852226

[2]

vite-plugin-sleep: https://github.com/IndexXuan/vite-plugin-sleep

[3]

插件 API —— 钩子: https://cn.vitejs.dev/guide/api-plugin.html#universal-hooks

[4]

configureServer: https://cn.vitejs.dev/guide/api-plugin.html#configresolved


相关文章
|
3月前
|
JavaScript 前端开发 Java
[JS]同事:这次就算了,下班回去赶紧补补内置函数,再犯肯定被主管骂
本文介绍了JavaScript中常用的函数和方法,包括通用函数、Global对象函数以及数组相关函数。详细列出了每个函数的参数、返回值及使用说明,并提供了示例代码。文章强调了函数的学习应结合源码和实践,适合JavaScript初学者和进阶开发者参考。
52 2
[JS]同事:这次就算了,下班回去赶紧补补内置函数,再犯肯定被主管骂
|
6月前
|
人工智能 数据安全/隐私保护
你试过一秒钟出现在世界各地的感觉吗?
【8月更文挑战第13天】你试过一秒钟出现在世界各地的感觉吗?
|
6月前
|
缓存 前端开发 JavaScript
快如闪电!揭秘网页秒开秘籍,网友:再也不怕网速拖后腿!
【8月更文挑战第6天】随着互联网的发展,快速的网页加载成为关键。本文介绍前端性能优化策略,涵盖资源压缩与合并、图片优化、缓存利用、CDN部署、CSS及JavaScript的加载顺序优化、异步加载及DOM和CSS渲染减少等方面,旨在全面提升页面加载速度与用户体验。通过实施这些技术,可有效改善网站性能,满足用户需求并提升搜索引擎排名。
78 2
|
6月前
|
缓存 Java 应用服务中间件
2021年9月28日,老是遇到一些非常奇葩的问题。就离谱、好好的一个web项目就莫名奇妙坏了。
开发者在使用IDEA 2020编辑器搭建的SSM框架图书管理系统中,遇到删除功能异常问题,经过一系列尝试后发现是IDEA编译缓存导致的,最终通过重新编译项目解决了问题。
|
缓存 前端开发 JavaScript
前端Vue小项目的一个非常诡异离谱的"眼神不好"Bug
公司放假, 现在来提升自己的前端的技术, 想着使用饿了么UI搭建一个简单的页面, 并完成mock数据的获取, 一个小项目就好了....
92 0
|
JavaScript 算法 前端开发
阿秀思考了很久,最后还是决定啦!
五月份离职后,我给自己放了半个月的假才去入职的新公司,emm,截止目前为止暂时还没后悔,如果以后真的发生北京hulu那样被一锅端的事就算我倒霉好了。
88 1
|
Web App开发 数据采集 存储
我给项目加了性能守卫插件,同事叫我晚上别睡的太死-1
由于我组主要是负责的是H5移动端项目,老板比较关注性能方面的指标,比如首页打开速度,所以一般会关注FP,FCP等等指标,所以一般项目写完以后都会用lighthouse查看,或者接入性能监控系统采集指标.
133 0
|
开发者
试着做点儿有趣的事情
一个游戏怎样才算是做完了?这是个因人而异的问题。有些游戏还没有做出来就做完了,因为开发者不想再做了。有的游戏看上去做完了,但是后续还在不停的更新,那我们就说这个游戏其实还没有做完。至于如何算是做完了,我觉得这应该交由该游戏的制作者来决定。
113 0
|
存储 机器学习/深度学习 监控
我是傻x,被迫看了 1 天源码,千万别学我!
大家好,我是零一,之前一直很忙,业余时间的输入和输出都 24k铝合金人眼可见 得下降,这不最近上海疫情严重么,算了一下居家办公也已经将近 1个月了,这才有些许时间学习,所以最近也是一直在鼓捣点新东西,不为别的,主要是想再多输入一些新的知识
188 0
我是傻x,被迫看了 1 天源码,千万别学我!