vite 会将代码分为两部分,依赖和源码。依赖就是我们所引入的各种三方库(vue、react),源码就是我们自己写的代码(css、js、html),vite工作流程是 启动是进行将依赖进行预构建为一个es模块,vite以esm模块的形式为浏览器提供源码。esm就是直接给浏览器提供export、import这类模块化的代码。
执行流程:
本期起一个服务,浏览器解析 import, 发起http请求,本期的服务的中间件拦截请求,调用pluginContainer发起构建流程,最后将解析后的文件返回到浏览器。
在 pluginContainer 中会依次执行 resolveId、load、transform 三个方法,这三个方法会将所有插件的三个钩子全部执行一边。注意:是先执行所有插件的resolveId、再执行所有插件load、在执行所有插件的transform。
执行npm run dev流程:
一:执行 resolveConfig 方法,主要是将vite.config文件中的配置与默认配置合并,获取最终配置
1:读取本地配置,这个过程中需要注意会用到esbuild编译配置文件得到本地配置对象,接着执行mergeConfig方法,将预先配置与本地配置进行合并。
2:对插件进行区分,依据插件执行的时机
通过sortUserPlugins方法,对插件进行拆分,得到三个数组插件,分别是re、post、normal,这三个数组插件执行的顺序不同。
3:执行config钩子(主要是对config进行hooks)
通过 runConfigHook 方法 执行每个插件的config钩子,最后返回一个config对象
4:接着处理config配置中的 resolve配置项(主要是将默认的配置与本地的配置进行merge)
5:利用 dotenv-expand 将env文件加载到 process.env 环境变量中
6:将本地配置的build与默认的build选项合并,得到最后最终的build
7:处理server和ssr配置,同上
8:接着是web work的一些配置
9:执行resolvePlugins,梳理所有插件以及插件的执行顺序。在这个方法添加的内置插件(很多)
vite插件分为内置插件和用户插件,每种类型的插件有三个执行顺序。pre>normal(部分条件插件)>post
aliasPlugin插件执行顺序最高,主要是处理别名。接着就是prePlugin。
esbuildPlugin:三方库,编译文件
importAnalysisPlugin:递归解析文件中的 import ,
import 'foo' -> import '/@fs//project/node_modules/foo/dist/foo.js'
import './style.css' -> import './style.css.js'
二、新建一个connect服务,加入中间件进行拦截。这个文件的编译过程就是在中间件中调用pluginContainer进行的。
插件开发:
插件就是vite在打包的过程中,在不同的时期执行不同的回调钩子。钩子调用的时机大致分为vite加载配置时(config)、vite加载完配置后(configResolved)、vite解析模块路径时(resolveId)、vite加载源文件时(load)、vite对源码进行处理(transform)
对源码处理的方式:
1:将源码转成ast语法树
2:字符串直接切割
流程:
在resolveid 钩子中读取文件路径,在load钩子中读取文件,在Transform钩子中转换。当在文件中读取到新的import,接着重新走一边以上流程
钩子总结:
1:全局钩子
config:修改默认配置
configResolved:获取加载后的配置
2:局部钩子
resolveid:解析文件路径,返回给load使用。多个插件有resolveid钩子时,当某一个钩子返回了结果,后续resolveid钩子便不再执行。如果模块名称以/0开头,意思就是 resolveid钩子对该模块不做任何处理,交给后面的钩子处理。
resolveId(id, source) {
// import jq from 'jquery' id
// id就是jq,source是上面这段代码所在的文件
console.log('----------------')
console.log(id) // 模块名
console.log(source) // 模块所在的文件
},
load:根据resolveid钩子返回的路径加载文件,load可以加载磁盘文件、网络文件、虚拟文件。虚拟文件就是在磁盘上不存的,一般指我们在插件中直接返回的字符串
transform:根据需求对加载的源码进行处理(code)
ast语法树:
主要是有两个,acorn和babel/parser,babel是acorn的扩展。增加了类型和写等操作。vite内置了acorn。在处理import时使用了es-module-lexer
网友评论