当我们的浏览器不支持ES Module的时候,我们会通过使用Webpack、Rollup、Parcel等工具来提取,处理、连接我们的源代码,但是当我们的项目变得越来越复杂,模块数量越来越多的时候,我们启动一个Dev Server所需要的时间也会变得越来越长,当我们在编辑代码,保存,即使有HRM功能,可能也要花费几秒钟,才能反映到页面中。这种开发体验是非常不好的,而Vite就是来解决这种开发体验上的问题。总的来说Vite有如下优点:
- 去掉打包步骤,快速的冷启动
- 及时的模块热更新,不会随着模块变多而使得热更新变慢
- 真正的按需编译
Bundle vs Bundleless
要学习了解Vite 首先谈论Bundle和Bundleless,这是两种不同的开发方式,在过去我们一般都会使用Webpack这个打包构建工具来打包构建我们的代码,那为什么过去需要打包,简单来说就是一下几点:
- HTTP/1.1 各浏览器有并行连接限制
- 浏览器不支持模块系统(如 CommonJS 包不能直接在浏览器运行)
- 代码依赖关系与顺序管理
为什么开始尝试不打包
- 随着项目不断变大,启动和热更新所等待的时间越来越长
- HTTP/2.0 多路并用
- 各大浏览器逐一支持 ESM
- 原生的解决了代码依赖和复用的问题
- 越来越多的 npm 包拥抱 ESM(尽管很多包的依赖并不是)
Bundle(Webpack) | Bundleless(Vite/Snowpack) | 启动时间 | 长,完成打包项目 | 短,只启动Server 按需加载 | 构建时间 | 随项目体积线性增长 | 构建时间复杂度O(1) | 加载性能 | 打包后加载对应Bundle | 请求映射至本地文件 | 缓存能力 | 缓存利用率一般,受split方式影响 | 缓存利用率近乎完美 | 文件更新 | 重新打包 | 重新请求单个文件 | 调试体验 | 通常需要SourceMap进行调试 | 不强依赖SourceMap,可单文件调试 | 生态 | 非常完善 | 目前先对不成熟,但是发展很快 |
---|
- Bundle vs Bundleless
- Bundle Refresh
- Bundleless Refresh
Vite原理
Vite分为开发模式和生产模式
开发模式:,Vite提供了一个开发服务器,然后结合原生的ESM,当代码中出现import的时候,发送一个资源请求,Vite开发服务器拦截请求,根据不同文件类型,在服务端完成模块的改写(比如单文件的解析编译等)和请求处理,实现真正的按需编译,然后返回给浏览器。请求的资源在服务器端按需编译返回,完全跳过了打包这个概念,不需要生成一个大的bundle。服务器随起随用,所以开发环境下的初次启动是非常快的。而且热更新的速度不会随着模块增多而变慢,因为代码改动后,并不会有bundle的过程。
Vite Server 所有逻辑基本都依赖中间件实现。这些中间件,拦截请求之后,完成了如下内容:
-
处理 ESM 语法,比如将业务代码中的 import 第三方依赖路径转为浏览器可识别的依赖路径;
-
对 .ts、.vue 等文件进行即时编译;
-
对 Sass/Less 的需要预编译的模块进行编译;
-
和浏览器端建立 socket 连接,实现 HMR。
生产模式: 利用Rollup来构建源代码。
Vite将需要处理的代码分为了两大类
第三方依赖:这类代码大部分都是纯JavaScript,而且不会怎么经常变化,Vite会通过pre-bundle的方式来处理这部分代码,至于为什么要pre-bundle,这个后面会讲。Vite2使用esbulid来构建这部分代码,esbuild是基于go的,处理速度会比用JavaScript写的打包器要快10-100倍,这也是Vite为什么在开发阶段很快的一个原因。
业务代码:通常这部分代码,都不是纯的JavaScript(例如:JSX,Vue等),经常会被修改,而且也不需要一次性全部加载(可以根据路由,做代码分割加载)
由于Vite使用了原生的ESM,Vite本身只需要按需编译代码,启动静态服务器就可以。只有当浏览器请求这些模块,这些模块才会被编译,动态加载到当前页面中。
特征
- NPM Dependency Resolving
原生的ESM不支持 bare module imports
,换句话说原生的ESM只支持通过一个相对或者绝对路径来引用资源,不支持通过一个包名来引用资源
import React from 'react'
Uncaught TypeError: Failed to resolve module specifier "test2.js". Relative references must start with either "/", "./", or "../".
我们之前在使用Webpack的项目进行构建的时候,我们都会使用这种引入方式去引入一个我们安装的第三方依赖的包,背后其实也是Webpack帮我们做了这样的一层转换,同样如果想在ESM中这样去引入一个包,那么也得做这样一层路径转换。
- Dependency pre-bundling
- Hot Module Replacement
- TypeScript
- Vue
- JSX
- CSS
自动URL改写:所有 url() 路径都会被自动改写从而确保在开发和构建中都指向正确的文件路径。
- Static Assets
- JSON
- Web Assembly
- Web Workers
- Dynamic Import Polyfill
- Async Chunk Loading Optimization
优化前
Entry ---> A ---> C
优化后
Entry ---> (A + C)
Caching
文件系统缓存 Vite会将pre-bundle的依赖存放在node_modules/.vite下。只有当以下情况发生时,才会重新pre-bundle来更新缓存。
浏览器缓存 Vite Dev Server 会将这些第三方依赖设置HTTP强缓存来提升性能,只有当这些依赖发生变化时,才会去更新query id使之前的的缓存失效。
Automatic Dependency Discovery
如果当依赖在缓存中没有找到的话,Vite会自动到node_modules中去找,并且把它提取到缓存中。Vite会将pre-bundle的依赖存放在node_modules/.vite下
为什么生产环境还是需要bundle
尽管现在已广泛支持native ESM,但由于嵌套import 会导致发送大量的网络请求,即使使用HTTP2,在生产中使用未捆绑的ESM仍然效率低下。 为了在生产中获得最佳的加载性能,最好将代码bundle一遍(结合Tree Shaking,lazy-loading和common chunk splitting等技术手段)
为什么不在生产环境使用ESbuild
esbuild的速度非常快,已经是一个非常强大的Bundler,但一些应用程序绑定所需的重要特性仍在开发中——特别是代码拆分和CSS处理。目前,Rollup在这些方面更加成熟和灵活。也就是说,当esbuild在将来稳定这些特性时,我们不排除在生产版本中使用esbuild的可能性
与Snowpack的比较
Snowpack 也是一个基于native ESM的本地开发服务器,有一些相似的地方,但是也有一些不同。
Production Build
Snowpack 默认build之后的文件是没有捆绑的,它将每个文件转换为单独的构建模块,然后将这些模块提供给不的'optimizers'来执行实际的捆绑操作。这样做的好处是,你可以在不同的end-bundlers(eg: webpack,rollup,esbuild),以满足特定的需求。
由于Vite集成了构建步骤,所以Vite支持更多的特性(这些特性在Snowpack中还不支持)
-
支持多页面
-
自动分割CSS
-
支持动态引入polyfill
-
Library Mode
-
优化的异步chunk加载
-
官方的 legacy mode plugin插件,可以生成支持现代/老旧浏览器的双重包,并根据浏览器自动交付正确的包。
Faster Dependency Pre-Bundling 由于在开发阶段,Vite采用了esbuild,来进行pre-bundling,相比Rollup会快很多
Monorepo Support CSS Pre-Processor Support First Class Vue Support
浏览器支持
- 在开发环境,需要原生支持ESM的浏览器
- 在生产环境,默认也是需要支持原生ESM的浏览器,但是可以通过@vitejs/plugin-legacy来构建支持低版本浏览器的包
在Webpack 构建的项目中,我们的入口文件通常是一个js, index.html仅仅作为一个模板,而在Vite构建的项目中,index.html作为入口文件。
参考文章
深入 vite 原理:尤大最新力作到底是如何实现的?
Vite 依赖预编译,缩短数倍的冷启动时间
聊聊 ESM、Bundle 、Bundleless 、Vite 、Snowpack
从 Bundleless 看前端构建
Demo地址
Vite-Study
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!