06-面试讲解
# vite插件面试讲解
# 技术点图谱
涉及到的技术点如下:
- 如何读取文件
- 生成路由配置
- 额外的路由元数据信息
- 如何制作Vite插件
- 如何测试插件
- 如何发布
# 难点描述
模拟问题:我看你项目亮点里面写的是“完成路由自动生成的Vite插件的编写与发布”,你当时为什么想着做这个事情?你做这个事情对整个项目来讲,有一些什么样的收益?
问题分析
- 当时做这个事情的背景,一般是遇到了 XXX 问题,然后需要解决这个问题
- 拿到这个问题之后,你是如何思考的
- 你思考出来的方案是什么
- 最终落地方案以及一个方案带来的效果,效果最好是有具像化的数据来做支撑
参考答案
面试老师,是这样的,当时我们整个项目是使用 Vite 搭建的,然后我发现整个项目的页面组件的层次,和路由的配置信息,感觉是高度耦合的,于是我就思考,能否根据页面组件的目录层次结构,自动生成路由配置信息,这样以后就不用每次新增页面组件都要去更新路由配置信息了。(阐述做这个事情的背景)
后来我在闲暇之余,查到像一些 nuxtjs、umijs 这样的框架,采用的就是这样的模式,而且这种模式还有一个专门的名字,叫做“约定大于配置”,是架构设计里面一种非常成熟的模式,因此我认为这个事情是可以做的。(我拿到这个问题后我的一个思考过程)
紧接着我就对该功能需求进行了拆解,其实并不复杂,主要就这么几步:
- 读取页面组件目录
- 根据读取到的信息生成路由的数组
- 在路由实例中使用自动生成的数组
当然这里面还有很多需要考虑的细节,例如读取目录用什么方式去读,路由额外的元数据信息如何配置等。(钩子🪝)整个自动生成路由的功能书写好了后,后期新增页面组件,就再也不用去修改路由配置文件了,这其实也从侧面遵循了设计原则中的开闭原则。
整个项目结束后,自动生成路由这一块儿的代码工作稳定,我就琢磨着将其封装成 Vite 插件,这样方便后面在其他项目里面复用。我认为这也算是从侧面在为项目,或者说帮公司做降本增效的事儿了。(这个事儿带来收益)
# 技术点描述
# 1. 读取目录
模拟问题:你刚才说里面有很多需要考虑的细节,例如读取目录就是其中一项,请问这一块儿主要需要考虑的是啥呢?
问题分析
- 读取文件和目录常规方案?
- 你选择的方案是什么?你为什么选择这种方案?
- 设置下一个钩子
参考答案
读取目录的话首先会想到使用 node.js 里面的 fs 模块来完成,我一开始也是这么考虑的,但是使用 fs 模块读取文件会存在这么一些问题:
- 不支持热模块替换功能
- 需要手动实现按需导入和懒加载功能
- 无法直接利用前端构建工具提供的优化功能,如代码分割和懒加载
(阐述你的一个思考过程)
后来我了解到其实在不同的构建工具,专门提供了读取文件和目录的方法的,例如:
- webpack 的 require.context
- 可以动态加载指定目录下的所有模块
- 支持模块热替换
- Vite 下则是使用 import.meta.glob
动态导入指定目录下的所有文件
支持代码分割和懒加载
与 Vite 的 HMR 功能无缝集成
(常见的和构建工具配套的读取方案)
所以读取目录这一块儿我选择了使用 import.meta.glob,通过这个方法读取到路由信息后,对路由信息做二次处理,生成路由配置的数组方便后面使用。(钩子🪝)
# 2. 路由细节
模拟问题:你这里所说的对路由信息做二次处理,主要是做一些什么样的处理?
问题分析
- 解释一下做了哪些二次处理
- 额外的路由元数据信息是怎么处理的
- 设置下一个钩子
参考答案
是这样的,通过 import.meta.glob 拿到的路由信息是没法直接用的。举个例子,能拿到的是文件路径是 ../views/Home.vue,但是最终要映射的路由路径是 /home,这就涉及到 JS 的基本工了,需要对文件路径进行字符串分割、过滤、合并处理,从而移除重复的目录名和文件名。
另外还有一点非常重要,通过文件路径我们最多分析出路由路径以及这个路径对应的组件是什么,但是路由配置里面往往还存在一些其他的路由元数据,例如页面标题、权限控制等信息。这一块儿我参考了微信小程序,为每一个页面组件配套了一个 meta.js 文件,该文件就用来提供额外的路由元数据信息。
所以我刚才所说的二次处理,主要就是处理这些细枝末节的东西,其实封装成 vite 插件的时候,封装的主要也就是这一块儿逻辑。(钩子🪝)
# 3. 如何制作Vite插件
模拟问题:说一下如何创建一个 vite 的插件呢?
问题分析
- 一定要回答到 vite 插件的本质是什么?
- 结合你的项目,说喜爱 vite 插件是如何封装的
- 额外补充一下 vite 插件是经过了测试的,工作正常
- 设置下一个钩子
参考答案
要创建一个 vite 插件其实并不难,官方也有相应的文档说明。(体现这些事儿对于我来讲都不是个事儿)实际上 vite 插件的本质就是一个具有特定结构的 JS 对象,这个对象提供了一些钩子函数,可以在 Vite 构建流程的不同阶段执行特定的逻辑。(讲清楚 vite 插件的一个本质)
我在自定义的 vite 插件中导出了一个函数,该函数的执行会返回一个对象,而这个对象的 configResolved 钩子方法里面所封装的,其实就是前面所讲的读取目录,根据读取到的信息做二次处理,组装路由配置信息的逻辑。(结合自己的项目说这一块儿具体怎么做)
这个 vite 插件写好后,我在原来的项目里面对该插件做了测试,能够正常工作。并且我也把这个插件发布到了 npm 上面,然后拉取新项目进行测试,也都是正常的。发布到 npm 上面有个好处(钩子🪝),就是以后能很方便的用于其他项目里面,并且我打算以后对这个插件做长期维护,这也算是为前端社区贡献一份自己的力量。
# 4. 插件的发布
模拟问题:讲一下发布之前有哪些准备工作要做?
问题分析
- 介绍一下发布的平台?两者之间的区别?
- 发布到 npm 前需要做哪些配置?白名单、黑名单之间的区别?
- 对整个项目亮点做一个收尾
- 要么突出个人的做事儿风格
- 要么突出项目收获
参考答案
准备工作这一块儿的话,具体要看发布到哪个平台,不同的平台,要准备的东西会有些不一样。
如果是 github 的话,主要是做源码分享的,所以准备工作这一块儿要多一些,涉及到 CHANGELOG、README 等各种文档。
如果是 npm 的话,主要是做包的发布,所以一般需要将代码进行打包压缩,然后发布的是打包后的代码到 npm 仓库。
我这边发布插件主要就是发布在的 npm 上面,用的 rollup 进行打包,然后在 pakcage.json 里面需要配置入口文件。另外还有一个非常重要的配置,就是指定上传哪些文件或者目录。有两种指定方式:
- 白名单:files
- 黑名单: .npmignore
一般要上传到 npm 上面的目录是打包后的 dist 目录,所以推荐用白名单的方式。这样即便后面新增了文件,白名单那一块儿也不需要任何修改。
通过封装 vite 插件,我对工程化相关的知识也比之前更加熟悉了,特别是 package.json 里面各种配置项,以前其实不怎么关心的,熟悉的就是 devDependencies 和 dependencies. 但是这里涉及到要发布包,所以针对入口文件配置呀、白名单配置呀、都有了更深的了解和掌握,这也算是我做这个项目时一个非常大的收获。(最后做一个总结,结束撒花🎉)
-EOF-