美文网首页
ONES插件开发的学习笔记

ONES插件开发的学习笔记

作者: 何小有 | 来源:发表于2023-10-30 00:26 被阅读0次

    首先插件的功能是私有化部署的功能, 只能在私有化部署的 ONES 上能安装和使用插件。

    安装最新版本 Node.js 的稳定版, 配置 ONES 的私有 npm 仓库:

    $ npm config set registry=https://registry.npmjs.org/
    $ npm config set @ones:registry=https://npm.partner.ones.cn/registry/
    $ npm config set @ones-op:registry=https://npm.partner.ones.cn/registry/
    

    这里本来想先安装 Homebrew 后通过 brew install n 安装 n 工具, 再使用 sudo n 16.13.0 安装 v16.13.0 版本的 Node.js 环境, 但是出现 github.com port 443: Operation timed out 异常, 尝试过更换中科院的镜像地址和 Leensa 网络代理工具均无效时, 放弃这个方案。

    下载 cmake-3.22.2-macos-universal.dmg 安装 CMake 工具, 然后通过 cmake --version 检查是否安装成功。

    这里遇到了 Error: Running Homebrew as root is extremely dangerous and no longer supported. 异常, 通过下面的命令解决:

    $ sudo chown -R `whoami` /usr/local/Homebrew/
    $ sudo chown -R $(whoami) $(brew --prefix)/*
    $ sudo mkdir /usr/local/Frameworks
    $ sudo chown -R `whoami` /usr/local/Frameworks/
    

    使用 npm install -g @ones/cli 安装 ONES CLI 脚手架工具, 再使用 ones --version 验证是否正确安装, 以后的升级用 npm update -g @ones/cli 命令来完成。

    创建插件

    插件在作用范围上, 分为 组织级别团队级别 两种;在功能范围上, 分为 业务插件账号管理与通知托管独立服务 三种。

    新建一个目录作为插件工程的根目录, 进入目录执行 ones create -d 命令创建一个插件工程, 其中的 -d 选项表示使用默认的工程创建预设配置。这样创建的是 团队级别 的插件, 可以用 --plugin-type organization 选项表示创建 组织级别 的插件。

    插件项目的目录 (ONES CLI 创建的插件工程目录结构) 生成后, 使用 npx op packup Demo 命令对插件进行打包, 模式 (no-modify-无修改 | major-主版本 | minor-次版本 | patch-修复版本) 选择 no-modify 无修改。

    打包完成后, 工程根目录中就可以看到 Demo.opk 这个 opk 包, 这个是 团队级别 的插件, 在 “配置中心 -> 插件管理” 选择 Demo.opk 文件完成安装, 如果是 组织级别 的则在 “组织管理 -> 插件管理” 页面安装。

    调试插件

    执行 npx op login 命令在私有化部署环境中获取用户凭证的参数 (执行前需要在 “配置中心 -> 插件管理” 删除掉之前安装), 并存储到 config/local.yaml 中。命令要求输入的参数 base URL 是私有化 ONES 平台的域名地址 (例如 “https://xxxx/”), 参数 host URL 是私有化 ONES 平台的 TCP 主机地址和 9006 端口号 (例如 “tcp://127.0.0.1:9006”), 还有就是登录私有化 ONES 平台的账号密码, 以及选择进入的团队。

    生成 config/local.yaml 后, 执行 npx op invoke run 启动本地调试, 这个命令会为插件工程的前端部分 (/web) 启动一个热更新的开发服务器, 第一次启动后控制台会返回 instance_uuid 值, 这个值是插件被安装到具体环境时动态生成的实例 uuid 值。

    现在 “配置中心 -> 插件管理” 里刷新, 可以看到插件已经被安装了, 中断前面的 npx op invoke run 进程, 再执行 npx op invoke clear 就可以卸载插件, 卸载完成后再中断当前进程, 这个就是插件的调试过程。

    修改插件的配置文件 (config/plugin.yaml) 后需要卸载插件后重新安装, 即重新执行 npx op invoke runnpx op invoke clear 命令。

    添加插槽

    插槽是纯前端的能力, 存放于 /web/src/modules/ 目录下以插槽模块命名的目录中, 插槽模块相当于一个独立的 React 应用, 支持 TypeScript 语言。

    以全局的顶栏公告插槽 ones:global:banner 为例, 执行 npx op add module 命令并选择 ones:global:banner 插槽, 输入 banner 或其他标题, 就完成插槽的创建, 在 /config/plugin.yaml 文件的最后多了一个 modules 字段, 在这个字段下有一个 entry 字段, 对应的是 /web/src/{entry} 目录下的文件路径, 这个文件目录下包含 index.tsxindex.css 两个文件。

    插槽模块目录下的 index.css 文件是样式代码, 自动生成的 #ones-mf-root {} 是插槽模块的根元素, 插槽支持 PostCSS 框架, 例如可以创建一个单独的样式文件 banner.css 并输入下面代码:

    .banner {
        width: 100%;
    }
    

    然后在 index.css 中引入这个 banner.css 文件:

    @import 'banner.css';
    
    #ones-mf-root {}
    

    保存以上代码后, 在 ONES 平台页面的顶部就可以看到插槽模块的效果, 插件在打包时仅执行 .ts.tsx 文件的转译, 插件模块的打包以模块内的 index.tsx 文件为入口, 这个文件里的 <ConfigProvider> 组件必须保留。

    添加能力

    能力有 基础能力-平台开放能力业务能力-应用开放能力 两种, 以 简单登录 能力为例, 执行 npx op add ability 指令向插件新增开放能力, 并选择 simple-auth 能力, 就完成能力的创建, 在 /config/plugin.yaml 文件的最后多了一个 abilities 字段, 同时在 /backend/src 目录下, 生成了 index.tssimple-auth.ts 两个文件。

    大概得出一个小结, 插槽是前端的显示, 能力是后端的实现, 插槽和能力如何进行关联需要更深入的了解。

    接口请求

    首先是前端请求, 进入插件工程的 /web 目录执行 npm install @ones-op/fetch 命令进行依赖安装, 使用 ONES CLI 创建工程的时默认帮注册的 APIhello 接口, 在 plugin.yaml 中有一个 apis 字段, 它的 url 字段是 /hello, 对应的是在 /backend/src/index.ts 里有一个 export async function hello(request: PluginRequest) 函数, 这个就是 API 的实现。这样就可以在插件中使用 OPFetch 来请求这个接口。

    直接用 Postman 请求时需要带上 Ones-Check-PointOnes-Plugin-IdOnes-Check-Id 三个请求头, 插件 ID 在 “配置中心 -> 插件管理 -> 插件详情” 的 URL 里看, 团队 ID 在 “配置中心 -> 团队配置 -> 团队消息” 的 URL 里看, 然后用 POST 请求 https://xxxx/project/api/project/hello 地址就可以获得响应。

    然后是后端请求, 进入插件工程的 /backend 目录执行 npm install @ones-op/node-fetch 命令进行依赖安装, 在 /backend/src/index.ts 文件里修改代码, 用 const projects = await fetchONES<ProjectResponseBody>({...})... 就可以调用接口请求。

    数据获取

    在插件里可以获取平台的 全局数据特定上下文数据 两种, 进入插件工程的 /web 目录执行 npm install @ones-op/store 命令进行依赖安装, 然后就可以通过下面代码获取当前团队信息:

    import { useTeamInfo } from '@ones-op/store'
    
    const { uuid, name } = useTeamInfo()
    

    把上面代码加到插槽模块里, 这样就可以在前面的插槽模块里显示当前团队信息。

    事件通信

    平台提供了一套事件通信库, 通过进入插件工程的 /web 目录执行 npm install @ones-op/event 命令进行依赖安装, 就可以使用一套事件通信库:

    大概实现的通过插槽模块里调用事件通信库, 来使用平台提供的事件, 例如在 “创建新用户时” 调用 “触发成员列表刷新”、“访问自定义的项目概率插件” 时 “激活全局进度管理器” 等实现。

    生命周期

    插件的生命周期是指插件在 ONES 私有环境中从上传到卸载整个阶段的完整过程, 包括 “未安装”、“未启用”、“启用” 三个过程, 而在这个过程中伴随着一系列的生命周期事件的钩子函数, 这些钩子函数在插件工程初始化后就包含在 /backend/src/index.ts 文件中, 直接看注释就可以理解其含义。

    插件打包

    在插件工程的根目录下执行 npx op packup 命令就可以打包插件了。

    插件自定义配置

    插件支持在 plugin.yaml 文件下的 config 字段添加自定义配置项, 配置项分3个类型, 通过配置项字段 type 区分:

    • type: Input # 单行输入框
    • type: TextArea # 多行输入框
    • type: Password # 密码输入框

    除了 type 还有另外4个配置项字段, 其中必填的有1个:

    配置项字段 说明 类型
    key 唯一标识 string

    其中必填的有3个:

    配置项字段 说明 类型 默认值
    required 字段是否必填 boolean false
    label 字段别名 string 取 key 字段的值
    value 字段默认值 string

    还可以在详情页面里新建选项卡, 在插件工程目录下执行 npx op add module 命令, 选择创建 settings 插槽的模块, 再输入一个标签页标题, 这样在插件详情页, 就可以在插件详情页面看到新的标签页。

    接口注册

    接口注册属于插件能力, 插件能力允许插件注册 插件级别团队级别 两种级别的接口, 它们在注册时的区别在于在 config/plugin.yaml 文件的 apis 字段的 type 子字段, 片段type: addition 表示 插件级别 的接口, 片段type: external 表示 团队级别 的接口, 它们的访问路径也不同:

    • 插件级别通过URL https://xxx/project/api/project/hello 访问
    • 团队级别通过URL https://xxx/project/api/project/team/:teamUUID/hello1 访问

    除了文档中提供的内容, 还有另外一种区分方法:

    • URL包含 /project/api/project/ 的为全局接口
    • URL包含 /project/api/project/team/:teamUUID/ 的为团队接口
    • URL包含 /project/api/project/organization/:organizationUUID/ 的为组织接口

    此外 apis 字段还有一个 scope 子字段, 用于定义当前接口的路由是 project 还是 wiki 路径:

    • scope: project 时URL为 /project/api/project/ 路径
    • scope: wiki 时URL为 /wiki/api/wiki/ 路径

    还有一些特殊情况, 例如 https://xxx/wiki/api/project/organization/:organizationUUID/user_list_filter_rules 接口, 就是 /wiki/api/project/ 这样的路径。

    接口劫持

    接口劫持可以替换平台已有的接口, 也可以对已有的接口请求前后添加 前置处理后置处理 逻辑, 实现接口劫持同样是在 config/plugin.yaml 文件 apis 字段的 type 子字段里:

    • type: replace 时为接口替换, 即重写接口
    • type: prefix 时为前置劫持, 即前置处理
    • type: suffix 时为后置劫持, 即后置处理

    因为是对已有接口做处, 所以填写的 url 必须跟访问 ONES API 的 url 保持一致, 同时要确认被操作接口是 POST 请求还是 GET 请求, 还要注意请求参数和响应内容。此外 apis 字段还有一个 query 子字段, 用于控制接口劫持的前置条件, 只有当请求值包含某些参数时才劫持接口。

    自定义权限点

    第一个 场景:系统顶栏右侧组件 例子中, 是通过 permission 字段和 permission: component_permissions插槽模块 直接配置一个独立的权限管理:

    service:
      permission:
        - name: Component permissions
          field: component_permissions
          desc: System sider permissions
    modules:
      - id: ones-layout-header-action-new-LZrd
        title: layoutHeaderAction
        moduleType: ones:layout:header:action:new
        enableMemoryRouter: true
        entry: modules/ones-layout-header-action-new-LZrd/index.html
        permission: component_permissions
    

    第二个 场景:支持权限上下文的自定义迭代组件 例子中, 先使用 npx op add ability 添加了 custom-permission 这个 插件能力 并将其与 插槽模块 关联, 实现权限控制。

    相关文章

      网友评论

          本文标题:ONES插件开发的学习笔记

          本文链接:https://www.haomeiwen.com/subject/pfqbidtx.html