本文仅作阅读笔记,建议阅读原文。
地址:浅谈 Vite 2.0 原理,依赖预编译,插件机制是如何兼容 Rollup 的?
vite原理
-
速度快的原因
-
利用了 ES Module加载模块支持,所有依赖模块不是一股脑的编译,而是代码按需进行实时加载。
传统的 bundle 模式是这样的:
-
依赖预加载
如果我们不进行预先加载的话,在访问的时候模块依赖按需加载时可能会突然出现几百上千的请求,这样反而会影响网页加载的速度。
如:引入 lodash的 deboundce,又会发现内部有 2 个
import
,再这样延伸下去,这个函数内部竟然带来了 600 次请求,耗时会在 1s 左右。所以需要预先处理依赖模块。
尤老师想了个折中的办法,正好利用 Esbuild 接近无敌的构建速度,让你在没有感知的情况下在启动的时候预先帮你把
debounce
所用到的所有内部模块全部打包成一个传统的js bundle
。Esbuild
使用 Go 编写,并且比以 JavaScript 编写的打包器预构建依赖快 10-100 倍。
启动过程
启动服务器会通过数据劫持的方式,把我们的预加载处理函数植入进去。
// server/index.ts const listen = httpServer.listen.bind(httpServer) httpServer.listen = (async (port: number, ...args: any[]) => {· try { await container.buildStart({}) // 这里会进行依赖的预构建 await runOptimize() } catch (e) { httpServer.emit('error', e) return } return listen(port, ...args) }) as any
这个过程主要进行了两步:
-
依赖收集:生成一个对应的依赖MAP
{ "lodash-es": "node_modules/lodash-es" }
这个过程会把一些多个模块引入打包成一个
bounder
,还有把CommonJS
模块转化成ES Module
-
-
插件机制
简单的介绍一下 Rollup 插件,其实插件这个东西,就是 Rollup 对外提供一些时机的钩子,还有一些工具方法,让用户去写一些配置代码,以此介入 Rollup 运行的各个时机之中。
只要确保 Rollup 插件只使用了这些共有的钩子,就很容易做到插件的通用。