看似nb的unbuild插桩技术,不过rewriting function尔🤔

看过element-plus的朋友都知道,它在开发阶段使用的是unbuild进行的打包编译。相比较传统的rollupwebpack等老牌构建工具而言,unbuild更快!!

但这个快并不是指的编译上更快,毕竟它说到底仍然是基于rollup的,和借力了esbuildvite相比它并不适合使用这个修饰词

这里的快,指的是次数,和其他构建工具监听文件变更后reCompile不同,unbuild只在启动时执行一次

而提供该能力的核心即jiti

jiti 是做什么的

jiti是一个npm包,它实现的核心能力即代码插桩

代码插桩是指在运行时动态修改代码的技术

如何启用

package.json文件的scripts配置中指定--stub,示例如下

json 复制代码
{
  "scripts": {
    "dev": "unbuild --stub"
  }
}

编译结果如下

ts 复制代码
import jiti from "jiti这个包对应的系统文件地址";

jiti(...)('目标工程的入口文件');

源码解析

注意,本文的重点是分析jiti的核心原理,因此对于unbuild不会进行深入探讨,同时,既是核心原理,因此对于jiti的实现细节也不在探讨范围

我们关心的是:

1-jiti 是什么

2-实时编译是如何实现的

  • 首先,jiti 是什么?

这要从其package.json包开始看起

从框红的webpack可以知道,它就是一个普通的不能再普通的常规npm包,并没有使用啥高大上的技术,换言之,它和插桩技术本身毫无关联

因此,只能从入口找答案,它由main字段标识,指向lib文件夹

json 复制代码
{
  "main": "./lib/index.js"
}
  • 实时编译是如何实现的

从它是由webpack构建的就可以猜出来,像es语法降级,ts to js转换这些操作一定是基于wb的某个loader或者plugin实现的,所以这一部分肯定也与插桩技术本身无关

故,去掉编译相关的逻辑之后,我们很容易就发现了如下代码。显然,jiti对源代码创建模块并重写了require方法

ts 复制代码
const mod = new Module(...);
mod.require = createJITI(...);

createJITI函数,其实就是对模块的编译过程,这就做到了,当访问某个模块的时候,再进行编译,即运行时,也即插桩

总结

搞了半天,原来插桩就是个函数重写😂

相关推荐
吴声子夜歌5 天前
Vue3——脚手架Vite
前端·javascript·vue.js·vite
DevilSeagull5 天前
电脑上安装的服务会自动消失? 推荐项目: localhostSCmanager. 更好管理你的服务!
测试工具·安全·react·vite·localhost·hono·trpc
kyriewen8 天前
Webpack vs Vite:一个是“老黄牛”,一个是“猎豹”,你选谁?
前端·webpack·vite
天渺工作室12 天前
别再写改名脚本了,一个 Vite 插件搞定压缩、校验、自动哈希命名vite-plugin-pack-orchestrator
前端·vite
Sheldon一蓑烟雨任平生14 天前
Vite 深度剖析(四)
性能优化·vite·图片压缩·gzip压缩·代码压缩·摇树·dns-prefetch
Sheldon一蓑烟雨任平生15 天前
Vite 深度剖析(二)
vite·静态资源处理·hmr·css工程化处理·模块热替换·vite 插件
Sheldon一蓑烟雨任平生15 天前
Vite 深度剖析(一)
vue·react·vite·环境变量·esbuild·vite.config.ts·依赖预构建
walking95716 天前
Vite 打包优化终极指南:从 30MB 到 800KB 的性能飞跃
前端·vue.js·vite
whyfail17 天前
CVE-2026-39363-Vite开发服务器安全漏洞深度分析
安全·vite
江上清风山间明月17 天前
Vite现代化的前端构建工具详解
前端·webpack·nodejs·vite