浅浅阅读umi中InitialState插件源码 - 杨磊

简介: InitialState插件源码的简要介绍

umi


umi 是一个企业级的前端解决方案,内部集成前端常用的构建工具、开发流程,以及官方提供了一系列核心的插件。简化前端开发中的各种配置。


umi 插件


任何一个工具的插件系统,无非就是扩展这个工具的能力。umi 插件也不例外。


基于 umi 的插件机制,你可以获得扩展项目的编译时和运行时的能力。你可以利用我们提供的 插件 API 来自由编写插件,进而实现修改代码打包配置,修改启动代码,约定目录结构,修改 HTML 等丰富的功能。


更加详细的介绍,请移步Umi 插件文档


umigithub地址, umi 官方提供的插件在`packages/plugins`目录下


umi 每个插件都是一个函数,这个函数接收一个 umi 提供的`api`参数。这个`api`上提供了许多`hooks`函数和一系列工具函数。具体 api 上有哪些属性和方法,可以参阅 umi 插件 Api


InitialState 插件


initial-state 插件的作用:**提供一份全局状态数据**


`src/app.ts` 的导出一个`getInitialState`函数,这个函数的返回值,就是初始的全局状态。默认在刷新页面的时候,重新执行。


单页应用,路由的切换,不会导致 `getInitialState` 的重新执行。如果想要手动执行,可以通过`useModel`返回的 set 方法。具体事例如下:

# src/app.ts;exportasyncfunctiongetInitialState(): Promise<{ name: string }> {
return { name: "@umijs/max" };
}
# 组件内 消费constHomePage: React.FC= () => {
// 手动刷新的方法const { initialState, setInitialState } =useModel('@@initialState');
return (
<h1onClick={() =>setInitialState({ name: 'xx-1'+newDate().toString() })}>      {initialState?.name}
</h1>  );
};

【packages/plugins/src/initial-state.ts】总揽

image-2.png

上面就是 `initial-state`插件的全部代码,总共调了五个 api,注册了相关的钩子。


细节

image-1.png


