从0到1深入理解vite

一、什么是构建工具

  1. ts:如果遇到ts文件,我们需要使用tsc把ts转换为js
  2. react/vue : 安装react-compiler、vue-conplier 将我们写的jsx或者vue文件转换成render函数
  3. less/sass/postcss/somponent-style:我们又需要less-loader、sass-loader等一系列编译工具
  4. 语法降级:babel--->将es的新语法转换成旧版浏览器可以接受的语法
  5. 体积优化:uglifyjs--->将代码进行压缩变成体积更小性能更高的文件
  6. ...

每次稍微改一点点东西,就会非常麻烦

我们需要把App.tsx通过tsc转换为App.jsx,再通过React-complier转换为js文件

有一个东西能够帮我们把tsc,react-complier,less,babel,uglifyjs全部集成到一起,我们只需要关心我们写的代码,如果代码一变化,就会全部把上述流程全部走一遍,这个东西就是构建工具

一个构建工具到底承担了哪些?

  1. 模块化开发支持:支持直接从node_modules中引入代码以及多种模块化支持
  2. 处理代码兼容性:比如babel语法降级、less、ts语法转换(不是构建工具做的,而是构建工具将这些语法对应的处理工具集成进来自动化处理)
  3. 提高项目性能 :压缩文件,代码分割
  4. 优化开发体验:
    • 构建工具会自动监听文件的变化,当文件变化会自动调用对应的集成工具进行重新打包,然后在浏览器重新运行,整个过程叫做热更新
    • 开发服务器:跨越问题,用react-cli,create-react-element、vue-cli 解决跨域问题

每次改一点,都需要走一遍这个构建的流程,顺序还不能错

构建工具就是为了让我们不用关心代码在浏览器如何运行,我们只需要首次给构建工具提供一个配置文件(这个配置文件也不是必须的,他会有默认的),有个这个集成的配置文件之后,我们就可以在下次需要更新的时候调用一次对应的命令就好了,如果我们再结合热更新,我们就不用关心生产的代码也不用关心代码如何在浏览器如何运行,只需要关心我们怎么写就行

市面上主流的构建工具

webpack

vite

parcel

esbuild

rollup

grunt

gulp

二、vite相较于webpack的优势

当我们开始构建越来越大型的应用时,需要处理的 JavaScript 代码量也呈指数级增长。包含数千个模块的大型项目相当普遍。基于 JavaScript 开发的工具就会开始遇到性能瓶颈:通常需要很长时间(甚至是几分钟!)才能启动开发服务器,即使使用模块热替换(HMR),文件修改后的效果也需要几秒钟才能在浏览器中反映出来。如此循环往复,迟钝的反馈会极大地影响开发者的开发效率和幸福感

如果我们的项目越大,webpack所要处理的js代码就越多,跟webpack的构建过程有关,造成需要很长时间才能启动开发服务器

webpack支持多种模块化:工程不止跑在浏览器端

他一开始必须要统一模块化代码,所以意味着他需要将所有的依赖全部读一遍

vite是基于esmodule的,不能写commonjs代码,就不需要讲所有的依赖都读一遍,就以为不需要很长的时间启动开发服务器

根据下图:webpack先从入口开始把所有的模块构建在开启开发服务器,而vite是先开启服务器,从入口只加载当前路由的模块,按需加载,所以很快

三、vite启动项目初体验

yarn create vite

  • 会帮我们全局安装一个create-vite(vite脚手架)
  • 会直接运行create-vite bin目录下的一个执行配置

很多人会误区 认为官网中使用yarn create构建项目的过程是vite在做的事情,create-vite只是一个脚手架

create-vitevite的关系是什么?

create-vite内置了vite

就像是使用vue-cli也会内置webpack

预设

我们自己搭建一个项目,需要下载vite、vue、post-scc、less、babel等,而create-vite/vue-cli会帮我们集成好这些东西,这个就叫预设

四、vite依赖预构建

在默认情况下,esmodule导入资源的时候要么是绝对路径,要么是相对路径,既然我们现在的最佳实践是node_modules,为什么在es官方在我们导入非绝对路径和非相对路径资源的时候不帮我们搜寻node_modules呢?

