优化
This commit is contained in:
@@ -0,0 +1,212 @@
|
||||
---
|
||||
sidebar_position: 3
|
||||
title: 开发一个主题插件
|
||||
---
|
||||
|
||||
在 `Tailchat` 中开发插件是非常方便的,我们从开发一个主题插件来开始
|
||||
|
||||
## 最终效果
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
## 创建插件
|
||||
|
||||
> 如果是第一次开发需要确保已经初始化了插件开发环境。 [了解更多](./init-env.md)
|
||||
|
||||
```bash
|
||||
tailchat create --template client-plugin
|
||||
```
|
||||
|
||||
因为主题样式是一个纯前端的实现,因此我们选择`client-plugin`模板
|
||||
|
||||
通过交互式命令行提示完成创建工作
|
||||
|
||||

|
||||
|
||||
此时的目录结构应该是这样的:
|
||||
```
|
||||
.
|
||||
├── package-lock.json
|
||||
├── package.json
|
||||
├── node_modules
|
||||
└── plugins
|
||||
└── com.test.hutao
|
||||
├── manifest.json
|
||||
├── package.json
|
||||
├── src
|
||||
│ ├── index.tsx
|
||||
│ └── translate.ts
|
||||
├── tsconfig.json
|
||||
└── types
|
||||
└── tailchat.d.ts
|
||||
```
|
||||
|
||||
这时候我们就可以立即开始编译插件了
|
||||
|
||||
```bash
|
||||
npm run plugins:all
|
||||
```
|
||||
|
||||
编译的产物会出现在 `/dist/plugins/com.test.hutao`。通过修改 `mini-star` 的配置可以让其输出在其他目录 *(这点会在服务端开发插件中会用到)*。
|
||||
|
||||
## 在 Tailchat 中安装插件
|
||||
|
||||
对于前端插件,我们需要把产物用一个http静态服务提供出来,比如在本地开发中我们可以这样:
|
||||
|
||||
```bash
|
||||
npx http-server .
|
||||
```
|
||||
|
||||

