Vite知识体系 | 青训营笔记

141 阅读6分钟

这是我参与「第四届青训营 」笔记创作活动的的第十七天。 今天学习了Vite知识体系,通过昨天对Webpack的学习,我逐渐建立起了前端工程化的概念,所谓前端工程化,就是使用软件工程的思想应用到前端开发中,将开发阶段的代码发布到生产环境,包含:构建,分支管理,自动化测试,部署。这些都需要降低开发者的维护成本,提高页面的响应速度,给用户更好的体验。

本堂课重点内容

  • 为什么需要Vite
  • 什么是Vite
  • Vite使用
  • Vite整体架构
  • Vite进阶

详细知识点介绍

详细笔记分享在文章最后,记得点个赞再走!

课后个人总结

通过今天的学习,我觉得vite最大的特点就是弥补了webpack的速度慢、配置繁琐、并且打包后的文件占用内存小,尽管 Webpack有大量的插件和社区支持,但是从很多方面来说,如今它算不上是最好的选择。Vite仍在发展,而且社区支持也是很丰富的,单单是基于配置方便这个优点,我觉得Vite完全是一个更好的选择。

笔记

Vite知识体系

一、为什么需要构建工具

前端工程的痛点

核心要素 ==> 资源

对于资源的处理,往往是很麻烦的事情。比如JS、TS、JXS、CSS、SCSS等资源文件。

解决

  • 模块化(ESM、CommonJS、UMD)
  • 资源编译(高级语法的编译)
  • 产物质量(代码体积、代码性能)
  • 开发效率(热更新)

前端构建工具的意义

  • 模块化方案

    • 1.提供模块加载方案
    • 2.兼容不同模块规范
  • 语法转译

    • 1.高级语法转译,如Sass、TypeScript
    • 2.资源加载,如图片、字体、worker
  • 产物质量

    • 产物压缩、无用代码删除、语法降级
  • 开发效率

    • 热更新

二、什么是Vite

1、Vite介绍

Vite新一代前端构建工具。

两大部分组成:

  • No-bundle开发服务,源文件无需打包
  • 生产环境基于Rollup的 Bundler

核心特性:

  • 高性能,dev启动速度和热更新速度非常快
  • 简单易用,开发者体验好

当下问题

当下打包工具,如parcel、webpack、rollup等,还是存在一些问题。

缓慢的启动 ==> 项目编译等待成本高

缓慢的热更新 ==> 修改代码后不能实时更新

这些问题的产生的原因在哪?

  • bundle 带来的性能开销
  • JavaScript语言的性能瓶颈

2、Vite特性

行业趋势

  • 全球浏览器对原生ESM的普遍支持(目前占比92%以上)
  • 基于原生语言(Go、Rust)编写前端编译工具链
  • 如Go语言编写的Esbuild、Rust 编写的Swc

浏览器原生ESM支持

两大要素:

1.script标签增加type="module”属性

<script type= "module">
    import { foo } from './foo .js 'console.log ( foo)
</ script>  

2.使用ESM模块导入导出语法

export const foo = 'foo';

(1)基于原生ESM的开发服务优势

  • 无需打包项目源代码
  • 天然的按需加载
  • 可以利用文件级的浏览器缓存

image-20220811102420721.png

(2)基于Esbuild的编译性能优化

Esbuild,基于Golang开发的前端工具。具备如下能力:

1.打包器 Bundler

2.编译器Transformer

3.压缩器Minifier

所以,由于性能极高的特性,在vite中被深度使用。

(3)内置的Web构建能力

Vite开箱即用的功能相当于 webpack、webpack-dev-server、class-loader、style-loader、less-loader....

可以将几十行的webpack.config.js代码简化成几行的vite.config.js

三、Vite使用

1、项目初始化

# 提前安装 pnpm
npm i -g pnpm
# 初始化命令
pnpm create vite
# 安装依赖
pnpm install
# 启动项目
npm run dev

初始化参数:

image-20220811103404661.png

启动后截图:

image-20220811103416766.png

启动完成后,打开浏览器访问对应地址即可。

2、使用Sass/Scss & CSS Modules

  • src目录结构

image-20220811103530924.png

  • 安装Sass
pnpm i sass -D
  • index.tsx
import styles from ' ./index.module.scss' ;
//使用CSS Modules模块化方案,防止 className命名冲突
export function Header() {
    return <p className={styles.header}>This is Header</p>
};
  • index.module.scss