原因就是太消耗性能了,在浏览器端,我们想要获取资源,都是通过http请求去加载资源,而一个资源往往也要引用好多个资源,这样一次就需要加载成千上万个资源,如果每个引入的资源都需要去加载,那么就会非常消耗性能


那么vite是怎么处理能够获取到这种非绝对路径或者相对路径的资源呢?

官网回答:https://cn.vitejs.dev/guide/features#npm-dependency-resolving-and-pre-bundling

vite在处理过程中如果遇到了非绝对路径或者相对路径的引用,则会尝试开启路径补全,比如我们引入import { cloneDeep } from "lodash";,会修改成如下图

找寻依赖的过程中,是自当前目录依次向上查找的过程,直到搜寻到根目录或者搜寻到对应依赖为止

而为何会把路径补齐成上图这样?

这是因为我们在导入第三方的包的时候,并不确定第三方包是以何种形式导出的,有的是commonjs(axios)规范导出,有的是esmodule规范导出,所以vite在导入这些第三方包的时候,就需要统一处理,vite会找到对应的依赖,然后用esbuild(对js语法进行处理的一个库),将其他规范的代码转换成esmodule规范的代码,然后放到当前目录下的node_modules/.vite/deps文件夹中,同时对

依赖预构建解决了什么问题

  1. 不同的第三方包会有不同的导出格式(这个是vite没法约束的事情),导入时统一格式

  2. 对路径的处理上可以直接使用.vite/deps,方便路径重写

  3. 网络多包传输的性能问题(也是原生esmodule不敢解决node_modules的问题),有了依赖预构建以后,无论有多少的额外的export和import,vite都会尽可能的将他们进行继承,最后生成一个或者几个模块

    假设loadsh又依赖了很多其他的模块,并且这些模块都是用export导出,比如lodash-es这个库,我们可以看到下图有很多导出

    而在浏览器中则会看到vite已经把lodash-es做了一层转换,转换成一个一个的函数

    javascript 复制代码
    export { default as add } from "./add.js" 
    //相当于 
    import add from "./add.js" 
    export const add = add 

    vite重写以后

    javascript 复制代码
    function add(){}

如果我们不让lodash-es进行预构建,可以再vite.config.js中配置

我们可以看到改变,足足有649个请求,并且lodash-es的代码也是没有打包过的

从上图不难看出,使用与构建之后只需要请求一,而不预构建则需求请求600多次,可想而知差距有多大,这也是为什么说解决了网络多包传输的性能问题

开发环境中 ,每次依赖预构建所重新构建的相对路径都是正确的
生产环境中vite会全权交给rollup去完成生产环境的打包

vite的基本安装和使用

vite的编译结果

vite的编译结果分析

vite的配置文件

vite中处理css,静态资源怎么去做

vite的插件以及常用插件的使用

vite与ts的结合

vite构建react项目,svelte项目,vue3项目

vite的构建原理

相关推荐
腾讯TNTWeb前端团队38 分钟前
helux v5 发布了,像pinia一样优雅地管理你的react状态吧
前端·javascript·react.js
范文杰4 小时前
AI 时代如何更高效开发前端组件?21st.dev 给了一种答案
前端·ai编程
拉不动的猪4 小时前
刷刷题50(常见的js数据通信与渲染问题)
前端·javascript·面试
拉不动的猪4 小时前
JS多线程Webworks中的几种实战场景演示
前端·javascript·面试
FreeCultureBoy5 小时前
macOS 命令行 原生挂载 webdav 方法
前端
uhakadotcom6 小时前
Astro 框架:快速构建内容驱动型网站的利器
前端·javascript·面试
uhakadotcom6 小时前
了解Nest.js和Next.js:如何选择合适的框架
前端·javascript·面试
uhakadotcom6 小时前
React与Next.js:基础知识及应用场景
前端·面试·github
uhakadotcom6 小时前
Remix 框架:性能与易用性的完美结合
前端·javascript·面试
uhakadotcom6 小时前
Node.js 包管理器:npm vs pnpm
前端·javascript·面试