vite | 青训营笔记

65 阅读4分钟

[这是我参与「第五届青训营 」伴学笔记创作活动的第 11 天]

1. 前端为什么需要构建工具

  • 前端工程的痛点
    • 模块化规范不统一
    • 资源编译的问题,针对高级语法的编译
    • 产物质量问题
      • 代码需要压缩, 以此来提升性能
      • 对于未使用的模块,需要剔除来优化体积
      • 产物的语法兼容问题
    • 开发效率
  • 前端构建工具的意义
    • 模块化方案
      • 提供模块加载方案
        • 比如 webpack 中的 runtime 便是一个模块加载器,对每个模块的导入和导出进行规范统一
      • 兼容不同的模块化规范
    • 语法转移
      • 高级语法转译,如 sass, ts 等
      • 资源加载,如字体,图片
    • 产物质量
      • 产物压缩,无用代码删除
      • 语法降级
    • 开发效率
      • 热更新

2. vite

  • 两大组成部分
    • No-bundle 开发服务,源文件无需打包
    • 生产环境基于 Rollup 的 Bundle
  • 核心特征
    • 高性能,dev 启动速度更快, 热更新的速度很快
    • 简单易用
  • 浏览器原生 ESM 支持
    • 两大要素
      • script 标签新增加 type = " module " 属性, vite 的 dev server 也正是基于此来实现不打包
      • 使用 ESM 模块导入导出语法
  • dev server 基于原生 ESM 的开发服务优势
    • 无需打包项目源代码,去除了 bundle 的开销
    • 天然的按需加载
    • 可以利用文件级的浏览器缓存
  • 内置的 Web 构建能力 image.png

3. 如何使用 vite

  • 项目初始化 image.png
  • 使用静态资源
    • 静态资源可以直接 import 使用 image.png
    • 除了常见的图片格式,Vite 也内置了对于 JSON,Worder,WASM 资源的加载支持
  • 使用 HMR
    • HMR 可以保持组件的状态
  • 生产环境的 Tree Shaking
    • 优化原理
      • 基于 ESM 的 import / export 语句依赖关系,与运行时无关
      • 在构建阶段将未使用到的代码进行删除

4. Vite 整体架构

image.png

  • 关键技术:开发环境的依赖预打包
    • node_modules 中包的依赖关系十分复杂,可能你想要引入一个包,最终会引入多个其他依赖包
    • node_modules 中代码的格式是不规范的
    • 所以为了解决以上问题, Vite 进行了预打包
      • 如何进行预打包
        • 首先在 dev server 启动之前,会扫描代码中用到的依赖
        • 接着对依赖的代码采用 esbuild 进行打包, 之后对业务代码中的 import 语句进行改写
  • 关键技术:单文件的编译
    • 使用 esbuild 进行打包
    • 优点: 编译速度提升 10 - 100x
    • 缺点
      • 不支持类型检查,这也是为什么 vite 在生产环境构建的时候要调用一次 tsc
      • 不支持将语法降级到 es5
  • 关键技术:代码压缩
    • 是生产环境当中重要的一个阶段
    • Esbuild 作为默认压缩工具,替换传统的 Terser 、 Uglify.js 等压缩工具
  • 关键技术:插件机制
    • 开发阶段: 模拟 Rollup 插件机制
    • 生产环境: 直接使用 Rollup
    • 最终就是 Vite 的插件既可以用到 dev 阶段也可以用到 生产环境
    • 但是 Rollup 中的插件不一定能使用到 Vite 当中 image.png

5. Vite 进阶之路

  • 进修之路 !
    • 深入双引擎
      • Vite 的底层中非常依赖的两个引擎: EsbuildRollup
      • 先了解基本使用,动手尝试各种配置项
      • 然后学习插件开发
    • Vite 的插件开发
      • 为什么需要插件机制?
        • 抽离核心逻辑
        • 易于拓展
      • Vite 提供的 hook image.png
      • 插件实例 image.png
  • Vite 代码分割(拆包)
    • 不拆包的问题
    • 因为最终文件没有进行拆包操作,所以打包产物只有一个文件,无法进行并发请求,无法发挥浏览器的优势
    • 由于产物没有进行拆包操作,一旦某个地方进行改动,那么就要重新打包,重新请求,缓存复用率低 image.png
  • JS 编译工具 Babel
    • JS 语法标准繁多,浏览器支持程度不一
    • 开发者需要用到高级语法 image.png
  • 语法的安全降级
    • 如何在构建产物中避免这类问题
      • 上层解决方案: @vitejs/plugin-legacy
      • 底层原理
        • 借助 Babel 进行语法自动降级
        • 提前注入 Polyfill 实现, 如 core-js
  • 服务端渲染
    • 一种常见的渲染模式,用于提升首屏性能和 SEO 优化 image.png