1、[describe 函数](https://umijs.org/docs/api/plugin-api#describe),一个接收对象而不是函数参数的 api。这意味着,这个函数不是回调形式的。主要用于描述插件 key、配置信息和启用方式等。


从上面代码可以看出, inititalState 插件的启用方式是*需要配置的*,并且接收的值有两种,`boolean`或者一个`object`,对象里面可以传递一个`loading`属性。这个属性传递一个字符串。后面我们会说到这个`loading`怎么使用的。


2、[register 函数](https://umijs.org/docs/api/plugin-api#register),注册一系列行为。在 umi 的其他插件,可以通过`api.applyPlugins`拿到相同`key`的一系列对象。


image-3.png


`inititalState`中注册的这个行为,会在 `model`插件中被消费。本质上`inititalState`就是内置的一个特殊的`model`,所以要想启用`inititalState`插件,必须先配置`model`插件。


总结:这一行代码(api.register),本质上就是添加一个全局`model`,他的文件路径在`.umi/plugin-initital-state/@@inititalState.ts`,这个`fn`函数只是返回了一个文件路径。具体的内容还在下面的`onGenerateFiles`回调中。这个路径 umi 内部还带了特殊的后缀。用来注册,我们消费的时候,传递给 useModel 的 key 值。


image-4.png


3、这两行代码很简单,`addRuntimePluginKey`,声明一个可以在`app.ts`中可以导出的变量名。`addRuntimePluginKey`函数是一个内部封装,本质上还是 JS 中注册和消费的形式。下图就是这个注册的对象,被消费的时的代码。

image-6.png


`addRuntimePlugin`,这行代码为项目声明一个运行时插件,返回一个路径。说实话,不太懂为啥这么设计,返回只返回一个路径,具体文件内容的写入,得在下面的回调里去做。个人感觉一个 api,可以全部搞定。


这里声明的插件路径,会在下图所在地被消费。初始值为`app.ts(x)`路径。看来`umi`内部把`app.ts`也当作一个运行时插件。


image-7.png


拿到所有插件路径后,就会在`.umi`临时目录下写一个新文件`core/plugin.ts`


image-8.png


core/plugin.ts

image-9.png


最后一步就是写文件了,把`inititalState`有关的代码,写入临时目录


`onGenerateFiles`生成临时文件时,随着文件变化会频繁触发,有缓存。


image-10.png


主要写了四个临时文件。

image-11.png


填一下上面留下的一个 loading 问题

image-12.png


从图上可以看到,这个`loading`的配置,本质上就是一个路径。写文件的时候,直接放在`import`里面。由于这个文件是写在`.umi`目录下的,所以可以享受项目里面配置的 alias。也就是可以自定义一个 loading 组件。例如,我在 src/components 目录下写一个默认导出的 loading 组件。我配置时候,传递 loading 的值就可以为`@/components/loading`


总结:其实可以看到,同步 api 的代码并不多,更多的是注册钩子,写运行时文件。但就这几个 api 就可以写一个比较完整的插件。更加具体的`inititalState`运行时代码,请大家移步.umi 下生成的文件。`umi`插件提供的`api`对象上,还有着更多的能力,大家写插件的时候可以打印出来看看,不仅有着完善的流程上的诸多钩子,也有着为跨平台提供的工具函数。利用 umi 提供的插件能力,企业自己也可以定制为自己业务服务的前端架构体系,完善项目里面各种不一致的问题。


上文代码所用umi版本为4.0.26。以上为自己拙见,如有不一致或者错误的地方,欢迎大家批评指正。



相关文章
|
开发框架 小程序 JavaScript
基于mpvue框架的小程序项目搭建入门教程一
基于mpvue框架的小程序项目搭建入门教程一
154 0
|
4月前
|
存储 JavaScript
这一定是最有用的vite插件入门教程了!
【8月更文挑战第3天】 vite插件核心在于几个钩子函数的理解与使用,想开发vite插件,掌握这几个插件即可。本文中探讨了**config钩子**和**transformIndexHtml钩子**,相信大家看完对插件开发一定有了最基本的认识与方向!
108 3
|
5月前
|
JavaScript Java 测试技术
基于SpringBoot+Vue+uniapp的古风生活体验交流网站的详细设计和实现(源码+lw+部署文档+讲解等)
基于SpringBoot+Vue+uniapp的古风生活体验交流网站的详细设计和实现(源码+lw+部署文档+讲解等)
|
6月前
|
JavaScript Java 测试技术
基于SpringBoot+Vue+uniapp的漫画阅读系统的详细设计和实现(源码+lw+部署文档+讲解等)
基于SpringBoot+Vue+uniapp的漫画阅读系统的详细设计和实现(源码+lw+部署文档+讲解等)
|
6月前
|
测试技术 数据安全/隐私保护 Java
基于SpringBoot+Vue+uniapp的小说阅读平台的详细设计和实现(源码+lw+部署文档+讲解等)
基于SpringBoot+Vue+uniapp的小说阅读平台的详细设计和实现(源码+lw+部署文档+讲解等)
基于SpringBoot+Vue+uniapp的小说阅读平台的详细设计和实现(源码+lw+部署文档+讲解等)
|
7月前
|
JavaScript Java 测试技术
基于SpringBoot+Vue+uniapp的中学课内小说阅读与学习系统的详细设计和实现(源码+lw+部署文档+讲解等)
基于SpringBoot+Vue+uniapp的中学课内小说阅读与学习系统的详细设计和实现(源码+lw+部署文档+讲解等)
|
7月前
|
JavaScript Java 测试技术
基于SpringBoot+Vue+uniapp的小学生课外知识学习网站的详细设计和实现(源码+lw+部署文档+讲解等)
基于SpringBoot+Vue+uniapp的小学生课外知识学习网站的详细设计和实现(源码+lw+部署文档+讲解等)
|
7月前
|
资源调度 JavaScript 搜索推荐
《VitePress 简易速速上手小册》第9章 VitePress 的扩展与插件(2024 最新版)
《VitePress 简易速速上手小册》第9章 VitePress 的扩展与插件(2024 最新版)
456 0
|
API 开发者
🚀两个简单的自定义插件,探究Vite的插件机制
🚀两个简单的自定义插件,探究Vite的插件机制
|
JavaScript 前端开发 开发工具
【从零到一手撕脚手架 | 第一节】配置基础项目结构 Vite + TypeScrpit + Vue3 初始化项目
今天为大家带来一套教程,教大家入门“脚手架”,相信你一定会有所收获。 目前项目已开源且仍处于开发阶段,后续会更新更多内容,如有不正确的地方请大家指正,我会及时更新并纠正我的错误。
551 0
【从零到一手撕脚手架 | 第一节】配置基础项目结构 Vite + TypeScrpit + Vue3 初始化项目