mirror of
https://github.com/halo-dev/docs.git
synced 2025-10-13 13:45:09 +00:00
docs: update documentations for plugin development (#504)
```release-note None ```
This commit is contained in:
@@ -9,7 +9,7 @@ Devtools 还提供了一些其他的构建任务,如插件打包、插件检
|
||||
|
||||
## 安装
|
||||
|
||||
Devtools 是使用 Java 开发的一个 [Gradle](https://gradle.org/) 插件,如果你使用的 [plugin-starter](https://github.com/halo-sigs/plugin-starter) 创建的插件项目,那么你无需任何操作,它已经默认集成了 Devtools 插件。
|
||||
Devtools 是使用 Java 开发的一个 [Gradle](https://gradle.org/) 插件,如果你使用的 [halo-dev/create-halo-plugin](https://github.com/halo-dev/create-halo-plugin) 创建的插件项目,那么你无需任何操作,它已经默认集成了 Devtools 插件。
|
||||
|
||||
你可以在项目的 `build.gradle` 中找到它:
|
||||
|
||||
|
@@ -3,19 +3,19 @@ title: 构建
|
||||
description: UI 部分的构建说明
|
||||
---
|
||||
|
||||
在 [halo-dev/plugin-starter](https://github.com/halo-dev/plugin-starter) 模板中,我们已经配置好了 UI 的构建工具和流程,此文档主要说明一些构建细节以及其他可能的构建选项。
|
||||
在 [halo-dev/create-halo-plugin](https://github.com/halo-dev/create-halo-plugin) 工具中,我们已经配置好了 UI 的构建工具和流程,此文档主要说明一些构建细节以及其他可能的构建选项。
|
||||
|
||||
## 原理
|
||||
|
||||
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 中加载这两个资源并解析。
|
||||
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 中加载这两个资源并解析。
|
||||
|
||||
所以本质上,我们只需要使用支持将 `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/) 的预配置,插件项目只需要通过简单的配置即可使用。
|
||||
所以本质上,我们只需要使用支持将 `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/) 的预配置,插件项目只需要通过简单的配置即可使用。
|
||||
|
||||
## @halo-dev/ui-plugin-bundler-kit
|
||||
|
||||
在这个库中,我们提供了三个预配置,分别是:
|
||||
|
||||
1. `viteConfig`: Vite 的预配置,[halo-dev/plugin-starter](https://github.com/halo-dev/plugin-starter) 中默认使用的配置
|
||||
1. `viteConfig`: Vite 的预配置
|
||||
2. `rsbuildConfig`: Rsbuild 的预配置
|
||||
3. `HaloUIPluginBundlerKit`:已过时,迁移方式可以参考下面的文档
|
||||
|
||||
@@ -23,7 +23,33 @@ Halo 插件的 UI 部分(Console / UC)的实现方式其实很简单,本
|
||||
|
||||
#### 使用
|
||||
|
||||
如果你想要使用 Vite 构建 UI 部分,那么使用 `viteConfig` 即可,并且已经在 [halo-dev/plugin-starter](https://github.com/halo-dev/plugin-starter) 中配置,直接使用即可。
|
||||
如果你在通过 [halo-dev/create-halo-plugin](https://github.com/halo-dev/create-halo-plugin) 创建项目时没有选择使用 Vite 作为 UI 的构建工具,那么可以通过以下方式改为使用 Vite。
|
||||
|
||||
安装依赖:
|
||||
|
||||
```bash
|
||||
pnpm install @halo-dev/ui-plugin-bundler-kit@2.21.1 vite -D
|
||||
```
|
||||
|
||||
创建 vite.config.ts:
|
||||
|
||||
```js
|
||||
import { viteConfig } from "@halo-dev/ui-plugin-bundler-kit";
|
||||
|
||||
export default viteConfig()
|
||||
```
|
||||
|
||||
更新 package.json:
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite build --watch --mode=development",
|
||||
"build": "vite build"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 配置
|
||||
|
||||
@@ -83,7 +109,7 @@ Rsbuild 是基于 Rspack 开发的上层构建工具,其优势在于兼容 Web
|
||||
|
||||
#### 使用
|
||||
|
||||
因为在 [halo-dev/plugin-starter](https://github.com/halo-dev/plugin-starter) 中,默认采用 Vite 构建,所以如果想要使用 Rsbuild 构建,需要手动配置,以下是切换到 Rsbuild 的过程:
|
||||
如果你在通过 [halo-dev/create-halo-plugin](https://github.com/halo-dev/create-halo-plugin) 创建项目时没有选择使用 Rsbuild 作为 UI 的构建工具,那么可以通过以下方式改为使用 Rsbuild。
|
||||
|
||||
安装依赖:
|
||||
|
||||
@@ -91,7 +117,7 @@ Rsbuild 是基于 Rspack 开发的上层构建工具,其优势在于兼容 Web
|
||||
pnpm install @halo-dev/ui-plugin-bundler-kit@2.21.1 @rsbuild/core -D
|
||||
```
|
||||
|
||||
创建 rsbuild.config.mjs:
|
||||
创建 rsbuild.config.ts:
|
||||
|
||||
```js
|
||||
import { rsbuildConfig } from "@halo-dev/ui-plugin-bundler-kit";
|
||||
@@ -255,74 +281,56 @@ export default definePlugin({
|
||||
|
||||
3. 更新项目根目录的 `build.gradle` 文件
|
||||
|
||||
```diff
|
||||
```gradle
|
||||
plugins {
|
||||
id 'java'
|
||||
- id "com.github.node-gradle.node" version "7.0.2"
|
||||
- id "io.freefair.lombok" version "8.0.1"
|
||||
- id "run.halo.plugin.devtools" version "0.2.0"
|
||||
+ id "io.freefair.lombok" version "8.13"
|
||||
+ id "run.halo.plugin.devtools" version "0.6.0"
|
||||
id "io.freefair.lombok" version "8.13"
|
||||
id "run.halo.plugin.devtools" version "0.6.0"
|
||||
}
|
||||
|
||||
|
||||
group 'run.halo.starter'
|
||||
-sourceCompatibility = JavaVersion.VERSION_17
|
||||
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
- maven { url 'https://s01.oss.sonatype.org/content/repositories/releases' }
|
||||
- maven { url 'https://s01.oss.sonatype.org/content/repositories/snapshots/' }
|
||||
- maven { url 'https://repo.spring.io/milestone' }
|
||||
}
|
||||
|
||||
|
||||
dependencies {
|
||||
- implementation platform('run.halo.tools.platform:plugin:2.20.0-SNAPSHOT')
|
||||
+ implementation platform('run.halo.tools.platform:plugin:2.21.0')
|
||||
implementation platform('run.halo.tools.platform:plugin:2.21.0')
|
||||
compileOnly 'run.halo.app:api'
|
||||
|
||||
|
||||
testImplementation 'run.halo.app:api'
|
||||
testImplementation 'org.springframework.boot:spring-boot-starter-test'
|
||||
+ testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
|
||||
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
|
||||
}
|
||||
|
||||
|
||||
test {
|
||||
useJUnitPlatform()
|
||||
}
|
||||
|
||||
-tasks.withType(JavaCompile).configureEach {
|
||||
- options.encoding = "UTF-8"
|
||||
-}
|
||||
-
|
||||
-node {
|
||||
- nodeProjectDir = file("${project.projectDir}/ui")
|
||||
+java {
|
||||
+ toolchain {
|
||||
+ languageVersion = JavaLanguageVersion.of(21)
|
||||
+ }
|
||||
|
||||
java {
|
||||
toolchain {
|
||||
languageVersion = JavaLanguageVersion.of(21)
|
||||
}
|
||||
}
|
||||
|
||||
-tasks.register('buildFrontend', PnpmTask) {
|
||||
- args = ['build']
|
||||
- dependsOn('installDepsForUI')
|
||||
+tasks.withType(JavaCompile).configureEach {
|
||||
+ options.encoding = "UTF-8"
|
||||
+ options.release = 21
|
||||
|
||||
tasks.withType(JavaCompile).configureEach {
|
||||
options.encoding = "UTF-8"
|
||||
options.release = 21
|
||||
}
|
||||
|
||||
-tasks.register('installDepsForUI', PnpmTask) {
|
||||
- args = ['install']
|
||||
+tasks.register('processUiResources', Copy) {
|
||||
+ from project(':ui').tasks.named('buildFrontend')
|
||||
+ into layout.buildDirectory.dir('resources/main/console')
|
||||
|
||||
tasks.register('processUiResources', Copy) {
|
||||
from project(':ui').layout.buildDirectory.dir('dist')
|
||||
into layout.buildDirectory.dir('resources/main/console')
|
||||
dependsOn project(':ui').tasks.named('assemble')
|
||||
shouldRunAfter tasks.named('processResources')
|
||||
}
|
||||
|
||||
-build {
|
||||
- // build frontend before build
|
||||
- tasks.named('compileJava').configure {
|
||||
- dependsOn('buildFrontend')
|
||||
- }
|
||||
+tasks.named('processResources', ProcessResources) {
|
||||
+ dependsOn tasks.named('processUiResources')
|
||||
|
||||
tasks.named('classes') {
|
||||
dependsOn tasks.named('processUiResources')
|
||||
}
|
||||
|
||||
halo {
|
||||
version = '2.21'
|
||||
}
|
||||
```
|
||||
|
||||
@@ -330,41 +338,42 @@ export default definePlugin({
|
||||
|
||||
```gradle
|
||||
plugins {
|
||||
id 'base'
|
||||
id "com.github.node-gradle.node" version "7.1.0"
|
||||
id 'base'
|
||||
id "com.github.node-gradle.node" version "7.1.0"
|
||||
}
|
||||
|
||||
group 'run.halo.starter.ui'
|
||||
|
||||
tasks.register('buildFrontend', PnpmTask) {
|
||||
args = ['build']
|
||||
dependsOn tasks.named('pnpmInstall')
|
||||
inputs.dir(layout.projectDirectory.dir('src'))
|
||||
inputs.files(fileTree(
|
||||
dir: layout.projectDirectory,
|
||||
includes: ['*.cjs', '*.ts', '*.js', '*.json', '*.yaml']))
|
||||
outputs.dir(layout.buildDirectory.dir('dist'))
|
||||
shouldRunAfter(tasks.named('check'))
|
||||
group = 'build'
|
||||
description = 'Builds the UI project using pnpm.'
|
||||
args = ['build']
|
||||
dependsOn tasks.named('pnpmInstall')
|
||||
inputs.dir(layout.projectDirectory.dir('src'))
|
||||
inputs.files(fileTree(
|
||||
dir: layout.projectDirectory,
|
||||
includes: ['*.cjs', '*.ts', '*.js', '*.json', '*.yaml']))
|
||||
outputs.dir(layout.buildDirectory.dir('dist'))
|
||||
}
|
||||
|
||||
tasks.register('checkFrontend', PnpmTask) {
|
||||
args = ['test:unit']
|
||||
dependsOn tasks.named('pnpmInstall')
|
||||
tasks.register('pnpmCheck', PnpmTask) {
|
||||
group = 'verification'
|
||||
description = 'Runs unit tests using pnpm.'
|
||||
args = ['test:unit']
|
||||
dependsOn tasks.named('pnpmInstall')
|
||||
}
|
||||
|
||||
tasks.named('check') {
|
||||
dependsOn tasks.named('checkFrontend')
|
||||
dependsOn tasks.named('pnpmCheck')
|
||||
}
|
||||
|
||||
tasks.named('build') {
|
||||
dependsOn tasks.named('buildFrontend')
|
||||
tasks.named('assemble') {
|
||||
dependsOn tasks.named('buildFrontend')
|
||||
}
|
||||
```
|
||||
|
||||
进行此变更的主要目的是保证 UI 构建的产物不直接输出到源码目录的 resources 目录中,而是通过 Gradle 构建插件时复制到 `src/main/resources/console` 目录中。
|
||||
|
||||
完整变更过程可参考:[halo-dev/plugin-starter#52](https://github.com/halo-dev/plugin-starter/pull/52)
|
||||
|
||||
如果你不想使用新的 Gradle 构建配置,也可以修改 viteConfig 或 rsbuildConfig 的输出目录,和旧版本保持一致:
|
||||
|
||||
viteConfig:
|
||||
|
@@ -5,7 +5,7 @@ description: UI 扩展部分的入口文件
|
||||
|
||||
入口文件即 Halo 核心会加载的文件,所有插件有且只有一个入口文件,构建之后会放置在插件项目的 `src/resources/console` 下,名为 `main.js`。
|
||||
|
||||
为了方便开发者,我们已经在 [halo-dev/plugin-starter](https://github.com/halo-dev/plugin-starter) 配置好了基础项目结构,包括构建配置,后续文档也会以此为准。
|
||||
为了方便开发者,我们已经在 [halo-dev/create-halo-plugin](https://github.com/halo-dev/create-halo-plugin) 配置好了基础项目结构,包括构建配置,后续文档也会以此为准。
|
||||
|
||||
## 定义入口文件
|
||||
|
||||
|
@@ -5,104 +5,9 @@ description: 这个例子展示了如何开发 Todo List 插件
|
||||
|
||||
本示例用于展示如何从插件模板创建一个插件并写一个 Todo List:
|
||||
|
||||
首先通过模板仓库创建一个插件,例如叫 `halo-plugin-todolist`
|
||||
首先参考 [入门 - 创建插件项目](../hello-world.md#创建插件项目) 文档创建一个新的插件项目并运行。
|
||||
|
||||
## 配置你的插件
|
||||
|
||||
1. 修改 `build.gradle` 中的 `group` 为你自己的,如:
|
||||
|
||||
```groovy
|
||||
group = 'run.halo.tutorial'
|
||||
```
|
||||
|
||||
2. 修改 `settings.gradle` 中的 `rootProject.name`
|
||||
|
||||
```groovy
|
||||
rootProject.name = 'halo-plugin-todolist'
|
||||
```
|
||||
|
||||
3. 修改插件的描述文件 `plugin.yaml`,它位于 `src/main/resources/plugin.yaml`。示例:
|
||||
|
||||
```yaml
|
||||
apiVersion: plugin.halo.run/v1alpha1
|
||||
kind: Plugin
|
||||
metadata:
|
||||
name: todolist
|
||||
spec:
|
||||
enabled: true
|
||||
requires: ">=2.0.0"
|
||||
author:
|
||||
name: halo-dev
|
||||
website: https://www.halo.run
|
||||
logo: https://www.halo.run/logo
|
||||
homepage: https://github.com/halo-dev/plugin-starter#readme
|
||||
repo: https://github.com/halo-dev/plugin-starter
|
||||
issues: https://github.com/halo-dev/plugin-starter/issues
|
||||
displayName: "插件 Todo List"
|
||||
description: "插件开发的 hello world,用于学习如何开发一个简单的 Halo 插件"
|
||||
license:
|
||||
- name: "GPL-3.0"
|
||||
url: "https://github.com/halo-dev/plugin-starter/blob/main/LICENSE"
|
||||
```
|
||||
|
||||
参考链接:
|
||||
|
||||
- [SemVer expression](https://github.com/zafarkhaja/jsemver#semver-expressions-api-ranges)
|
||||
- [表单定义](../../form-schema.md)
|
||||
|
||||
此时我们已经准备好了可以开发一个 TodoList 插件的一切,下面让我们正式进入 TodoList 插件开发教程。
|
||||
|
||||
## 运行插件
|
||||
|
||||
为了看到效果,首先我们需要让插件能最简单的运行起来。
|
||||
|
||||
1. 在 `src/main/java` 下创建包,如 `run.halo.tutorial`,在创建一个类 `TodoListPlugin`,它继承自 `BasePlugin` 类内容如下:
|
||||
|
||||
```java
|
||||
package run.halo.tutorial;
|
||||
|
||||
import run.halo.app.plugin.PluginContext;
|
||||
import org.springframework.stereotype.Component;
|
||||
import run.halo.app.plugin.BasePlugin;
|
||||
|
||||
@Component
|
||||
public class TodoListPlugin extends BasePlugin {
|
||||
public TodoListPlugin(PluginContext pluginContext) {
|
||||
super(pluginContext);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
`src/main/java` 下的文件结构如下:
|
||||
|
||||
```text
|
||||
.
|
||||
└── run
|
||||
└── halo
|
||||
└── tutorial
|
||||
└── TodoListPlugin.java
|
||||
```
|
||||
|
||||
2. 然后在项目目录执行命令
|
||||
|
||||
```shell
|
||||
./gradlew build
|
||||
```
|
||||
|
||||
3. 使用 `IntelliJ IDEA` 打开 Halo,参考 [Halo 开发环境运行](../../core/run.md) 及 [插件入门](../hello-world.md) 配置插件的运行模式和路径:
|
||||
|
||||
```yaml
|
||||
halo:
|
||||
plugin:
|
||||
runtime-mode: development
|
||||
fixed-plugin-path:
|
||||
# 配置为插件绝对路径
|
||||
- /Users/guqing/halo-plugin-todolist
|
||||
```
|
||||
|
||||
4. 启动 Halo,然后访问 `http://localhost:8090/console`
|
||||
|
||||
在插件列表将能看到插件已经被正确启用:
|
||||
如果能在插件列表中看到插件已经被正确启用,则说明插件已经运行成功。
|
||||
|
||||

|
||||
|
||||
|
@@ -7,25 +7,38 @@ description: 了解如何构建你的第一个插件并在 Halo 中使用它。
|
||||
|
||||
## 创建插件项目
|
||||
|
||||
1. 打开 [halo-dev/plugin-starter](https://github.com/halo-dev/plugin-starter)。
|
||||
我们为插件开发者提供了一个插件创建工具,可以帮助你快速创建一个插件项目。
|
||||
|
||||
> 这是一个插件的初始模板,你可以基于它来开发自己的插件。
|
||||
|
||||
2. 点击 `Use this template` -> `Create a new repository`。
|
||||
3. 如图所示填写仓库名后点击 `Create repository from template`。
|
||||
|
||||

|
||||
|
||||
你现在已经基于 Halo 插件模板创建了自己的存储库。接下来,你需要将它克隆到你的计算机上。
|
||||
|
||||
```shell
|
||||
# clone your repository
|
||||
git clone https://github.com/<your-username>/halo-plugin-hello-world.git
|
||||
|
||||
# enter the directory
|
||||
cd halo-plugin-hello-world
|
||||
```bash
|
||||
pnpm create halo-plugin
|
||||
```
|
||||
|
||||
```bash
|
||||
🚀 Welcome to Halo Plugin Creator!
|
||||
|
||||
✔ Plugin name: › hello-world
|
||||
✔ Domain (for group and package name): › com.example
|
||||
✔ Author name: › Halo
|
||||
✔ Choose UI build tool: › Rsbuild
|
||||
|
||||
📋 Project Configuration:
|
||||
Name: hello-world
|
||||
Domain: com.example
|
||||
Package: com.example.hello-world
|
||||
Author: Halo
|
||||
UI Tool: rsbuild
|
||||
Output Directory: /path/to/hello-world
|
||||
|
||||
✔ Create project? › yes
|
||||
```
|
||||
|
||||
- **Plugin name**: 插件的名称,用于插件的标识,此字段必须由小写字母、数字和连字符组成
|
||||
- **Domain**: 插件的包名
|
||||
- **Author name**: 插件的作者
|
||||
- **Choose UI build tool**: 插件的 UI 构建工具,目前支持 `Rsbuild` 和 `Vite`
|
||||
|
||||
更多关于插件创建工具的信息可查阅:[halo-dev/create-halo-plugin](https://github.com/halo-dev/create-halo-plugin)
|
||||
|
||||
## 运行插件
|
||||
|
||||
现在有了一个空项目,我们需要让插件能最最小化的运行起来,这里提供两种运行方式。
|
||||
@@ -36,17 +49,7 @@ Halo 提供了一个用于插件开发的 DevTools,它可以帮助你快速的
|
||||
|
||||
使用 DevTools 运行插件的前提是需要你的电脑上已经安装了 Docker 环境,这是我们推荐的用户开发时运行插件的方式,只需要执行以下命令即可。
|
||||
|
||||
1. 执行前端部分的依赖安装命令:
|
||||
|
||||
```shell
|
||||
# macOS / Linux
|
||||
./gradlew pnpmInstall
|
||||
|
||||
# Windows
|
||||
./gradlew.bat pnpmInstall
|
||||
```
|
||||
|
||||
2. 运行插件:
|
||||
1. 运行插件:
|
||||
|
||||
```shell
|
||||
# macOS / Linux
|
||||
@@ -58,7 +61,7 @@ Halo 提供了一个用于插件开发的 DevTools,它可以帮助你快速的
|
||||
|
||||
执行此命令后,会自动创建一个 Halo 的 Docker 容器并加载当前的插件。
|
||||
|
||||
3. 启动成功后,可以看到如下日志输出:
|
||||
2. 启动成功后,可以看到如下日志输出:
|
||||
|
||||
```shell
|
||||
Halo 初始化成功,访问:http://localhost:8090/console
|
||||
@@ -78,17 +81,7 @@ Halo 提供了一个用于插件开发的 DevTools,它可以帮助你快速的
|
||||
|
||||
但由于此方式需要先使用源码运行 Halo 才能启动插件,请确保已经在开发环境运行了 Halo,可以参考 [Halo 开发环境运行](../core/run.md)
|
||||
|
||||
1. 安装前端部分的依赖
|
||||
|
||||
```shell
|
||||
# macOS / Linux
|
||||
./gradlew pnpmInstall
|
||||
|
||||
# Windows
|
||||
./gradlew.bat pnpmInstall
|
||||
```
|
||||
|
||||
2. 编译插件
|
||||
1. 编译插件
|
||||
|
||||
```shell
|
||||
# macOS / Linux
|
||||
@@ -98,7 +91,7 @@ Halo 提供了一个用于插件开发的 DevTools,它可以帮助你快速的
|
||||
./gradlew.bat build
|
||||
```
|
||||
|
||||
3. 修改 Halo 配置文件:
|
||||
2. 修改 Halo 配置文件:
|
||||
|
||||
```shell
|
||||
# 进入 Halo 项目根目录后,使用 cd 命令进入配置文件目录
|
||||
@@ -128,7 +121,7 @@ Halo 提供了一个用于插件开发的 DevTools,它可以帮助你快速的
|
||||
- C:\path\to\halo-plugin-hello-world
|
||||
```
|
||||
|
||||
4. 启动 Halo
|
||||
3. 启动 Halo
|
||||
|
||||
```shell
|
||||
# macOS / Linux
|
||||
|
@@ -11,7 +11,7 @@ description: 了解如何与我们的社区分享你的插件
|
||||
|
||||
## 自动构建
|
||||
|
||||
如果你是基于 [halo-dev/plugin-starter](https://github.com/halo-dev/plugin-starter) 创建的插件项目,那么已经包含了适用于 GitHub Action 的 `ci.yaml` 和 `cd.yaml` 文件,里面包含了构建插件和发布插件资源到 Release 的步骤,可以根据自己的实际需要进行修改,以下是示例:
|
||||
如果你是使用 [halo-dev/create-halo-plugin](https://github.com/halo-dev/create-halo-plugin) 创建的插件项目,那么已经包含了适用于 GitHub Action 的 `ci.yaml` 和 `cd.yaml` 文件,里面包含了构建插件和发布插件资源到 Release 的步骤,可以根据自己的实际需要进行修改,以下是示例:
|
||||
|
||||
```yaml
|
||||
name: CI
|
||||
|
@@ -80,7 +80,7 @@ export default definePlugin({
|
||||
});
|
||||
```
|
||||
|
||||
参考:[plugin-starter](https://github.com/halo-dev/plugin-starter/blob/5a4a25db252a7986900368a5fbf35e8d27f5257f/ui/src/index.ts#L6-L29)
|
||||
参考:[halo-dev/create-halo-plugin#template/ui/src/index.ts](https://github.com/halo-dev/create-halo-plugin/blob/a4ce935a637faff4a7f00fecbdee08f55fd66ffd/template/ui/src/index.ts)
|
||||
|
||||
> 该配置示例为在插件前端部分入口文件 `index.ts`
|
||||
|
||||
|
@@ -9,6 +9,10 @@
|
||||
"message": "页面已崩溃。",
|
||||
"description": "The title of the fallback page when the page crashed"
|
||||
},
|
||||
"theme.BackToTopButton.buttonAriaLabel": {
|
||||
"message": "回到顶部",
|
||||
"description": "The ARIA label for the back to top button"
|
||||
},
|
||||
"theme.blog.archive.title": {
|
||||
"message": "历史博文",
|
||||
"description": "The page & hero title of the blog archive page"
|
||||
@@ -17,10 +21,6 @@
|
||||
"message": "历史博文",
|
||||
"description": "The page & hero description of the blog archive page"
|
||||
},
|
||||
"theme.BackToTopButton.buttonAriaLabel": {
|
||||
"message": "回到顶部",
|
||||
"description": "The ARIA label for the back to top button"
|
||||
},
|
||||
"theme.blog.paginator.navAriaLabel": {
|
||||
"message": "博文列表分页导航",
|
||||
"description": "The ARIA label for the blog pagination"
|
||||
@@ -65,14 +65,14 @@
|
||||
"message": "切换浅色/暗黑模式(当前为{mode})",
|
||||
"description": "The ARIA label for the color mode toggle"
|
||||
},
|
||||
"theme.docs.DocCard.categoryDescription.plurals": {
|
||||
"message": "{count} 个项目",
|
||||
"description": "The default description for a category card in the generated index about how many items this category includes"
|
||||
},
|
||||
"theme.docs.breadcrumbs.navAriaLabel": {
|
||||
"message": "页面路径",
|
||||
"description": "The ARIA label for the breadcrumbs"
|
||||
},
|
||||
"theme.docs.DocCard.categoryDescription.plurals": {
|
||||
"message": "{count} 个项目",
|
||||
"description": "The default description for a category card in the generated index about how many items this category includes"
|
||||
},
|
||||
"theme.docs.paginator.navAriaLabel": {
|
||||
"message": "文件选项卡",
|
||||
"description": "The ARIA label for the docs pagination"
|
||||
@@ -96,6 +96,10 @@
|
||||
"theme.docs.versionBadge.label": {
|
||||
"message": "版本:{versionLabel}"
|
||||
},
|
||||
"theme.common.editThisPage": {
|
||||
"message": "编辑此页",
|
||||
"description": "The link label to edit the current page"
|
||||
},
|
||||
"theme.docs.versions.unreleasedVersionLabel": {
|
||||
"message": "此为 {siteTitle} {versionLabel} 版尚未发行的文档。",
|
||||
"description": "The label used to tell the user that he's browsing an unreleased doc version"
|
||||
@@ -112,10 +116,6 @@
|
||||
"message": "最新版本",
|
||||
"description": "The label used for the latest version suggestion link label"
|
||||
},
|
||||
"theme.common.editThisPage": {
|
||||
"message": "编辑此页",
|
||||
"description": "The link label to edit the current page"
|
||||
},
|
||||
"theme.common.headingLinkTitle": {
|
||||
"message": "{heading}的直接链接",
|
||||
"description": "Title for link to heading"
|
||||
@@ -168,14 +168,14 @@
|
||||
"message": "注意",
|
||||
"description": "The default label used for the Warning admonition (:::warning)"
|
||||
},
|
||||
"theme.blog.sidebar.navAriaLabel": {
|
||||
"message": "最近博文导航",
|
||||
"description": "The ARIA label for recent posts in the blog sidebar"
|
||||
},
|
||||
"theme.AnnouncementBar.closeButtonAriaLabel": {
|
||||
"message": "关闭",
|
||||
"description": "The ARIA label for close button of announcement bar"
|
||||
},
|
||||
"theme.blog.sidebar.navAriaLabel": {
|
||||
"message": "最近博文导航",
|
||||
"description": "The ARIA label for recent posts in the blog sidebar"
|
||||
},
|
||||
"theme.DocSidebarItem.expandCategoryAriaLabel": {
|
||||
"message": "展开侧边栏分类 '{label}'",
|
||||
"description": "The ARIA label to expand the sidebar category"
|
||||
@@ -204,6 +204,10 @@
|
||||
"message": "本页总览",
|
||||
"description": "The label used by the button on the collapsible TOC component"
|
||||
},
|
||||
"theme.blog.post.readingTime.plurals": {
|
||||
"message": "阅读需 {readingTime} 分钟",
|
||||
"description": "Pluralized label for \"{readingTime} min read\". Use as much plural forms (separated by \"|\") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)"
|
||||
},
|
||||
"theme.blog.post.readMore": {
|
||||
"message": "阅读更多",
|
||||
"description": "The label used in blog post item excerpts to link to full blog posts"
|
||||
@@ -212,21 +216,9 @@
|
||||
"message": "阅读 {title} 的全文",
|
||||
"description": "The ARIA label for the link to full blog posts from excerpts"
|
||||
},
|
||||
"theme.blog.post.readingTime.plurals": {
|
||||
"message": "阅读需 {readingTime} 分钟",
|
||||
"description": "Pluralized label for \"{readingTime} min read\". Use as much plural forms (separated by \"|\") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)"
|
||||
},
|
||||
"theme.CodeBlock.copy": {
|
||||
"message": "复制",
|
||||
"description": "The copy button label on code blocks"
|
||||
},
|
||||
"theme.CodeBlock.copied": {
|
||||
"message": "复制成功",
|
||||
"description": "The copied button label on code blocks"
|
||||
},
|
||||
"theme.CodeBlock.copyButtonAriaLabel": {
|
||||
"message": "复制代码到剪贴板",
|
||||
"description": "The ARIA label for copy code blocks button"
|
||||
"theme.docs.breadcrumbs.home": {
|
||||
"message": "主页面",
|
||||
"description": "The ARIA label for the home page in the breadcrumbs"
|
||||
},
|
||||
"theme.CodeBlock.wordWrapToggle": {
|
||||
"message": "切换自动换行",
|
||||
@@ -244,13 +236,17 @@
|
||||
"message": "文档侧边栏",
|
||||
"description": "The ARIA label for the sidebar navigation"
|
||||
},
|
||||
"theme.docs.breadcrumbs.home": {
|
||||
"message": "主页面",
|
||||
"description": "The ARIA label for the home page in the breadcrumbs"
|
||||
"theme.CodeBlock.copy": {
|
||||
"message": "复制",
|
||||
"description": "The copy button label on code blocks"
|
||||
},
|
||||
"theme.docs.sidebar.closeSidebarButtonAriaLabel": {
|
||||
"message": "关闭导航栏",
|
||||
"description": "The ARIA label for close button of mobile sidebar"
|
||||
"theme.CodeBlock.copied": {
|
||||
"message": "复制成功",
|
||||
"description": "The copied button label on code blocks"
|
||||
},
|
||||
"theme.CodeBlock.copyButtonAriaLabel": {
|
||||
"message": "复制代码到剪贴板",
|
||||
"description": "The ARIA label for copy code blocks button"
|
||||
},
|
||||
"theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel": {
|
||||
"message": "← 回到主菜单",
|
||||
@@ -260,6 +256,10 @@
|
||||
"message": "切换导航栏",
|
||||
"description": "The ARIA label for hamburger menu button of mobile navigation"
|
||||
},
|
||||
"theme.docs.sidebar.closeSidebarButtonAriaLabel": {
|
||||
"message": "关闭导航栏",
|
||||
"description": "The ARIA label for close button of mobile sidebar"
|
||||
},
|
||||
"theme.navbar.mobileDropdown.collapseButton.expandAriaLabel": {
|
||||
"message": "Expand the dropdown",
|
||||
"description": "The ARIA label of the button to expand the mobile dropdown navbar item"
|
||||
|
@@ -9,7 +9,7 @@ Devtools 还提供了一些其他的构建任务,如插件打包、插件检
|
||||
|
||||
## 安装
|
||||
|
||||
Devtools 是使用 Java 开发的一个 [Gradle](https://gradle.org/) 插件,如果你使用的 [plugin-starter](https://github.com/halo-sigs/plugin-starter) 创建的插件项目,那么你无需任何操作,它已经默认集成了 Devtools 插件。
|
||||
Devtools 是使用 Java 开发的一个 [Gradle](https://gradle.org/) 插件,如果你使用的 [halo-dev/create-halo-plugin](https://github.com/halo-dev/create-halo-plugin) 创建的插件项目,那么你无需任何操作,它已经默认集成了 Devtools 插件。
|
||||
|
||||
你可以在项目的 `build.gradle` 中找到它:
|
||||
|
||||
|
@@ -3,19 +3,19 @@ title: 构建
|
||||
description: UI 部分的构建说明
|
||||
---
|
||||
|
||||
在 [halo-dev/plugin-starter](https://github.com/halo-dev/plugin-starter) 模板中,我们已经配置好了 UI 的构建工具和流程,此文档主要说明一些构建细节以及其他可能的构建选项。
|
||||
在 [halo-dev/create-halo-plugin](https://github.com/halo-dev/create-halo-plugin) 工具中,我们已经配置好了 UI 的构建工具和流程,此文档主要说明一些构建细节以及其他可能的构建选项。
|
||||
|
||||
## 原理
|
||||
|
||||
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 中加载这两个资源并解析。
|
||||
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 中加载这两个资源并解析。
|
||||
|
||||
所以本质上,我们只需要使用支持将 `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/) 的预配置,插件项目只需要通过简单的配置即可使用。
|
||||
所以本质上,我们只需要使用支持将 `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/) 的预配置,插件项目只需要通过简单的配置即可使用。
|
||||
|
||||
## @halo-dev/ui-plugin-bundler-kit
|
||||
|
||||
在这个库中,我们提供了三个预配置,分别是:
|
||||
|
||||
1. `viteConfig`: Vite 的预配置,[halo-dev/plugin-starter](https://github.com/halo-dev/plugin-starter) 中默认使用的配置
|
||||
1. `viteConfig`: Vite 的预配置
|
||||
2. `rsbuildConfig`: Rsbuild 的预配置
|
||||
3. `HaloUIPluginBundlerKit`:已过时,迁移方式可以参考下面的文档
|
||||
|
||||
@@ -23,7 +23,33 @@ Halo 插件的 UI 部分(Console / UC)的实现方式其实很简单,本
|
||||
|
||||
#### 使用
|
||||
|
||||
如果你想要使用 Vite 构建 UI 部分,那么使用 `viteConfig` 即可,并且已经在 [halo-dev/plugin-starter](https://github.com/halo-dev/plugin-starter) 中配置,直接使用即可。
|
||||
如果你在通过 [halo-dev/create-halo-plugin](https://github.com/halo-dev/create-halo-plugin) 创建项目时没有选择使用 Vite 作为 UI 的构建工具,那么可以通过以下方式改为使用 Vite。
|
||||
|
||||
安装依赖:
|
||||
|
||||
```bash
|
||||
pnpm install @halo-dev/ui-plugin-bundler-kit@2.21.1 vite -D
|
||||
```
|
||||
|
||||
创建 vite.config.ts:
|
||||
|
||||
```js
|
||||
import { viteConfig } from "@halo-dev/ui-plugin-bundler-kit";
|
||||
|
||||
export default viteConfig()
|
||||
```
|
||||
|
||||
更新 package.json:
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite build --watch --mode=development",
|
||||
"build": "vite build"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 配置
|
||||
|
||||
@@ -83,7 +109,7 @@ Rsbuild 是基于 Rspack 开发的上层构建工具,其优势在于兼容 Web
|
||||
|
||||
#### 使用
|
||||
|
||||
因为在 [halo-dev/plugin-starter](https://github.com/halo-dev/plugin-starter) 中,默认采用 Vite 构建,所以如果想要使用 Rsbuild 构建,需要手动配置,以下是切换到 Rsbuild 的过程:
|
||||
如果你在通过 [halo-dev/create-halo-plugin](https://github.com/halo-dev/create-halo-plugin) 创建项目时没有选择使用 Rsbuild 作为 UI 的构建工具,那么可以通过以下方式改为使用 Rsbuild。
|
||||
|
||||
安装依赖:
|
||||
|
||||
@@ -91,7 +117,7 @@ Rsbuild 是基于 Rspack 开发的上层构建工具,其优势在于兼容 Web
|
||||
pnpm install @halo-dev/ui-plugin-bundler-kit@2.21.1 @rsbuild/core -D
|
||||
```
|
||||
|
||||
创建 rsbuild.config.mjs:
|
||||
创建 rsbuild.config.ts:
|
||||
|
||||
```js
|
||||
import { rsbuildConfig } from "@halo-dev/ui-plugin-bundler-kit";
|
||||
@@ -255,74 +281,56 @@ export default definePlugin({
|
||||
|
||||
3. 更新项目根目录的 `build.gradle` 文件
|
||||
|
||||
```diff
|
||||
```gradle
|
||||
plugins {
|
||||
id 'java'
|
||||
- id "com.github.node-gradle.node" version "7.0.2"
|
||||
- id "io.freefair.lombok" version "8.0.1"
|
||||
- id "run.halo.plugin.devtools" version "0.2.0"
|
||||
+ id "io.freefair.lombok" version "8.13"
|
||||
+ id "run.halo.plugin.devtools" version "0.6.0"
|
||||
id "io.freefair.lombok" version "8.13"
|
||||
id "run.halo.plugin.devtools" version "0.6.0"
|
||||
}
|
||||
|
||||
|
||||
group 'run.halo.starter'
|
||||
-sourceCompatibility = JavaVersion.VERSION_17
|
||||
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
- maven { url 'https://s01.oss.sonatype.org/content/repositories/releases' }
|
||||
- maven { url 'https://s01.oss.sonatype.org/content/repositories/snapshots/' }
|
||||
- maven { url 'https://repo.spring.io/milestone' }
|
||||
}
|
||||
|
||||
|
||||
dependencies {
|
||||
- implementation platform('run.halo.tools.platform:plugin:2.20.0-SNAPSHOT')
|
||||
+ implementation platform('run.halo.tools.platform:plugin:2.21.0')
|
||||
implementation platform('run.halo.tools.platform:plugin:2.21.0')
|
||||
compileOnly 'run.halo.app:api'
|
||||
|
||||
|
||||
testImplementation 'run.halo.app:api'
|
||||
testImplementation 'org.springframework.boot:spring-boot-starter-test'
|
||||
+ testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
|
||||
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
|
||||
}
|
||||
|
||||
|
||||
test {
|
||||
useJUnitPlatform()
|
||||
}
|
||||
|
||||
-tasks.withType(JavaCompile).configureEach {
|
||||
- options.encoding = "UTF-8"
|
||||
-}
|
||||
-
|
||||
-node {
|
||||
- nodeProjectDir = file("${project.projectDir}/ui")
|
||||
+java {
|
||||
+ toolchain {
|
||||
+ languageVersion = JavaLanguageVersion.of(21)
|
||||
+ }
|
||||
|
||||
java {
|
||||
toolchain {
|
||||
languageVersion = JavaLanguageVersion.of(21)
|
||||
}
|
||||
}
|
||||
|
||||
-tasks.register('buildFrontend', PnpmTask) {
|
||||
- args = ['build']
|
||||
- dependsOn('installDepsForUI')
|
||||
+tasks.withType(JavaCompile).configureEach {
|
||||
+ options.encoding = "UTF-8"
|
||||
+ options.release = 21
|
||||
|
||||
tasks.withType(JavaCompile).configureEach {
|
||||
options.encoding = "UTF-8"
|
||||
options.release = 21
|
||||
}
|
||||
|
||||
-tasks.register('installDepsForUI', PnpmTask) {
|
||||
- args = ['install']
|
||||
+tasks.register('processUiResources', Copy) {
|
||||
+ from project(':ui').tasks.named('buildFrontend')
|
||||
+ into layout.buildDirectory.dir('resources/main/console')
|
||||
|
||||
tasks.register('processUiResources', Copy) {
|
||||
from project(':ui').layout.buildDirectory.dir('dist')
|
||||
into layout.buildDirectory.dir('resources/main/console')
|
||||
dependsOn project(':ui').tasks.named('assemble')
|
||||
shouldRunAfter tasks.named('processResources')
|
||||
}
|
||||
|
||||
-build {
|
||||
- // build frontend before build
|
||||
- tasks.named('compileJava').configure {
|
||||
- dependsOn('buildFrontend')
|
||||
- }
|
||||
+tasks.named('processResources', ProcessResources) {
|
||||
+ dependsOn tasks.named('processUiResources')
|
||||
|
||||
tasks.named('classes') {
|
||||
dependsOn tasks.named('processUiResources')
|
||||
}
|
||||
|
||||
halo {
|
||||
version = '2.21'
|
||||
}
|
||||
```
|
||||
|
||||
@@ -330,41 +338,42 @@ export default definePlugin({
|
||||
|
||||
```gradle
|
||||
plugins {
|
||||
id 'base'
|
||||
id "com.github.node-gradle.node" version "7.1.0"
|
||||
id 'base'
|
||||
id "com.github.node-gradle.node" version "7.1.0"
|
||||
}
|
||||
|
||||
group 'run.halo.starter.ui'
|
||||
|
||||
tasks.register('buildFrontend', PnpmTask) {
|
||||
args = ['build']
|
||||
dependsOn tasks.named('pnpmInstall')
|
||||
inputs.dir(layout.projectDirectory.dir('src'))
|
||||
inputs.files(fileTree(
|
||||
dir: layout.projectDirectory,
|
||||
includes: ['*.cjs', '*.ts', '*.js', '*.json', '*.yaml']))
|
||||
outputs.dir(layout.buildDirectory.dir('dist'))
|
||||
shouldRunAfter(tasks.named('check'))
|
||||
group = 'build'
|
||||
description = 'Builds the UI project using pnpm.'
|
||||
args = ['build']
|
||||
dependsOn tasks.named('pnpmInstall')
|
||||
inputs.dir(layout.projectDirectory.dir('src'))
|
||||
inputs.files(fileTree(
|
||||
dir: layout.projectDirectory,
|
||||
includes: ['*.cjs', '*.ts', '*.js', '*.json', '*.yaml']))
|
||||
outputs.dir(layout.buildDirectory.dir('dist'))
|
||||
}
|
||||
|
||||
tasks.register('checkFrontend', PnpmTask) {
|
||||
args = ['test:unit']
|
||||
dependsOn tasks.named('pnpmInstall')
|
||||
tasks.register('pnpmCheck', PnpmTask) {
|
||||
group = 'verification'
|
||||
description = 'Runs unit tests using pnpm.'
|
||||
args = ['test:unit']
|
||||
dependsOn tasks.named('pnpmInstall')
|
||||
}
|
||||
|
||||
tasks.named('check') {
|
||||
dependsOn tasks.named('checkFrontend')
|
||||
dependsOn tasks.named('pnpmCheck')
|
||||
}
|
||||
|
||||
tasks.named('build') {
|
||||
dependsOn tasks.named('buildFrontend')
|
||||
tasks.named('assemble') {
|
||||
dependsOn tasks.named('buildFrontend')
|
||||
}
|
||||
```
|
||||
|
||||
进行此变更的主要目的是保证 UI 构建的产物不直接输出到源码目录的 resources 目录中,而是通过 Gradle 构建插件时复制到 `src/main/resources/console` 目录中。
|
||||
|
||||
完整变更过程可参考:[halo-dev/plugin-starter#52](https://github.com/halo-dev/plugin-starter/pull/52)
|
||||
|
||||
如果你不想使用新的 Gradle 构建配置,也可以修改 viteConfig 或 rsbuildConfig 的输出目录,和旧版本保持一致:
|
||||
|
||||
viteConfig:
|
||||
|
@@ -5,7 +5,7 @@ description: UI 扩展部分的入口文件
|
||||
|
||||
入口文件即 Halo 核心会加载的文件,所有插件有且只有一个入口文件,构建之后会放置在插件项目的 `src/resources/console` 下,名为 `main.js`。
|
||||
|
||||
为了方便开发者,我们已经在 [halo-dev/plugin-starter](https://github.com/halo-dev/plugin-starter) 配置好了基础项目结构,包括构建配置,后续文档也会以此为准。
|
||||
为了方便开发者,我们已经在 [halo-dev/create-halo-plugin](https://github.com/halo-dev/create-halo-plugin) 配置好了基础项目结构,包括构建配置,后续文档也会以此为准。
|
||||
|
||||
## 定义入口文件
|
||||
|
||||
|
@@ -5,104 +5,9 @@ description: 这个例子展示了如何开发 Todo List 插件
|
||||
|
||||
本示例用于展示如何从插件模板创建一个插件并写一个 Todo List:
|
||||
|
||||
首先通过模板仓库创建一个插件,例如叫 `halo-plugin-todolist`
|
||||
首先参考 [入门 - 创建插件项目](../hello-world.md#创建插件项目) 文档创建一个新的插件项目并运行。
|
||||
|
||||
## 配置你的插件
|
||||
|
||||
1. 修改 `build.gradle` 中的 `group` 为你自己的,如:
|
||||
|
||||
```groovy
|
||||
group = 'run.halo.tutorial'
|
||||
```
|
||||
|
||||
2. 修改 `settings.gradle` 中的 `rootProject.name`
|
||||
|
||||
```groovy
|
||||
rootProject.name = 'halo-plugin-todolist'
|
||||
```
|
||||
|
||||
3. 修改插件的描述文件 `plugin.yaml`,它位于 `src/main/resources/plugin.yaml`。示例:
|
||||
|
||||
```yaml
|
||||
apiVersion: plugin.halo.run/v1alpha1
|
||||
kind: Plugin
|
||||
metadata:
|
||||
name: todolist
|
||||
spec:
|
||||
enabled: true
|
||||
requires: ">=2.0.0"
|
||||
author:
|
||||
name: halo-dev
|
||||
website: https://www.halo.run
|
||||
logo: https://www.halo.run/logo
|
||||
homepage: https://github.com/halo-dev/plugin-starter#readme
|
||||
repo: https://github.com/halo-dev/plugin-starter
|
||||
issues: https://github.com/halo-dev/plugin-starter/issues
|
||||
displayName: "插件 Todo List"
|
||||
description: "插件开发的 hello world,用于学习如何开发一个简单的 Halo 插件"
|
||||
license:
|
||||
- name: "GPL-3.0"
|
||||
url: "https://github.com/halo-dev/plugin-starter/blob/main/LICENSE"
|
||||
```
|
||||
|
||||
参考链接:
|
||||
|
||||
- [SemVer expression](https://github.com/zafarkhaja/jsemver#semver-expressions-api-ranges)
|
||||
- [表单定义](../../form-schema.md)
|
||||
|
||||
此时我们已经准备好了可以开发一个 TodoList 插件的一切,下面让我们正式进入 TodoList 插件开发教程。
|
||||
|
||||
## 运行插件
|
||||
|
||||
为了看到效果,首先我们需要让插件能最简单的运行起来。
|
||||
|
||||
1. 在 `src/main/java` 下创建包,如 `run.halo.tutorial`,在创建一个类 `TodoListPlugin`,它继承自 `BasePlugin` 类内容如下:
|
||||
|
||||
```java
|
||||
package run.halo.tutorial;
|
||||
|
||||
import run.halo.app.plugin.PluginContext;
|
||||
import org.springframework.stereotype.Component;
|
||||
import run.halo.app.plugin.BasePlugin;
|
||||
|
||||
@Component
|
||||
public class TodoListPlugin extends BasePlugin {
|
||||
public TodoListPlugin(PluginContext pluginContext) {
|
||||
super(pluginContext);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
`src/main/java` 下的文件结构如下:
|
||||
|
||||
```text
|
||||
.
|
||||
└── run
|
||||
└── halo
|
||||
└── tutorial
|
||||
└── TodoListPlugin.java
|
||||
```
|
||||
|
||||
2. 然后在项目目录执行命令
|
||||
|
||||
```shell
|
||||
./gradlew build
|
||||
```
|
||||
|
||||
3. 使用 `IntelliJ IDEA` 打开 Halo,参考 [Halo 开发环境运行](../../core/run.md) 及 [插件入门](../hello-world.md) 配置插件的运行模式和路径:
|
||||
|
||||
```yaml
|
||||
halo:
|
||||
plugin:
|
||||
runtime-mode: development
|
||||
fixed-plugin-path:
|
||||
# 配置为插件绝对路径
|
||||
- /Users/guqing/halo-plugin-todolist
|
||||
```
|
||||
|
||||
4. 启动 Halo,然后访问 `http://localhost:8090/console`
|
||||
|
||||
在插件列表将能看到插件已经被正确启用:
|
||||
如果能在插件列表中看到插件已经被正确启用,则说明插件已经运行成功。
|
||||
|
||||

|
||||
|
||||
|
@@ -7,25 +7,38 @@ description: 了解如何构建你的第一个插件并在 Halo 中使用它。
|
||||
|
||||
## 创建插件项目
|
||||
|
||||
1. 打开 [halo-dev/plugin-starter](https://github.com/halo-dev/plugin-starter)。
|
||||
我们为插件开发者提供了一个插件创建工具,可以帮助你快速创建一个插件项目。
|
||||
|
||||
> 这是一个插件的初始模板,你可以基于它来开发自己的插件。
|
||||
|
||||
2. 点击 `Use this template` -> `Create a new repository`。
|
||||
3. 如图所示填写仓库名后点击 `Create repository from template`。
|
||||
|
||||

|
||||
|
||||
你现在已经基于 Halo 插件模板创建了自己的存储库。接下来,你需要将它克隆到你的计算机上。
|
||||
|
||||
```shell
|
||||
# clone your repository
|
||||
git clone https://github.com/<your-username>/halo-plugin-hello-world.git
|
||||
|
||||
# enter the directory
|
||||
cd halo-plugin-hello-world
|
||||
```bash
|
||||
pnpm create halo-plugin
|
||||
```
|
||||
|
||||
```bash
|
||||
🚀 Welcome to Halo Plugin Creator!
|
||||
|
||||
✔ Plugin name: › hello-world
|
||||
✔ Domain (for group and package name): › com.example
|
||||
✔ Author name: › Halo
|
||||
✔ Choose UI build tool: › Rsbuild
|
||||
|
||||
📋 Project Configuration:
|
||||
Name: hello-world
|
||||
Domain: com.example
|
||||
Package: com.example.hello-world
|
||||
Author: Halo
|
||||
UI Tool: rsbuild
|
||||
Output Directory: /path/to/hello-world
|
||||
|
||||
✔ Create project? › yes
|
||||
```
|
||||
|
||||
- **Plugin name**: 插件的名称,用于插件的标识,此字段必须由小写字母、数字和连字符组成
|
||||
- **Domain**: 插件的包名
|
||||
- **Author name**: 插件的作者
|
||||
- **Choose UI build tool**: 插件的 UI 构建工具,目前支持 `Rsbuild` 和 `Vite`
|
||||
|
||||
更多关于插件创建工具的信息可查阅:[halo-dev/create-halo-plugin](https://github.com/halo-dev/create-halo-plugin)
|
||||
|
||||
## 运行插件
|
||||
|
||||
现在有了一个空项目,我们需要让插件能最最小化的运行起来,这里提供两种运行方式。
|
||||
@@ -36,17 +49,7 @@ Halo 提供了一个用于插件开发的 DevTools,它可以帮助你快速的
|
||||
|
||||
使用 DevTools 运行插件的前提是需要你的电脑上已经安装了 Docker 环境,这是我们推荐的用户开发时运行插件的方式,只需要执行以下命令即可。
|
||||
|
||||
1. 执行前端部分的依赖安装命令:
|
||||
|
||||
```shell
|
||||
# macOS / Linux
|
||||
./gradlew pnpmInstall
|
||||
|
||||
# Windows
|
||||
./gradlew.bat pnpmInstall
|
||||
```
|
||||
|
||||
2. 运行插件:
|
||||
1. 运行插件:
|
||||
|
||||
```shell
|
||||
# macOS / Linux
|
||||
@@ -58,7 +61,7 @@ Halo 提供了一个用于插件开发的 DevTools,它可以帮助你快速的
|
||||
|
||||
执行此命令后,会自动创建一个 Halo 的 Docker 容器并加载当前的插件。
|
||||
|
||||
3. 启动成功后,可以看到如下日志输出:
|
||||
2. 启动成功后,可以看到如下日志输出:
|
||||
|
||||
```shell
|
||||
Halo 初始化成功,访问:http://localhost:8090/console
|
||||
@@ -78,17 +81,7 @@ Halo 提供了一个用于插件开发的 DevTools,它可以帮助你快速的
|
||||
|
||||
但由于此方式需要先使用源码运行 Halo 才能启动插件,请确保已经在开发环境运行了 Halo,可以参考 [Halo 开发环境运行](../core/run.md)
|
||||
|
||||
1. 安装前端部分的依赖
|
||||
|
||||
```shell
|
||||
# macOS / Linux
|
||||
./gradlew pnpmInstall
|
||||
|
||||
# Windows
|
||||
./gradlew.bat pnpmInstall
|
||||
```
|
||||
|
||||
2. 编译插件
|
||||
1. 编译插件
|
||||
|
||||
```shell
|
||||
# macOS / Linux
|
||||
@@ -98,7 +91,7 @@ Halo 提供了一个用于插件开发的 DevTools,它可以帮助你快速的
|
||||
./gradlew.bat build
|
||||
```
|
||||
|
||||
3. 修改 Halo 配置文件:
|
||||
2. 修改 Halo 配置文件:
|
||||
|
||||
```shell
|
||||
# 进入 Halo 项目根目录后,使用 cd 命令进入配置文件目录
|
||||
@@ -128,7 +121,7 @@ Halo 提供了一个用于插件开发的 DevTools,它可以帮助你快速的
|
||||
- C:\path\to\halo-plugin-hello-world
|
||||
```
|
||||
|
||||
4. 启动 Halo
|
||||
3. 启动 Halo
|
||||
|
||||
```shell
|
||||
# macOS / Linux
|
||||
|
@@ -11,7 +11,7 @@ description: 了解如何与我们的社区分享你的插件
|
||||
|
||||
## 自动构建
|
||||
|
||||
如果你是基于 [halo-dev/plugin-starter](https://github.com/halo-dev/plugin-starter) 创建的插件项目,那么已经包含了适用于 GitHub Action 的 `ci.yaml` 和 `cd.yaml` 文件,里面包含了构建插件和发布插件资源到 Release 的步骤,可以根据自己的实际需要进行修改,以下是示例:
|
||||
如果你是使用 [halo-dev/create-halo-plugin](https://github.com/halo-dev/create-halo-plugin) 创建的插件项目,那么已经包含了适用于 GitHub Action 的 `ci.yaml` 和 `cd.yaml` 文件,里面包含了构建插件和发布插件资源到 Release 的步骤,可以根据自己的实际需要进行修改,以下是示例:
|
||||
|
||||
```yaml
|
||||
name: CI
|
||||
|
@@ -80,7 +80,7 @@ export default definePlugin({
|
||||
});
|
||||
```
|
||||
|
||||
参考:[plugin-starter](https://github.com/halo-dev/plugin-starter/blob/5a4a25db252a7986900368a5fbf35e8d27f5257f/ui/src/index.ts#L6-L29)
|
||||
参考:[halo-dev/create-halo-plugin#template/ui/src/index.ts](https://github.com/halo-dev/create-halo-plugin/blob/a4ce935a637faff4a7f00fecbdee08f55fd66ffd/template/ui/src/index.ts)
|
||||
|
||||
> 该配置示例为在插件前端部分入口文件 `index.ts`
|
||||
|
||||
|
Reference in New Issue
Block a user