|
||||
|
||||
此时我们可以通过地址访问到我们编译出来的结果了,如 [http://127.0.0.1:8080/dist/plugins/com.test.hutao/index.js](http://127.0.0.1:8080/dist/plugins/com.test.hutao/index.js)
|
||||
|
||||
在 Tailchat 中提供了手动安装插件的方式,我们可以通过手动安装的方式安装插件。
|
||||
|
||||
复制插件目录下 `plugins/com.test.hutao/manifest.json` 的内容,粘贴到手动安装插件部分。
|
||||
|
||||
修改url为可以访问到的真实地址。点击确定按钮后自动执行安装命令:
|
||||
|
||||

|
||||
|
||||
如果提示安装成功,打开控制台则可以看到对应输出:
|
||||
|
||||

|
||||
|
||||
这里是插件里默认生成的逻辑,当日志输出了插件加载完毕的提示说明我们的插件已经被安装成功了。
|
||||
|
||||
## 编写样式文件并应用
|
||||
|
||||
因为我们需要修改主题样式,因此涉及到样式文件和静态资源的处理。接下来我们先来创建我们主题的样式
|
||||
|
||||
在`plugins/com.test.hutao/src/theme.less`中写入样式:
|
||||
|
||||
```less
|
||||
#tailchat-app.theme-genshin-hutao {
|
||||
@primary-color: #dd5545;
|
||||
|
||||
--tc-primary-color: @primary-color;
|
||||
--tc-background-image: url(./bg.jpg);
|
||||
--tc-content-background-image: url(./avatar.png);
|
||||
--tc-content-background-image-opacity: 0.15;
|
||||
|
||||
.bg-navbar-light {
|
||||
background-color: @primary-color;
|
||||
|
||||
.bg-gray-400 {
|
||||
background-color: darken(@primary-color, 10%);
|
||||
}
|
||||
}
|
||||
|
||||
.bg-sidebar-light {
|
||||
background-color: lighten(@primary-color, 20%);
|
||||
}
|
||||
|
||||
.bg-content-light {
|
||||
background-color: lighten(@primary-color, 40%);
|
||||
}
|
||||
|
||||
&.dark {
|
||||
--tc-primary-color: darken(@primary-color, 10%);
|
||||
|
||||
.dark\:bg-navbar-dark {
|
||||
background-color: darken(@primary-color, 40%);
|
||||
}
|
||||
|
||||
.dark\:bg-sidebar-dark {
|
||||
background-color: darken(@primary-color, 20%);
|
||||
}
|
||||
|
||||
.dark\:bg-content-dark {
|
||||
background-color: @primary-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
这个样式文件做了三件事情:
|
||||
|
||||
- 通过 `less变量` 的方式指定主色调, 大幅度减少冗余代码
|
||||
- 通过 `css变量` 的方式指定 `Tailchat` 的各处背景图, 主要是登录页的背景图与头像
|
||||
- 在根节点使用`#tailchat-app.theme-genshin-hutao`选择器确保不会污染全局样式。
|
||||
|
||||
**对应的,需要在根节点下放入`bg.jpg`和`avatar.png`作为静态资源**
|
||||
|
||||
为了让 `Tailchat` 能够知道有这么一个主题存在,我们需要将这个主题相关的信息注册到 `Tailchat` 中.
|
||||
|
||||
```js
|
||||
// plugins/com.test.hutao/src/index.tsx
|
||||
import { regPluginColorScheme, sharedEvent } from '@capital/common';
|
||||
|
||||
regPluginColorScheme({
|
||||
label: '原神-胡桃测试主题',
|
||||
name: 'light+genshin-hutao',
|
||||
});
|
||||
|
||||
sharedEvent.on('loadColorScheme', (colorSchemeName) => {
|
||||
if (colorSchemeName === 'light+genshin-hutao') {
|
||||
console.log('正在加载胡桃主题...');
|
||||
import('./theme.less');
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
这个插件做了两件事情:
|
||||
- 调用 `regPluginColorScheme` 将主题生命注册到 `Tailchat` 中,这样 `Tailchat` 就会在系统设置中显示该主题。
|
||||
- 需要注意的是主题的 `name` 是以 `<color>+<theme-name>`的形式组成的,默认的 `Tailchat` 会提供 `auto`/`light`/`dark`三种配色方案,这里是指基于亮色模式追加样式覆盖的意思。
|
||||
- 通过 `sharedEvent` 监听加载主题样式事件,如果配色主题是我们的主题,则异步加载主题(异步加载的目的是减少无意义的网络请求)
|
||||
|
||||
此时我们的编译是无法通过的,因为对于less类型的文件还没有处理
|
||||
|
||||
`mini-star` 已经默认对less文件进行处理,我们只需要安装一下 `less` 包以后 `mini-star` 会自动调用安装的less进行编译
|
||||
|
||||
```bash
|
||||
npm install less
|
||||
```
|
||||
|
||||
此时执行`npm run plugins:all`进行编译操作,最后目录应当如下:
|
||||
|
||||
```
|
||||
.
|
||||
├── dist
|
||||
│ └── plugins
|
||||
│ └── com.test.hutao
|
||||
│ ├── index.js
|
||||
│ ├── index.js.map
|
||||
│ ├── theme-475203da.js
|
||||
│ └── theme-475203da.js.map
|
||||
├── package-lock.json
|
||||
├── package.json
|
||||
└── plugins
|
||||
└── com.test.hutao
|
||||
├── manifest.json
|
||||
├── package.json
|
||||
├── src
|
||||
│ ├── avatar.png
|
||||
│ ├── bg.jpg
|
||||
│ ├── index.tsx
|
||||
│ ├── theme.less
|
||||
│ └── translate.ts
|
||||
├── tsconfig.json
|
||||
└── types
|
||||
└── tailchat.d.ts
|
||||
```
|
||||
|
||||
为了便于管理,`mini-star` 在处理less引用的静态资源时会直接以 `base64` 的格式把图片打包到样式文件中。因此主题文件会非常大,这也是为什么我们需要按需异步加载的原因
|
||||
|
||||

|
||||
|
||||
因为我们之前已经在 Tailchat 中安装过我们开发中的插件了,因此直接刷新即可。
|
||||
|
||||
在左下角设置菜单中点开系统设置的主题页面,我们就可以看到我们的主题了。切换过去立即界面会变成我们想要的主题风格。
|
||||
|
||||

|
||||
|
||||
|
||||
## 源码参考
|
||||
|
||||
官方的该主题实现可以访问 [https://github.com/msgbyte/tailchat/tree/master/client/web/plugins/com.msgbyte.theme.genshin](https://github.com/msgbyte/tailchat/tree/master/client/web/plugins/com.msgbyte.theme.genshin) 查看
|
||||
@@ -0,0 +1,54 @@
|
||||
---
|
||||
sidebar_position: 90
|
||||
title: 部署插件
|
||||
---
|
||||
|
||||
:::info
|
||||
插件的部署策略后续会进行优化,目前tailchat对部署时自定义插件还做的不够便利,因此可能会有些困惑。因此本文档仅代表现状,后续会不断改进
|
||||
:::
|
||||
|
||||
首先说一下 Tailchat 插件的分类,Tailchat 的插件分为 `纯前端插件`, `纯后端插件`, `前后端插件`
|
||||
|
||||
`纯前端插件`最为容易理解,表示插件仅运行在前端代码中,依赖已有的上下文进行沟通,无需Tailchat后端支持。(特别的,对于与自定义后端进行通信的也是前端插件,如`com.msgbyte.ai-assistant`插件)
|
||||
|
||||
`纯后端插件为`为与Tailchat网络进行通信的插件,无前端界面,通过rpc调用其他服务的action来实现一些目的。对于后端插件来说,意味着插件本身接入了Tailchat后端网络,拥有最高的权限,可以访问一些可见性为`public`的action(默认只有`publish`级别的action可以被外部访问,其他级别的都是只有内部服务才能访问),一个无前端的后端插件如`com.msgbyte.simplenotify`插件
|
||||
|
||||
`前后端插件` 表示既有前端又有后端的插件,是最复杂但是能力最完全的插件类型,通过前端插件与后端交互,通过后端插件与其他的服务进行交互,在不修改核心代码的前提下能完成大部分的开发工作
|
||||
|
||||
你可以在这个文档中查看对应的插件示例: [插件列表](/docs/plugin-list/fe)
|
||||
|
||||
## 部署流程
|
||||
|
||||
在不同的插件部署的流程是不一样的
|
||||
|
||||
### 纯前端插件
|
||||
|
||||
纯前端插件你可以将代码放置在项目内部`client/web/plugins`目录下或者使用单独的静态文件服务管理。确保项目的js文档都是能正常访问的。
|
||||
|
||||
如果这是一个个人使用的插件,你可以通过插件中心的手动安装来安装,输入`manifest.json`的json配置即可。注意确保配置文件中的地址都是可以正常访问的。
|
||||
|
||||
如果想让所有的用户都能够看见代码,你需要在`client/web/registry.json`中添加你自己的插件配置。
|
||||
|
||||
如果想要成为一个默认安装的内置插件,需要修改`client/web/src/plugin/builtin.ts`文件来让前端代码在启动时加载插件。
|
||||
|
||||
### 纯后端插件
|
||||
|
||||
为了让插件能够被自动加载,你可以将代码放置与 `server/plugins` 目录下或者独立部署,只需要确保能够连入同一个网络即可(共用同一个TRANSPORTER)
|
||||
|
||||
默认部署的插件服务会将该目录下的所有后端插件统一加载。需要确保插件服务的命名为`*.service.ts`/`*.service.js`
|
||||
|
||||
*如果仅想在开发环境运行而在生产环境忽略,请将文件命名为 `*.service.dev.ts`*
|
||||
|
||||
你可以访问后端 `/health`(如:`http://localhost:11000/health`) 路由或者使用`tailchat connect`工具查看已加载的微服务列表
|
||||
|
||||
### 前后端插件
|
||||
|
||||
前后端插件的部署与后端差不多,但是需要修改编译命令让构建时能够把前后端插件的前端代码部署到`public/plugins`目录下
|
||||
|
||||
具体方式是: 修改`package.json`, 在 `build:server` 命令中追加想要编译的插件名称
|
||||
|
||||
> 配置文件中的 {BACKEND} 指代后端地址,因为前后端分离的关系后端地址不一定和前端地址保持一致
|
||||
|
||||
--------
|
||||
|
||||
所有操作完毕后记得重新构建 docker 镜像
|
||||
@@ -0,0 +1,62 @@
|
||||
---
|
||||
sidebar_position: 1
|
||||
title: 初始化插件开发环境
|
||||
---
|
||||
|
||||
在开发一个插件之前,我们需要创建一个插件开发环境,这个环境可以是直接复用 Tailchat 官方源码的插件环境([https://github.com/msgbyte/tailchat/tree/master/client/web/plugins](https://github.com/msgbyte/tailchat/tree/master/client/web/plugins)),也可以是一个独立的项目
|
||||
|
||||
这里主要教大家怎么创建一个独立的插件开发环境
|
||||
|
||||
## 前端插件开发环境
|
||||
|
||||
创建一个插件非常简单, 在此之前如果我们没有初始化插件环境的话需要先初始化一下开发环境
|
||||
|
||||
我们先随便找个地方建一个项目文件夹:
|
||||
|
||||
```bash
|
||||
mkdir tailchat-plugin-test && cd tailchat-plugin-test
|
||||
```
|
||||
|
||||
在根目录下执行:
|
||||
|
||||
```bash
|
||||
npm init -y
|
||||
npm install mini-star
|
||||
```
|
||||
|
||||
在根目录创建 `mini-star` 的配置文件 `.ministarrc.js`,内容如下:
|
||||
|
||||
```js
|
||||
// .ministarrc.js
|
||||
const path = require('path');
|
||||
|
||||
module.exports = {
|
||||
externalDeps: [
|
||||
'react',
|
||||
'react-router',
|
||||
'axios',
|
||||
'styled-components',
|
||||
'zustand',
|
||||
'zustand/middleware/immer',
|
||||
],
|
||||
};
|
||||
```
|
||||
|
||||
在 `package.json` 中写入编译脚本
|
||||
|
||||
```json
|
||||
{
|
||||
//...
|
||||
"scripts": {
|
||||
// ...
|
||||
"plugins:all": "ministar buildPlugin all",
|
||||
"plugins:watch": "ministar watchPlugin all",
|
||||
// ...
|
||||
}
|
||||
//...
|
||||
}
|
||||
```
|
||||
|
||||
## 后端插件开发环境
|
||||
|
||||
TODO
|
||||
@@ -0,0 +1,51 @@
|
||||
---
|
||||
sidebar_position: 2
|
||||
title: Typescript 类型支持
|
||||
---
|
||||
|
||||
在 `Tailchat` 中拥有一些从核心项目共享出来的工具函数或者组件,你可以通过 `@capital/common` 或 `@capital/component` 来引用。
|
||||
|
||||
当然,如果直接引用的话会有一些类型问题。因为此时typescript的类型系统是不知道能够引入什么以及有什么类型的。
|
||||
|
||||
在这里可能会有两种情况:
|
||||
|
||||
## 在Tailchat本体项目中进行开发
|
||||
|
||||
你可以通过`tsconfig.json`的`paths`字段来引入同一目录下的文件, 这样在解析时typescript可以直接加载完整的类型系统
|
||||
|
||||
如:
|
||||
|
||||
```json
|
||||
{
|
||||
"compilerOptions": {
|
||||
"baseUrl": "./src",
|
||||
"esModuleInterop": true,
|
||||
"jsx": "react",
|
||||
"paths": {
|
||||
"@capital/*": ["../../../src/plugin/*"],
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 在独立项目中进行开发
|
||||
|
||||
你可以通过获取 Tailchat 预生成好的声明文件进行开发。
|
||||
|
||||
> 因为类型要手动重写因为有部分类型尚是any。但是能够保证开发者不会引入不存在的函数
|
||||
|
||||
如果你使用的是 `tailchat create` 命令创建的项目,命令行工具模板已为您添加了如下命令
|
||||
|
||||
```json
|
||||
"scripts": {
|
||||
"sync:declaration": "tailchat declaration github"
|
||||
},
|
||||
```
|
||||
|
||||
用法
|
||||
|
||||
```bash
|
||||
pnpm sync:declaration
|
||||
```
|
||||
|
||||
该命令会自动拉取远程的配置文件并写入当前目录下的 `types/tailchat.d.ts` 文件中。如果你是手动创建的项目,你可以将其添加到你的`package.json`中以方便后续使用
|
||||
Reference in New Issue
Block a user