@hyacine/vite 0.0.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/package.json ADDED
@@ -0,0 +1,38 @@
1
+ {
2
+ "name": "@hyacine/vite",
3
+ "version": "0.0.1",
4
+ "files": [
5
+ "dist",
6
+ "src"
7
+ ],
8
+ "type": "module",
9
+ "typesVersions": {
10
+ "*": {
11
+ "*": [
12
+ "./src/virtual-modules.d.ts"
13
+ ]
14
+ }
15
+ },
16
+ "exports": {
17
+ ".": {
18
+ "types": "./src/index.ts",
19
+ "default": "./src/index.ts"
20
+ }
21
+ },
22
+ "scripts": {
23
+ "build": "tsc",
24
+ "lint": "bunx --bun oxlint --type-aware --type-check . --fix",
25
+ "format": "bunx oxfmt ."
26
+ },
27
+ "dependencies": {
28
+ "@hyacine/core": "workspace:*",
29
+ "@hyacine/helper": "workspace:*"
30
+ },
31
+ "devDependencies": {
32
+ "typescript": "^5",
33
+ "vite": "^7.3.1"
34
+ },
35
+ "peerDependencies": {
36
+ "vite": "^5.0.0 || ^6.0.0 || ^7.0.0"
37
+ }
38
+ }
@@ -0,0 +1,187 @@
1
+ import type { Plugin as VitePlugin } from "vite";
2
+ import { existsSync } from "node:fs";
3
+ import { join } from "node:path";
4
+ import { pathToFileURL } from "node:url";
5
+ import type { HyacinePluginSystemConfig } from "@hyacine/core";
6
+ import type { PluginManifest, RuntimeOnlyEntry } from "@hyacine/core";
7
+ import {
8
+ CONFIG_FILE_NAMES,
9
+ collectRuntimeOnlyEntries,
10
+ findConfigFilePath,
11
+ generateTempRuntimeFile,
12
+ getPluginManifests,
13
+ } from "@hyacine/helper";
14
+
15
+ // 虚拟模块 ID 常量
16
+ const RUNTIME_VIRTUAL_ID = "virtual:hyacine/runtime";
17
+ const RUNTIME_RESOLVED_ID = "\0virtual:hyacine/runtime";
18
+
19
+ /**
20
+ * 读取插件配置文件
21
+ * 支持 hyacine.plugin.ts 和 hyacine.plugin.mjs
22
+ * @param rootPath 项目根目录路径
23
+ * @param bypassCache 是否绕过模块缓存(开发模式 HMR 时使用)
24
+ */
25
+ async function loadPluginConfig(
26
+ rootPath: string,
27
+ bypassCache = false,
28
+ ): Promise<HyacinePluginSystemConfig | null> {
29
+ const configPath = findConfigFilePath(rootPath);
30
+
31
+ if (!configPath) {
32
+ console.warn("[hyacine-vite] 未找到插件配置文件 (hyacine.plugin.ts 或 .mjs)");
33
+ return null;
34
+ }
35
+
36
+ try {
37
+ // 使用原生动态导入加载配置文件
38
+ let configUrl = pathToFileURL(configPath).href;
39
+ if (bypassCache) {
40
+ configUrl = `${configUrl}?t=${Date.now()}`;
41
+ }
42
+ const configModule = await import(/* @vite-ignore */ configUrl);
43
+
44
+ const moduleAsRecord = configModule as Record<string, unknown>;
45
+ const config = moduleAsRecord.default as HyacinePluginSystemConfig;
46
+
47
+ if (!config || !config.plugins) {
48
+ console.warn("[hyacine-vite] 配置文件格式无效,缺少 plugins 字段");
49
+ return null;
50
+ }
51
+
52
+ return config;
53
+ } catch (error) {
54
+ console.error("[hyacine-vite] 加载配置文件失败:", error);
55
+ return null;
56
+ }
57
+ }
58
+
59
+ /**
60
+ * 收集所有 runtime-only 类型的 entry,并对非 runtime-only entry 发出警告
61
+ */
62
+ function getRuntimeOnlyEntries(manifests: PluginManifest[]): RuntimeOnlyEntry[] {
63
+ // 检查非 runtime-only entries 并发出警告
64
+ for (const manifest of manifests) {
65
+ for (const entry of manifest.entry) {
66
+ if (entry.type !== "runtime-only") {
67
+ console.warn(
68
+ `[hyacine-vite] 警告: 插件 "${manifest.name}" 包含非 Runtime-Only Entry (type: "${entry.type}", name: "${entry.name}"),Vite 集成仅支持 Runtime-Only 插件,该 Entry 将被忽略`,
69
+ );
70
+ }
71
+ }
72
+ }
73
+
74
+ return collectRuntimeOnlyEntries(manifests);
75
+ }
76
+
77
+ export interface HyacineVitePluginOptions {
78
+ /**
79
+ * 项目根目录路径
80
+ * 如果未提供,将使用 process.cwd()
81
+ */
82
+ root?: string;
83
+ }
84
+
85
+ /**
86
+ * Hyacine 插件系统 Vite 集成
87
+ * 仅支持 Runtime-Only 插件
88
+ */
89
+ export default function hyacineVitePlugin(options: HyacineVitePluginOptions = {}): VitePlugin {
90
+ const rootPath = options.root ?? process.cwd();
91
+ const configFiles = CONFIG_FILE_NAMES;
92
+
93
+ // 缓存配置和 manifests
94
+ let cachedConfig: HyacinePluginSystemConfig | null = null;
95
+ let cachedManifests: PluginManifest[] | null = null;
96
+
97
+ return {
98
+ name: "vite-plugin-hyacine",
99
+ enforce: "pre",
100
+
101
+ async configResolved() {
102
+ // 在 Vite 配置解析后加载插件配置
103
+ const pluginConfig = await loadPluginConfig(rootPath, false);
104
+ if (pluginConfig) {
105
+ cachedConfig = pluginConfig;
106
+ cachedManifests = getPluginManifests(pluginConfig);
107
+
108
+ // 检查是否有非 runtime-only entries 并发出警告
109
+ getRuntimeOnlyEntries(cachedManifests);
110
+
111
+ console.info(`[hyacine-vite] 已加载 ${cachedManifests.length} 个插件`);
112
+ }
113
+ },
114
+
115
+ resolveId(id: string) {
116
+ if (id === RUNTIME_VIRTUAL_ID) {
117
+ return RUNTIME_RESOLVED_ID;
118
+ }
119
+ return null;
120
+ },
121
+
122
+ load(id: string) {
123
+ if (id !== RUNTIME_RESOLVED_ID) {
124
+ return null;
125
+ }
126
+
127
+ if (!cachedConfig || !cachedManifests) {
128
+ return null;
129
+ }
130
+
131
+ const runtimeEntries = getRuntimeOnlyEntries(cachedManifests);
132
+ return generateTempRuntimeFile(runtimeEntries, cachedConfig.injectPoints);
133
+ },
134
+
135
+ configureServer(server: any) {
136
+ // 监听配置文件变化
137
+ for (const fileName of configFiles) {
138
+ const configPath = join(rootPath, fileName);
139
+ if (existsSync(configPath)) {
140
+ server.watcher.add(configPath);
141
+ }
142
+ }
143
+
144
+ server.watcher.on("change", async (filePath: string) => {
145
+ const isPluginConfig = configFiles.some((name) => filePath.endsWith(name));
146
+
147
+ if (isPluginConfig) {
148
+ console.info("[hyacine-vite] 检测到配置变化,重新加载插件配置...");
149
+
150
+ try {
151
+ // 重新加载配置(绕过缓存)
152
+ const config = await loadPluginConfig(rootPath, true);
153
+ if (config) {
154
+ // 更新缓存
155
+ cachedConfig = config;
156
+ cachedManifests = getPluginManifests(config);
157
+
158
+ // 使虚拟模块失效
159
+ const mod = server.moduleGraph.getModuleById(RUNTIME_RESOLVED_ID);
160
+ if (mod) {
161
+ server.moduleGraph.invalidateModule(mod);
162
+ }
163
+
164
+ // 触发完整页面重载(HMR)
165
+ server.ws.send({
166
+ type: "full-reload",
167
+ path: "*",
168
+ });
169
+
170
+ console.info("[hyacine-vite] 配置已重新加载,页面即将刷新");
171
+ }
172
+ } catch (error) {
173
+ console.error(
174
+ `[hyacine-vite] 重新加载失败: ${error instanceof Error ? error.message : String(error)}`,
175
+ );
176
+ }
177
+ }
178
+ });
179
+ },
180
+
181
+ buildStart() {
182
+ if (!cachedConfig || !cachedManifests) {
183
+ console.warn("[hyacine-vite] 未找到有效的插件配置");
184
+ }
185
+ },
186
+ };
187
+ }
package/src/index.ts ADDED
@@ -0,0 +1,2 @@
1
+ export { default as hyacineVitePlugin } from "./hyacine-plugin";
2
+ export type { HyacineVitePluginOptions } from "./hyacine-plugin";
@@ -0,0 +1,9 @@
1
+ /**
2
+ * 虚拟模块类型声明
3
+ * Hyacine 插件系统 - Vite 集成
4
+ */
5
+
6
+ declare module "virtual:hyacine/runtime" {
7
+ // runtime 虚拟模块不导出任何内容
8
+ // 它的作用是在入口文件中初始化所有 runtime-only 插件
9
+ }