Skip to content

Commit 90d3104

Browse files
authored
docs: update documentations for plugin development (#504)
```release-note None ```
1 parent 7e097c9 commit 90d3104

File tree

15 files changed

+277
-463
lines changed

15 files changed

+277
-463
lines changed

docs/developer-guide/plugin/basics/devtools.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ Devtools 还提供了一些其他的构建任务,如插件打包、插件检
99

1010
## 安装
1111

12-
Devtools 是使用 Java 开发的一个 [Gradle](https://gradle.org/) 插件,如果你使用的 [plugin-starter](https://github.com/halo-sigs/plugin-starter) 创建的插件项目,那么你无需任何操作,它已经默认集成了 Devtools 插件。
12+
Devtools 是使用 Java 开发的一个 [Gradle](https://gradle.org/) 插件,如果你使用的 [halo-dev/create-halo-plugin](https://github.com/halo-dev/create-halo-plugin) 创建的插件项目,那么你无需任何操作,它已经默认集成了 Devtools 插件。
1313

1414
你可以在项目的 `build.gradle` 中找到它:
1515

docs/developer-guide/plugin/basics/ui/build.md

Lines changed: 84 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -3,27 +3,53 @@ title: 构建
33
description: UI 部分的构建说明
44
---
55

6-
[halo-dev/plugin-starter](https://github.com/halo-dev/plugin-starter) 模板中,我们已经配置好了 UI 的构建工具和流程,此文档主要说明一些构建细节以及其他可能的构建选项。
6+
[halo-dev/create-halo-plugin](https://github.com/halo-dev/create-halo-plugin) 工具中,我们已经配置好了 UI 的构建工具和流程,此文档主要说明一些构建细节以及其他可能的构建选项。
77

88
## 原理
99

10-
Halo 插件的 UI 部分(Console / UC)的实现方式其实很简单,本质上就是构建一个结构固定的大对象,交给 Halo 去解析,其中包括全局注册的组件、路由定义、扩展点等。在 [halo-dev/plugin-starter](https://github.com/halo-dev/plugin-starter) 模板中,我们使用 `index.ts` 作为入口文件,并在构建之后将 `main.js``style.css` 放到插件项目的 `src/main/resources/console` 目录中,后续 Halo 在内部会自动合并所有插件的 `main.js``style.css` 文件,并生成最终的 `bundle.js``bundle.css` 文件,然后在 Console 和 UC 中加载这两个资源并解析。
10+
Halo 插件的 UI 部分(Console / UC)的实现方式其实很简单,本质上就是构建一个结构固定的大对象,交给 Halo 去解析,其中包括全局注册的组件、路由定义、扩展点等。在 [halo-dev/create-halo-plugin](https://github.com/halo-dev/create-halo-plugin) 工具创建的项目中,我们使用 `index.ts` 作为入口文件,并在构建之后将 `main.js``style.css` 放到插件项目的 `src/main/resources/console` 目录中,后续 Halo 在内部会自动合并所有插件的 `main.js``style.css` 文件,并生成最终的 `bundle.js``bundle.css` 文件,然后在 Console 和 UC 中加载这两个资源并解析。
1111

12-
所以本质上,我们只需要使用支持将 `index.ts` 编译为 `main.js``style.css` 的工具,然后输出到插件项目的 `src/main/resources/console` 目录中即可,在 [halo-dev/plugin-starter](https://github.com/halo-dev/plugin-starter) 模板中可以看到,我们提供了一个名为 `@halo-dev/ui-plugin-bundler-kit` 的库,这个库包含了 [Vite](https://vite.dev/)[Rsbuild](https://rsbuild.dev/) 的预配置,插件项目只需要通过简单的配置即可使用。
12+
所以本质上,我们只需要使用支持将 `index.ts` 编译为 `main.js``style.css` 的工具,然后输出到插件项目的 `src/main/resources/console` 目录中即可,在 [halo-dev/create-halo-plugin](https://github.com/halo-dev/create-halo-plugin) 的模板中可以看到,我们提供了一个名为 `@halo-dev/ui-plugin-bundler-kit` 的库,这个库包含了 [Vite](https://vite.dev/)[Rsbuild](https://rsbuild.dev/) 的预配置,插件项目只需要通过简单的配置即可使用。
1313

1414
## @halo-dev/ui-plugin-bundler-kit
1515

1616
在这个库中,我们提供了三个预配置,分别是:
1717

18-
1. `viteConfig`: Vite 的预配置[halo-dev/plugin-starter](https://github.com/halo-dev/plugin-starter) 中默认使用的配置
18+
1. `viteConfig`: Vite 的预配置
1919
2. `rsbuildConfig`: Rsbuild 的预配置
2020
3. `HaloUIPluginBundlerKit`:已过时,迁移方式可以参考下面的文档
2121

2222
### viteConfig
2323

2424
#### 使用
2525

26-
如果你想要使用 Vite 构建 UI 部分,那么使用 `viteConfig` 即可,并且已经在 [halo-dev/plugin-starter](https://github.com/halo-dev/plugin-starter) 中配置,直接使用即可。
26+
如果你在通过 [halo-dev/create-halo-plugin](https://github.com/halo-dev/create-halo-plugin) 创建项目时没有选择使用 Vite 作为 UI 的构建工具,那么可以通过以下方式改为使用 Vite。
27+
28+
安装依赖:
29+
30+
```bash
31+
pnpm install @halo-dev/ui-plugin-bundler-kit@2.21.1 vite -D
32+
```
33+
34+
创建 vite.config.ts:
35+
36+
```js
37+
import { viteConfig } from "@halo-dev/ui-plugin-bundler-kit";
38+
39+
export default viteConfig()
40+
```
41+
42+
更新 package.json:
43+
44+
```json
45+
{
46+
"type": "module",
47+
"scripts": {
48+
"dev": "vite build --watch --mode=development",
49+
"build": "vite build"
50+
}
51+
}
52+
```
2753

2854
#### 配置
2955

@@ -83,15 +109,15 @@ Rsbuild 是基于 Rspack 开发的上层构建工具,其优势在于兼容 Web
83109

84110
#### 使用
85111

86-
因为在 [halo-dev/plugin-starter](https://github.com/halo-dev/plugin-starter) 中,默认采用 Vite 构建,所以如果想要使用 Rsbuild 构建,需要手动配置,以下是切换到 Rsbuild 的过程:
112+
如果你在通过 [halo-dev/create-halo-plugin](https://github.com/halo-dev/create-halo-plugin) 创建项目时没有选择使用 Rsbuild 作为 UI 的构建工具,那么可以通过以下方式改为使用 Rsbuild
87113

88114
安装依赖:
89115

90116
```bash
91117
pnpm install @halo-dev/ui-plugin-bundler-kit@2.21.1 @rsbuild/core -D
92118
```
93119

94-
创建 rsbuild.config.mjs:
120+
创建 rsbuild.config.ts:
95121

96122
```js
97123
import { rsbuildConfig } from "@halo-dev/ui-plugin-bundler-kit";
@@ -255,116 +281,99 @@ export default definePlugin({
255281

256282
3. 更新项目根目录的 `build.gradle` 文件
257283

258-
```diff
284+
```gradle
259285
plugins {
260286
id 'java'
261-
- id "com.github.node-gradle.node" version "7.0.2"
262-
- id "io.freefair.lombok" version "8.0.1"
263-
- id "run.halo.plugin.devtools" version "0.2.0"
264-
+ id "io.freefair.lombok" version "8.13"
265-
+ id "run.halo.plugin.devtools" version "0.6.0"
287+
id "io.freefair.lombok" version "8.13"
288+
id "run.halo.plugin.devtools" version "0.6.0"
266289
}
267-
290+
268291
group 'run.halo.starter'
269-
-sourceCompatibility = JavaVersion.VERSION_17
270-
292+
271293
repositories {
272294
mavenCentral()
273-
- maven { url 'https://s01.oss.sonatype.org/content/repositories/releases' }
274-
- maven { url 'https://s01.oss.sonatype.org/content/repositories/snapshots/' }
275-
- maven { url 'https://repo.spring.io/milestone' }
276295
}
277-
296+
278297
dependencies {
279-
- implementation platform('run.halo.tools.platform:plugin:2.20.0-SNAPSHOT')
280-
+ implementation platform('run.halo.tools.platform:plugin:2.21.0')
298+
implementation platform('run.halo.tools.platform:plugin:2.21.0')
281299
compileOnly 'run.halo.app:api'
282-
300+
283301
testImplementation 'run.halo.app:api'
284302
testImplementation 'org.springframework.boot:spring-boot-starter-test'
285-
+ testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
303+
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
286304
}
287-
305+
288306
test {
289307
useJUnitPlatform()
290308
}
291-
292-
-tasks.withType(JavaCompile).configureEach {
293-
- options.encoding = "UTF-8"
294-
-}
295-
-
296-
-node {
297-
- nodeProjectDir = file("${project.projectDir}/ui")
298-
+java {
299-
+ toolchain {
300-
+ languageVersion = JavaLanguageVersion.of(21)
301-
+ }
309+
310+
java {
311+
toolchain {
312+
languageVersion = JavaLanguageVersion.of(21)
313+
}
314+
}
315+
316+
tasks.withType(JavaCompile).configureEach {
317+
options.encoding = "UTF-8"
318+
options.release = 21
302319
}
303-
304-
-tasks.register('buildFrontend', PnpmTask) {
305-
- args = ['build']
306-
- dependsOn('installDepsForUI')
307-
+tasks.withType(JavaCompile).configureEach {
308-
+ options.encoding = "UTF-8"
309-
+ options.release = 21
320+
321+
tasks.register('processUiResources', Copy) {
322+
from project(':ui').layout.buildDirectory.dir('dist')
323+
into layout.buildDirectory.dir('resources/main/console')
324+
dependsOn project(':ui').tasks.named('assemble')
325+
shouldRunAfter tasks.named('processResources')
310326
}
311-
312-
-tasks.register('installDepsForUI', PnpmTask) {
313-
- args = ['install']
314-
+tasks.register('processUiResources', Copy) {
315-
+ from project(':ui').tasks.named('buildFrontend')
316-
+ into layout.buildDirectory.dir('resources/main/console')
327+
328+
tasks.named('classes') {
329+
dependsOn tasks.named('processUiResources')
317330
}
318-
319-
-build {
320-
- // build frontend before build
321-
- tasks.named('compileJava').configure {
322-
- dependsOn('buildFrontend')
323-
- }
324-
+tasks.named('processResources', ProcessResources) {
325-
+ dependsOn tasks.named('processUiResources')
331+
332+
halo {
333+
version = '2.21'
326334
}
327335
```
328336

329337
4. 在 ui 或者 console 目录新建 `build.gradle` 文件,内容如下:
330338

331339
```gradle
332340
plugins {
333-
id 'base'
334-
id "com.github.node-gradle.node" version "7.1.0"
341+
id 'base'
342+
id "com.github.node-gradle.node" version "7.1.0"
335343
}
336344
337345
group 'run.halo.starter.ui'
338346
339347
tasks.register('buildFrontend', PnpmTask) {
340-
args = ['build']
341-
dependsOn tasks.named('pnpmInstall')
342-
inputs.dir(layout.projectDirectory.dir('src'))
343-
inputs.files(fileTree(
344-
dir: layout.projectDirectory,
345-
includes: ['*.cjs', '*.ts', '*.js', '*.json', '*.yaml']))
346-
outputs.dir(layout.buildDirectory.dir('dist'))
347-
shouldRunAfter(tasks.named('check'))
348+
group = 'build'
349+
description = 'Builds the UI project using pnpm.'
350+
args = ['build']
351+
dependsOn tasks.named('pnpmInstall')
352+
inputs.dir(layout.projectDirectory.dir('src'))
353+
inputs.files(fileTree(
354+
dir: layout.projectDirectory,
355+
includes: ['*.cjs', '*.ts', '*.js', '*.json', '*.yaml']))
356+
outputs.dir(layout.buildDirectory.dir('dist'))
348357
}
349358
350-
tasks.register('checkFrontend', PnpmTask) {
351-
args = ['test:unit']
352-
dependsOn tasks.named('pnpmInstall')
359+
tasks.register('pnpmCheck', PnpmTask) {
360+
group = 'verification'
361+
description = 'Runs unit tests using pnpm.'
362+
args = ['test:unit']
363+
dependsOn tasks.named('pnpmInstall')
353364
}
354365
355366
tasks.named('check') {
356-
dependsOn tasks.named('checkFrontend')
367+
dependsOn tasks.named('pnpmCheck')
357368
}
358369
359-
tasks.named('build') {
360-
dependsOn tasks.named('buildFrontend')
370+
tasks.named('assemble') {
371+
dependsOn tasks.named('buildFrontend')
361372
}
362373
```
363374

364375
进行此变更的主要目的是保证 UI 构建的产物不直接输出到源码目录的 resources 目录中,而是通过 Gradle 构建插件时复制到 `src/main/resources/console` 目录中。
365376

366-
完整变更过程可参考:[halo-dev/plugin-starter#52](https://github.com/halo-dev/plugin-starter/pull/52)
367-
368377
如果你不想使用新的 Gradle 构建配置,也可以修改 viteConfig 或 rsbuildConfig 的输出目录,和旧版本保持一致:
369378

370379
viteConfig:

docs/developer-guide/plugin/basics/ui/entry.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ description: UI 扩展部分的入口文件
55

66
入口文件即 Halo 核心会加载的文件,所有插件有且只有一个入口文件,构建之后会放置在插件项目的 `src/resources/console` 下,名为 `main.js`
77

8-
为了方便开发者,我们已经在 [halo-dev/plugin-starter](https://github.com/halo-dev/plugin-starter) 配置好了基础项目结构,包括构建配置,后续文档也会以此为准。
8+
为了方便开发者,我们已经在 [halo-dev/create-halo-plugin](https://github.com/halo-dev/create-halo-plugin) 配置好了基础项目结构,包括构建配置,后续文档也会以此为准。
99

1010
## 定义入口文件
1111

docs/developer-guide/plugin/examples/todolist.md

Lines changed: 2 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -5,104 +5,9 @@ description: 这个例子展示了如何开发 Todo List 插件
55

66
本示例用于展示如何从插件模板创建一个插件并写一个 Todo List:
77

8-
首先通过模板仓库创建一个插件,例如叫 `halo-plugin-todolist`
8+
首先参考 [入门 - 创建插件项目](../hello-world.md#创建插件项目) 文档创建一个新的插件项目并运行。
99

10-
## 配置你的插件
11-
12-
1. 修改 `build.gradle` 中的 `group` 为你自己的,如:
13-
14-
```groovy
15-
group = 'run.halo.tutorial'
16-
```
17-
18-
2. 修改 `settings.gradle` 中的 `rootProject.name`
19-
20-
```groovy
21-
rootProject.name = 'halo-plugin-todolist'
22-
```
23-
24-
3. 修改插件的描述文件 `plugin.yaml`,它位于 `src/main/resources/plugin.yaml`。示例:
25-
26-
```yaml
27-
apiVersion: plugin.halo.run/v1alpha1
28-
kind: Plugin
29-
metadata:
30-
name: todolist
31-
spec:
32-
enabled: true
33-
requires: ">=2.0.0"
34-
author:
35-
name: halo-dev
36-
website: https://www.halo.run
37-
logo: https://www.halo.run/logo
38-
homepage: https://github.com/halo-dev/plugin-starter#readme
39-
repo: https://github.com/halo-dev/plugin-starter
40-
issues: https://github.com/halo-dev/plugin-starter/issues
41-
displayName: "插件 Todo List"
42-
description: "插件开发的 hello world,用于学习如何开发一个简单的 Halo 插件"
43-
license:
44-
- name: "GPL-3.0"
45-
url: "https://github.com/halo-dev/plugin-starter/blob/main/LICENSE"
46-
```
47-
48-
参考链接:
49-
50-
- [SemVer expression](https://github.com/zafarkhaja/jsemver#semver-expressions-api-ranges)
51-
- [表单定义](../../form-schema.md)
52-
53-
此时我们已经准备好了可以开发一个 TodoList 插件的一切,下面让我们正式进入 TodoList 插件开发教程。
54-
55-
## 运行插件
56-
57-
为了看到效果,首先我们需要让插件能最简单的运行起来。
58-
59-
1. 在 `src/main/java` 下创建包,如 `run.halo.tutorial`,在创建一个类 `TodoListPlugin`,它继承自 `BasePlugin` 类内容如下:
60-
61-
```java
62-
package run.halo.tutorial;
63-
64-
import run.halo.app.plugin.PluginContext;
65-
import org.springframework.stereotype.Component;
66-
import run.halo.app.plugin.BasePlugin;
67-
68-
@Component
69-
public class TodoListPlugin extends BasePlugin {
70-
public TodoListPlugin(PluginContext pluginContext) {
71-
super(pluginContext);
72-
}
73-
}
74-
```
75-
76-
`src/main/java` 下的文件结构如下:
77-
78-
```text
79-
.
80-
└── run
81-
└── halo
82-
└── tutorial
83-
└── TodoListPlugin.java
84-
```
85-
86-
2. 然后在项目目录执行命令
87-
88-
```shell
89-
./gradlew build
90-
```
91-
92-
3. 使用 `IntelliJ IDEA` 打开 Halo,参考 [Halo 开发环境运行](../../core/run.md) 及 [插件入门](../hello-world.md) 配置插件的运行模式和路径:
93-
94-
```yaml
95-
halo:
96-
plugin:
97-
runtime-mode: development
98-
fixed-plugin-path:
99-
# 配置为插件绝对路径
100-
- /Users/guqing/halo-plugin-todolist
101-
```
102-
103-
4. 启动 Halo,然后访问 `http://localhost:8090/console`
104-
105-
在插件列表将能看到插件已经被正确启用:
10+
如果能在插件列表中看到插件已经被正确启用,则说明插件已经运行成功。
10611

10712
![plugin-todolist-in-list-view](/img/todolist-in-list.png)
10813

0 commit comments

Comments
 (0)