.header {
    color: red;
}

3、使用Scss & CSS Module

  • src目录结构

image-20220811103816616.png

  • 引入Header组件
import { Header } from " ./components/Header " ;
function App() {
    return (
        <div>
            <Header/>
        </div>
    );
}
export default App;

4、使用静态资源

  • src目录结构

image-20220811103955216.png

  • 以svg图片为例
import { Header } from " ./components/Header ";
import logoUrl from ' ./logo.svg ';
function App() {
    return (
        <div>
            <Header />
            <img src={logoUrl} alt=""/>
        </div>
    );
}
export default App;
  • 除了常见的图片格式, Vite也内置了对于JSON、Worker、WASM资源的加载支持

[Vite内置资源加载]  cn.vitejs.dev/guide/featu… 

5、生产环境 Tree Shaking

优化原理:

1.基于ESM的import/export语句依赖关系,与运行时状态无关

2.在构建阶段将未使用到的代码进行删除

Tree Shaking在Vite中无需配置,默认开启。

6、Vite直观印象

  • 响应迅速
  • 开箱即用

四、Vite整体架构

image-20220811193725551.png

1、依赖预打包

为什么要进行预打包

  • 避免node_modules过多的文件请求
  • 将CommonJS格式转换为ESM格式

实现原理

1.服务启动前扫描代码中用到的依赖

2.用Esbuild对依赖代码进行预打包

3.改写import语句,指定依赖为预构建产物路径

//改写前
import React from "react";
//改写后
import React from ' /node_modules /.vite/react. js'

2、单文件编译

用Esbuild 编译TS/JSX

  • 优势:编译速度提升10-1000

  • 局限性:

    • 不支持类型检查
    • 不支持语法降级到ES5

3、代码压缩

Esbuild 作为默认压缩工具,替换传统的Terser.Uglify.js等压缩工具

4、插件机制

image-20220811194106467.png

  • 开发阶段:模拟Rollup插件机制
  • 生产环境:直接使用Rollup

五、Vite进阶路线

1、深入双引擎

  • esbuild
  • rollup.js

推荐学习顺序:先了解基本使用,手动尝试各项常用配置,然后学习其插件开发。

2、Vite插件开发

为什么需要插件机制?

  • 抽离核心逻辑
  • 易于拓展

(1)服务启动阶段:

config -> configResolved -> options -> configureServer -> buildStart

(2)请求响应阶段:

-> transformIndexHtml

-> resolveId -> load -> transfrom

(3)热更新阶段

handleHotUpdate

(4)服务关闭阶段

buildEnd -> closeBundle

通过上述的Hook,我们可以在不同的构建阶段插入自定义的逻辑、

[​Vite插件开发文档]  cn.vitejs.dev/guide/api-p… 

[json加载插件​]  github.com/vitejs/vite… 

[Esbuild接入插件​]  github.com/vitejs/vite… 

[官方React插件​]  github.com/vitejs/vite… 

3、代码分割(拆包)

拆包前:

image-20220811194909543.png

存在的问题:

  • 无法进行并发请求
  • 缓存复用率低

拆包后:

image-20220811194940762.png

参考资料

[​构建选项]  cn.vitejs.dev/config/buil… 

[​rollup.js]  rollupjs.org/guide/en/#o… 

4、JS编译工具(Babel)

image-20220811195106259.png

出现的原因:

  • JavaScript语法标准繁多,浏览器支持程度不一
  • 开发者需要用到高级语法

参考资料

[babel官方站点​]  babeljs.io/docs/en/ 

[babel插件手册​]  github.com/jamiebuilds… 

5、安全语法降级

以Promise语法为例,IE11没有支持。

image-20220811195314324.png

如何在构建产物中避免这类问题?

  • 上层解决方案:@vitejs/plugin-legacy

  • 底层原理

    • 借助Babel进行语法自动降级
    • 提前注入Polyfill实现,如core-js、regenerator-runtime

参考资料

[@babel/preset-env官方文档​]  babeljs.io/docs/en/bab… 

[​Vite官方降级插件文档]  github.com/vitejs/vite… 

6、服务端渲染(SSR)

一种常见的渲染模式,用于提升首屏性能和SEO优化

构建阶段:

image-20220811195632900.png

代码执行阶段:

image-20220811195606252.png