webpack和vite

232 阅读3分钟

前言

webpack一直是前端打包管理的主流,但近几年vite开始出现在大众视野。那webpack和vite有什么区别呢?

webpack

特别是在大项目启动的时候,最明显的两个问题:

  1. 会发现启动时间会花比较久的时间
  2. 热更新反应速度比较慢
webpack的运行原理:
webpack是采用模块打包的方式启动项目,通常是通过词法分析(token集),语法分析生成AST语法树,然后将所有的模块打包成一个或多个bundle,交给服务器运行

热更新:
代码修改过后,需要重新进行打包,然后运行

浏览器是无法识别cjs或umd模块的语法的,所有的解析都是webpack做的处理

打包问题:
1.webpack会打包一个个体积较大的bundle.js
2.浏览器并不支持模块化
3.零散的模块文件会产生大量的http请求(此时会造成浏览器并发请求资源的问题)

vite

实现原理:

利用浏览器es moudle原理,采用按需加载的形式。只要将script的type设置成module,就会向服务器发送请求,服务器整合后返回浏览器可以识别的代码(省去了打包编译的过程)

生产环境:采用rollup打包
开发环境:利用浏览器支持esm的原理,让浏览器去解析模块,服务器按需编译返回,跳过了打包的概念

特点:
1.预构建依赖(在服务器还未启动前,通过入口文件将需要用到的模块缓存到.vite包中)
2.按需加载

vite原理的相关问题:

1.vite热更新和dev构建为什么快

vite基本原理是基于浏览器原生支持esm。可以不用打包,且每次更新仅仅需要整理修改的那一部分模块,所以热更新快。vite采用了预构建依赖

2.vite热更新是如何处理的?

启动 客户端和websoket两个服务。监听本地文件变更,针对不同类型然后做相应的处理,通过ws通知客户端去加载新的资源或刷新网页
热更新时,不同文件有不同的处理方式:
1.js文件变更,刷新网页
2.vue文件,会将它划分成三部分,script,tempalte,style。style直接引入;tempalte转换成createElement;script转换成esm;最后让浏览器进行识别

3.vite对源文件做的转换和处理(浏览器知道去node-modules里去找文件)

vite会对文件导入的依赖路径做node_modules对应位置的转换,让浏览器知道在哪儿去访问
例如:import {reactive} from 'vue'
会被转换成 import { reactive } from '/node_modules/.vite/vue.js?v=9c1d7fbb'

4.vite第一次构建为什么慢?

第一次慢的原因是因为vite需要做预构建依赖。第二次访问的时候就直接走缓存(node_modules里的.vite中)
如何清除缓存
(1)--force
(2)package.json / lockfile / vite.config.js => 三者之一发生变化 => 重新预构建
(3)通过路由直接访问esm模块,通过浏览器缓存解析依赖进行强缓存优化

5.为什么需要做预构建依赖?

(1)兼容:需要去兼容commonJs和umd。浏览器只能识别esm
(2)性能:vite会将内部拥有多个模块的esm关系转换为单个模块。以减少http请求(例如lodash有很多内置模块,本来会发送多个http请求,转换过后变成一个单独的模块,就只需要发送一次请求)

6.碰到大模块会怎么处理?

vite的预构建依赖

7.依赖遇到多种模块化格式是怎么处理的(例如cjs,esm)

vite的预构建依赖

8.公共依赖部分的处理

浏览器会自行处理,esm依赖包中多次导入的公共包x,只会下载和解析一次