@halo-dev/ui-plugin-bundler-kit 2.24.0 → 2.25.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +85 -13
- package/dist/index.d.mts +16 -4
- package/dist/index.mjs +118 -11
- package/package.json +7 -4
- package/src/__tests__/halo-plugin.spec.ts +102 -0
- package/src/__tests__/legacy.spec.ts +128 -0
- package/src/__tests__/provider.spec.ts +301 -0
- package/src/constants/build.ts +12 -1
- package/src/constants/externals.ts +1 -0
- package/src/constants/halo-plugin.ts +8 -2
- package/src/rsbuild.ts +79 -11
- package/src/utils/halo-plugin.ts +60 -4
- package/src/vite.ts +79 -10
package/README.md
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
# @halo-dev/ui-plugin-bundler-kit
|
|
2
2
|
|
|
3
|
-
A frontend build toolkit for Halo plugin development, supporting both Vite and Rsbuild build systems.
|
|
3
|
+
A frontend build toolkit for Halo UI plugin development, supporting both Vite and Rsbuild build systems.
|
|
4
4
|
|
|
5
5
|
## Introduction
|
|
6
6
|
|
|
7
|
-
`@halo-dev/ui-plugin-bundler-kit` is a frontend build configuration toolkit specifically designed for Halo plugin development. It provides pre-configured build settings to help developers quickly set up and build frontend interfaces for Halo plugins.
|
|
7
|
+
`@halo-dev/ui-plugin-bundler-kit` is a frontend build configuration toolkit specifically designed for Halo UI plugin development. It provides pre-configured build settings to help developers quickly set up and build frontend interfaces for Halo plugins and theme-provided UI plugins.
|
|
8
8
|
|
|
9
9
|
### Key Features
|
|
10
10
|
|
|
11
11
|
- 🚀 **Ready to Use** - Provides pre-configured Vite and Rsbuild build settings
|
|
12
12
|
- 📦 **Multi-Build Tool Support** - Supports both Vite and Rsbuild
|
|
13
13
|
- 🔧 **Flexible Configuration** - Supports custom build configurations
|
|
14
|
-
- 🎯 **Halo Optimized** - External dependencies and global variables optimized for Halo plugin development
|
|
14
|
+
- 🎯 **Halo Optimized** - External dependencies and global variables optimized for Halo UI plugin development
|
|
15
15
|
- 📁 **Smart Output** - Automatically selects output directory based on environment
|
|
16
16
|
|
|
17
17
|
## Installation
|
|
@@ -45,12 +45,13 @@ npm install @rsbuild/core
|
|
|
45
45
|
|
|
46
46
|
### Vite Configuration
|
|
47
47
|
|
|
48
|
-
Create or update `vite.config.ts` file in your project root:
|
|
48
|
+
Create or update `vite.config.ts` file in your UI plugin project root:
|
|
49
49
|
|
|
50
50
|
```typescript
|
|
51
51
|
import { viteConfig } from "@halo-dev/ui-plugin-bundler-kit";
|
|
52
52
|
|
|
53
53
|
export default viteConfig({
|
|
54
|
+
// provider defaults to "plugin"
|
|
54
55
|
vite: {
|
|
55
56
|
// Your custom Vite configuration
|
|
56
57
|
plugins: [
|
|
@@ -65,12 +66,13 @@ export default viteConfig({
|
|
|
65
66
|
|
|
66
67
|
### Rsbuild Configuration
|
|
67
68
|
|
|
68
|
-
Create or update `rsbuild.config.ts` file in your project root:
|
|
69
|
+
Create or update `rsbuild.config.ts` file in your UI plugin project root:
|
|
69
70
|
|
|
70
71
|
```typescript
|
|
71
72
|
import { rsbuildConfig } from "@halo-dev/ui-plugin-bundler-kit";
|
|
72
73
|
|
|
73
74
|
export default rsbuildConfig({
|
|
75
|
+
// provider defaults to "plugin"
|
|
74
76
|
rsbuild: {
|
|
75
77
|
// Your custom Rsbuild configuration
|
|
76
78
|
plugins: [
|
|
@@ -83,9 +85,46 @@ export default rsbuildConfig({
|
|
|
83
85
|
|
|
84
86
|
> **Note**: Vue plugin is pre-configured, no need to add it manually.
|
|
85
87
|
|
|
88
|
+
### Theme UI Plugin Configuration
|
|
89
|
+
|
|
90
|
+
For theme-provided Console/User Center UI plugins, place the frontend project under the theme's `ui-plugin/` directory:
|
|
91
|
+
|
|
92
|
+
```text
|
|
93
|
+
theme-root/
|
|
94
|
+
├── theme.yaml
|
|
95
|
+
└── ui-plugin/
|
|
96
|
+
├── package.json
|
|
97
|
+
├── src/index.ts
|
|
98
|
+
└── vite.config.ts
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Vite:
|
|
102
|
+
|
|
103
|
+
```typescript
|
|
104
|
+
import { viteConfig } from "@halo-dev/ui-plugin-bundler-kit";
|
|
105
|
+
|
|
106
|
+
export default viteConfig({
|
|
107
|
+
provider: "theme",
|
|
108
|
+
vite: {},
|
|
109
|
+
});
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Rsbuild:
|
|
113
|
+
|
|
114
|
+
```typescript
|
|
115
|
+
import { rsbuildConfig } from "@halo-dev/ui-plugin-bundler-kit";
|
|
116
|
+
|
|
117
|
+
export default rsbuildConfig({
|
|
118
|
+
provider: "theme",
|
|
119
|
+
rsbuild: {},
|
|
120
|
+
});
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
The theme provider reads `../theme.yaml`, outputs to `dist`, registers the module as `theme:{metadata.name}`, and configures assets for `/themes/{metadata.name}/ui-plugin/assets/`. Halo reads only `ui-plugin/dist/**` from the theme package.
|
|
124
|
+
|
|
86
125
|
### Legacy Configuration (Deprecated)
|
|
87
126
|
|
|
88
|
-
> ⚠️ **Note**: The `HaloUIPluginBundlerKit` function is deprecated. Please use `viteConfig` or `rsbuildConfig` instead.
|
|
127
|
+
> ⚠️ **Note**: The `HaloUIPluginBundlerKit` function is deprecated. Please use `viteConfig` or `rsbuildConfig` instead. It does not support `provider: "theme"`.
|
|
89
128
|
|
|
90
129
|
```typescript
|
|
91
130
|
import { HaloUIPluginBundlerKit } from "@halo-dev/ui-plugin-bundler-kit";
|
|
@@ -106,8 +145,14 @@ export default {
|
|
|
106
145
|
```typescript
|
|
107
146
|
interface ViteUserConfig {
|
|
108
147
|
/**
|
|
109
|
-
*
|
|
110
|
-
* @default "
|
|
148
|
+
* UI plugin provider type
|
|
149
|
+
* @default "plugin"
|
|
150
|
+
*/
|
|
151
|
+
provider?: "plugin" | "theme";
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Halo plugin or theme manifest file path
|
|
155
|
+
* @default "../src/main/resources/plugin.yaml" for plugins, "../theme.yaml" for themes
|
|
111
156
|
*/
|
|
112
157
|
manifestPath?: string;
|
|
113
158
|
|
|
@@ -123,8 +168,14 @@ interface ViteUserConfig {
|
|
|
123
168
|
```typescript
|
|
124
169
|
interface RsBuildUserConfig {
|
|
125
170
|
/**
|
|
126
|
-
*
|
|
127
|
-
* @default "
|
|
171
|
+
* UI plugin provider type
|
|
172
|
+
* @default "plugin"
|
|
173
|
+
*/
|
|
174
|
+
provider?: "plugin" | "theme";
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Halo plugin or theme manifest file path
|
|
178
|
+
* @default "../src/main/resources/plugin.yaml" for plugins, "../theme.yaml" for themes
|
|
128
179
|
*/
|
|
129
180
|
manifestPath?: string;
|
|
130
181
|
|
|
@@ -216,6 +267,20 @@ export default viteConfig({
|
|
|
216
267
|
});
|
|
217
268
|
```
|
|
218
269
|
|
|
270
|
+
### Custom Theme Manifest Path
|
|
271
|
+
|
|
272
|
+
```typescript
|
|
273
|
+
import { viteConfig } from "@halo-dev/ui-plugin-bundler-kit";
|
|
274
|
+
|
|
275
|
+
export default viteConfig({
|
|
276
|
+
provider: "theme",
|
|
277
|
+
manifestPath: "../custom-theme.yaml",
|
|
278
|
+
vite: {
|
|
279
|
+
// Other configurations...
|
|
280
|
+
},
|
|
281
|
+
});
|
|
282
|
+
```
|
|
283
|
+
|
|
219
284
|
## Development Scripts
|
|
220
285
|
|
|
221
286
|
Recommended scripts to add to your `package.json`:
|
|
@@ -242,10 +307,17 @@ For Rsbuild:
|
|
|
242
307
|
|
|
243
308
|
## Build Output
|
|
244
309
|
|
|
245
|
-
> Relative to the
|
|
310
|
+
> Relative to the UI plugin project root
|
|
311
|
+
|
|
312
|
+
Plugin provider:
|
|
313
|
+
|
|
314
|
+
- **Development**: `../build/resources/main/ui` or `../build/resources/main/console`
|
|
315
|
+
- **Production**: `./build/dist`
|
|
316
|
+
|
|
317
|
+
Theme provider:
|
|
246
318
|
|
|
247
|
-
- **Development**: `
|
|
248
|
-
- **Production**: `
|
|
319
|
+
- **Development**: `dist`
|
|
320
|
+
- **Production**: `dist`
|
|
249
321
|
|
|
250
322
|
> **Note**: The production build output directory of `HaloUIPluginBundlerKit` is still `src/main/resources/console` to ensure compatibility.
|
|
251
323
|
|
package/dist/index.d.mts
CHANGED
|
@@ -17,9 +17,15 @@ declare function HaloUIPluginBundlerKit(options?: HaloUIPluginBundlerKitOptions)
|
|
|
17
17
|
//#region src/rsbuild.d.ts
|
|
18
18
|
interface RsBuildUserConfig {
|
|
19
19
|
/**
|
|
20
|
-
*
|
|
20
|
+
* UI plugin provider type.
|
|
21
21
|
*
|
|
22
|
-
* @default "
|
|
22
|
+
* @default "plugin"
|
|
23
|
+
*/
|
|
24
|
+
provider?: "plugin" | "theme";
|
|
25
|
+
/**
|
|
26
|
+
* Halo plugin or theme manifest path.
|
|
27
|
+
*
|
|
28
|
+
* @default "../src/main/resources/plugin.yaml" for plugins, "../theme.yaml" for themes
|
|
23
29
|
*/
|
|
24
30
|
manifestPath?: string;
|
|
25
31
|
/**
|
|
@@ -48,9 +54,15 @@ declare function rsbuildConfig(config?: RsBuildUserConfig): (env: ConfigParams)
|
|
|
48
54
|
//#region src/vite.d.ts
|
|
49
55
|
interface ViteUserConfig {
|
|
50
56
|
/**
|
|
51
|
-
*
|
|
57
|
+
* UI plugin provider type.
|
|
58
|
+
*
|
|
59
|
+
* @default "plugin"
|
|
60
|
+
*/
|
|
61
|
+
provider?: "plugin" | "theme";
|
|
62
|
+
/**
|
|
63
|
+
* Halo plugin or theme manifest path.
|
|
52
64
|
*
|
|
53
|
-
* @default "../src/main/resources/plugin.yaml"
|
|
65
|
+
* @default "../src/main/resources/plugin.yaml" for plugins, "../theme.yaml" for themes
|
|
54
66
|
*/
|
|
55
67
|
manifestPath?: string;
|
|
56
68
|
/**
|
package/dist/index.mjs
CHANGED
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import yaml from "js-yaml";
|
|
3
|
+
import { gte, minVersion } from "semver";
|
|
3
4
|
import { defineConfig, mergeRsbuildConfig } from "@rsbuild/core";
|
|
4
5
|
import { pluginVue } from "@rsbuild/plugin-vue";
|
|
5
6
|
import Vue from "@vitejs/plugin-vue";
|
|
6
7
|
import { defineConfig as defineConfig$1, mergeConfig } from "vite";
|
|
7
8
|
//#region src/constants/build.ts
|
|
8
9
|
const DEFAULT_OUT_DIR_DEV = "../build/resources/main/console";
|
|
10
|
+
const DEFAULT_OUT_DIR_DEV_BASE = "../build/resources/main";
|
|
9
11
|
const DEFAULT_OUT_DIR_PROD = "./build/dist";
|
|
12
|
+
const DEFAULT_THEME_OUT_DIR = "dist";
|
|
13
|
+
function getDefaultOutDirDev(bundleLocation) {
|
|
14
|
+
return `${DEFAULT_OUT_DIR_DEV_BASE}/${bundleLocation}`;
|
|
15
|
+
}
|
|
10
16
|
//#endregion
|
|
11
17
|
//#region src/constants/externals.ts
|
|
12
18
|
const GLOBALS = {
|
|
@@ -20,12 +26,50 @@ const GLOBALS = {
|
|
|
20
26
|
"@halo-dev/components": "HaloComponents",
|
|
21
27
|
"@halo-dev/api-client": "HaloApiClient",
|
|
22
28
|
"@halo-dev/richtext-editor": "RichTextEditor",
|
|
29
|
+
"@formkit/vue": "FormKitVue",
|
|
23
30
|
axios: "axios"
|
|
24
31
|
};
|
|
25
32
|
const EXTERNALS = Object.keys(GLOBALS);
|
|
26
33
|
//#endregion
|
|
34
|
+
//#region src/constants/halo-plugin.ts
|
|
35
|
+
const DEFAULT_PLUGIN_MANIFEST_PATH = "../src/main/resources/plugin.yaml";
|
|
36
|
+
const DEFAULT_THEME_MANIFEST_PATH = "../theme.yaml";
|
|
37
|
+
//#endregion
|
|
27
38
|
//#region src/utils/halo-plugin.ts
|
|
39
|
+
const UI_BUNDLE_MIN_HALO_VERSION = "2.25.0";
|
|
40
|
+
const UI_BUNDLE_LOCATION = "ui";
|
|
41
|
+
const CONSOLE_BUNDLE_LOCATION = "console";
|
|
42
|
+
const THEME_MODULE_NAME_PREFIX = "theme:";
|
|
28
43
|
function getHaloPluginManifest(manifestPath) {
|
|
44
|
+
return readManifest(manifestPath);
|
|
45
|
+
}
|
|
46
|
+
function getHaloThemeManifest(manifestPath) {
|
|
47
|
+
return readManifest(manifestPath);
|
|
48
|
+
}
|
|
49
|
+
function getManifestName(manifest) {
|
|
50
|
+
return manifest.metadata.name;
|
|
51
|
+
}
|
|
52
|
+
function getHaloThemeModuleName(manifest) {
|
|
53
|
+
return `${THEME_MODULE_NAME_PREFIX}${getManifestName(manifest)}`;
|
|
54
|
+
}
|
|
55
|
+
function getHaloThemeAssetPublicPath(manifest) {
|
|
56
|
+
return `/themes/${getManifestName(manifest)}/ui-plugin/assets/`;
|
|
57
|
+
}
|
|
58
|
+
function getHaloPluginBundleLocation(manifest) {
|
|
59
|
+
const requiresMinVersion = getRequiresMinVersion(manifest.spec.requires);
|
|
60
|
+
return requiresMinVersion && gte(requiresMinVersion, UI_BUNDLE_MIN_HALO_VERSION) ? UI_BUNDLE_LOCATION : CONSOLE_BUNDLE_LOCATION;
|
|
61
|
+
}
|
|
62
|
+
function getRequiresMinVersion(requires) {
|
|
63
|
+
const normalizedRequires = requires?.trim();
|
|
64
|
+
if (!normalizedRequires) return;
|
|
65
|
+
try {
|
|
66
|
+
return minVersion(normalizedRequires);
|
|
67
|
+
} catch {
|
|
68
|
+
console.warn(`[ui-plugin-bundler-kit] Invalid semver range in plugin manifest "spec.requires": "${requires}". Falling back to "${CONSOLE_BUNDLE_LOCATION}" bundle location.`);
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
function readManifest(manifestPath) {
|
|
29
73
|
return yaml.load(fs.readFileSync(manifestPath, "utf8"));
|
|
30
74
|
}
|
|
31
75
|
//#endregion
|
|
@@ -69,10 +113,10 @@ function HaloUIPluginBundlerKit(options = {}) {
|
|
|
69
113
|
}
|
|
70
114
|
//#endregion
|
|
71
115
|
//#region src/rsbuild.ts
|
|
72
|
-
function createRsbuildPresetsConfig(manifestPath) {
|
|
73
|
-
const
|
|
116
|
+
function createRsbuildPresetsConfig(provider, manifestPath) {
|
|
117
|
+
const defaults = provider === "theme" ? getThemeProviderDefaults$1(manifestPath) : getPluginProviderDefaults$1(manifestPath);
|
|
74
118
|
return defineConfig(({ envMode }) => {
|
|
75
|
-
const outDir = envMode === "production" ?
|
|
119
|
+
const outDir = envMode === "production" ? defaults.outDir.prod : defaults.outDir.dev;
|
|
76
120
|
return {
|
|
77
121
|
mode: envMode || "production",
|
|
78
122
|
plugins: [pluginVue()],
|
|
@@ -88,11 +132,11 @@ function createRsbuildPresetsConfig(manifestPath) {
|
|
|
88
132
|
experiments: { rspackFuture: { bundlerInfo: { force: false } } },
|
|
89
133
|
module: { parser: { javascript: { importMeta: false } } },
|
|
90
134
|
output: {
|
|
91
|
-
publicPath:
|
|
135
|
+
publicPath: defaults.publicPath,
|
|
92
136
|
library: {
|
|
93
137
|
type: "window",
|
|
94
138
|
export: "default",
|
|
95
|
-
name:
|
|
139
|
+
name: defaults.moduleName
|
|
96
140
|
},
|
|
97
141
|
globalObject: "window",
|
|
98
142
|
iife: true
|
|
@@ -124,6 +168,36 @@ function createRsbuildPresetsConfig(manifestPath) {
|
|
|
124
168
|
};
|
|
125
169
|
});
|
|
126
170
|
}
|
|
171
|
+
function getPluginProviderDefaults$1(manifestPath) {
|
|
172
|
+
const manifest = getHaloPluginManifest(manifestPath);
|
|
173
|
+
const bundleLocation = getHaloPluginBundleLocation(manifest);
|
|
174
|
+
return {
|
|
175
|
+
moduleName: getManifestName(manifest),
|
|
176
|
+
outDir: {
|
|
177
|
+
prod: DEFAULT_OUT_DIR_PROD,
|
|
178
|
+
dev: getDefaultOutDirDev(bundleLocation)
|
|
179
|
+
},
|
|
180
|
+
publicPath: `/plugins/${getManifestName(manifest)}/assets/${bundleLocation}/`
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
function getThemeProviderDefaults$1(manifestPath) {
|
|
184
|
+
const manifest = getHaloThemeManifest(manifestPath);
|
|
185
|
+
return {
|
|
186
|
+
moduleName: getHaloThemeModuleName(manifest),
|
|
187
|
+
outDir: {
|
|
188
|
+
prod: DEFAULT_THEME_OUT_DIR,
|
|
189
|
+
dev: DEFAULT_THEME_OUT_DIR
|
|
190
|
+
},
|
|
191
|
+
publicPath: getHaloThemeAssetPublicPath(manifest)
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
function getProvider$1(config) {
|
|
195
|
+
return config?.provider || "plugin";
|
|
196
|
+
}
|
|
197
|
+
function getManifestPath$1(provider, config) {
|
|
198
|
+
if (config?.manifestPath) return config.manifestPath;
|
|
199
|
+
return provider === "theme" ? DEFAULT_THEME_MANIFEST_PATH : DEFAULT_PLUGIN_MANIFEST_PATH;
|
|
200
|
+
}
|
|
127
201
|
/**
|
|
128
202
|
* Rsbuild config for Halo UI Plugin.
|
|
129
203
|
*
|
|
@@ -141,27 +215,29 @@ function createRsbuildPresetsConfig(manifestPath) {
|
|
|
141
215
|
* @returns
|
|
142
216
|
*/
|
|
143
217
|
function rsbuildConfig(config) {
|
|
144
|
-
const
|
|
218
|
+
const provider = getProvider$1(config);
|
|
219
|
+
const presetsConfigFn = createRsbuildPresetsConfig(provider, getManifestPath$1(provider, config));
|
|
145
220
|
return defineConfig((env) => {
|
|
146
221
|
return mergeRsbuildConfig(presetsConfigFn(env), typeof config?.rsbuild === "function" ? config.rsbuild(env) : config?.rsbuild || {});
|
|
147
222
|
});
|
|
148
223
|
}
|
|
149
224
|
//#endregion
|
|
150
225
|
//#region src/vite.ts
|
|
151
|
-
function createVitePresetsConfig(manifestPath) {
|
|
152
|
-
const
|
|
226
|
+
function createVitePresetsConfig(provider, manifestPath) {
|
|
227
|
+
const defaults = provider === "theme" ? getThemeProviderDefaults(manifestPath) : getPluginProviderDefaults(manifestPath);
|
|
153
228
|
return defineConfig$1(({ mode }) => {
|
|
154
229
|
const isProduction = mode === "production";
|
|
155
230
|
return {
|
|
156
231
|
mode: mode || "production",
|
|
232
|
+
base: defaults.base,
|
|
157
233
|
plugins: [Vue()],
|
|
158
234
|
define: { "process.env.NODE_ENV": "'production'" },
|
|
159
235
|
build: {
|
|
160
|
-
outDir: isProduction ?
|
|
236
|
+
outDir: isProduction ? defaults.outDir.prod : defaults.outDir.dev,
|
|
161
237
|
emptyOutDir: true,
|
|
162
238
|
lib: {
|
|
163
239
|
entry: "src/index.ts",
|
|
164
|
-
name:
|
|
240
|
+
name: defaults.moduleName,
|
|
165
241
|
formats: ["iife"],
|
|
166
242
|
fileName: () => "main.js",
|
|
167
243
|
cssFileName: "style"
|
|
@@ -177,6 +253,36 @@ function createVitePresetsConfig(manifestPath) {
|
|
|
177
253
|
};
|
|
178
254
|
});
|
|
179
255
|
}
|
|
256
|
+
function getPluginProviderDefaults(manifestPath) {
|
|
257
|
+
const manifest = getHaloPluginManifest(manifestPath);
|
|
258
|
+
const bundleLocation = getHaloPluginBundleLocation(manifest);
|
|
259
|
+
return {
|
|
260
|
+
moduleName: getManifestName(manifest),
|
|
261
|
+
outDir: {
|
|
262
|
+
prod: DEFAULT_OUT_DIR_PROD,
|
|
263
|
+
dev: getDefaultOutDirDev(bundleLocation)
|
|
264
|
+
},
|
|
265
|
+
base: void 0
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
function getThemeProviderDefaults(manifestPath) {
|
|
269
|
+
const manifest = getHaloThemeManifest(manifestPath);
|
|
270
|
+
return {
|
|
271
|
+
moduleName: getHaloThemeModuleName(manifest),
|
|
272
|
+
outDir: {
|
|
273
|
+
prod: DEFAULT_THEME_OUT_DIR,
|
|
274
|
+
dev: DEFAULT_THEME_OUT_DIR
|
|
275
|
+
},
|
|
276
|
+
base: getHaloThemeAssetPublicPath(manifest)
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
function getProvider(config) {
|
|
280
|
+
return config?.provider || "plugin";
|
|
281
|
+
}
|
|
282
|
+
function getManifestPath(provider, config) {
|
|
283
|
+
if (config?.manifestPath) return config.manifestPath;
|
|
284
|
+
return provider === "theme" ? DEFAULT_THEME_MANIFEST_PATH : DEFAULT_PLUGIN_MANIFEST_PATH;
|
|
285
|
+
}
|
|
180
286
|
/**
|
|
181
287
|
* Vite config for Halo UI Plugin.
|
|
182
288
|
*
|
|
@@ -192,7 +298,8 @@ function createVitePresetsConfig(manifestPath) {
|
|
|
192
298
|
* ```
|
|
193
299
|
*/
|
|
194
300
|
function viteConfig(config) {
|
|
195
|
-
const
|
|
301
|
+
const provider = getProvider(config);
|
|
302
|
+
const presetsConfigFn = createVitePresetsConfig(provider, getManifestPath(provider, config));
|
|
196
303
|
return defineConfig$1((env) => {
|
|
197
304
|
return mergeConfig(presetsConfigFn(env), typeof config?.vite === "function" ? config.vite(env) : config?.vite || {});
|
|
198
305
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@halo-dev/ui-plugin-bundler-kit",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.25.1",
|
|
4
4
|
"homepage": "https://github.com/halo-dev/halo/tree/main/ui/packages/ui-plugin-bundler-kit#readme",
|
|
5
5
|
"bugs": {
|
|
6
6
|
"url": "https://github.com/halo-dev/halo/issues"
|
|
@@ -20,10 +20,12 @@
|
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
22
|
"js-yaml": "^4.1.1",
|
|
23
|
-
"
|
|
23
|
+
"semver": "^7.7.4",
|
|
24
|
+
"@halo-dev/api-client": "2.25.1"
|
|
24
25
|
},
|
|
25
26
|
"devDependencies": {
|
|
26
|
-
"@types/js-yaml": "^4.0.9"
|
|
27
|
+
"@types/js-yaml": "^4.0.9",
|
|
28
|
+
"@types/semver": "^7.7.1"
|
|
27
29
|
},
|
|
28
30
|
"peerDependencies": {
|
|
29
31
|
"@rsbuild/core": "^1.0.0 || ^2.0.0",
|
|
@@ -36,6 +38,7 @@
|
|
|
36
38
|
},
|
|
37
39
|
"scripts": {
|
|
38
40
|
"build": "vp pack",
|
|
39
|
-
"dev": "vp pack --watch"
|
|
41
|
+
"dev": "vp pack --watch",
|
|
42
|
+
"test:unit": "vp test --run"
|
|
40
43
|
}
|
|
41
44
|
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import os from "node:os";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
5
|
+
import {
|
|
6
|
+
getHaloPluginBundleLocation,
|
|
7
|
+
getHaloPluginManifest,
|
|
8
|
+
getHaloThemeAssetPublicPath,
|
|
9
|
+
getHaloThemeManifest,
|
|
10
|
+
getHaloThemeModuleName,
|
|
11
|
+
getManifestName,
|
|
12
|
+
} from "../utils/halo-plugin";
|
|
13
|
+
|
|
14
|
+
const tempDirs: string[] = [];
|
|
15
|
+
|
|
16
|
+
afterEach(() => {
|
|
17
|
+
vi.restoreAllMocks();
|
|
18
|
+
while (tempDirs.length > 0) {
|
|
19
|
+
const tempDir = tempDirs.pop();
|
|
20
|
+
if (tempDir) {
|
|
21
|
+
fs.rmSync(tempDir, { recursive: true, force: true });
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
describe("halo manifest utilities", () => {
|
|
27
|
+
it("reads plugin manifests", () => {
|
|
28
|
+
const manifestPath = writeManifest([
|
|
29
|
+
"metadata:",
|
|
30
|
+
" name: plugin-a",
|
|
31
|
+
"spec:",
|
|
32
|
+
" requires: '>=2.25.0'",
|
|
33
|
+
"",
|
|
34
|
+
]);
|
|
35
|
+
|
|
36
|
+
const manifest = getHaloPluginManifest(manifestPath);
|
|
37
|
+
|
|
38
|
+
expect(getManifestName(manifest)).toBe("plugin-a");
|
|
39
|
+
expect(manifest.spec.requires).toBe(">=2.25.0");
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it("reads theme manifests and derives theme bundle values", () => {
|
|
43
|
+
const manifestPath = writeManifest(["metadata:", " name: theme-a", ""]);
|
|
44
|
+
|
|
45
|
+
const manifest = getHaloThemeManifest(manifestPath);
|
|
46
|
+
|
|
47
|
+
expect(getManifestName(manifest)).toBe("theme-a");
|
|
48
|
+
expect(getHaloThemeModuleName(manifest)).toBe("theme:theme-a");
|
|
49
|
+
expect(getHaloThemeAssetPublicPath(manifest)).toBe(
|
|
50
|
+
"/themes/theme-a/ui-plugin/assets/"
|
|
51
|
+
);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it("selects ui bundle location for plugins requiring Halo 2.25 or newer", () => {
|
|
55
|
+
expect(
|
|
56
|
+
getHaloPluginBundleLocation({
|
|
57
|
+
metadata: { name: "plugin-a" },
|
|
58
|
+
spec: { requires: ">=2.25.0" },
|
|
59
|
+
} as never)
|
|
60
|
+
).toBe("ui");
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
it("falls back to console bundle location for older or missing requirements", () => {
|
|
64
|
+
expect(
|
|
65
|
+
getHaloPluginBundleLocation({
|
|
66
|
+
metadata: { name: "plugin-a" },
|
|
67
|
+
spec: { requires: ">=2.24.0" },
|
|
68
|
+
} as never)
|
|
69
|
+
).toBe("console");
|
|
70
|
+
expect(
|
|
71
|
+
getHaloPluginBundleLocation({
|
|
72
|
+
metadata: { name: "plugin-a" },
|
|
73
|
+
spec: {},
|
|
74
|
+
} as never)
|
|
75
|
+
).toBe("console");
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it("warns and falls back to console bundle location for invalid requirements", () => {
|
|
79
|
+
const warn = vi.spyOn(console, "warn").mockImplementation(() => undefined);
|
|
80
|
+
|
|
81
|
+
expect(
|
|
82
|
+
getHaloPluginBundleLocation({
|
|
83
|
+
metadata: { name: "plugin-a" },
|
|
84
|
+
spec: { requires: "not semver" },
|
|
85
|
+
} as never)
|
|
86
|
+
).toBe("console");
|
|
87
|
+
expect(warn).toHaveBeenCalledWith(
|
|
88
|
+
'[ui-plugin-bundler-kit] Invalid semver range in plugin manifest "spec.requires": "not semver". ' +
|
|
89
|
+
'Falling back to "console" bundle location.'
|
|
90
|
+
);
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
function writeManifest(lines: string[]) {
|
|
95
|
+
const tempDir = fs.mkdtempSync(
|
|
96
|
+
path.join(os.tmpdir(), "halo-ui-plugin-manifest-")
|
|
97
|
+
);
|
|
98
|
+
tempDirs.push(tempDir);
|
|
99
|
+
const manifestPath = path.join(tempDir, "manifest.yaml");
|
|
100
|
+
fs.writeFileSync(manifestPath, lines.join("\n"));
|
|
101
|
+
return manifestPath;
|
|
102
|
+
}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import os from "node:os";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import type { Plugin } from "vite";
|
|
5
|
+
import { afterEach, describe, expect, it } from "vitest";
|
|
6
|
+
import { HaloUIPluginBundlerKit } from "../legacy";
|
|
7
|
+
|
|
8
|
+
const originalCwd = process.cwd();
|
|
9
|
+
const tempDirs: string[] = [];
|
|
10
|
+
|
|
11
|
+
afterEach(() => {
|
|
12
|
+
process.chdir(originalCwd);
|
|
13
|
+
while (tempDirs.length > 0) {
|
|
14
|
+
const tempDir = tempDirs.pop();
|
|
15
|
+
if (tempDir) {
|
|
16
|
+
fs.rmSync(tempDir, { recursive: true, force: true });
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
describe("HaloUIPluginBundlerKit", () => {
|
|
22
|
+
it("keeps legacy default output directories", () => {
|
|
23
|
+
const uiDir = setupPluginProject("legacy-plugin");
|
|
24
|
+
process.chdir(uiDir);
|
|
25
|
+
|
|
26
|
+
const plugin = HaloUIPluginBundlerKit();
|
|
27
|
+
|
|
28
|
+
expect(resolveLegacyConfig(plugin, "development").build).toMatchObject({
|
|
29
|
+
outDir: "../build/resources/main/console",
|
|
30
|
+
emptyOutDir: true,
|
|
31
|
+
lib: {
|
|
32
|
+
entry: "src/index.ts",
|
|
33
|
+
name: "legacy-plugin",
|
|
34
|
+
formats: ["iife"],
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
expect(resolveLegacyConfig(plugin, "production").build).toMatchObject({
|
|
38
|
+
outDir: "../src/main/resources/console",
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it("applies string outDir override for every mode", () => {
|
|
43
|
+
const uiDir = setupPluginProject("legacy-plugin");
|
|
44
|
+
process.chdir(uiDir);
|
|
45
|
+
|
|
46
|
+
const plugin = HaloUIPluginBundlerKit({ outDir: "custom" });
|
|
47
|
+
|
|
48
|
+
expect(resolveLegacyConfig(plugin, "development").build).toMatchObject({
|
|
49
|
+
outDir: "custom",
|
|
50
|
+
});
|
|
51
|
+
expect(resolveLegacyConfig(plugin, "production").build).toMatchObject({
|
|
52
|
+
outDir: "custom",
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it("applies mode-specific outDir overrides", () => {
|
|
57
|
+
const uiDir = setupPluginProject("legacy-plugin");
|
|
58
|
+
process.chdir(uiDir);
|
|
59
|
+
|
|
60
|
+
const plugin = HaloUIPluginBundlerKit({
|
|
61
|
+
outDir: {
|
|
62
|
+
dev: "dev-dist",
|
|
63
|
+
prod: "prod-dist",
|
|
64
|
+
},
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
expect(resolveLegacyConfig(plugin, "development").build).toMatchObject({
|
|
68
|
+
outDir: "dev-dist",
|
|
69
|
+
});
|
|
70
|
+
expect(resolveLegacyConfig(plugin, "production").build).toMatchObject({
|
|
71
|
+
outDir: "prod-dist",
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
it("uses custom manifest path", () => {
|
|
76
|
+
const projectRoot = createTempDir();
|
|
77
|
+
const manifestPath = path.join(projectRoot, "plugin.yaml");
|
|
78
|
+
fs.writeFileSync(
|
|
79
|
+
manifestPath,
|
|
80
|
+
["metadata:", " name: custom-legacy-plugin", "spec:", ""].join("\n")
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
const plugin = HaloUIPluginBundlerKit({ manifestPath });
|
|
84
|
+
|
|
85
|
+
expect(resolveLegacyConfig(plugin, "production").build).toMatchObject({
|
|
86
|
+
lib: {
|
|
87
|
+
name: "custom-legacy-plugin",
|
|
88
|
+
},
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
function resolveLegacyConfig(plugin: Plugin, mode: string) {
|
|
94
|
+
if (typeof plugin.config !== "function") {
|
|
95
|
+
throw new Error("Expected plugin config hook");
|
|
96
|
+
}
|
|
97
|
+
return plugin.config(
|
|
98
|
+
{},
|
|
99
|
+
{
|
|
100
|
+
command: "build",
|
|
101
|
+
mode,
|
|
102
|
+
isSsrBuild: false,
|
|
103
|
+
isPreview: false,
|
|
104
|
+
}
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function setupPluginProject(name: string) {
|
|
109
|
+
const projectRoot = createTempDir();
|
|
110
|
+
const uiDir = path.join(projectRoot, "ui");
|
|
111
|
+
fs.mkdirSync(path.join(projectRoot, "src/main/resources"), {
|
|
112
|
+
recursive: true,
|
|
113
|
+
});
|
|
114
|
+
fs.mkdirSync(uiDir, { recursive: true });
|
|
115
|
+
fs.writeFileSync(
|
|
116
|
+
path.join(projectRoot, "src/main/resources/plugin.yaml"),
|
|
117
|
+
["metadata:", ` name: ${name}`, "spec:", ""].join("\n")
|
|
118
|
+
);
|
|
119
|
+
return uiDir;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function createTempDir() {
|
|
123
|
+
const tempDir = fs.mkdtempSync(
|
|
124
|
+
path.join(os.tmpdir(), "halo-ui-plugin-legacy-")
|
|
125
|
+
);
|
|
126
|
+
tempDirs.push(tempDir);
|
|
127
|
+
return tempDir;
|
|
128
|
+
}
|
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import os from "node:os";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import type { ConfigParams, RsbuildConfig } from "@rsbuild/core";
|
|
5
|
+
import type { ConfigEnv, UserConfig } from "vite";
|
|
6
|
+
import { afterEach, describe, expect, it } from "vitest";
|
|
7
|
+
import { rsbuildConfig } from "../rsbuild";
|
|
8
|
+
import { viteConfig } from "../vite";
|
|
9
|
+
|
|
10
|
+
const originalCwd = process.cwd();
|
|
11
|
+
const tempDirs: string[] = [];
|
|
12
|
+
|
|
13
|
+
afterEach(() => {
|
|
14
|
+
process.chdir(originalCwd);
|
|
15
|
+
while (tempDirs.length > 0) {
|
|
16
|
+
const tempDir = tempDirs.pop();
|
|
17
|
+
if (tempDir) {
|
|
18
|
+
fs.rmSync(tempDir, { recursive: true, force: true });
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
describe("provider defaults", () => {
|
|
24
|
+
it("keeps plugin provider defaults when provider is omitted", () => {
|
|
25
|
+
const uiDir = setupPluginProject();
|
|
26
|
+
process.chdir(uiDir);
|
|
27
|
+
|
|
28
|
+
const vite = resolveViteConfig(viteConfig({ vite: {} }), "development");
|
|
29
|
+
expect(vite.base).toBeUndefined();
|
|
30
|
+
expect(vite.build?.outDir).toBe("../build/resources/main/ui");
|
|
31
|
+
expect(vite.build?.lib).toMatchObject({
|
|
32
|
+
entry: "src/index.ts",
|
|
33
|
+
name: "fake-plugin",
|
|
34
|
+
formats: ["iife"],
|
|
35
|
+
cssFileName: "style",
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
const rsbuild = resolveRsbuildConfig(
|
|
39
|
+
rsbuildConfig({ rsbuild: {} }),
|
|
40
|
+
"development"
|
|
41
|
+
);
|
|
42
|
+
expect(rsbuild.output?.distPath?.root).toBe("../build/resources/main/ui");
|
|
43
|
+
expect(rsbuild.tools?.rspack?.output?.publicPath).toBe(
|
|
44
|
+
"/plugins/fake-plugin/assets/ui/"
|
|
45
|
+
);
|
|
46
|
+
expect(rsbuild.tools?.rspack?.output?.library).toMatchObject({
|
|
47
|
+
type: "window",
|
|
48
|
+
export: "default",
|
|
49
|
+
name: "fake-plugin",
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
const productionVite = resolveViteConfig(viteConfig({ vite: {} }));
|
|
53
|
+
expect(productionVite.build?.outDir).toBe("./build/dist");
|
|
54
|
+
|
|
55
|
+
const productionRsbuild = resolveRsbuildConfig(
|
|
56
|
+
rsbuildConfig({ rsbuild: {} })
|
|
57
|
+
);
|
|
58
|
+
expect(productionRsbuild.output?.distPath?.root).toBe("./build/dist");
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it("keeps plugin provider defaults when provider is explicit", () => {
|
|
62
|
+
const uiDir = setupPluginProject();
|
|
63
|
+
process.chdir(uiDir);
|
|
64
|
+
|
|
65
|
+
const vite = resolveViteConfig(
|
|
66
|
+
viteConfig({ provider: "plugin", vite: {} }),
|
|
67
|
+
"development"
|
|
68
|
+
);
|
|
69
|
+
expect(vite.build?.outDir).toBe("../build/resources/main/ui");
|
|
70
|
+
|
|
71
|
+
const rsbuild = resolveRsbuildConfig(
|
|
72
|
+
rsbuildConfig({ provider: "plugin", rsbuild: {} }),
|
|
73
|
+
"development"
|
|
74
|
+
);
|
|
75
|
+
expect(rsbuild.tools?.rspack?.output?.publicPath).toBe(
|
|
76
|
+
"/plugins/fake-plugin/assets/ui/"
|
|
77
|
+
);
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
it("uses custom manifest paths for plugin and theme providers", () => {
|
|
81
|
+
const projectRoot = createTempDir();
|
|
82
|
+
const pluginManifestPath = path.join(projectRoot, "custom-plugin.yaml");
|
|
83
|
+
const themeManifestPath = path.join(projectRoot, "custom-theme.yaml");
|
|
84
|
+
fs.writeFileSync(
|
|
85
|
+
pluginManifestPath,
|
|
86
|
+
[
|
|
87
|
+
"metadata:",
|
|
88
|
+
" name: custom-plugin",
|
|
89
|
+
"spec:",
|
|
90
|
+
" requires: '>=2.25.0'",
|
|
91
|
+
"",
|
|
92
|
+
].join("\n")
|
|
93
|
+
);
|
|
94
|
+
fs.writeFileSync(
|
|
95
|
+
themeManifestPath,
|
|
96
|
+
["metadata:", " name: custom-theme", ""].join("\n")
|
|
97
|
+
);
|
|
98
|
+
|
|
99
|
+
const pluginConfig = resolveViteConfig(
|
|
100
|
+
viteConfig({
|
|
101
|
+
manifestPath: pluginManifestPath,
|
|
102
|
+
vite: {},
|
|
103
|
+
})
|
|
104
|
+
);
|
|
105
|
+
expect(pluginConfig.build?.lib).toMatchObject({
|
|
106
|
+
name: "custom-plugin",
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
const themeConfig = resolveRsbuildConfig(
|
|
110
|
+
rsbuildConfig({
|
|
111
|
+
provider: "theme",
|
|
112
|
+
manifestPath: themeManifestPath,
|
|
113
|
+
rsbuild: {},
|
|
114
|
+
})
|
|
115
|
+
);
|
|
116
|
+
expect(themeConfig.tools?.rspack?.output?.publicPath).toBe(
|
|
117
|
+
"/themes/custom-theme/ui-plugin/assets/"
|
|
118
|
+
);
|
|
119
|
+
expect(themeConfig.tools?.rspack?.output?.library).toMatchObject({
|
|
120
|
+
name: "theme:custom-theme",
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
it("generates Vite theme provider defaults", () => {
|
|
125
|
+
const uiPluginDir = setupThemeProject();
|
|
126
|
+
process.chdir(uiPluginDir);
|
|
127
|
+
|
|
128
|
+
const config = resolveViteConfig(
|
|
129
|
+
viteConfig({ provider: "theme", vite: {} })
|
|
130
|
+
);
|
|
131
|
+
|
|
132
|
+
expect(config.base).toBe("/themes/earth/ui-plugin/assets/");
|
|
133
|
+
expect(config.build?.outDir).toBe("dist");
|
|
134
|
+
expect(config.build?.lib).toMatchObject({
|
|
135
|
+
entry: "src/index.ts",
|
|
136
|
+
name: "theme:earth",
|
|
137
|
+
formats: ["iife"],
|
|
138
|
+
cssFileName: "style",
|
|
139
|
+
});
|
|
140
|
+
expect(config.build?.rollupOptions?.external).toContain("vue");
|
|
141
|
+
expect(config.build?.rollupOptions?.output).toMatchObject({
|
|
142
|
+
globals: expect.objectContaining({
|
|
143
|
+
vue: "Vue",
|
|
144
|
+
}),
|
|
145
|
+
extend: true,
|
|
146
|
+
});
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
it("generates Rsbuild theme provider defaults", () => {
|
|
150
|
+
const uiPluginDir = setupThemeProject();
|
|
151
|
+
process.chdir(uiPluginDir);
|
|
152
|
+
|
|
153
|
+
const config = resolveRsbuildConfig(
|
|
154
|
+
rsbuildConfig({ provider: "theme", rsbuild: {} })
|
|
155
|
+
);
|
|
156
|
+
|
|
157
|
+
expect(config.output?.distPath?.root).toBe("dist");
|
|
158
|
+
expect(config.output?.filename?.js).toBeDefined();
|
|
159
|
+
expect(config.output?.filename?.css).toBeDefined();
|
|
160
|
+
expect(config.output?.externals).toMatchObject({
|
|
161
|
+
vue: "Vue",
|
|
162
|
+
});
|
|
163
|
+
expect(config.tools?.rspack?.output?.publicPath).toBe(
|
|
164
|
+
"/themes/earth/ui-plugin/assets/"
|
|
165
|
+
);
|
|
166
|
+
expect(config.tools?.rspack?.output?.library).toMatchObject({
|
|
167
|
+
type: "window",
|
|
168
|
+
export: "default",
|
|
169
|
+
name: "theme:earth",
|
|
170
|
+
});
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
it("merges user config after provider defaults", () => {
|
|
174
|
+
const uiPluginDir = setupThemeProject();
|
|
175
|
+
process.chdir(uiPluginDir);
|
|
176
|
+
|
|
177
|
+
const vite = resolveViteConfig(
|
|
178
|
+
viteConfig({
|
|
179
|
+
provider: "theme",
|
|
180
|
+
vite: {
|
|
181
|
+
base: "/custom/",
|
|
182
|
+
build: {
|
|
183
|
+
outDir: "custom-dist",
|
|
184
|
+
},
|
|
185
|
+
},
|
|
186
|
+
})
|
|
187
|
+
);
|
|
188
|
+
expect(vite.base).toBe("/custom/");
|
|
189
|
+
expect(vite.build?.outDir).toBe("custom-dist");
|
|
190
|
+
|
|
191
|
+
const rsbuild = resolveRsbuildConfig(
|
|
192
|
+
rsbuildConfig({
|
|
193
|
+
provider: "theme",
|
|
194
|
+
rsbuild: {
|
|
195
|
+
output: {
|
|
196
|
+
distPath: {
|
|
197
|
+
root: "custom-dist",
|
|
198
|
+
},
|
|
199
|
+
},
|
|
200
|
+
tools: {
|
|
201
|
+
rspack: {
|
|
202
|
+
output: {
|
|
203
|
+
publicPath: "/custom/",
|
|
204
|
+
},
|
|
205
|
+
},
|
|
206
|
+
},
|
|
207
|
+
},
|
|
208
|
+
})
|
|
209
|
+
);
|
|
210
|
+
expect(rsbuild.output?.distPath?.root).toBe("custom-dist");
|
|
211
|
+
expect(rsbuild.tools?.rspack?.output?.publicPath).toBe("/custom/");
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
it("merges function user config after provider defaults", () => {
|
|
215
|
+
const uiPluginDir = setupThemeProject();
|
|
216
|
+
process.chdir(uiPluginDir);
|
|
217
|
+
|
|
218
|
+
const vite = resolveViteConfig(
|
|
219
|
+
viteConfig({
|
|
220
|
+
provider: "theme",
|
|
221
|
+
vite: ({ mode }) => ({
|
|
222
|
+
define: {
|
|
223
|
+
__MODE__: JSON.stringify(mode),
|
|
224
|
+
},
|
|
225
|
+
}),
|
|
226
|
+
})
|
|
227
|
+
);
|
|
228
|
+
expect(vite.define).toMatchObject({
|
|
229
|
+
"process.env.NODE_ENV": "'production'",
|
|
230
|
+
__MODE__: '"production"',
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
const rsbuild = resolveRsbuildConfig(
|
|
234
|
+
rsbuildConfig({
|
|
235
|
+
provider: "theme",
|
|
236
|
+
rsbuild: ({ envMode }) => ({
|
|
237
|
+
output: {
|
|
238
|
+
filename: {
|
|
239
|
+
js: `custom-${envMode}.js`,
|
|
240
|
+
},
|
|
241
|
+
},
|
|
242
|
+
}),
|
|
243
|
+
})
|
|
244
|
+
);
|
|
245
|
+
expect(rsbuild.output?.filename?.js).toBe("custom-production.js");
|
|
246
|
+
});
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
function setupPluginProject() {
|
|
250
|
+
const projectRoot = createTempDir();
|
|
251
|
+
const uiDir = path.join(projectRoot, "ui");
|
|
252
|
+
fs.mkdirSync(path.join(projectRoot, "src/main/resources"), {
|
|
253
|
+
recursive: true,
|
|
254
|
+
});
|
|
255
|
+
fs.mkdirSync(uiDir, { recursive: true });
|
|
256
|
+
fs.writeFileSync(
|
|
257
|
+
path.join(projectRoot, "src/main/resources/plugin.yaml"),
|
|
258
|
+
[
|
|
259
|
+
"metadata:",
|
|
260
|
+
" name: fake-plugin",
|
|
261
|
+
"spec:",
|
|
262
|
+
" requires: '>=2.25.0'",
|
|
263
|
+
"",
|
|
264
|
+
].join("\n")
|
|
265
|
+
);
|
|
266
|
+
return uiDir;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
function setupThemeProject() {
|
|
270
|
+
const projectRoot = createTempDir();
|
|
271
|
+
const uiPluginDir = path.join(projectRoot, "ui-plugin");
|
|
272
|
+
fs.mkdirSync(uiPluginDir, { recursive: true });
|
|
273
|
+
fs.writeFileSync(
|
|
274
|
+
path.join(projectRoot, "theme.yaml"),
|
|
275
|
+
["metadata:", " name: earth", ""].join("\n")
|
|
276
|
+
);
|
|
277
|
+
return uiPluginDir;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
function createTempDir() {
|
|
281
|
+
const tempDir = fs.mkdtempSync(
|
|
282
|
+
path.join(os.tmpdir(), "halo-ui-plugin-bundler-kit-")
|
|
283
|
+
);
|
|
284
|
+
tempDirs.push(tempDir);
|
|
285
|
+
return tempDir;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
function resolveViteConfig(config: unknown, mode = "production") {
|
|
289
|
+
return (config as (env: ConfigEnv) => UserConfig)({
|
|
290
|
+
command: "build",
|
|
291
|
+
mode,
|
|
292
|
+
isSsrBuild: false,
|
|
293
|
+
isPreview: false,
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
function resolveRsbuildConfig(config: unknown, envMode = "production") {
|
|
298
|
+
return (config as (env: ConfigParams) => RsbuildConfig)({
|
|
299
|
+
envMode,
|
|
300
|
+
} as ConfigParams);
|
|
301
|
+
}
|
package/src/constants/build.ts
CHANGED
|
@@ -1,4 +1,15 @@
|
|
|
1
1
|
const DEFAULT_OUT_DIR_DEV = "../build/resources/main/console";
|
|
2
|
+
const DEFAULT_OUT_DIR_DEV_BASE = "../build/resources/main";
|
|
2
3
|
const DEFAULT_OUT_DIR_PROD = "./build/dist";
|
|
4
|
+
const DEFAULT_THEME_OUT_DIR = "dist";
|
|
3
5
|
|
|
4
|
-
|
|
6
|
+
function getDefaultOutDirDev(bundleLocation: string) {
|
|
7
|
+
return `${DEFAULT_OUT_DIR_DEV_BASE}/${bundleLocation}`;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export {
|
|
11
|
+
DEFAULT_OUT_DIR_DEV,
|
|
12
|
+
DEFAULT_OUT_DIR_PROD,
|
|
13
|
+
DEFAULT_THEME_OUT_DIR,
|
|
14
|
+
getDefaultOutDirDev,
|
|
15
|
+
};
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
-
const
|
|
1
|
+
const DEFAULT_PLUGIN_MANIFEST_PATH = "../src/main/resources/plugin.yaml";
|
|
2
|
+
const DEFAULT_THEME_MANIFEST_PATH = "../theme.yaml";
|
|
3
|
+
const DEFAULT_MANIFEST_PATH = DEFAULT_PLUGIN_MANIFEST_PATH;
|
|
2
4
|
|
|
3
|
-
export {
|
|
5
|
+
export {
|
|
6
|
+
DEFAULT_MANIFEST_PATH,
|
|
7
|
+
DEFAULT_PLUGIN_MANIFEST_PATH,
|
|
8
|
+
DEFAULT_THEME_MANIFEST_PATH,
|
|
9
|
+
};
|
package/src/rsbuild.ts
CHANGED
|
@@ -6,16 +6,39 @@ import {
|
|
|
6
6
|
type RsbuildMode,
|
|
7
7
|
} from "@rsbuild/core";
|
|
8
8
|
import { pluginVue } from "@rsbuild/plugin-vue";
|
|
9
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
DEFAULT_OUT_DIR_PROD,
|
|
11
|
+
DEFAULT_THEME_OUT_DIR,
|
|
12
|
+
getDefaultOutDirDev,
|
|
13
|
+
} from "./constants/build";
|
|
10
14
|
import { GLOBALS } from "./constants/externals";
|
|
11
|
-
import {
|
|
12
|
-
|
|
15
|
+
import {
|
|
16
|
+
DEFAULT_PLUGIN_MANIFEST_PATH,
|
|
17
|
+
DEFAULT_THEME_MANIFEST_PATH,
|
|
18
|
+
} from "./constants/halo-plugin";
|
|
19
|
+
import {
|
|
20
|
+
getHaloPluginBundleLocation,
|
|
21
|
+
getHaloPluginManifest,
|
|
22
|
+
getHaloThemeAssetPublicPath,
|
|
23
|
+
getHaloThemeManifest,
|
|
24
|
+
getHaloThemeModuleName,
|
|
25
|
+
getManifestName,
|
|
26
|
+
} from "./utils/halo-plugin";
|
|
27
|
+
|
|
28
|
+
type Provider = "plugin" | "theme";
|
|
13
29
|
|
|
14
30
|
export interface RsBuildUserConfig {
|
|
15
31
|
/**
|
|
16
|
-
*
|
|
32
|
+
* UI plugin provider type.
|
|
33
|
+
*
|
|
34
|
+
* @default "plugin"
|
|
35
|
+
*/
|
|
36
|
+
provider?: "plugin" | "theme";
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Halo plugin or theme manifest path.
|
|
17
40
|
*
|
|
18
|
-
* @default "../src/main/resources/plugin.yaml"
|
|
41
|
+
* @default "../src/main/resources/plugin.yaml" for plugins, "../theme.yaml" for themes
|
|
19
42
|
*/
|
|
20
43
|
manifestPath?: string;
|
|
21
44
|
|
|
@@ -25,13 +48,16 @@ export interface RsBuildUserConfig {
|
|
|
25
48
|
rsbuild: RsbuildConfig | ((env: ConfigParams) => RsbuildConfig);
|
|
26
49
|
}
|
|
27
50
|
|
|
28
|
-
function createRsbuildPresetsConfig(manifestPath: string) {
|
|
29
|
-
const
|
|
51
|
+
function createRsbuildPresetsConfig(provider: Provider, manifestPath: string) {
|
|
52
|
+
const defaults =
|
|
53
|
+
provider === "theme"
|
|
54
|
+
? getThemeProviderDefaults(manifestPath)
|
|
55
|
+
: getPluginProviderDefaults(manifestPath);
|
|
30
56
|
|
|
31
57
|
return defineConfig(({ envMode }) => {
|
|
32
58
|
const isProduction = envMode === "production";
|
|
33
59
|
|
|
34
|
-
const outDir = isProduction ?
|
|
60
|
+
const outDir = isProduction ? defaults.outDir.prod : defaults.outDir.dev;
|
|
35
61
|
|
|
36
62
|
return {
|
|
37
63
|
mode: (envMode as RsbuildMode) || "production",
|
|
@@ -72,11 +98,11 @@ function createRsbuildPresetsConfig(manifestPath: string) {
|
|
|
72
98
|
},
|
|
73
99
|
},
|
|
74
100
|
output: {
|
|
75
|
-
publicPath:
|
|
101
|
+
publicPath: defaults.publicPath,
|
|
76
102
|
library: {
|
|
77
103
|
type: "window",
|
|
78
104
|
export: "default",
|
|
79
|
-
name:
|
|
105
|
+
name: defaults.moduleName,
|
|
80
106
|
},
|
|
81
107
|
globalObject: "window",
|
|
82
108
|
iife: true,
|
|
@@ -113,6 +139,46 @@ function createRsbuildPresetsConfig(manifestPath: string) {
|
|
|
113
139
|
});
|
|
114
140
|
}
|
|
115
141
|
|
|
142
|
+
function getPluginProviderDefaults(manifestPath: string) {
|
|
143
|
+
const manifest = getHaloPluginManifest(manifestPath);
|
|
144
|
+
const bundleLocation = getHaloPluginBundleLocation(manifest);
|
|
145
|
+
|
|
146
|
+
return {
|
|
147
|
+
moduleName: getManifestName(manifest),
|
|
148
|
+
outDir: {
|
|
149
|
+
prod: DEFAULT_OUT_DIR_PROD,
|
|
150
|
+
dev: getDefaultOutDirDev(bundleLocation),
|
|
151
|
+
},
|
|
152
|
+
publicPath: `/plugins/${getManifestName(manifest)}/assets/${bundleLocation}/`,
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
function getThemeProviderDefaults(manifestPath: string) {
|
|
157
|
+
const manifest = getHaloThemeManifest(manifestPath);
|
|
158
|
+
|
|
159
|
+
return {
|
|
160
|
+
moduleName: getHaloThemeModuleName(manifest),
|
|
161
|
+
outDir: {
|
|
162
|
+
prod: DEFAULT_THEME_OUT_DIR,
|
|
163
|
+
dev: DEFAULT_THEME_OUT_DIR,
|
|
164
|
+
},
|
|
165
|
+
publicPath: getHaloThemeAssetPublicPath(manifest),
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
function getProvider(config?: RsBuildUserConfig): Provider {
|
|
170
|
+
return config?.provider || "plugin";
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
function getManifestPath(provider: Provider, config?: RsBuildUserConfig) {
|
|
174
|
+
if (config?.manifestPath) {
|
|
175
|
+
return config.manifestPath;
|
|
176
|
+
}
|
|
177
|
+
return provider === "theme"
|
|
178
|
+
? DEFAULT_THEME_MANIFEST_PATH
|
|
179
|
+
: DEFAULT_PLUGIN_MANIFEST_PATH;
|
|
180
|
+
}
|
|
181
|
+
|
|
116
182
|
/**
|
|
117
183
|
* Rsbuild config for Halo UI Plugin.
|
|
118
184
|
*
|
|
@@ -132,8 +198,10 @@ function createRsbuildPresetsConfig(manifestPath: string) {
|
|
|
132
198
|
export function rsbuildConfig(
|
|
133
199
|
config?: RsBuildUserConfig
|
|
134
200
|
): (env: ConfigParams) => RsbuildConfig {
|
|
201
|
+
const provider = getProvider(config);
|
|
135
202
|
const presetsConfigFn = createRsbuildPresetsConfig(
|
|
136
|
-
|
|
203
|
+
provider,
|
|
204
|
+
getManifestPath(provider, config)
|
|
137
205
|
);
|
|
138
206
|
return defineConfig((env) => {
|
|
139
207
|
const presetsConfig = presetsConfigFn(env);
|
package/src/utils/halo-plugin.ts
CHANGED
|
@@ -1,11 +1,67 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import type { Plugin as HaloPlugin } from "@halo-dev/api-client";
|
|
3
3
|
import yaml from "js-yaml";
|
|
4
|
+
import { gte, minVersion } from "semver";
|
|
5
|
+
|
|
6
|
+
const UI_BUNDLE_MIN_HALO_VERSION = "2.25.0";
|
|
7
|
+
const UI_BUNDLE_LOCATION = "ui";
|
|
8
|
+
const CONSOLE_BUNDLE_LOCATION = "console";
|
|
9
|
+
const THEME_MODULE_NAME_PREFIX = "theme:";
|
|
10
|
+
|
|
11
|
+
interface HaloThemeManifest {
|
|
12
|
+
metadata: {
|
|
13
|
+
name: string;
|
|
14
|
+
};
|
|
15
|
+
}
|
|
4
16
|
|
|
5
17
|
export function getHaloPluginManifest(manifestPath: string) {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
18
|
+
return readManifest<HaloPlugin>(manifestPath);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function getHaloThemeManifest(manifestPath: string) {
|
|
22
|
+
return readManifest<HaloThemeManifest>(manifestPath);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function getManifestName(
|
|
26
|
+
manifest: Pick<HaloPlugin, "metadata"> | HaloThemeManifest
|
|
27
|
+
) {
|
|
28
|
+
return manifest.metadata.name;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function getHaloThemeModuleName(manifest: HaloThemeManifest) {
|
|
32
|
+
return `${THEME_MODULE_NAME_PREFIX}${getManifestName(manifest)}`;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function getHaloThemeAssetPublicPath(manifest: HaloThemeManifest) {
|
|
36
|
+
return `/themes/${getManifestName(manifest)}/ui-plugin/assets/`;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function getHaloPluginBundleLocation(manifest: HaloPlugin) {
|
|
40
|
+
const requiresMinVersion = getRequiresMinVersion(manifest.spec.requires);
|
|
41
|
+
return requiresMinVersion &&
|
|
42
|
+
gte(requiresMinVersion, UI_BUNDLE_MIN_HALO_VERSION)
|
|
43
|
+
? UI_BUNDLE_LOCATION
|
|
44
|
+
: CONSOLE_BUNDLE_LOCATION;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function getRequiresMinVersion(requires: string | undefined) {
|
|
48
|
+
const normalizedRequires = requires?.trim();
|
|
49
|
+
|
|
50
|
+
if (!normalizedRequires) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
try {
|
|
55
|
+
return minVersion(normalizedRequires);
|
|
56
|
+
} catch {
|
|
57
|
+
console.warn(
|
|
58
|
+
`[ui-plugin-bundler-kit] Invalid semver range in plugin manifest "spec.requires": "${requires}". ` +
|
|
59
|
+
`Falling back to "${CONSOLE_BUNDLE_LOCATION}" bundle location.`
|
|
60
|
+
);
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
9
64
|
|
|
10
|
-
|
|
65
|
+
function readManifest<T>(manifestPath: string) {
|
|
66
|
+
return yaml.load(fs.readFileSync(manifestPath, "utf8")) as T;
|
|
11
67
|
}
|
package/src/vite.ts
CHANGED
|
@@ -5,16 +5,39 @@ import {
|
|
|
5
5
|
UserConfig,
|
|
6
6
|
UserConfigFnObject,
|
|
7
7
|
} from "vite";
|
|
8
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
DEFAULT_OUT_DIR_PROD,
|
|
10
|
+
DEFAULT_THEME_OUT_DIR,
|
|
11
|
+
getDefaultOutDirDev,
|
|
12
|
+
} from "./constants/build";
|
|
9
13
|
import { EXTERNALS, GLOBALS } from "./constants/externals";
|
|
10
|
-
import {
|
|
11
|
-
|
|
14
|
+
import {
|
|
15
|
+
DEFAULT_PLUGIN_MANIFEST_PATH,
|
|
16
|
+
DEFAULT_THEME_MANIFEST_PATH,
|
|
17
|
+
} from "./constants/halo-plugin";
|
|
18
|
+
import {
|
|
19
|
+
getHaloPluginBundleLocation,
|
|
20
|
+
getHaloPluginManifest,
|
|
21
|
+
getHaloThemeAssetPublicPath,
|
|
22
|
+
getHaloThemeManifest,
|
|
23
|
+
getHaloThemeModuleName,
|
|
24
|
+
getManifestName,
|
|
25
|
+
} from "./utils/halo-plugin";
|
|
26
|
+
|
|
27
|
+
type Provider = "plugin" | "theme";
|
|
12
28
|
|
|
13
29
|
export interface ViteUserConfig {
|
|
14
30
|
/**
|
|
15
|
-
*
|
|
31
|
+
* UI plugin provider type.
|
|
32
|
+
*
|
|
33
|
+
* @default "plugin"
|
|
34
|
+
*/
|
|
35
|
+
provider?: "plugin" | "theme";
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Halo plugin or theme manifest path.
|
|
16
39
|
*
|
|
17
|
-
* @default "../src/main/resources/plugin.yaml"
|
|
40
|
+
* @default "../src/main/resources/plugin.yaml" for plugins, "../theme.yaml" for themes
|
|
18
41
|
*/
|
|
19
42
|
manifestPath?: string;
|
|
20
43
|
|
|
@@ -24,22 +47,26 @@ export interface ViteUserConfig {
|
|
|
24
47
|
vite: UserConfig | UserConfigFnObject;
|
|
25
48
|
}
|
|
26
49
|
|
|
27
|
-
function createVitePresetsConfig(manifestPath: string) {
|
|
28
|
-
const
|
|
50
|
+
function createVitePresetsConfig(provider: Provider, manifestPath: string) {
|
|
51
|
+
const defaults =
|
|
52
|
+
provider === "theme"
|
|
53
|
+
? getThemeProviderDefaults(manifestPath)
|
|
54
|
+
: getPluginProviderDefaults(manifestPath);
|
|
29
55
|
|
|
30
56
|
return defineConfig(({ mode }) => {
|
|
31
57
|
const isProduction = mode === "production";
|
|
32
58
|
|
|
33
59
|
return {
|
|
34
60
|
mode: mode || "production",
|
|
61
|
+
base: defaults.base,
|
|
35
62
|
plugins: [Vue()],
|
|
36
63
|
define: { "process.env.NODE_ENV": "'production'" },
|
|
37
64
|
build: {
|
|
38
|
-
outDir: isProduction ?
|
|
65
|
+
outDir: isProduction ? defaults.outDir.prod : defaults.outDir.dev,
|
|
39
66
|
emptyOutDir: true,
|
|
40
67
|
lib: {
|
|
41
68
|
entry: "src/index.ts",
|
|
42
|
-
name:
|
|
69
|
+
name: defaults.moduleName,
|
|
43
70
|
formats: ["iife"],
|
|
44
71
|
fileName: () => "main.js",
|
|
45
72
|
cssFileName: "style",
|
|
@@ -56,6 +83,46 @@ function createVitePresetsConfig(manifestPath: string) {
|
|
|
56
83
|
});
|
|
57
84
|
}
|
|
58
85
|
|
|
86
|
+
function getPluginProviderDefaults(manifestPath: string) {
|
|
87
|
+
const manifest = getHaloPluginManifest(manifestPath);
|
|
88
|
+
const bundleLocation = getHaloPluginBundleLocation(manifest);
|
|
89
|
+
|
|
90
|
+
return {
|
|
91
|
+
moduleName: getManifestName(manifest),
|
|
92
|
+
outDir: {
|
|
93
|
+
prod: DEFAULT_OUT_DIR_PROD,
|
|
94
|
+
dev: getDefaultOutDirDev(bundleLocation),
|
|
95
|
+
},
|
|
96
|
+
base: undefined,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function getThemeProviderDefaults(manifestPath: string) {
|
|
101
|
+
const manifest = getHaloThemeManifest(manifestPath);
|
|
102
|
+
|
|
103
|
+
return {
|
|
104
|
+
moduleName: getHaloThemeModuleName(manifest),
|
|
105
|
+
outDir: {
|
|
106
|
+
prod: DEFAULT_THEME_OUT_DIR,
|
|
107
|
+
dev: DEFAULT_THEME_OUT_DIR,
|
|
108
|
+
},
|
|
109
|
+
base: getHaloThemeAssetPublicPath(manifest),
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function getProvider(config?: ViteUserConfig): Provider {
|
|
114
|
+
return config?.provider || "plugin";
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
function getManifestPath(provider: Provider, config?: ViteUserConfig) {
|
|
118
|
+
if (config?.manifestPath) {
|
|
119
|
+
return config.manifestPath;
|
|
120
|
+
}
|
|
121
|
+
return provider === "theme"
|
|
122
|
+
? DEFAULT_THEME_MANIFEST_PATH
|
|
123
|
+
: DEFAULT_PLUGIN_MANIFEST_PATH;
|
|
124
|
+
}
|
|
125
|
+
|
|
59
126
|
/**
|
|
60
127
|
* Vite config for Halo UI Plugin.
|
|
61
128
|
*
|
|
@@ -71,8 +138,10 @@ function createVitePresetsConfig(manifestPath: string) {
|
|
|
71
138
|
* ```
|
|
72
139
|
*/
|
|
73
140
|
export function viteConfig(config?: ViteUserConfig) {
|
|
141
|
+
const provider = getProvider(config);
|
|
74
142
|
const presetsConfigFn = createVitePresetsConfig(
|
|
75
|
-
|
|
143
|
+
provider,
|
|
144
|
+
getManifestPath(provider, config)
|
|
76
145
|
);
|
|
77
146
|
return defineConfig((env) => {
|
|
78
147
|
const presetsConfig = presetsConfigFn(env);
|