- vite是什么?
- 新一代前端构建工具,在开发环境中,利用浏览器到ESM特性导入组织代码,在服务器端按需要编译返回,跳过了打包这个概念,生产环境中则利用Rollup作为打包工具。
- vite有以下特点
- 快速的冷启动:不用打包(浏览器支持ESM)+esbuild预构建
- 动态模块热替换:基于ESM的HMR,利用HTTP加速整个页面的重新加载,源码模块使用协商缓存,依赖模块强缓存
- 真正的按需加载:利用浏览器ESM支持,实现真正的按需要加载
- 浏览器需要支持原生的ESM script标签,支持原生的ESM动态导入和import.meta
- Chrome >=87
- Firefox >=78
- Safari >=13
- Edge >=88
-
ESM
- ESM是JavaScript提出的官方标准化模块系统,不同于之前的CJS,AMD,CMD等等,ESM提供了更原生以及更动态的模块加载方案,最重要的就是它是浏览器原生支持的,也就是说我们可以直接在浏览器中去执行import,动态引入我们需要的模块,而不是把所有模块打包在一起。
- script标签里面的属性 type为module
-
ESBULID
-
开发环境下,Vite底层使用Esbuild实现对.``ts、jsx、.``js代码文件的转化。esbulid其实是一个js bundler打包和压缩工具,使用go语言编写,相对于js编写的同类工具,速度快出10到100倍
-
esbulid对依赖进行预编译
- 支持commonJS和UMD依赖,转化为ESM模块,可以被浏览器直接加载
- vite是基于浏览器支持ESM的能力实现的,要求用户代码模块必须是ESM
- 减少模块和请求数量
- vite将许多内部模块的ESM依赖关系转化为一个模块
- 存在于node_modules/.vite/deps,使用max-age强缓存
-
为什么选择ESBUILD
-
-
ROLLUP
- 生产环境下,使用rollup进行打包
- rollup是基于ESM的JavaScript打包工具。相比于其他打包工具如Webpack,他总是能打出更小、更快的包。因为 Rollup 基于 ESM 模块,比 Webpack 和 Browserify 使用的 CommonJS模块机制更高效。Rollup的亮点在于同一个地方,一次性加载。能针对源码进行 Tree Shaking(去除那些已被定义但没被使用的代码),以及 Scope Hoisting 以减小输出文件大小提升运行性能。
-
Vite其核心原理是利用浏览器现在已经支持ES6的import,碰见import就会发送一个HTTP请求去加载文件,Vite启动一个 koa 服务器拦截这些请求,并在后端进行相应的处理将项目中使用的文件通过简单的分解与整合,然后再以ESM格式返回返回给浏览器。Vite整个过程中没有对文件进行打包编译,做到了真正的按需加载,所以其运行速度比原始的webpack开发编译速度快出许多!
-
开发环境,基于ESM
-
webpack是先解析依赖,打包构建成bundle文件后在启动服务器。当我们修改了bundle文件中某个子模块后整个,整个bundle文件需要重新打包输出。
-
vite则是先启动开发服务器,没有对依赖进行解析打包,当import模块时,浏览器再下载该模块。import再加载,本质上实现了动态加载。
- 使用http加速页面加载,源码文件设置协商缓存,依赖文件使用强缓存(启动过一次后)
-
-
为什么生产环境使用rollup?
- Rollup 在应用打包方面更加成熟和灵活(官方原话,以后也不排除使用esbuild可能性)
- 生产环境仍然需要打包?
- import嵌套导入,减少http请求数量
- 提高加载性能,将代码进行tree-shaking,懒加载,chunk分割
-
vite独有钩子函数
config
:可以在Vite
被解析之前修改Vite
的相关配置。钩子接收原始用户配置config
和一个描述配置环境的变量env
configResolved
:解析Vite
配置后调用,配置确认- 可以用来获取vite.config里面配置的参数
- 这次的copyAssetsPlugin里面就用它来获取assetsDir的名字了
- 可以用来获取vite.config里面配置的参数
configureserver
:主要用来配置开发服务器,为dev-server
添加自定义的中间件transformindexhtml
:主要用来转换index.html
,钩子接收当前的HTML
字符串和转换上下文handlehotupdate
:执行自定义HMR
更新,可以通过ws
往客户端发送自定义的事件
-
通用钩子
- 在开发中,Vite 开发服务器会创建一个插件容器来调用 Rollup构建钩子,与 Rollup 如出一辙。
- 以下钩子在服务器启动时被调用:
- options
- 获取Rollup的配置
- buildStart
- 获取options 钩子配置后的Rollup 配置和一些默认值,这个钩子开发和生产环境值都存在
- options
- 以下钩子会在每个传入模块请求时被调用:
- resolveID
- 可以获取文件路径,在该钩子下可以对文件路径进行重写或其他操作
- load
- 可拦截文件读取,模块引入读取操作,例如我想拦截某个组件读取,这样写后,对应的组件里面的内容加载时就会被替换成code的内容。
- transform
- 可以转换单个模块对应的代码,和load钩子不同的是,他有两个参数,
code
和id
,这里的id
和上面一样,这个code
就是他对应的代码
- 可以转换单个模块对应的代码,和load钩子不同的是,他有两个参数,
- resolveID
- 以下钩子在服务器关闭时被调用:
- buildEnd
- 打包代码码未输出
- closeBundle
- 打包代码码已经输出
- 这次的copyAssetsPlugin里面就用它来修改输出的map文件的路径
- buildEnd