专栏名称: 前端大全
分享 Web 前端相关的技术文章、工具资源、精选课程、热点资讯
目录
相关文章推荐
前端早读课  ·  【第3452期】React 开发中使用开闭原则 ·  6 小时前  
启四说  ·  启四VIP策略网站,有哪些功能?如何使用? ·  17 小时前  
启四说  ·  启四VIP策略网站,有哪些功能?如何使用? ·  17 小时前  
前端早读课  ·  【第3451期】前端 TypeError ... ·  昨天  
江苏司法行政在线  ·  宿迁司法行政人、江苏监狱戒毒民警,给您拜年啦! ·  3 天前  
江苏司法行政在线  ·  宿迁司法行政人、江苏监狱戒毒民警,给您拜年啦! ·  3 天前  
51好读  ›  专栏  ›  前端大全

深入了解Vite:依赖预构建原理

前端大全  · 公众号  · 前端  · 2024-09-23 11:50

主要观点总结

本文主要介绍了Vite开发阶段的no-bundle理念,以及Vite如何处理第三方依赖的预构建。文章详细解释了预构建的原因、过程以及Vite的配置选项。

关键观点总结

关键观点1: Vite的no-bundle理念及预构建概念

Vite在开发阶段采用no-bundle理念,将项目中的模块分为依赖和源码两部分。依赖部分使用预构建方式处理,以提高页面加载性能。预构建是基于Esbuild完成的,不会造成明显的打包性能问题。

关键观点2: 预构建的原因

预构建的主要原因包括:确保commonJS和UMD兼容性,因为不是所有第三方依赖都有ESM版本;提高页面加载性能,通过将具有多个内部模块的ESM依赖项转换为单个模块。

关键观点3: Vite预构建的过程和配置

Vite在启动服务时执行initDepsOptimizer进行依赖优化。通过loadCachedDepOptimizationmetadata获取本地缓存的metadata数据,如果没有缓存则进行依赖扫描,使用esbuild对扫描出的依赖项进行预编译。Vite提供了优化相关的配置选项,如exclude、include等。

关键观点4: 推荐阅读

文章最后推荐了几篇相关文章,包括Vite的发展、Next.js对Vite的选择、前端代码规范等。


正文

前言

我们提到Vite在开发阶段,提倡的是一个no-bundle的理念,不必与webpack那样需要先将整个项目进行打包构建。但是no-bundle的理念只适合源代码部分(我们自己写的代码),vite会将项目中的所有模块分为依赖与源码两部分。

依赖: 指的是一些不会变动的一些模块,如: node_modules 中的第三方依赖,这部分代码 vite 会在启动本地服务之前使用 esbuild 进行预构建。esbuild 使用 Go 编写,比使用 JavaScript 编写的打包器预构建依赖快 10-100 倍。

源码: 指的是我们自己开发时写的那部分代码,这部分代码可能会经常变动,并且一般不会同时加载所有源代码。

所以总结来说: no-bundle是针对源码的,而预构建是针对第三方依赖的

使用预构建的原因

主要有以下两点:

  • commonJS 与 UMD兼容 :因为 Vite 在开发阶段主要是依赖浏览器原生ES模块化规范,所以无论是我们的源代码还是第三方依赖都得符合ESM的规范,但是目前并不是所有第三方依赖都有ESM的版本,所以需要对第三方依赖进行预编译,将它们转换成EMS规范的产物。

比如 React ,它就没有 ESM 的版本,所以在使用 Vite 时需要预构建

  • 性能: 为了提高后续页面的加载性能,Vite将那些具有许多内部模块的 ESM 依赖项转换为单个模块。

比如常用的 loads-es

我们引入 lodash-es 工具包中的 debounce 方法,此时它理想状态应该是只发出一个请求

import  { debounce }  from 'lodash-es'

事实也是这样

但这是预构建的功劳,如果我们对 lodash-es 关闭预构建呢?

vite 配置文件加上如下代码,再来试试:

// vite.config.js
optimizeDeps: {
    exclude: ['lodash-es']
  }

可以看到,此时发起了600多个请求,这是因为 lodash-es 有超过 600 个内置模块!

vite通过将 lodash-es 预构建成单个模块,只需要发起一个HTTP请求!可以很大程度地提高加载性能

由于Vite的预构建是基于性能优异的Esbuild来完成的,所以并不会造成明显的打包性能问题

开启预构建

默认配置

一般来说, Vite 帮我们默认开启了预构建

预构建产物会存放在: node_modules/.vite/deps

里面会有一个 _metadata.json 的文件,这里保存着已经预构建过的依赖信息

对于预构建产物的请求, Vite 会设置为强缓存,有效时间为1年,对于有效期内的请求,会直接使用缓存内容

如果只有HTTP强缓存肯定也不行,如果用户更新了依赖版本,在缓存过期之前,浏览器拿到的一直是旧版本的内容。

所以 Vite 对本地文件也设置了缓存判断,如果下面几个地方任意一个地方有变动, Vite 将会对依赖进行重新预构建:

  • 项目依赖 dependencies 变更

  • 各种包管理器的 lock 文件变更

  • optimizeDeps 配置内容变更

自定义配置

entries

默认情况下, Vite 会抓取项目中的 index.html 来检测需要预构建的依赖

optimizeDeps: {
  entries: ['index.html']
}

如果指定了 build.rollupOptions.input ,Vite 将转而去抓取这些入口点。

exclude

排除需要预构建的依赖项

optimizeDeps: {
  exclude: ['lodash-es']
}


include

默认情况下,不在 node_modules 中的依赖不会被预构建。使用此选项可强制选择预构建的依赖项。

optimizeDeps: {
  include: ['lodash-es']
}







请到「今天看啥」查看全文