Vite 相关
vite 可以类比成 webpack+webpack-dev-server,特点是:
- 快速的冷启动
- 即时的模块热更新(HMR)
- 按需编译 vite 会直接启动开发服务器,而 webpack 需要构建依赖图等等,将所有代码打包到一起,再放到开发服务器上运行。 主要区别在开发阶段,生产阶段的区别主要是 Rollup 和 Webpack 的区别
开发阶段
冷启动
- Webpack:启动时执行 webpack 打包命令,将所有模块的依赖都打包到一起放到服务器上运行
- Vite:快速冷启动,只启动一个开发服务器。遇到模块时作为单独的 HTTP 请求向开发服务器请求,开发服务器编译,加载相关依赖后返回
HMR
- Webpack:重新编译被改动的模块的所有相关依赖模块
- Vite:重新请求被改动的模块
生态
- Webpack:生态更成熟,plugins 更多
- Vite:还比较年轻
打包工具
- Webpack:适合开发应用,对于 CommonJS,AMD,ES Module 语法都兼容
- Rollup:适合开发类库,只支持 ES Module
esbuild 依赖预构建
什么是依赖预构建 (类似于打包构建,但是没有组 合
-
首次启动的时候 Vite 默认情况下,Vite 会抓取你的 index.html 来检测需要预构建的依赖项,将 HTML 文件作为应用入口(也可以通过 optimizeDeps.entries 属性自定义入口)
-
然后根据入口文件扫描出(由 scanImports 函数完成,/packages/vite/src/node/optimizer/scan.ts)项目中用到的第三方依赖
-
最后对这些依赖逐个进行编译,最后将编译后的文件缓存在内存中(node_modules/.vite 文件下),在启动 DevServer 时(启动时而不是打开页面时)直接请求该缓存内容。
.png)
- 但是,vite 的扫描并不是百分之百准确的,比如在某些动态 import 的场景下,由于 Vite 天然按需加载的特性,经常会导致某些依赖只能在运行时被识别出来。
在 vite.config.js 文件中配置 optimizeDeps optimizeDeps.include:string 或者 optimizeDeps.exclude:string 选项可以选择需要或不需要进行预编译的依赖的名称
Vite 则会根据该选项来确定是否对该依赖进行预编译。如果依赖项很大(包含很多内部模块)或者是 CommonJS,那么你应该包含它;因为 commonjs 需要被处理成 esm,会消耗时间,既然我们可以提前编译,就应该预编译它
如果依赖项很小,并且已经是有效的 ESM,则可以排除它,让浏览器直接加载它(不需要放入预构建的缓存里,浏览器启动后才去加载)。(性能优化思路)
- 在启动时添加 --force options,可以用来强制重新(强制重新依赖预构建指的是忽略之前已构建的文件,直接重新编译)进行依赖预构建。