依赖预构建
vite是一个基于浏览器原生ES-Module的前端构建工具。
当你首次启动vite的时候,vite会在本地加载你的站点之前预构建项目依赖。
原因:
- CommonJS和UMD兼容性:在开发阶段中,Vite的开发服务器将所有的代码视为原生ES模块。因此,Vite必须先将以CommonJS或UMD形式提供的依赖项转换为ES模块。
- 性能:为了提高后续页面的加载性能,Vite将那些具有许多内部模块的ESM依赖项转换为单个模块。有些包将他们的ES模块构建成许多单独的文件,例如,lodash-es有超过600个内置模块,当我们执行import引入的时候,浏览器会同时发出600多个HTTP请求!大量的请求会导致浏览器端的网络拥堵,使页面加载变得明显缓慢。预构建会将lodash-es预构建为单个模块,现在我们只需要一个HTTP请求。
依赖预构建仅仅适用于开发模式,并使用esbuild将依赖项转换为ES模块。
预构建的内容是什么?
一个项目里,存在很多模块,并不是所有的模块都会被预构建,只有裸依赖(bare import)会执行依赖预构建。
什么是裸依赖呢?
//bare import
import xxx from "vue"
import xxx from "vue/xxx"
//下面不是
import xxx from "./foo.ts"
用名称去访问的模块是裸依赖,用路径去访问的模块不是
Node.js定义了bare import的寻址机制——在当前目录下的node_modules下寻找
裸依赖一般是npm安装的模块,是第三方模块,不是我们自己写的代码,一般情况下不会被修改,因此对这部分的模块提前构建,有利于提升性能。
相反,如果对开发者写的代码执行预构建,将项目打包成chunk文件,当开发者修改代码时,需要再重新执行构建,在打包成chunk,反而影响性能。
事实上,vite会判断模块的实际路径,是否在node_modules中:
- 实际路径在node_modules的模块会被预构建,这是第三方模块
- 实际路径不在node_modules的模块,证明该模块是通过文件链接,连接到node_modules的,是开发者自己写的代码,不执行预构建
缓存
文件系统缓存
vite将预构建的依赖项缓存到node_modules/.vite中。它会基于以下几个来源决定是否需要重新运行预构建步骤:
- 包管理器的锁文件内容:package.lock.json,yarn.lock等
- 补丁文件夹的修改时间patch-package
- vite.config.js中的相关字段
- NODE_ENV的值
只有上述的其中一项发生改变的时候,才需要重新运行预构建。
如果出于某种原因想要强制重新预构建,可以在启动开发服务器的时候指定 --force选项,或者手动删除node_modules/.vite缓存目录
浏览器缓存
已经预构建的依赖请求使用HTTP进行强缓存,以提高开发期间页面重新加载的性能。一旦被缓存,这些请求将永远不会再次访问开发服务器。
静态资源处理
在vue中,静态资源分为两种:
1.存放在public中的静态资源,这部分资源会被完全的复制,不会经过构建工具处理,可以通过根绝对路径来引用他们。
- 路径设置时不需要添加public/,默认加载public文件夹下的图片
- 不需要使用require(当构建工具为webpack的时候,因为webpack使用的是commrnJS规范)
2.存放在assets目录下,属于代码的一部分,只支持相对路径,会被构建工具打包,并且和样式会被压缩打到一起,可以避免额外的网络请求。 - 需要使用require(当构建工具为webpack的时候,因为webpack使用的是commrnJS规范)
vite怎样加载静态资源
我们主要讨论public目录下的静态资源。
主要从js、jpg、json、mp4、css五类文件讨论。
当我们在一个项目中引入这五类资源,并且打印的时候,我们可以看到
执行dev命令,我们可以看到,
所有静态资源都被引入了,但是vite对他们的处理方式并不同,css、js文件被直接输出内部定义的内容,json被转为了对象形式,而url和mp4被输出他们文件的url地址。
当然,我们可以通过一些手段来控制css和js也输出他们的路径。
比如:
1.assetsInclude选项配置
注意,这个配置里不能写json文件哦,写了要报错的。
2.使用?url后缀,显式的导入一个url
同样的,我们也能控制img和mp4以原文件输出
3.使用?raw后缀,将文件作为源文件输出
这时候jpg和mp4会以流的形式输出。
这个时候要说到另一个文件格式,svg格式,他和图片一样,也会被vite处理输出为url,但是当用?raw后缀的时候,会被直接输出为HTML。