Umi 插件实战教程,你学会了吗?|信息
笔者最近开发了一款 umi 插件:plugin-umi-cmdk[1],该插件的功能主要是:在 umi 项目里可以方便的集成 cmd + k ,实现菜单等搜索。
主体功能并不复杂,但是在集成作为 umi 插件过程中踩了不少坑,主要是 umi 官方文档的,开发插件 | UmiJS[2]实属写得烂,看完之后根本无法上手。
所以写一篇完整的插件开发教程,手把手上手 umi 插件开发。
【资料图】
准备工作创建项目新建一个文件夹umi-plugin-demo,直接通过 umi 的官方模版进行创建。
yarn create umi
之后选择模板的时候选择:Umi Plugin。
创建 example 目录用于测试然后创建完之后在umi-plugin-demo的根目录新建一个example文件夹,用于测试。
将 example 初始化成一个 umi 项目:
cd example// 然后yarn create umi
根据你的需求选择一个模板。
我选了 Ant Design Pro ,现在整个目录结构大致是这样。
挂载插件1、在src/index.ts里增加 log。
import type { IApi } from "umi";export default (api: IApi) => { // See https://umijs.org/docs/guides/plugins api.onStart(() => { console.log("欢迎关注前端桃园!"); });};
这个代码的意思就是在插件启动的时候打一个 log「插件开始加载了!!!」。
2、在example/.umirc里引入插件。
import { defineConfig } from "@umijs/max";import { join } from "path";export default defineConfig({ plugins: [join(__dirname, "../src/index.ts")], // 其他的配置 })
通过 plugins 这个配置,将插件文件进行引入,在启动 example 项目的时候插件就会被加载。
3、查看 logo 然后在 example 下,通过npm start启动项目,即可看到控制台的 log。
当我们看到控制台输出了想要的日志,到这一步,准备工作已经就绪,接下来就可以开始写插件了。
更多挂载方式除了通过plugins配置项挂载插件,umi还提供了一种约定式的挂载方式。
在umi体系中,约定根目录下存在plugin文件夹作为本地插件的约定入口。只要存在该文件夹,其中的插件就会被自动挂载,无需再进行额外的配置。
例如,在我们的示例中,可以直接在example目录下创建一个plugin.ts文件,即可将插件挂载到umi中,无需在.umirc配置文件中添加插件配置。这种方式通常用于本地测试插件。
编写插件一般的插件机制是通过暴露钩子来实现的,钩子会在运行时执行并提供一些属性供插件开发者使用。插件开发者可以在钩子中实现想要的功能,从而扩展插件的功能。因此,插件开发就是在钩子中编写代码实现自定义功能的过程。
所以一般在编写框架插件的时候就需要先了解一下该框架提供了哪些钩子,这个决定了开发者可以做哪些扩展的事情。
一般开发插件的基本流程如下:1、 浏览 umi 提供的插件 API2、确定插件的目的和功能 3、找到需要的插件 API 和生命周期方法
功能分析我以我写的插件 cmdk 插件举例分析。
cmdk 搜索那个就是一个纯 react 组件的功能,作为插件的话其实就是想办法把这个插件在 umi 运行的时候就插入到整个 umi 的最外层。
另外就是支持配置一些参数,比如有些用户不想用cmd + k,想用cmd + m来调出弹框。那么就需要配置快捷键的 key。
大致就这两个功能吧。
将 cmkd 的 react 组件插入到 umi。支持配置快捷键需要用到 API[api. describe ()](https://umijs.org/docs/api/plugin-api#describe "api. describe ( "api. describe ()")")。用于在插件注册阶段执行,用于描述插件或者插件集的 key、配置信息和启用方式等。在 .umirc 配置快捷键的时候需要用到。[api. onGenerateFiles ()](https://umijs.org/docs/api/plugin-api#ongeneratefiles "api. onGenerateFiles ( "api. onGenerateFiles ()")")。生成临时文件的钩子,就是把运行时需要的文件生成到 .umi 目录下的那个钩子。[api. writeTmpFile ()](https://umijs.org/docs/api/plugin-api#writetmpfile "api. writeTmpFile ( "api. writeTmpFile ()")").生成临时文件的方法,在 onGenerateFiles 阶段进行调用的,将临时文件写入进去。看到这些文件,这些就是在 umi 运行时需要用到的文件,都是对应的插件生成的。umi 在运行时这些代码都是会执行的,在我们这里也是需要把 cmdk 那个 react 组件写到这里面来,这样在运行时才能用。
1、给插件传递属性并做参数校验比如我们需要将.umirc的快捷键配置传递给插件,配置文件大致是这样配置:
export default defineConfig({ plugins: [join(__dirname, "../src/index.ts")], cmdk: { keyFilter: "cmd+w", },}
意思就是插件的 key 叫 cmdk,有一个 keyFilter 的配置。插件里的代码就可以这样的写。
import type { IApi } from "umi";export default (api: IApi) => { api.describe({ key: "cmdk", // 定义插件名称,跟 .umirc 的配置的 key 相同。 config: { schema(joi) { // 返回值,定义配置的 schema 结构,我们只需要这个对象里有一个 keyFilter 的字符串。 return joi.object({ keyFilter: joi.string(), }); }, }, enableBy: api.EnableBy.config, })}
这样就可以实现对配置参数的校验了。我们可以通过api.userConfig.cmdk拿到配置。
2、给 react 组件传递属性可以通过api.userConfig.cmdk拿到了配置参数,最终目的是要传递给 react 组件的。
在src下新建一个文件cmdk.tpl用于方 cmdk 的 react 代码。
然后通过 [api. writeTmpFile ()](https://umijs.org/docs/api/plugin-api#writetmpfile "api. writeTmpFile ( "api. writeTmpFile ()")") 将配置参数传进去,在 umi 插件里由于不是 react 组件,没办法通过 props 传递属性,所以只能通过用模板的方式进行传递参数。
umi 插件用的模板引擎是 Mustache 。
所以插件代码这里就可以这么写:
import type { IApi } from "umi";export default (api: IApi) => { // 其他代码 api.onGenerateFiles({ fn() { const runtimeTpl = readFileSync( join(__dirname, "cmdk.tpl"), "utf-8", ); api.writeTmpFile({ path: "runtime.tsx", content: Mustache.render(runtimeTpl, { props: JSON.stringify(api.userConfig.cmdk) }), }); } })}
这段代码的意思就是在 onGenerateFiles 钩子里,就是生成临时文件的钩子。
先通过readFileSync从插件的源码里读取要写入临时文件的模板文件cmkd.tpl,然后再通过writeTmpFile写入到.umi下去,同时将api.userConfig.cmdk作为参数,写入到 props 这个模板参数里.
umi 会自动写到对应的插件目录下。
在cmdk.tpl里可以这样拿到传递的参数。
const _props = {{{ props }}};const { keyFilter = "meta.k" } = _props;
第一行是 Mustache 模板引擎的语法,用于变量替换,第二行就是简单的一个解构。这样就可以拿到keyFilter了。
大致思路就是这样了。
另外--如何拿到整个 rootContainer因为我们需要把我们的 react 组件,放到组件的最外层,可以通过 rootContainer 这个函数进行处理。代码如下:
export function rootContainer(container) { return <> {container} >}
CommandMenu就是写的 React 组件,跟 container 平级放就好了,container 就是整个 react 容器。
到此,基本功能就可以了,接下来就是发布了。
发布打包构建由于该例子是基于 umi 脚手架创建的,本身集成了 umi,打包什么的都很方便。
只需要关注 2 个点:
.fatherrc.ts的配置是否正确:import { defineConfig } from "father";export default defineConfig({ cjs: { output: "dist" }, esm: { output: "es" },});
主要关注需要打包的模块化文件,cjs 是 commonjs 的,如果需要在 node 环境,就需要配置一下,如果只是浏览器环境用的包,只需要配置 esm 即可。
需要关注一下 package.json 里的入口文件是否跟输出的文件匹配:
module 填的是 es module 的入口文件。
最后再执行一下 npm run build ,即可将产物构建出来。
发布到 npm产物构建出来之后,然后再执行:
npm publish
将模块发布到 npm 上供别人使用。
小结本文介绍了如何编写 umi 插件,包括插件的结构和编写过程。通过编写 umi 插件,你可以扩展 umi 的功能,提高开发效率,并且可以将你的插件分享给其他人使用。
当你开始编写 umi 插件时,建议你先了解 umi 的基本用法和原理,并且熟悉 React、Webpack 和 Node. js 等相关技术。同时,你也可以参考 umi 官方提供的插件列表和开源社区中的插件,以了解其他人是如何编写 umi 插件的,并从中学习到一些有用的技巧和经验。
希望本文能对你有所帮助,祝你编写出高质量的 umi 插件!
参考文章[插件开发 (umijs.org)](https://v3.umijs.org/zh-CN/guide/plugin-develop "插件开发 (umijs.org "插件开发 (umijs.org)")")。参考资料[1]plugin-umi-cmdk:https://github.com/crazylxr/plugin-umi-cmdk。
[2]开发插件 | UmiJS:https://umijs.org/docs/guides/plugins。
标签:
- 网络百科全书 情人节唱什么歌
- 知识百科 空落落的意思 空落落是什么意思
- 百科知识 在天津哪能吃到正宗的灌汤包
- 中文百科 钟浈封北宸的小说叫什么
- 知识问答 成都买公寓限购吗
- 权威百科知识 歌之王子殿下歌曲是什么
- 黄山提升政府采购透明度 助力实体经济持续健康稳定发展
- 1-2月黄山新签“双招双引”项目103个 总投资额139.7亿元
- 池州海关共签发RCEP原产地证书22份 签证金额92.7万美元
- 宿州泗县深入推进文旅融合发展 擦亮城市品牌
- 河北工业生产平稳开局 固定资产投资较快增长
- 昆明西山区深入实施人才强区战略 建立健全招商招才引资并轨新模式
- 2月唐山新建商品住宅销售价格与上月持平 同比下降0.8%
- 去年河北电子信息产业实现主营业务收入2367.7亿元 同比增长22.4%
- 绥化望奎以工业化思维为引领 推动肉类加工制造产业腾飞
- 绥化市监局推出多项举措 大力促进有机产品产业发展
- 半路出家无心插柳 杭州西湖区“菌菇宝宝”变废为宝
- 温州鹿城区藤桥主打藤桥熏鸡 近两年销售额年均增长20%以上
- 1-2月安徽限额以上消费品零售额1030.4亿元 同比增长10.4%
- 2021年合肥市茶园面积13.6万亩 产值176350万元
- 淡季不忘引流 京郊民宿市场将很快迎来回暖
- 郴州安仁文旅项目集中开工 总投资1000万元
- 江苏服务业继续保持发展强劲势头 为高质量发展提供有力支撑
- 黄山休宁经开区摸排基础设施项目17个 计划总投资29709万元
- 前两个月宣城出口31亿元 增长34.4%
- 滁州凤阳2021年共接待游客225万人次 旅游综合收入20.25亿元
- 1-2月宿州市民间投资同比增长19.2% 居全省第3位
- 宿州严格审核把关 抢抓发行地方政府专项债券政策机遇
- 1-2月亳州市进出口总值5.5亿元 同比下降17.4%
- 合肥:弘扬茶文化 初步形成一条生态发展之路
- 合肥:建成“数字中国”领先城市 推进城市数字化转型
- 甘肃再续“艾黎情”:探职业教育德技并修
- 【城市守望者】致敬抗“疫”一线的“拆弹专家”
- 浙江绍兴越城区核酸检测结果公布 除1例阳性外其余均为阴性
- 内地首例奥密克戎变异株感染者身体状况如何?来自哪里?专家解读→
- 对变异病毒已有准备!关于中国新冠药物,钟南山发声→
- 江苏睢宁小网格大担当 织就乡村振兴“幸福网”
- 改造老旧小区 共享幸福生活
- 天津静海:群众在哪里,文明实践就延伸到哪里
- 齐齐哈尔:初步判断疫情感染来源为接触新冠病毒污染环境和物品
- 重庆大竹林派出所副所长因对群众态度简单粗暴被停职
- 黑龙江讷河病例感染源初步判断为新冠病毒污染的环境和物品
- 致敬2021
- 浙江瑞安民警捐献造血干细胞:14年前的心愿终将如愿
- “考研房”涨价离谱 律师:借机宰客有违市场伦理
- 广州白云机场:14天内有东莞旅居史的旅客须凭48小时核酸阴性证明乘机
- 浙江绍兴本轮疫情已报告确诊病例145例 无症状感染者1例
- 福建龙岩一男子和前妻斗气 扛着126斤硬币到法院“还钱”
- 重庆这座立交酷似“悟空” 走红 设计师揭秘(图)
- 青海警方破获特大电诈案 涉案流水高达1.7亿
- 云南新增境外输入确诊病例3例
- 黑龙江讷河市5名核酸阳性人员流调溯源:接触被新冠病毒污染的环境和物品
- 男子爱上女主播 假扮女主播闺蜜教其他男粉丝刷单
- 广西三市警方联手破获毒品案 全链条摧毁跨境贩毒团伙
- 广东东莞发现2例无症状感染者,部分镇今起全员筛查
- 从百二秦关到闻道凯旋 一个殉职医生最后的朋友圈
- 浙江发补充说明:三地铁路出行政策随风险等级同步调整
- 内蒙古新增本土确诊病例5例 均在呼伦贝尔满洲里市
- 陕西新增本土确诊病例1例 系隔离酒店工作人员
- 31省份新增新冠肺炎确诊病例76例 其中本土51例
- 浙江新增新冠肺炎确诊病例45例 其中本土44例
- 技能就是财富 技工也是人才
- 黑龙江新增本土确诊病例1例、本土无症状感染者4例
- 冷空气“调休”!我国大部陆续迎回暖 中东部雨雪稀少
- 华北黄淮等地大气扩散条件转差 冷空气将影响中东部
- 别误读了野猪或将不再是“三有”动物
- 您的ETC已到期?当心这个诈骗短信!
- 对回家的“宝贝”少一些关注,也是一种帮助
- 升温!北京今日阳光在线 最高气温将升至8℃
- 那年今日 | 一张漫画涨知识之12月14日
- 40岁男子一觉醒来突然听不见了 原因是……
- 本年度星空压轴大赏上演 双子座流星雨观赏地图来了
- 广东东莞大朗镇报告2例新冠肺炎无症状感染者
- 商丘4885份被盗出生证去哪了?10年“悬案”引关注
- 浙江海宁警方通报国家公祭日女子穿和服逛街
- 厨艺不精调料凑?懒人调料:年轻人的“下厨神器”
- “您的ETC已到期?”警方提醒:当心这个诈骗短信
- “网红”局长的热度 自述:走红后我就没有周末了
- 寻回被拐10年的儿子后又送走 儿子:害我没家了
- 小城里的三张面孔和警号301137
- 倡导“就地过年”,需因地制宜科学防疫
- 别用“入乡随俗”为星巴克找借口
- 北京地铁14号线年底全线贯通运营
- 天津市从入境人员中检出奥密克戎变异株
- “外滩活地图”黄俊:一个不想出圈的段子手交警
- 寻找一双儿女的25年
- 无锡市场监管部门责成星巴克涉事门店停业整改
- 海岛警事:为了一座岛和2900平方公里的海
- 北京民警宏福苑抗疫26天:“今夜我和雪花一起出发”
- 星巴克的“金标准”缘何败给了“潜规则”
- 患者被低价药“惊呆”的场面应该更多些
- 影视剧“超前点评”不止是“低级错误”
- “南昌鹦鹉案”下发不起诉决定书 网店上架费氏牡丹鹦鹉被拒
- 河南商丘4885份出生医学证明被盗始末追踪
- 绍兴市病例62-109活动轨迹公布
- 12月7日以来,杭州累计报告新冠肺炎确诊病例19例
- 浙江绍兴新增确诊病例37例 上虞区占36例
- 河南高院对张成功案作出死刑判决
- 四川一滑雪场停电游客被困索道 官方回应
- 浙江绍兴越城区新增1例新冠肺炎确诊病例 当地对防控区域划分进行调整
广告
广告
- 生活知识 宁陕县景点
- 长治襄垣县增收11517万元 提前15天实现首季“开门红”
- 黑龙江讷河新增1例确诊4例无症状 病例详情公布
- 浙江宁波余姚奉化宁海三地开展核酸检测 结果均为阴性
- 浙江湖州南浔三处棋牌室经营者被行拘
- 那年今日 | 一张漫画涨知识之12月13日
- 在宁波乘火车跨省出行须持48小时内核酸阴性证明
- 浙江温州一地发现核酸弱阳性?复采复检结果均为阴性
- 浙江三门发现一名密接者:二次核酸检测结果均为阴性
- 贱卖的发电机 新买的制茶机——安徽水电供区改革两周年回访见闻
- 浙江杭州新增1例新冠肺炎确诊病例 为集中隔离人员
- 2022年研考在即,学硕缩招,专硕时代真的来了?
- 探访杭州核酸检测点:排队高峰多在夜间 医院24小时运转
- 浙江发挥零售药店“哨点”作用 织就疫情防控监测网
- 哈尔滨市本轮疫情首批1名确诊患者出院
- 宁波镇海第三轮全员核酸检测574181人 结果均为阴性
- 陕西新增本土确诊病例1例、境外输入无症状感染者2例
- 齐齐哈尔讷河一地调整为中风险地区
- 浙江新增新冠肺炎确诊病例75例 其中本土74例
- 内蒙古新增本土确诊病例5例 均在呼伦贝尔满洲里市