浅浅阅读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)。
1312 0
Vue2使用全局函数或变量的两种常用方式
|
6月前
|
人工智能 算法 安全
AI时代:不可替代的“人类+”职业技能
在生成式人工智能快速发展的背景下,关于“人类工作者是否会被算法取代”的焦虑日益增加。本文探讨了AI对职业的重塑作用,指出真正的挑战在于如何通过职业技能培训重新定义人类的不可替代性。文章分析了替代与创造的辩证关系,强调人机协作时代的核心能力,如架构设计力、情感智慧和伦理决策力,并提出职业技能培训应从岗位技能导向转向能力生态构建。最终,通过系统性培训发展“人类+”特质,使AI成为解放人类潜能的工具,而非竞争对手。
|
开发工具 git
Stylelint—— Expected class selector ".nut-popup--top" to be kebab-case selector-class-pattern
新项目制定规范接入了stylelint,并通过husky在git提交时去触发检测修复,因为使用的是NutUi,所以无法直接调整组件对应的类名称,只好在stylelint.config.js中加入相应的rules进行配置。
325 0
|
人工智能 自然语言处理 并行计算
【AI大模型】Transformers大模型库(六):torch.cuda.OutOfMemoryError: CUDA out of memory解决
【AI大模型】Transformers大模型库(六):torch.cuda.OutOfMemoryError: CUDA out of memory解决
959 0
【AI大模型】Transformers大模型库(六):torch.cuda.OutOfMemoryError: CUDA out of memory解决
|
JSON 前端开发 JavaScript
Go怎么解析不定JSON数据?
在Go中处理不确定结构的JSON数据,可以使用`map[string]interface{}`来解析,它能适应各种JSON键值对,但需要类型检查。另一种方法是使用`json.RawMessage`保存原始JSON,之后按需解析。此外,`json.Number`用于处理任意精度的数字。当JSON字段类型未知时,可以先解码到`interface{}`并做类型断言。第三方库如gjson和jsonparser提供更灵活的解析选项。
497 1
|
前端开发 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
1517 2
|
缓存 前端开发 JavaScript
浅浅阅读umi中InitialState插件源码
InitialState插件源码的简要介绍
862 1
浅浅阅读umi中InitialState插件源码
|
JSON 小程序 JavaScript
【微信小程序-原生开发】TDesign 实战模板——账号密码登录页(含密码显示隐藏的技巧)
【微信小程序-原生开发】TDesign 实战模板——账号密码登录页(含密码显示隐藏的技巧)
546 0
TS 快速入门
TS 快速入门
185 0
|
机器学习/深度学习 编解码 自动驾驶
自动驾驶感知多任务框架 | MultiTask V3、HybridNets和YOLOP谁更强呢?
自动驾驶感知多任务框架 | MultiTask V3、HybridNets和YOLOP谁更强呢?
405 1

热门文章

最新文章