浅浅阅读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
Vue2使用全局函数或变量的两种常用方式
这篇文章介绍了在Vue 2项目中实现全局函数或变量的两种常用方式:一种是通过挂载到Vue的`prototype`,另一种是使用Vue的全局混入(Vue.mixin)。
1266 0
Vue2使用全局函数或变量的两种常用方式
|
XML SQL Java
Maven的三种打包方式(jar、shade、assembly)
Maven的三种打包方式(jar、shade、assembly)
5845 0
|
消息中间件 数据可视化 Java
Linxu下RocketMq及可视化界面的搭建
Linxu下RocketMq配置信息及可视化界面的搭建
1502 0
|
人工智能 Java Serverless
【MCP教程系列】搭建基于 Spring AI 的 SSE 模式 MCP 服务并自定义部署至阿里云百炼
本文详细介绍了如何基于Spring AI搭建支持SSE模式的MCP服务,并成功集成至阿里云百炼大模型平台。通过四个步骤实现从零到Agent的构建,包括项目创建、工具开发、服务测试与部署。文章还提供了具体代码示例和操作截图,帮助读者快速上手。最终,将自定义SSE MCP服务集成到百炼平台,完成智能体应用的创建与测试。适合希望了解SSE实时交互及大模型集成的开发者参考。
10193 60
完美解决 fatal: unable to access ‘https://github.com/Homebrew/brew/‘
完美解决 fatal: unable to access ‘https://github.com/Homebrew/brew/‘
2073 0
|
5月前
|
人工智能 算法 安全
AI时代:不可替代的“人类+”职业技能
在生成式人工智能快速发展的背景下,关于“人类工作者是否会被算法取代”的焦虑日益增加。本文探讨了AI对职业的重塑作用,指出真正的挑战在于如何通过职业技能培训重新定义人类的不可替代性。文章分析了替代与创造的辩证关系,强调人机协作时代的核心能力,如架构设计力、情感智慧和伦理决策力,并提出职业技能培训应从岗位技能导向转向能力生态构建。最终,通过系统性培训发展“人类+”特质,使AI成为解放人类潜能的工具,而非竞争对手。
|
前端开发 小程序 Java
【规范】SpringBoot接口返回结果及异常统一处理,这样封装才优雅
本文详细介绍了如何在SpringBoot项目中统一处理接口返回结果及全局异常。首先,通过封装`ResponseResult`类,实现了接口返回结果的规范化,包括状态码、状态信息、返回信息和数据等字段,提供了多种成功和失败的返回方法。其次,利用`@RestControllerAdvice`和`@ExceptionHandler`注解配置全局异常处理,捕获并友好地处理各种异常信息。
5877 0
【规范】SpringBoot接口返回结果及异常统一处理,这样封装才优雅
|
前端开发 JavaScript
umi 中useSearchParams 的使用样例
在umi中,`useSearchParams`是一个React Hook,用于获取和操作URL查询参数。以下是一个使用`useSearchParams`的样例: 首先,确保你已经安装了umi和react-router-dom。 1. 在页面组件中使用`useSearchParams`来获取和操作URL查询参数: ```javascript import { useSearchParams } from 'umi'; export default function SearchPage() { const [searchParams, setSearchParams] = useSea
1444 2
|
Kubernetes 网络协议 Cloud Native
Kubernetes网络问题排查分享两则(1)——calico特定场景下的网络性能问题
在对Kubernetes项目[kosmos](https://github.com/kosmos-io/kosmos)与Calico网络性能进行对比测试时,发现kosmos在跨集群容器网络的性能显著优于Calico的集群内网络(约6Gbit/s对比2.9Gbit/s)。物理机网络测试达到9.38Gbit/s,显示Calico有68%的性能损耗。问题定位到网卡的checksum/offload参数,尝试用`ethtool`调整后虽短暂提升,但随后恢复原状。转载自:https://mp.weixin.qq.com/s/XsQZCSqZAXJK46zqc7IpLw
|
缓存 前端开发 JavaScript
浅浅阅读umi中InitialState插件源码
InitialState插件源码的简要介绍
827 1
浅浅阅读umi中InitialState插件源码