vite
目前大多数框架的前端构建工具都已经被vite代替,相信你已经使用过vite了。但是在使用过程中,vite对我来说一直是含糊的,现在就来一探究竟,为啥它更好?
接下来我将为从以下几点出发,究其原理
一、原生ES模块
1、Common JS
- 文件即模块,每一个文件都是一个 Module 实例,全部代码都运行带模块作用域,不会污染全局作用域(由于CommonJS 输出的是值的拷贝)
- 全部文件运行时同步加载,模块加载的顺序是按照其在代码中出现的顺序,加载完再执行。
- 每个模块加载一次后就会被缓存。后续require时,①先查抄缓存中是否存在,②假如缓存中没有,查抄是否是焦点模块,假如是就直接加载,③假如不是焦点模块,查抄是否是文件模块,剖析路径,根据解出的路径定位文件,然后执行,④假如以上都不是,沿当前路径向上级逐级递归,直到根目次的 node_modules 目次
- CommonJS 模块直接放在欣赏器中是无法执行的,所以要想在欣赏器中运行,须要使用额外的工具(browserify)
2、ES Module
- 欣赏器支持: ES6 Module 也被成为 ES Module,是由ESMAScript 官方提出的模块化规范。目前已经得到了当代欣赏器的支持。假如在HTML中到场type ="module"属性的 script 标签,那么欣赏器会按照 ES Module 规范来举行以来加载和模块剖析,这也是 vite 在开发阶段实现 no-bundle 的原因。由于欣赏器可以加载模块,所以即使不打包可以顺遂运行模块代码。
- 动态导入,按需加载
- <script type="module">
- (async () => {
- const moduleSpecifier = './lib.mjs';
- const {repeat, shout} = await import(moduleSpecifier);
- repeat('hello');
- // → 'hello hello'
- shout('Dynamic import in action');
- // → 'DYNAMIC IMPORT IN ACTION!'
- })();
- </script>
复制代码
- import map:支持绝对路径(www.baidi.com)、相对路径(./module),同时支持直接写一个第三方包名,如 react、lodash。前两种都是欣赏器原生支持的,但是对于第三中,放在欣赏器中是无法直接执行的,ESM 办理了这个问题,这里不详细表明,可自行搜索
vite 使用欣赏器对原生ES模块的支持,接纳按需加载的方式,每次请求一个模块,Vite仅仅返回该模块的内容,而不是整个应用的捆绑文件。
但是!webpack是通过捆绑的方式,将全部模块打包成一个或多个文件,这意味着什么,意味着我们在启动项目是须要对整个应用举行打包,会导致长时间的等待
二、预构建
1、预构建办理了什么问题
- 将其他格式(比方 UMD 、CommonJS)的产物转换为 ESM 格式,使其在欣赏器通过 <script type = "module"><script/> 的方式正常加载。举个例子:大名鼎鼎的 React 就是基于 CommonJS ,而这种格式在vite中是无法直接运行的,但是Vite 没有办法限定第三方的规范,所以改变不了别人,那就改变自己,内部转换
- 打包第三方库的代码,将各个第三方库分散的文件归并在一起,镌汰 HTTP 请求,制止页面加载性能劣化。举个例子:loadsh-es 是ES 版本,vite可以直接运行,但实际上,在它加载时会发出特别多的请求,导致页面加载的前几秒几乎处于卡顿状态。每次 import 都会触发一个新的文件请求,假如不加控制,会触发成百上千个网络请求,而 Chrome 对同一个域名在只能同时支持 6 个 HTTP 并发请求,导致页面加载十分缓慢。在到场依靠预构建之后,loadsh-es 的代码被打包成一个文件,这样请求的数量会镌汰很多,减轻欣赏器压力,页面加载速率变快。
三、双引擎(EsBuild 和 Rollup)
1、EsBuild 预构建
esbuild 在 Vite 中的作用会合在提拔构建速率、优化依靠处置惩罚和简化开发体验
- 快速构建
esbuild 是用 go 编写的构建工具,具有极快的编译速率。使得 Vite 在开发环境中可以快速响应文件变动,提供及时反馈
- 多核并存
js 是单线程串行,esbuild 直接新开一个线程 ,多线程并行,充分发挥多核优势
- 代码压缩,镌汰内存
esbuild 提供了一个 minify 配置允许用户去压缩代码体积
2、Rollup 打包
vite 选择在生产环境中使用Rollup打包,并基于Rollup 本身成熟的打包能力举行扩展和优化
- css代码分割。假如某个异步模块中引入了一些 CSS 代码,Vite 就会主动将这些 CSS 抽取出来生成单独的文件,进步线上产物的缓存复用率。
- 主动预加载。Vite 会主动为入口 chunk 的依靠主动生成预加载标签。这种恰当预加载的做法会让欣赏器提前下载好资源,优化页面性能。
- 异步Chunks 加载优化。在异步引入的 Chunk 中,通常会有一些公用的模块,如现有两个异步引入的 Chunk: A 和 B,而且两者有一个公共依靠 C一般情况下,Rollup 打包之后,会先请求 A,然后欣赏器在加载 A 的过程中才决定请求和加载 C,但 Vite 举行优化之后,请求 A的同时会主动预加载 C,通过优化 Rollup 产物依靠加载方式节流了不须要的网络开销。
- 多产物配置。同一个入口文件,打包出多种格式的产物
- const buildOptions = {
- input: ["src/index.js"],
- // 将 output 改造成一个数组
- output: [
- {
- dir: "dist/es",
- format: "esm",
- },
- {
- dir: "dist/cjs",
- format: "cjs",
- },
- ],
- };
- export default buildOptions;
复制代码
- 多入口配置,将 input 设置为一个数组或者一个对象:
- {
- input: ["src/index.js", "src/util.js"]
- }
- // 或者
- {
- input: {
- index: "src/index.js",
- util: "src/util.js",
- },
- }
复制代码 四、热模块更新(HMR)
vite 热更新过程
- 创建一个 websocket 服务端和 client 文件,启动服务
- 通过 chokidar 监听文件变动
- 当代码变动后,服务端举行判断并推送到客户端
- 客户端根据保举的信息执行不同操纵的更新
webpack 热更新过程
- 使用 webpack-dev-server (后面简称 WDS)托管静态资源,同时以 Runtime 方式注入一段处置惩罚 HMR 逻辑的客户端代码;
- 欣赏器加载页面后,与 WDS 建立 WebSocket 连接;
Webpack 监听到文件变化后,增量构建发生变动的模块,
- 通过 WebSocket 发送 hash 变乱;
- 欣赏器吸收到 hash 变乱后,请求 manifest 资源文件,确认增量变动范围;
- 欣赏器加载发生变动的增量模块;
- Webpack 运行时触发变动模块的 module.hot.accept 回调,执行代码变动逻辑;
- done。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |