@ikkin/plugin-unocss 1.1.1 → 1.1.3

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.
@@ -31,7 +31,7 @@ var path__namespace = /*#__PURE__*/_interopNamespace(path);
31
31
 
32
32
  // plugin-unocss.ts
33
33
  var __filename$1 = url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('plugin-unocss.js', document.baseURI).href)));
34
- var __dirname$1 = path__namespace.dirname(__filename$1);
34
+ path__namespace.dirname(__filename$1);
35
35
  function pluginUnocss(options = {}) {
36
36
  const {
37
37
  unocssConfig = "./uno.config.ts",
@@ -55,16 +55,24 @@ function pluginUnocss(options = {}) {
55
55
  fullRegenerationDelay = 2e3,
56
56
  verbose = false
57
57
  } = options;
58
- const pluginDir = __dirname$1;
59
58
  let resolvedOutputPath;
60
59
  if (!outputPath) {
61
- resolvedOutputPath = path__namespace.resolve(pluginDir, "./generated/uno.css");
60
+ resolvedOutputPath = path__namespace.resolve(rootContext, "./generated/uno.css");
62
61
  } else if (path__namespace.isAbsolute(outputPath)) {
63
62
  resolvedOutputPath = outputPath;
64
63
  } else if (outputPath.startsWith("./")) {
65
64
  resolvedOutputPath = path__namespace.resolve(rootContext, outputPath);
66
65
  } else {
67
- resolvedOutputPath = path__namespace.resolve(pluginDir, outputPath);
66
+ resolvedOutputPath = path__namespace.resolve(rootContext, outputPath);
67
+ }
68
+ const outputDir = path__namespace.dirname(resolvedOutputPath);
69
+ if (!fs__namespace.existsSync(outputDir)) {
70
+ try {
71
+ fs__namespace.mkdirSync(outputDir, { recursive: true });
72
+ console.log("[UnoCSS Hybrid] Created output directory:", outputDir);
73
+ } catch (err) {
74
+ console.error("[UnoCSS Hybrid] Failed to create output directory:", err);
75
+ }
68
76
  }
69
77
  let currentCssPath = resolvedOutputPath;
70
78
  const getCssOutputPaths = (fileName) => {
@@ -122,14 +130,19 @@ function pluginUnocss(options = {}) {
122
130
  } else {
123
131
  cssPath = "/uno.css";
124
132
  }
125
- tags.headTags.unshift({
126
- tag: "link",
127
- attrs: {
128
- rel: "stylesheet",
129
- href: cssPath
130
- }
131
- });
132
- console.log(`[UnoCSS Hybrid] Auto-injected CSS link: ${cssPath}`);
133
+ const isLinkInjected = tags.headTags.some(
134
+ (tag) => tag.tag === "link" && tag.attrs && tag.attrs.href === cssPath
135
+ );
136
+ if (!isLinkInjected) {
137
+ tags.headTags.unshift({
138
+ tag: "link",
139
+ attrs: {
140
+ rel: "stylesheet",
141
+ href: cssPath
142
+ }
143
+ });
144
+ console.log(`[UnoCSS Hybrid] Auto-injected CSS link: ${cssPath}`);
145
+ }
133
146
  if (!isProd) {
134
147
  const hotReloadScript = `
135
148
  (function() {
@@ -210,21 +223,32 @@ function pluginUnocss(options = {}) {
210
223
  connect();
211
224
  })();
212
225
  `;
213
- tags.bodyTags.push({
214
- tag: "script",
215
- children: hotReloadScript
216
- });
217
- console.log("[UnoCSS Hybrid] Hot reload script injected");
226
+ const isScriptInjected = tags.bodyTags.some(
227
+ (tag) => tag.tag === "script" && tag.attrs && tag.attrs["data-unocss-hmr"]
228
+ );
229
+ if (!isScriptInjected) {
230
+ tags.bodyTags.push({
231
+ tag: "script",
232
+ attrs: { "data-unocss-hmr": "true" },
233
+ children: hotReloadScript
234
+ });
235
+ console.log("[UnoCSS Hybrid] Hot reload script injected");
236
+ }
218
237
  }
219
238
  return tags;
220
239
  });
221
240
  }
222
- const loadConfig = async () => {
241
+ let cachedConfig = null;
242
+ const loadConfig = async (reload = false) => {
243
+ if (cachedConfig && !reload) {
244
+ return cachedConfig;
245
+ }
223
246
  if (typeof unocssConfig === "string") {
224
247
  const configPath = path__namespace.resolve(rootContext, unocssConfig);
225
248
  try {
226
249
  const configModule = await import(`file:///${configPath.replace(/\\/g, "/")}`);
227
- return configModule.default || configModule;
250
+ cachedConfig = configModule.default || configModule;
251
+ return cachedConfig;
228
252
  } catch (err) {
229
253
  console.warn(
230
254
  `[UnoCSS Hybrid] Failed to load config from ${configPath}, using default config`
@@ -232,6 +256,7 @@ function pluginUnocss(options = {}) {
232
256
  return {};
233
257
  }
234
258
  }
259
+ cachedConfig = unocssConfig;
235
260
  return unocssConfig;
236
261
  };
237
262
  const getFileHash = (content) => {
@@ -257,18 +282,25 @@ function pluginUnocss(options = {}) {
257
282
  cwd: rootContext,
258
283
  absolute: true
259
284
  });
260
- const allContents = files.map((file) => {
261
- const content = fs__namespace.readFileSync(file, "utf-8");
262
- const hash = getFileHash(content);
263
- const relPath = path__namespace.relative(rootContext, file);
264
- fileContentCache.set(relPath, hash);
265
- return content;
266
- }).join("\n");
285
+ const contentPromises = files.map(async (file) => {
286
+ try {
287
+ const content = await fs__namespace.promises.readFile(file, "utf-8");
288
+ const hash = getFileHash(content);
289
+ const relPath = path__namespace.relative(rootContext, file);
290
+ fileContentCache.set(relPath, hash);
291
+ return content;
292
+ } catch (readErr) {
293
+ console.warn(`[UnoCSS Hybrid] Failed to read file ${file} during regeneration:`, readErr);
294
+ return "";
295
+ }
296
+ });
297
+ const contents = await Promise.all(contentPromises);
298
+ const allContents = contents.join("\n");
267
299
  const generator = await getGenerator(config);
268
300
  const result = await generator.generate(allContents);
269
301
  if (result.css && result.css.trim().length > 0) {
270
- fs__namespace.writeFileSync(resolvedOutputPath, result.css);
271
- const stats = fs__namespace.statSync(resolvedOutputPath);
302
+ await fs__namespace.promises.writeFile(resolvedOutputPath, result.css);
303
+ const stats = await fs__namespace.promises.stat(resolvedOutputPath);
272
304
  console.log(
273
305
  `[UnoCSS Hybrid] Full regeneration completed: ${resolvedOutputPath} (${(stats.size / 1024).toFixed(2)} KB)`
274
306
  );
@@ -303,15 +335,6 @@ function pluginUnocss(options = {}) {
303
335
  const generateCSS = async (changedFiles) => {
304
336
  try {
305
337
  const config = await loadConfig();
306
- const { globby } = await import('globby');
307
- const files = await globby(contentPatterns, {
308
- cwd: rootContext,
309
- absolute: true
310
- });
311
- if (files.length === 0) {
312
- console.warn("[UnoCSS Hybrid] No files found to scan");
313
- return resolvedOutputPath;
314
- }
315
338
  if (!isProd && changedFiles && fileContentCache.size > 0) {
316
339
  if (isFullRegenerationInProgress) {
317
340
  log("Skipping incremental update during full regeneration");
@@ -326,7 +349,7 @@ function pluginUnocss(options = {}) {
326
349
  log(`File removed: ${relPath2}`);
327
350
  continue;
328
351
  }
329
- const content = fs__namespace.readFileSync(file, "utf-8");
352
+ const content = await fs__namespace.promises.readFile(file, "utf-8");
330
353
  const hash = getFileHash(content);
331
354
  const relPath = path__namespace.relative(rootContext, file);
332
355
  if (fileContentCache.get(relPath) !== hash) {
@@ -341,7 +364,7 @@ function pluginUnocss(options = {}) {
341
364
  const changedContents = [];
342
365
  for (const file of changedFiles) {
343
366
  if (fs__namespace.existsSync(file)) {
344
- const content = fs__namespace.readFileSync(file, "utf-8");
367
+ const content = await fs__namespace.promises.readFile(file, "utf-8");
345
368
  changedContents.push(content);
346
369
  }
347
370
  }
@@ -349,12 +372,12 @@ function pluginUnocss(options = {}) {
349
372
  const result2 = await generator2.generate(changedContent);
350
373
  if (result2.css && result2.css.trim().length > 0) {
351
374
  if (fs__namespace.existsSync(resolvedOutputPath)) {
352
- fs__namespace.appendFileSync(resolvedOutputPath, "\n" + result2.css);
375
+ await fs__namespace.promises.appendFile(resolvedOutputPath, "\n" + result2.css);
353
376
  } else {
354
- fs__namespace.writeFileSync(resolvedOutputPath, result2.css);
377
+ await fs__namespace.promises.writeFile(resolvedOutputPath, result2.css);
355
378
  }
356
379
  incrementalUpdateCount++;
357
- const stats2 = fs__namespace.statSync(resolvedOutputPath);
380
+ const stats2 = await fs__namespace.promises.stat(resolvedOutputPath);
358
381
  console.log(
359
382
  `[UnoCSS Hybrid] Incremental update: ${resolvedOutputPath} (${(stats2.size / 1024).toFixed(2)} KB, update #${incrementalUpdateCount}/${incrementalThreshold})`
360
383
  );
@@ -370,14 +393,30 @@ function pluginUnocss(options = {}) {
370
393
  }
371
394
  }
372
395
  console.log("[UnoCSS Hybrid] Full CSS generation...");
396
+ const { globby } = await import('globby');
397
+ const files = await globby(contentPatterns, {
398
+ cwd: rootContext,
399
+ absolute: true
400
+ });
401
+ if (files.length === 0) {
402
+ console.warn("[UnoCSS Hybrid] No files found to scan");
403
+ return resolvedOutputPath;
404
+ }
373
405
  const generator = await getGenerator(config);
374
- const allContents = files.map((file) => {
375
- const content = fs__namespace.readFileSync(file, "utf-8");
376
- const hash = getFileHash(content);
377
- const relPath = path__namespace.relative(rootContext, file);
378
- fileContentCache.set(relPath, hash);
379
- return content;
380
- }).join("\n");
406
+ const contentPromises = files.map(async (file) => {
407
+ try {
408
+ const content = await fs__namespace.promises.readFile(file, "utf-8");
409
+ const hash = getFileHash(content);
410
+ const relPath = path__namespace.relative(rootContext, file);
411
+ fileContentCache.set(relPath, hash);
412
+ return content;
413
+ } catch (readErr) {
414
+ console.warn(`[UnoCSS Hybrid] Failed to read file ${file}:`, readErr);
415
+ return "";
416
+ }
417
+ });
418
+ const contents = await Promise.all(contentPromises);
419
+ const allContents = contents.join("\n");
381
420
  const result = await generator.generate(allContents);
382
421
  if (!result.css || result.css.trim().length === 0) {
383
422
  console.warn("[UnoCSS Hybrid] Generated CSS is empty");
@@ -394,12 +433,12 @@ function pluginUnocss(options = {}) {
394
433
  finalOutputPath = resolvedOutputPath;
395
434
  currentCssPath = resolvedOutputPath;
396
435
  }
397
- const outputDir = path__namespace.dirname(finalOutputPath);
398
- if (!fs__namespace.existsSync(outputDir)) {
399
- fs__namespace.mkdirSync(outputDir, { recursive: true });
436
+ const outputDir2 = path__namespace.dirname(finalOutputPath);
437
+ if (!fs__namespace.existsSync(outputDir2)) {
438
+ await fs__namespace.promises.mkdir(outputDir2, { recursive: true });
400
439
  }
401
- fs__namespace.writeFileSync(finalOutputPath, result.css);
402
- const stats = fs__namespace.statSync(finalOutputPath);
440
+ await fs__namespace.promises.writeFile(finalOutputPath, result.css);
441
+ const stats = await fs__namespace.promises.stat(finalOutputPath);
403
442
  console.log(
404
443
  `[UnoCSS Hybrid] CSS generated: ${finalOutputPath} (${(stats.size / 1024).toFixed(2)} KB)`
405
444
  );
@@ -428,24 +467,36 @@ function pluginUnocss(options = {}) {
428
467
  middlewares.unshift(async (req, res, next) => {
429
468
  if (req.url?.startsWith("/uno.css")) {
430
469
  try {
431
- if (!fs__namespace.existsSync(resolvedOutputPath)) {
432
- res.statusCode = 404;
433
- res.setHeader("Content-Type", "text/plain; charset=utf-8");
434
- res.end("CSS file not found. Please restart the dev server to generate it.");
435
- console.warn("[UnoCSS Hybrid] CSS file not found at:", resolvedOutputPath);
436
- return;
437
- }
438
470
  res.setHeader("Content-Type", "text/css; charset=utf-8");
439
471
  res.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
440
472
  res.setHeader("Pragma", "no-cache");
441
473
  res.setHeader("Expires", "0");
474
+ if (!fs__namespace.existsSync(resolvedOutputPath)) {
475
+ const outputDir2 = path__namespace.dirname(resolvedOutputPath);
476
+ if (!fs__namespace.existsSync(outputDir2)) {
477
+ try {
478
+ await fs__namespace.promises.mkdir(outputDir2, { recursive: true });
479
+ console.log("[UnoCSS Hybrid] Created output directory:", outputDir2);
480
+ } catch (mkdirErr) {
481
+ console.error("[UnoCSS Hybrid] Failed to create directory:", mkdirErr);
482
+ }
483
+ }
484
+ if (!fs__namespace.existsSync(resolvedOutputPath)) {
485
+ console.warn("[UnoCSS Hybrid] CSS file not found yet at:", resolvedOutputPath);
486
+ console.log("[UnoCSS Hybrid] Returning empty CSS, will try to regenerate...");
487
+ res.end("/* UnoCSS: CSS file will be generated shortly */");
488
+ generateCSS().catch((err) => {
489
+ console.error("[UnoCSS Hybrid] Background regeneration failed:", err);
490
+ });
491
+ return;
492
+ }
493
+ }
442
494
  const css = fs__namespace.readFileSync(resolvedOutputPath, "utf-8");
443
495
  res.end(css);
444
496
  } catch (err) {
445
497
  console.error("[UnoCSS Hybrid] Error serving CSS:", err);
446
- res.statusCode = 500;
447
- res.setHeader("Content-Type", "text/plain; charset=utf-8");
448
- res.end("Error loading CSS file. Check console for details.");
498
+ res.setHeader("Content-Type", "text/css; charset=utf-8");
499
+ res.end("/* UnoCSS: Error loading CSS file */");
449
500
  }
450
501
  } else {
451
502
  next();
@@ -1 +1 @@
1
- {"version":3,"sources":["../plugin-unocss.ts"],"names":["__filename","fileURLToPath","__dirname","path","createHash","fs","relPath","generator","result","stats"],"mappings":"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","file":"plugin-unocss.js","sourcesContent":["import type { RsbuildPlugin } from '@rsbuild/core';\nimport type { UserConfig } from 'unocss';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport { fileURLToPath } from 'url';\nimport { createHash } from 'crypto';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\nexport interface PluginUnocssOptions {\n /** UnoCSS 配置文件路径或直接配置对象 (默认: './uno.config.ts') */\n unocssConfig?: string | UserConfig;\n\n /**\n * 生成的 CSS 文件输出路径\n *\n * 路径解析规则:\n * - 以 './' 开头: 相对于项目根目录 (推荐)\n * - 相对路径: 相对于插件目录\n * - 绝对路径: 直接使用\n * - 未配置: 默认为 'generated/uno.css' 相对于插件目录\n */\n outputPath?: string;\n\n /** 扫描的内容文件路径模式 (支持 glob 模式) */\n contentPatterns?: string[];\n\n /** 监听的目录路径 (用于开发环境的 watch 模式, 默认: 'src') */\n watchDirectory?: string;\n\n /** 是否自动在 HTML 中注入生成的 CSS link 标签 (默认: true) */\n autoInject?: boolean;\n\n /** 是否在开发环境启用文件监听模式 (默认: true) */\n watch?: boolean;\n\n /**\n * 是否在生产环境为 CSS 文件名添加 content hash\n *\n * 启用后, 文件名格式为 'uno.[hash].css', hash 基于 CSS 内容生成 (默认: true)\n */\n enableHash?: boolean;\n\n /**\n * 增量更新阈值:达到此次数后触发全量重建 (默认: 30)\n */\n incrementalThreshold?: number;\n\n /**\n * 文件变化防抖延迟,单位毫秒 (默认: 300)\n */\n debounceDelay?: number;\n\n /**\n * 全量重建前的等待延迟,单位毫秒 (默认: 2000)\n */\n fullRegenerationDelay?: number;\n\n /**\n * 是否启用详细日志 (默认: false)\n */\n verbose?: boolean;\n}\n\n/**\n * UnoCSS Plugin for Rsbuild\n *\n * 一个用于 Rsbuild 的 UnoCSS 插件,提供 CLI 预生成和自动注入功能.\n *\n * 特性:\n * - 扫描项目文件并生成独立的 CSS 文件\n * - 开发环境支持文件监听和热更新\n * - 生产环境支持 CSS 文件名 hash\n * - 自动在 HTML 中注入 CSS link 标签\n *\n * @param options - 插件配置选项\n * @returns Rsbuild 插件实例\n *\n * @example\n * ```ts\n * import { pluginUnocss } from '@ikkin/plugin-unocss';\n *\n * export default {\n * plugins: [\n * pluginUnocss({\n * outputPath: './src/generated/uno.css',\n * enableHash: true,\n * })\n * ]\n * };\n * ```\n */\nexport function pluginUnocss(\n options: PluginUnocssOptions = {},\n): RsbuildPlugin {\n const {\n unocssConfig = './uno.config.ts',\n outputPath = '',\n contentPatterns = [\n './src/**/*.{html,js,ts,jsx,tsx}',\n './index.html',\n ],\n watchDirectory = 'src',\n autoInject = true,\n watch = true,\n enableHash = true,\n } = options;\n\n return {\n name: 'unocss',\n\n setup(api) {\n const rootContext = api.context.rootPath;\n\n // 解析配置选项\n const {\n incrementalThreshold = 30,\n debounceDelay = 300,\n fullRegenerationDelay = 2000,\n verbose = false,\n } = options;\n\n // 解析输出路径\n const pluginDir = __dirname;\n let resolvedOutputPath: string;\n\n if (!outputPath) {\n // 未配置:使用默认路径(相对于插件目录)\n resolvedOutputPath = path.resolve(pluginDir, './generated/uno.css');\n } else if (path.isAbsolute(outputPath)) {\n // 绝对路径:直接使用\n resolvedOutputPath = outputPath;\n } else if (outputPath.startsWith('./')) {\n // 以 ./ 开头:相对于项目根目录(推荐,更明确)\n resolvedOutputPath = path.resolve(rootContext, outputPath);\n } else {\n // 相对路径(不带 ./):相对于插件目录(更简洁)\n resolvedOutputPath = path.resolve(pluginDir, outputPath);\n }\n\n // 用于保存当前生成的 CSS 文件路径(可能包含 hash)\n let currentCssPath = resolvedOutputPath;\n\n // 获取 rsbuild 的 CSS 输出路径配置\n const getCssOutputPaths = (fileName: string) => {\n try {\n const normalizedConfig = api.getNormalizedConfig();\n const distRoot = normalizedConfig.output.distPath.root || 'dist';\n const cssPath = normalizedConfig.output.distPath.css || 'static/css';\n // 获取 server.base 配置(用于部署到子目录)\n const serverBase = normalizedConfig.server?.base || '/';\n\n // 返回绝对路径和相对路径(用于 HTML 注入)\n const absoluteDir = path.isAbsolute(distRoot)\n ? distRoot\n : path.join(rootContext, distRoot);\n\n // 确保 base 路径以 / 开头和结尾\n const normalizedBase = serverBase.startsWith('/')\n ? serverBase\n : `/${serverBase}`;\n const baseWithTrailingSlash = normalizedBase.endsWith('/')\n ? normalizedBase\n : `${normalizedBase}/`;\n\n return {\n // CSS 文件的绝对输出目录\n absoluteDir: path.join(absoluteDir, cssPath),\n // CSS 文件的 URL 相对路径(用于 HTML 中引用)\n // 移除开头的 / 因为 base 已经包含了\n urlPath: `${baseWithTrailingSlash}${cssPath.startsWith('/') ? cssPath.slice(1) : cssPath}/${fileName}`,\n };\n } catch (err) {\n // 如果获取配置失败,使用默认值\n console.warn('[UnoCSS Hybrid] Failed to get rsbuild config, using default CSS path');\n return {\n absoluteDir: path.join(rootContext, 'dist', 'static', 'css'),\n urlPath: `/static/css/${fileName}`,\n };\n }\n };\n\n // WebSocket 类型定义\n type WebSocketServer = import('ws').WebSocketServer;\n\n // 用于保存 WebSocket 服务器实例和端口\n let wss: WebSocketServer | null = null;\n // 动态分配的 WebSocket 端口(避免端口冲突)\n let wsPort = 0;\n\n // 通过环境变量判断是否是生产环境\n const isProd = process.env.NODE_ENV === 'production';\n\n // 文件内容哈希缓存(用于增量生成)\n const fileContentCache = new Map<string, string>();\n // 增量更新计数器\n let incrementalUpdateCount = 0;\n // 全量重建锁(防止重复重建)\n let isFullRegenerationInProgress = false;\n // 全量重建的定时器\n let fullRegenerationTimer: NodeJS.Timeout | null = null;\n // 待处理的重建请求(在重建完成后再次触发)\n let pendingFullRegeneration = false;\n\n // Generator 实例复用\n let generatorInstance: any = null;\n\n // 日志辅助函数\n const log = (message: string, force = false) => {\n if (verbose || force) {\n console.log(`[UnoCSS Hybrid] ${message}`);\n }\n };\n\n // 初始化或获取 generator 实例\n const getGenerator = async (config: UserConfig): Promise<any> => {\n if (!generatorInstance) {\n const { createGenerator } = await import('unocss');\n generatorInstance = await createGenerator(config);\n }\n return generatorInstance;\n };\n\n // 自动注入:通过修改 HTML 标签来注入 CSS(不污染源码)\n if (autoInject) {\n api.modifyHTMLTags((tags) => {\n let cssPath: string;\n\n if (isProd && enableHash) {\n // 生产环境:使用 rsbuild 配置的 CSS 输出路径\n // 此时 currentCssPath 可能还未更新,所以使用占位符\n const cssFileName = path.basename(currentCssPath || 'uno.css');\n const { urlPath } = getCssOutputPaths(cssFileName);\n cssPath = urlPath;\n } else {\n // 开发环境或未启用 hash:使用固定文件名\n cssPath = '/uno.css';\n }\n\n tags.headTags.unshift({\n tag: 'link',\n attrs: {\n rel: 'stylesheet',\n href: cssPath,\n },\n });\n\n console.log(`[UnoCSS Hybrid] Auto-injected CSS link: ${cssPath}`);\n\n // 开发环境:注入热更新脚本和 WebSocket 端口\n if (!isProd) {\n const hotReloadScript = `\n (function() {\n function reloadCSS(version) {\n const oldLink = document.querySelector('link[href*=\"/uno.css\"]');\n if (oldLink && oldLink.parentNode) {\n const newLink = document.createElement('link');\n newLink.rel = 'stylesheet';\n newLink.href = '/uno.css?v=' + version;\n oldLink.parentNode.insertBefore(newLink, oldLink);\n\n newLink.onload = function() {\n if (oldLink.parentNode) {\n oldLink.parentNode.removeChild(oldLink);\n }\n };\n\n newLink.onerror = function() {\n console.error('[UnoCSS] Failed to reload CSS');\n if (newLink.parentNode) {\n newLink.parentNode.removeChild(newLink);\n }\n };\n }\n }\n\n const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';\n const host = window.location.hostname;\n const wsUrl = protocol + '//' + host + ':${wsPort}';\n\n let socket = null;\n let reconnectCount = 0;\n const maxReconnect = 10;\n\n function connect() {\n if (reconnectCount === 0) {\n console.log('[UnoCSS] WebSocket connecting to ' + wsUrl);\n }\n\n socket = new WebSocket(wsUrl);\n\n socket.onopen = function() {\n console.log('[UnoCSS] WebSocket connected.');\n reconnectCount = 0;\n };\n\n socket.onmessage = function(event) {\n try {\n const data = JSON.parse(event.data);\n if (data.type === 'css-update' && data.version) {\n reloadCSS(data.version);\n }\n } catch (e) {\n // 忽略解析错误\n }\n };\n\n socket.onclose = function() {\n if (reconnectCount >= maxReconnect) {\n console.warn('[UnoCSS] WebSocket connection failed after maximum retry attempts.');\n return;\n }\n\n if (reconnectCount === 0) {\n console.log('[UnoCSS] WebSocket connection lost. Reconnecting...');\n }\n\n reconnectCount++;\n const delay = Math.min(1000 * Math.pow(1.5, reconnectCount), 30000);\n setTimeout(connect, delay);\n };\n\n socket.onerror = function(error) {\n console.error('[UnoCSS] WebSocket error:', error);\n };\n }\n\n connect();\n })();\n `;\n tags.bodyTags.push({\n tag: 'script',\n children: hotReloadScript,\n });\n console.log('[UnoCSS Hybrid] Hot reload script injected');\n }\n\n return tags;\n });\n }\n\n // 读取 UnoCSS 配置\n const loadConfig = async (): Promise<UserConfig> => {\n if (typeof unocssConfig === 'string') {\n const configPath = path.resolve(rootContext, unocssConfig);\n try {\n const configModule = await import(\n `file:///${configPath.replace(/\\\\/g, '/')}`\n );\n return configModule.default || configModule;\n } catch (err) {\n console.warn(\n `[UnoCSS Hybrid] Failed to load config from ${configPath}, using default config`,\n );\n return {};\n }\n }\n return unocssConfig;\n };\n\n // 生成文件内容的哈希\n const getFileHash = (content: string): string => {\n return createHash('md5').update(content).digest('hex');\n };\n\n // 异步全量重建(可在后台执行,不阻塞)\n const scheduleFullRegeneration = () => {\n if (isFullRegenerationInProgress) {\n log('Full regeneration already in progress, will schedule after current finishes');\n pendingFullRegeneration = true;\n return;\n }\n\n // 清除旧的定时器\n if (fullRegenerationTimer) {\n clearTimeout(fullRegenerationTimer);\n }\n\n // 延迟执行(确保文件变化暂停)\n fullRegenerationTimer = setTimeout(async () => {\n log('Starting full regeneration in background...', true);\n isFullRegenerationInProgress = true;\n pendingFullRegeneration = false;\n\n try {\n const config = await loadConfig();\n const { globby } = await import('globby');\n\n const files = await globby(contentPatterns, {\n cwd: rootContext,\n absolute: true,\n });\n\n // 读取所有文件内容\n const allContents = files.map(file => {\n const content = fs.readFileSync(file, 'utf-8');\n const hash = getFileHash(content);\n const relPath = path.relative(rootContext, file);\n fileContentCache.set(relPath, hash);\n return content;\n }).join('\\n');\n\n const generator = await getGenerator(config);\n const result = await generator.generate(allContents);\n\n if (result.css && result.css.trim().length > 0) {\n fs.writeFileSync(resolvedOutputPath, result.css);\n\n const stats = fs.statSync(resolvedOutputPath);\n console.log(\n `[UnoCSS Hybrid] Full regeneration completed: ${resolvedOutputPath} (${(stats.size / 1024).toFixed(2)} KB)`,\n );\n\n // 重置计数器\n incrementalUpdateCount = 0;\n\n // 通知浏览器刷新\n if (wss) {\n const version = Date.now();\n const message = JSON.stringify({\n type: 'css-update',\n version: version,\n });\n\n wss.clients.forEach((client: any) => {\n if (client.readyState === 1) {\n client.send(message);\n }\n });\n\n console.log(`[UnoCSS Hybrid] Broadcasted full regeneration to ${wss.clients.size} client(s)`);\n }\n }\n } catch (err) {\n console.error('[UnoCSS Hybrid] Full regeneration failed:', err);\n } finally {\n isFullRegenerationInProgress = false;\n fullRegenerationTimer = null;\n\n // 如果在重建期间有新的文件变化,再次触发重建\n if (pendingFullRegeneration) {\n log('Pending regeneration detected, scheduling...');\n pendingFullRegeneration = false;\n scheduleFullRegeneration();\n }\n }\n }, fullRegenerationDelay);\n };\n\n // 生成 UnoCSS CSS(开发模式支持增量生成)\n const generateCSS = async (changedFiles?: string[]): Promise<string> => {\n try {\n const config = await loadConfig();\n\n // 扫描文件\n const { globby } = await import('globby');\n const files = await globby(contentPatterns, {\n cwd: rootContext,\n absolute: true,\n });\n\n if (files.length === 0) {\n console.warn('[UnoCSS Hybrid] No files found to scan');\n return resolvedOutputPath;\n }\n\n // 开发模式的增量生成逻辑\n if (!isProd && changedFiles && fileContentCache.size > 0) {\n // 全量重建期间,跳过增量更新\n if (isFullRegenerationInProgress) {\n log('Skipping incremental update during full regeneration');\n return resolvedOutputPath;\n }\n\n // 检测是否有真正的内容变化\n let hasRealChanges = false;\n\n for (const file of changedFiles) {\n if (!fs.existsSync(file)) {\n // 文件被删除,从缓存中移除\n const relPath = path.relative(rootContext, file);\n fileContentCache.delete(relPath);\n hasRealChanges = true;\n log(`File removed: ${relPath}`);\n continue;\n }\n\n const content = fs.readFileSync(file, 'utf-8');\n const hash = getFileHash(content);\n const relPath = path.relative(rootContext, file);\n\n if (fileContentCache.get(relPath) !== hash) {\n // 文件内容变化了\n fileContentCache.set(relPath, hash);\n hasRealChanges = true;\n log(`File changed: ${relPath} (hash: ${hash.substring(0, 8)})`);\n }\n }\n\n // 如果有真正的变化,进行增量生成\n if (hasRealChanges) {\n console.log(`[UnoCSS Hybrid] Files changed, performing incremental update...`);\n\n const generator = await getGenerator(config);\n\n // 只读取变化的文件内容\n const changedContents: string[] = [];\n for (const file of changedFiles) {\n if (fs.existsSync(file)) {\n const content = fs.readFileSync(file, 'utf-8');\n changedContents.push(content);\n }\n }\n\n // 生成变化文件的 CSS\n const changedContent = changedContents.join('\\n');\n const result = await generator.generate(changedContent);\n\n if (result.css && result.css.trim().length > 0) {\n // 直接追加新 CSS(简单快速)\n if (fs.existsSync(resolvedOutputPath)) {\n fs.appendFileSync(resolvedOutputPath, '\\n' + result.css);\n } else {\n fs.writeFileSync(resolvedOutputPath, result.css);\n }\n\n // 增加计数器\n incrementalUpdateCount++;\n\n const stats = fs.statSync(resolvedOutputPath);\n console.log(\n `[UnoCSS Hybrid] Incremental update: ${resolvedOutputPath} (${(stats.size / 1024).toFixed(2)} KB, update #${incrementalUpdateCount}/${incrementalThreshold})`,\n );\n\n // 检查是否需要触发全量重建\n if (incrementalUpdateCount >= incrementalThreshold) {\n console.log(`[UnoCSS Hybrid] Threshold reached (${incrementalUpdateCount} updates), scheduling full regeneration...`);\n scheduleFullRegeneration();\n }\n\n return resolvedOutputPath;\n }\n } else {\n log('No content changes detected, skipping generation');\n return resolvedOutputPath;\n }\n }\n\n // 全量生成(生产环境或首次生成)\n console.log('[UnoCSS Hybrid] Full CSS generation...');\n\n const generator = await getGenerator(config);\n\n // 读取所有文件内容并更新缓存\n const allContents = files.map(file => {\n const content = fs.readFileSync(file, 'utf-8');\n const hash = getFileHash(content);\n const relPath = path.relative(rootContext, file);\n fileContentCache.set(relPath, hash);\n return content;\n }).join('\\n');\n\n // 生成 CSS\n const result = await generator.generate(allContents);\n\n if (!result.css || result.css.trim().length === 0) {\n console.warn('[UnoCSS Hybrid] Generated CSS is empty');\n return resolvedOutputPath;\n }\n\n // 计算输出路径\n let finalOutputPath: string;\n if (isProd && enableHash) {\n // 生产环境:生成到 rsbuild 配置的 CSS 输出目录,文件名带 hash\n const hash = createHash('md5').update(result.css).digest('hex').substring(0, 8);\n const cssFileName = `uno.${hash}.css`;\n const { absoluteDir } = getCssOutputPaths(cssFileName);\n finalOutputPath = path.join(absoluteDir, cssFileName);\n currentCssPath = finalOutputPath;\n } else {\n // 开发环境:生成到插件目录的 generated 子目录,文件名固定\n finalOutputPath = resolvedOutputPath;\n currentCssPath = resolvedOutputPath;\n }\n\n // 确保输出目录存在\n const outputDir = path.dirname(finalOutputPath);\n if (!fs.existsSync(outputDir)) {\n fs.mkdirSync(outputDir, { recursive: true });\n }\n\n // 写入 CSS 文件\n fs.writeFileSync(finalOutputPath, result.css);\n\n const stats = fs.statSync(finalOutputPath);\n console.log(\n `[UnoCSS Hybrid] CSS generated: ${finalOutputPath} (${(stats.size / 1024).toFixed(2)} KB)`,\n );\n\n return finalOutputPath;\n } catch (err) {\n console.error('[UnoCSS Hybrid] Failed to generate CSS:', err);\n return resolvedOutputPath;\n }\n };\n\n // 生产环境:构建前生成 CSS\n if (isProd) {\n api.onBeforeBuild(async () => {\n await generateCSS();\n });\n }\n\n // 开发环境:配置静态文件服务和热更新\n if (!isProd) {\n\n api.modifyRsbuildConfig((config) => {\n const existingSetupMiddlewares = config.dev?.setupMiddlewares;\n const setupMiddlewaresArray = Array.isArray(existingSetupMiddlewares)\n ? existingSetupMiddlewares\n : existingSetupMiddlewares\n ? [existingSetupMiddlewares]\n : [];\n\n return {\n ...config,\n dev: {\n ...config.dev,\n setupMiddlewares: [\n ...setupMiddlewaresArray,\n (middlewares, _devServer) => {\n // 添加自定义中间件来提供 CSS 文件\n middlewares.unshift(async (req, res, next) => {\n // 处理带查询参数的请求 (如 /uno.css?v=123456)\n if (req.url?.startsWith('/uno.css')) {\n try {\n // 检查文件是否存在\n if (!fs.existsSync(resolvedOutputPath)) {\n res.statusCode = 404;\n res.setHeader('Content-Type', 'text/plain; charset=utf-8');\n res.end('CSS file not found. Please restart the dev server to generate it.');\n console.warn('[UnoCSS Hybrid] CSS file not found at:', resolvedOutputPath);\n return;\n }\n\n // 设置正确的 Content-Type 和缓存控制\n res.setHeader('Content-Type', 'text/css; charset=utf-8');\n // 禁用缓存,确保每次都获取最新内容\n res.setHeader('Cache-Control', 'no-cache, no-store, must-revalidate');\n res.setHeader('Pragma', 'no-cache');\n res.setHeader('Expires', '0');\n\n const css = fs.readFileSync(resolvedOutputPath, 'utf-8');\n res.end(css);\n } catch (err) {\n console.error('[UnoCSS Hybrid] Error serving CSS:', err);\n res.statusCode = 500;\n res.setHeader('Content-Type', 'text/plain; charset=utf-8');\n res.end('Error loading CSS file. Check console for details.');\n }\n } else {\n next();\n }\n });\n },\n ],\n },\n };\n });\n\n // 启动时生成 CSS 并创建 WebSocket 服务器\n api.onBeforeStartDevServer(async () => {\n console.log('[UnoCSS Hybrid] Development mode: CLI generation enabled');\n await generateCSS();\n\n // 提前创建 WebSocket 服务器,以便在 HTML 生成前获取端口\n try {\n const { WebSocketServer } = await import('ws');\n\n // 创建 WebSocket 服务器,使用 port: 0 让系统自动分配可用端口\n wss = new WebSocketServer({ port: 0 });\n wsPort = (wss.address() as any).port;\n\n console.log(`[UnoCSS Hybrid] WebSocket server created on port ${wsPort}`);\n\n // 当客户端连接时\n wss.on('connection', (ws: any) => {\n console.log('[UnoCSS Hybrid] Client connected to WebSocket');\n\n ws.on('close', () => {\n console.log('[UnoCSS Hybrid] Client disconnected from WebSocket');\n });\n });\n\n console.log('[UnoCSS Hybrid] UnoCSS HMR WebSocket server ready');\n } catch (err) {\n console.error('[UnoCSS Hybrid] Failed to create WebSocket server:', err);\n }\n });\n\n // 合并启动后的操作\n api.onAfterStartDevServer(async () => {\n console.log('[UnoCSS Hybrid] Dev server started, CSS available at /uno.css');\n\n // Watch 模式\n if (watch) {\n try {\n log('Initializing watch mode...', true);\n\n // 动态导入 chokidar\n const chokidar = await import('chokidar');\n log('chokidar imported successfully');\n\n // 监听指定目录\n const watchDir = path.resolve(rootContext, watchDirectory);\n console.log(`[UnoCSS Hybrid] Watching directory: ${watchDir}`);\n\n // 监听内容文件变化\n const watcher = chokidar.watch(watchDir, {\n ignored: /(^|[\\/\\\\])\\../, // ignore dotfiles\n ignoreInitial: true,\n persistent: true,\n });\n\n log('Watcher created, setting up event handlers...');\n\n watcher.on('ready', () => {\n log('Watcher ready, scanning for files...');\n });\n\n watcher.on('error', (error) => {\n console.error('[UnoCSS Hybrid] Watcher error:', error);\n });\n\n // 防抖:避免频繁重新生成\n let regenerateTimer: NodeJS.Timeout | null = null;\n // 收集本次防抖周期内的变化文件\n let changedFilesInBatch: string[] = [];\n\n watcher.on('all', async (event: string, filePath: string) => {\n log(`Watcher event: ${event} on ${path.relative(rootContext, filePath)}`);\n\n // 检查文件扩展名\n const ext = path.extname(filePath);\n const shouldWatch = ['.html', '.js', '.ts', '.jsx', '.tsx'].includes(ext);\n\n log(`File extension: ${ext}, shouldWatch: ${shouldWatch}`);\n\n // 监听文件添加、修改和删除\n if (shouldWatch && (event === 'change' || event === 'add' || event === 'unlink')) {\n log(`File ${event}: ${path.relative(rootContext, filePath)} - queuing`);\n\n // 将变化的文件添加到批次中\n changedFilesInBatch.push(filePath);\n\n if (regenerateTimer) {\n clearTimeout(regenerateTimer);\n }\n\n regenerateTimer = setTimeout(async () => {\n console.log(`[UnoCSS Hybrid] Regenerating CSS... (${changedFilesInBatch.length} file(s) changed)`);\n\n // 传递变化文件列表,启用增量生成\n await generateCSS(changedFilesInBatch);\n\n const version = Date.now();\n console.log('[UnoCSS Hybrid] Broadcasting CSS update via WebSocket, version:', version);\n\n // 通过我们自己的 WebSocket 广播更新\n if (wss) {\n const message = JSON.stringify({\n type: 'css-update',\n version: version,\n });\n\n wss.clients.forEach((client: any) => {\n if (client.readyState === 1) { // WebSocket.OPEN\n client.send(message);\n }\n });\n\n console.log(`[UnoCSS Hybrid] Broadcasted to ${wss.clients.size} client(s)`);\n } else {\n console.warn('[UnoCSS Hybrid] WebSocket server not available');\n }\n\n // 清空批次\n changedFilesInBatch = [];\n }, debounceDelay);\n } else {\n log(`Event ignored - ext: ${ext}, event: ${event}`);\n }\n });\n\n console.log('[UnoCSS Hybrid] Watch mode: enabled');\n } catch (err) {\n console.warn('[UnoCSS Hybrid] Watch mode not available:', (err as Error).message);\n }\n }\n });\n }\n\n // 构建完成后的日志\n api.onAfterBuild(() => {\n if (isProd && fs.existsSync(currentCssPath)) {\n const stats = fs.statSync(currentCssPath);\n const fileName = path.basename(currentCssPath);\n console.log(\n `[UnoCSS Hybrid] Final CSS: ${fileName} (${(stats.size / 1024).toFixed(2)} KB)`,\n );\n }\n });\n\n // 关闭 dev server 时清理 WebSocket 服务器\n api.onCloseDevServer(async () => {\n if (wss) {\n console.log('[UnoCSS Hybrid] Closing WebSocket server...');\n wss.close();\n wss = null;\n }\n });\n },\n };\n}\n\nexport default pluginUnocss;\n"]}
1
+ {"version":3,"sources":["../plugin-unocss.ts"],"names":["__filename","fileURLToPath","path","fs","createHash","relPath","generator","result","stats","outputDir"],"mappings":"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","file":"plugin-unocss.js","sourcesContent":["import type { RsbuildPlugin } from '@rsbuild/core';\nimport type { UserConfig } from 'unocss';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport { fileURLToPath } from 'url';\nimport { createHash } from 'crypto';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\nexport interface PluginUnocssOptions {\n /** UnoCSS 配置文件路径或直接配置对象 (默认: './uno.config.ts') */\n unocssConfig?: string | UserConfig;\n\n /**\n * 生成的 CSS 文件输出路径\n *\n * 路径解析规则:\n * - 以 './' 开头: 相对于项目根目录 (推荐)\n * - 相对路径: 相对于插件目录\n * - 绝对路径: 直接使用\n * - 未配置: 默认为 'generated/uno.css' 相对于插件目录\n */\n outputPath?: string;\n\n /** 扫描的内容文件路径模式 (支持 glob 模式) */\n contentPatterns?: string[];\n\n /** 监听的目录路径 (用于开发环境的 watch 模式, 默认: 'src') */\n watchDirectory?: string;\n\n /** 是否自动在 HTML 中注入生成的 CSS link 标签 (默认: true) */\n autoInject?: boolean;\n\n /** 是否在开发环境启用文件监听模式 (默认: true) */\n watch?: boolean;\n\n /**\n * 是否在生产环境为 CSS 文件名添加 content hash\n *\n * 启用后, 文件名格式为 'uno.[hash].css', hash 基于 CSS 内容生成 (默认: true)\n */\n enableHash?: boolean;\n\n /**\n * 增量更新阈值:达到此次数后触发全量重建 (默认: 30)\n */\n incrementalThreshold?: number;\n\n /**\n * 文件变化防抖延迟,单位毫秒 (默认: 300)\n */\n debounceDelay?: number;\n\n /**\n * 全量重建前的等待延迟,单位毫秒 (默认: 2000)\n */\n fullRegenerationDelay?: number;\n\n /**\n * 是否启用详细日志 (默认: false)\n */\n verbose?: boolean;\n}\n\n/**\n * UnoCSS Plugin for Rsbuild\n *\n * 一个用于 Rsbuild 的 UnoCSS 插件,提供 CLI 预生成和自动注入功能.\n *\n * 特性:\n * - 扫描项目文件并生成独立的 CSS 文件\n * - 开发环境支持文件监听和热更新\n * - 生产环境支持 CSS 文件名 hash\n * - 自动在 HTML 中注入 CSS link 标签\n *\n * @param options - 插件配置选项\n * @returns Rsbuild 插件实例\n *\n * @example\n * ```ts\n * import { pluginUnocss } from '@ikkin/plugin-unocss';\n *\n * export default {\n * plugins: [\n * pluginUnocss({\n * outputPath: './src/generated/uno.css',\n * enableHash: true,\n * })\n * ]\n * };\n * ```\n */\nexport function pluginUnocss(\n options: PluginUnocssOptions = {},\n): RsbuildPlugin {\n const {\n unocssConfig = './uno.config.ts',\n outputPath = '',\n contentPatterns = [\n './src/**/*.{html,js,ts,jsx,tsx}',\n './index.html',\n ],\n watchDirectory = 'src',\n autoInject = true,\n watch = true,\n enableHash = true,\n } = options;\n\n return {\n name: 'unocss',\n\n setup(api) {\n const rootContext = api.context.rootPath;\n\n // 解析配置选项\n const {\n incrementalThreshold = 30,\n debounceDelay = 300,\n fullRegenerationDelay = 2000,\n verbose = false,\n } = options;\n\n // 解析输出路径\n const pluginDir = __dirname;\n let resolvedOutputPath: string;\n\n if (!outputPath) {\n // 未配置:使用默认路径(相对于项目根目录)\n // 修复:改为项目根目录,避免跨电脑路径问题\n resolvedOutputPath = path.resolve(rootContext, './generated/uno.css');\n } else if (path.isAbsolute(outputPath)) {\n // 绝对路径:直接使用\n resolvedOutputPath = outputPath;\n } else if (outputPath.startsWith('./')) {\n // 以 ./ 开头:相对于项目根目录(推荐,更明确)\n resolvedOutputPath = path.resolve(rootContext, outputPath);\n } else {\n // 相对路径(不带 ./):相对于项目根目录(保持一致性)\n resolvedOutputPath = path.resolve(rootContext, outputPath);\n }\n\n // 确保输出目录存在(在初始化时就创建,避免时序问题)\n const outputDir = path.dirname(resolvedOutputPath);\n if (!fs.existsSync(outputDir)) {\n try {\n fs.mkdirSync(outputDir, { recursive: true });\n console.log('[UnoCSS Hybrid] Created output directory:', outputDir);\n } catch (err) {\n console.error('[UnoCSS Hybrid] Failed to create output directory:', err);\n }\n }\n\n // 用于保存当前生成的 CSS 文件路径(可能包含 hash)\n let currentCssPath = resolvedOutputPath;\n\n // 获取 rsbuild 的 CSS 输出路径配置\n const getCssOutputPaths = (fileName: string) => {\n try {\n const normalizedConfig = api.getNormalizedConfig();\n const distRoot = normalizedConfig.output.distPath.root || 'dist';\n const cssPath = normalizedConfig.output.distPath.css || 'static/css';\n // 获取 server.base 配置(用于部署到子目录)\n const serverBase = normalizedConfig.server?.base || '/';\n\n // 返回绝对路径和相对路径(用于 HTML 注入)\n const absoluteDir = path.isAbsolute(distRoot)\n ? distRoot\n : path.join(rootContext, distRoot);\n\n // 确保 base 路径以 / 开头和结尾\n const normalizedBase = serverBase.startsWith('/')\n ? serverBase\n : `/${serverBase}`;\n const baseWithTrailingSlash = normalizedBase.endsWith('/')\n ? normalizedBase\n : `${normalizedBase}/`;\n\n return {\n // CSS 文件的绝对输出目录\n absoluteDir: path.join(absoluteDir, cssPath),\n // CSS 文件的 URL 相对路径(用于 HTML 中引用)\n // 移除开头的 / 因为 base 已经包含了\n urlPath: `${baseWithTrailingSlash}${cssPath.startsWith('/') ? cssPath.slice(1) : cssPath}/${fileName}`,\n };\n } catch (err) {\n // 如果获取配置失败,使用默认值\n console.warn('[UnoCSS Hybrid] Failed to get rsbuild config, using default CSS path');\n return {\n absoluteDir: path.join(rootContext, 'dist', 'static', 'css'),\n urlPath: `/static/css/${fileName}`,\n };\n }\n };\n\n // WebSocket 类型定义\n type WebSocketServer = import('ws').WebSocketServer;\n\n // 用于保存 WebSocket 服务器实例和端口\n let wss: WebSocketServer | null = null;\n // 动态分配的 WebSocket 端口(避免端口冲突)\n let wsPort = 0;\n\n // 通过环境变量判断是否是生产环境\n const isProd = process.env.NODE_ENV === 'production';\n\n // 文件内容哈希缓存(用于增量生成)\n const fileContentCache = new Map<string, string>();\n // 增量更新计数器\n let incrementalUpdateCount = 0;\n // 全量重建锁(防止重复重建)\n let isFullRegenerationInProgress = false;\n // 全量重建的定时器\n let fullRegenerationTimer: NodeJS.Timeout | null = null;\n // 待处理的重建请求(在重建完成后再次触发)\n let pendingFullRegeneration = false;\n\n // Generator 实例复用\n let generatorInstance: any = null;\n\n // 日志辅助函数\n const log = (message: string, force = false) => {\n if (verbose || force) {\n console.log(`[UnoCSS Hybrid] ${message}`);\n }\n };\n\n // 初始化或获取 generator 实例\n const getGenerator = async (config: UserConfig): Promise<any> => {\n if (!generatorInstance) {\n const { createGenerator } = await import('unocss');\n generatorInstance = await createGenerator(config);\n }\n return generatorInstance;\n };\n\n // 自动注入:通过修改 HTML 标签来注入 CSS(不污染源码)\n if (autoInject) {\n api.modifyHTMLTags((tags) => {\n let cssPath: string;\n\n if (isProd && enableHash) {\n // 生产环境:使用 rsbuild 配置的 CSS 输出路径\n // 此时 currentCssPath 可能还未更新,所以使用占位符\n const cssFileName = path.basename(currentCssPath || 'uno.css');\n const { urlPath } = getCssOutputPaths(cssFileName);\n cssPath = urlPath;\n } else {\n // 开发环境或未启用 hash:使用固定文件名\n cssPath = '/uno.css';\n }\n\n // 检查是否已注入 CSS link\n const isLinkInjected = tags.headTags.some(\n (tag) => tag.tag === 'link' && tag.attrs && tag.attrs.href === cssPath\n );\n\n if (!isLinkInjected) {\n tags.headTags.unshift({\n tag: 'link',\n attrs: {\n rel: 'stylesheet',\n href: cssPath,\n },\n });\n\n console.log(`[UnoCSS Hybrid] Auto-injected CSS link: ${cssPath}`);\n }\n\n // 开发环境:注入热更新脚本和 WebSocket 端口\n if (!isProd) {\n const hotReloadScript = `\n (function() {\n function reloadCSS(version) {\n const oldLink = document.querySelector('link[href*=\"/uno.css\"]');\n if (oldLink && oldLink.parentNode) {\n const newLink = document.createElement('link');\n newLink.rel = 'stylesheet';\n newLink.href = '/uno.css?v=' + version;\n oldLink.parentNode.insertBefore(newLink, oldLink);\n\n newLink.onload = function() {\n if (oldLink.parentNode) {\n oldLink.parentNode.removeChild(oldLink);\n }\n };\n\n newLink.onerror = function() {\n console.error('[UnoCSS] Failed to reload CSS');\n if (newLink.parentNode) {\n newLink.parentNode.removeChild(newLink);\n }\n };\n }\n }\n\n const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';\n const host = window.location.hostname;\n const wsUrl = protocol + '//' + host + ':${wsPort}';\n\n let socket = null;\n let reconnectCount = 0;\n const maxReconnect = 10;\n\n function connect() {\n if (reconnectCount === 0) {\n console.log('[UnoCSS] WebSocket connecting to ' + wsUrl);\n }\n\n socket = new WebSocket(wsUrl);\n\n socket.onopen = function() {\n console.log('[UnoCSS] WebSocket connected.');\n reconnectCount = 0;\n };\n\n socket.onmessage = function(event) {\n try {\n const data = JSON.parse(event.data);\n if (data.type === 'css-update' && data.version) {\n reloadCSS(data.version);\n }\n } catch (e) {\n // 忽略解析错误\n }\n };\n\n socket.onclose = function() {\n if (reconnectCount >= maxReconnect) {\n console.warn('[UnoCSS] WebSocket connection failed after maximum retry attempts.');\n return;\n }\n\n if (reconnectCount === 0) {\n console.log('[UnoCSS] WebSocket connection lost. Reconnecting...');\n }\n\n reconnectCount++;\n const delay = Math.min(1000 * Math.pow(1.5, reconnectCount), 30000);\n setTimeout(connect, delay);\n };\n\n socket.onerror = function(error) {\n console.error('[UnoCSS] WebSocket error:', error);\n };\n }\n\n connect();\n })();\n `;\n\n // 检查是否已注入热更新脚本\n const isScriptInjected = tags.bodyTags.some(\n (tag) => tag.tag === 'script' && tag.attrs && tag.attrs['data-unocss-hmr']\n );\n\n if (!isScriptInjected) {\n tags.bodyTags.push({\n tag: 'script',\n attrs: { 'data-unocss-hmr': 'true' },\n children: hotReloadScript,\n });\n console.log('[UnoCSS Hybrid] Hot reload script injected');\n }\n }\n\n return tags;\n });\n }\n\n // 缓存配置对象\n let cachedConfig: UserConfig | null = null;\n\n // 读取 UnoCSS 配置 (带缓存)\n const loadConfig = async (reload = false): Promise<UserConfig> => {\n if (cachedConfig && !reload) {\n return cachedConfig;\n }\n\n if (typeof unocssConfig === 'string') {\n const configPath = path.resolve(rootContext, unocssConfig);\n try {\n // 添加时间戳查询参数以绕过可能的模块缓存(仅在强制 reload 时有用,但常规使用 import 缓存即可)\n const configModule = await import(\n `file:///${configPath.replace(/\\\\/g, '/')}`\n );\n cachedConfig = configModule.default || configModule;\n return cachedConfig as UserConfig;\n } catch (err) {\n console.warn(\n `[UnoCSS Hybrid] Failed to load config from ${configPath}, using default config`,\n );\n return {};\n }\n }\n cachedConfig = unocssConfig;\n return unocssConfig;\n };\n\n // 生成文件内容的哈希\n const getFileHash = (content: string): string => {\n return createHash('md5').update(content).digest('hex');\n };\n\n // 异步全量重建(可在后台执行,不阻塞)\n const scheduleFullRegeneration = () => {\n if (isFullRegenerationInProgress) {\n log('Full regeneration already in progress, will schedule after current finishes');\n pendingFullRegeneration = true;\n return;\n }\n\n // 清除旧的定时器\n if (fullRegenerationTimer) {\n clearTimeout(fullRegenerationTimer);\n }\n\n // 延迟执行(确保文件变化暂停)\n fullRegenerationTimer = setTimeout(async () => {\n log('Starting full regeneration in background...', true);\n isFullRegenerationInProgress = true;\n pendingFullRegeneration = false;\n\n try {\n const config = await loadConfig();\n const { globby } = await import('globby');\n\n const files = await globby(contentPatterns, {\n cwd: rootContext,\n absolute: true,\n });\n\n // 并发读取所有文件内容 (优化点:异步并发)\n const contentPromises = files.map(async (file) => {\n try {\n const content = await fs.promises.readFile(file, 'utf-8');\n const hash = getFileHash(content);\n const relPath = path.relative(rootContext, file);\n fileContentCache.set(relPath, hash);\n return content;\n } catch (readErr) {\n console.warn(`[UnoCSS Hybrid] Failed to read file ${file} during regeneration:`, readErr);\n return '';\n }\n });\n\n const contents = await Promise.all(contentPromises);\n const allContents = contents.join('\\n');\n\n const generator = await getGenerator(config);\n const result = await generator.generate(allContents);\n\n if (result.css && result.css.trim().length > 0) {\n await fs.promises.writeFile(resolvedOutputPath, result.css);\n\n const stats = await fs.promises.stat(resolvedOutputPath);\n console.log(\n `[UnoCSS Hybrid] Full regeneration completed: ${resolvedOutputPath} (${(stats.size / 1024).toFixed(2)} KB)`,\n );\n\n // 重置计数器\n incrementalUpdateCount = 0;\n\n // 通知浏览器刷新\n if (wss) {\n const version = Date.now();\n const message = JSON.stringify({\n type: 'css-update',\n version: version,\n });\n\n wss.clients.forEach((client: any) => {\n if (client.readyState === 1) {\n client.send(message);\n }\n });\n\n console.log(`[UnoCSS Hybrid] Broadcasted full regeneration to ${wss.clients.size} client(s)`);\n }\n }\n } catch (err) {\n console.error('[UnoCSS Hybrid] Full regeneration failed:', err);\n } finally {\n isFullRegenerationInProgress = false;\n fullRegenerationTimer = null;\n\n // 如果在重建期间有新的文件变化,再次触发重建\n if (pendingFullRegeneration) {\n log('Pending regeneration detected, scheduling...');\n pendingFullRegeneration = false;\n scheduleFullRegeneration();\n }\n }\n }, fullRegenerationDelay);\n };\n\n // 生成 UnoCSS CSS(开发模式支持增量生成)\n const generateCSS = async (changedFiles?: string[]): Promise<string> => {\n try {\n const config = await loadConfig();\n\n // 开发模式的增量生成逻辑\n if (!isProd && changedFiles && fileContentCache.size > 0) {\n // 全量重建期间,跳过增量更新\n if (isFullRegenerationInProgress) {\n log('Skipping incremental update during full regeneration');\n return resolvedOutputPath;\n }\n\n // 检测是否有真正的内容变化\n let hasRealChanges = false;\n\n for (const file of changedFiles) {\n if (!fs.existsSync(file)) {\n // 文件被删除,从缓存中移除\n const relPath = path.relative(rootContext, file);\n fileContentCache.delete(relPath);\n hasRealChanges = true;\n log(`File removed: ${relPath}`);\n continue;\n }\n\n const content = await fs.promises.readFile(file, 'utf-8');\n const hash = getFileHash(content);\n const relPath = path.relative(rootContext, file);\n\n if (fileContentCache.get(relPath) !== hash) {\n // 文件内容变化了\n fileContentCache.set(relPath, hash);\n hasRealChanges = true;\n log(`File changed: ${relPath} (hash: ${hash.substring(0, 8)})`);\n }\n }\n\n // 如果有真正的变化,进行增量生成\n if (hasRealChanges) {\n console.log(`[UnoCSS Hybrid] Files changed, performing incremental update...`);\n\n const generator = await getGenerator(config);\n\n // 只读取变化的文件内容\n const changedContents: string[] = [];\n for (const file of changedFiles) {\n if (fs.existsSync(file)) {\n const content = await fs.promises.readFile(file, 'utf-8');\n changedContents.push(content);\n }\n }\n\n // 生成变化文件的 CSS\n const changedContent = changedContents.join('\\n');\n const result = await generator.generate(changedContent);\n\n if (result.css && result.css.trim().length > 0) {\n // 直接追加新 CSS(简单快速)\n if (fs.existsSync(resolvedOutputPath)) {\n await fs.promises.appendFile(resolvedOutputPath, '\\n' + result.css);\n } else {\n await fs.promises.writeFile(resolvedOutputPath, result.css);\n }\n\n // 增加计数器\n incrementalUpdateCount++;\n\n const stats = await fs.promises.stat(resolvedOutputPath);\n console.log(\n `[UnoCSS Hybrid] Incremental update: ${resolvedOutputPath} (${(stats.size / 1024).toFixed(2)} KB, update #${incrementalUpdateCount}/${incrementalThreshold})`,\n );\n\n // 检查是否需要触发全量重建\n if (incrementalUpdateCount >= incrementalThreshold) {\n console.log(`[UnoCSS Hybrid] Threshold reached (${incrementalUpdateCount} updates), scheduling full regeneration...`);\n scheduleFullRegeneration();\n }\n\n return resolvedOutputPath;\n }\n } else {\n log('No content changes detected, skipping generation');\n return resolvedOutputPath;\n }\n }\n\n // 全量生成(生产环境或首次生成或全量重建)\n console.log('[UnoCSS Hybrid] Full CSS generation...');\n\n // 扫描文件 (移到这里,仅在全量生成时执行)\n const { globby } = await import('globby');\n const files = await globby(contentPatterns, {\n cwd: rootContext,\n absolute: true,\n });\n\n if (files.length === 0) {\n console.warn('[UnoCSS Hybrid] No files found to scan');\n return resolvedOutputPath;\n }\n\n const generator = await getGenerator(config);\n\n // 并发读取所有文件内容并更新缓存 (优化点:使用 Promise.all 并发读取)\n const contentPromises = files.map(async (file) => {\n try {\n const content = await fs.promises.readFile(file, 'utf-8');\n const hash = getFileHash(content);\n const relPath = path.relative(rootContext, file);\n fileContentCache.set(relPath, hash);\n return content;\n } catch (readErr) {\n console.warn(`[UnoCSS Hybrid] Failed to read file ${file}:`, readErr);\n return '';\n }\n });\n\n const contents = await Promise.all(contentPromises);\n const allContents = contents.join('\\n');\n\n // 生成 CSS\n const result = await generator.generate(allContents);\n\n if (!result.css || result.css.trim().length === 0) {\n console.warn('[UnoCSS Hybrid] Generated CSS is empty');\n return resolvedOutputPath;\n }\n\n // 计算输出路径\n let finalOutputPath: string;\n if (isProd && enableHash) {\n // 生产环境:生成到 rsbuild 配置的 CSS 输出目录,文件名带 hash\n const hash = createHash('md5').update(result.css).digest('hex').substring(0, 8);\n const cssFileName = `uno.${hash}.css`;\n const { absoluteDir } = getCssOutputPaths(cssFileName);\n finalOutputPath = path.join(absoluteDir, cssFileName);\n currentCssPath = finalOutputPath;\n } else {\n // 开发环境:生成到插件目录的 generated 子目录,文件名固定\n finalOutputPath = resolvedOutputPath;\n currentCssPath = resolvedOutputPath;\n }\n\n // 确保输出目录存在\n const outputDir = path.dirname(finalOutputPath);\n if (!fs.existsSync(outputDir)) {\n await fs.promises.mkdir(outputDir, { recursive: true });\n }\n\n // 写入 CSS 文件\n await fs.promises.writeFile(finalOutputPath, result.css);\n\n const stats = await fs.promises.stat(finalOutputPath);\n console.log(\n `[UnoCSS Hybrid] CSS generated: ${finalOutputPath} (${(stats.size / 1024).toFixed(2)} KB)`,\n );\n\n return finalOutputPath;\n } catch (err) {\n console.error('[UnoCSS Hybrid] Failed to generate CSS:', err);\n return resolvedOutputPath;\n }\n };\n\n // 生产环境:构建前生成 CSS\n if (isProd) {\n api.onBeforeBuild(async () => {\n await generateCSS();\n });\n }\n\n // 开发环境:配置静态文件服务和热更新\n if (!isProd) {\n\n api.modifyRsbuildConfig((config) => {\n const existingSetupMiddlewares = config.dev?.setupMiddlewares;\n const setupMiddlewaresArray = Array.isArray(existingSetupMiddlewares)\n ? existingSetupMiddlewares\n : existingSetupMiddlewares\n ? [existingSetupMiddlewares]\n : [];\n\n return {\n ...config,\n dev: {\n ...config.dev,\n setupMiddlewares: [\n ...setupMiddlewaresArray,\n (middlewares, _devServer) => {\n // 添加自定义中间件来提供 CSS 文件\n middlewares.unshift(async (req, res, next) => {\n // 处理带查询参数的请求 (如 /uno.css?v=123456)\n if (req.url?.startsWith('/uno.css')) {\n try {\n // 设置正确的 Content-Type 和缓存控制\n res.setHeader('Content-Type', 'text/css; charset=utf-8');\n // 禁用缓存,确保每次都获取最新内容\n res.setHeader('Cache-Control', 'no-cache, no-store, must-revalidate');\n res.setHeader('Pragma', 'no-cache');\n res.setHeader('Expires', '0');\n\n // 检查文件是否存在\n if (!fs.existsSync(resolvedOutputPath)) {\n // 文件不存在:确保目录存在,并尝试读取(可能刚刚生成)\n const outputDir = path.dirname(resolvedOutputPath);\n if (!fs.existsSync(outputDir)) {\n try {\n await fs.promises.mkdir(outputDir, { recursive: true });\n console.log('[UnoCSS Hybrid] Created output directory:', outputDir);\n } catch (mkdirErr) {\n console.error('[UnoCSS Hybrid] Failed to create directory:', mkdirErr);\n }\n }\n\n // 再次检查文件(可能刚刚生成)\n if (!fs.existsSync(resolvedOutputPath)) {\n // 文件仍然不存在:返回空 CSS 而不是 404\n // 这样可以避免页面加载错误,等待 CSS 生成后重新请求\n console.warn('[UnoCSS Hybrid] CSS file not found yet at:', resolvedOutputPath);\n console.log('[UnoCSS Hybrid] Returning empty CSS, will try to regenerate...');\n res.end('/* UnoCSS: CSS file will be generated shortly */');\n\n // 触发异步生成(不阻塞响应)\n generateCSS().catch(err => {\n console.error('[UnoCSS Hybrid] Background regeneration failed:', err);\n });\n return;\n }\n }\n\n const css = fs.readFileSync(resolvedOutputPath, 'utf-8');\n res.end(css);\n } catch (err) {\n console.error('[UnoCSS Hybrid] Error serving CSS:', err);\n // 出错时也返回空 CSS,避免页面崩溃\n res.setHeader('Content-Type', 'text/css; charset=utf-8');\n res.end('/* UnoCSS: Error loading CSS file */');\n }\n } else {\n next();\n }\n });\n },\n ],\n },\n };\n });\n\n // 启动时生成 CSS 并创建 WebSocket 服务器\n api.onBeforeStartDevServer(async () => {\n console.log('[UnoCSS Hybrid] Development mode: CLI generation enabled');\n await generateCSS();\n\n // 提前创建 WebSocket 服务器,以便在 HTML 生成前获取端口\n try {\n const { WebSocketServer } = await import('ws');\n\n // 创建 WebSocket 服务器,使用 port: 0 让系统自动分配可用端口\n wss = new WebSocketServer({ port: 0 });\n wsPort = (wss.address() as any).port;\n\n console.log(`[UnoCSS Hybrid] WebSocket server created on port ${wsPort}`);\n\n // 当客户端连接时\n wss.on('connection', (ws: any) => {\n console.log('[UnoCSS Hybrid] Client connected to WebSocket');\n\n ws.on('close', () => {\n console.log('[UnoCSS Hybrid] Client disconnected from WebSocket');\n });\n });\n\n console.log('[UnoCSS Hybrid] UnoCSS HMR WebSocket server ready');\n } catch (err) {\n console.error('[UnoCSS Hybrid] Failed to create WebSocket server:', err);\n }\n });\n\n // 合并启动后的操作\n api.onAfterStartDevServer(async () => {\n console.log('[UnoCSS Hybrid] Dev server started, CSS available at /uno.css');\n\n // Watch 模式\n if (watch) {\n try {\n log('Initializing watch mode...', true);\n\n // 动态导入 chokidar\n const chokidar = await import('chokidar');\n log('chokidar imported successfully');\n\n // 监听指定目录\n const watchDir = path.resolve(rootContext, watchDirectory);\n console.log(`[UnoCSS Hybrid] Watching directory: ${watchDir}`);\n\n // 监听内容文件变化\n const watcher = chokidar.watch(watchDir, {\n ignored: /(^|[\\/\\\\])\\../, // ignore dotfiles\n ignoreInitial: true,\n persistent: true,\n });\n\n log('Watcher created, setting up event handlers...');\n\n watcher.on('ready', () => {\n log('Watcher ready, scanning for files...');\n });\n\n watcher.on('error', (error) => {\n console.error('[UnoCSS Hybrid] Watcher error:', error);\n });\n\n // 防抖:避免频繁重新生成\n let regenerateTimer: NodeJS.Timeout | null = null;\n // 收集本次防抖周期内的变化文件\n let changedFilesInBatch: string[] = [];\n\n watcher.on('all', async (event: string, filePath: string) => {\n log(`Watcher event: ${event} on ${path.relative(rootContext, filePath)}`);\n\n // 检查文件扩展名\n const ext = path.extname(filePath);\n const shouldWatch = ['.html', '.js', '.ts', '.jsx', '.tsx'].includes(ext);\n\n log(`File extension: ${ext}, shouldWatch: ${shouldWatch}`);\n\n // 监听文件添加、修改和删除\n if (shouldWatch && (event === 'change' || event === 'add' || event === 'unlink')) {\n log(`File ${event}: ${path.relative(rootContext, filePath)} - queuing`);\n\n // 将变化的文件添加到批次中\n changedFilesInBatch.push(filePath);\n\n if (regenerateTimer) {\n clearTimeout(regenerateTimer);\n }\n\n regenerateTimer = setTimeout(async () => {\n console.log(`[UnoCSS Hybrid] Regenerating CSS... (${changedFilesInBatch.length} file(s) changed)`);\n\n // 传递变化文件列表,启用增量生成\n await generateCSS(changedFilesInBatch);\n\n const version = Date.now();\n console.log('[UnoCSS Hybrid] Broadcasting CSS update via WebSocket, version:', version);\n\n // 通过我们自己的 WebSocket 广播更新\n if (wss) {\n const message = JSON.stringify({\n type: 'css-update',\n version: version,\n });\n\n wss.clients.forEach((client: any) => {\n if (client.readyState === 1) { // WebSocket.OPEN\n client.send(message);\n }\n });\n\n console.log(`[UnoCSS Hybrid] Broadcasted to ${wss.clients.size} client(s)`);\n } else {\n console.warn('[UnoCSS Hybrid] WebSocket server not available');\n }\n\n // 清空批次\n changedFilesInBatch = [];\n }, debounceDelay);\n } else {\n log(`Event ignored - ext: ${ext}, event: ${event}`);\n }\n });\n\n console.log('[UnoCSS Hybrid] Watch mode: enabled');\n } catch (err) {\n console.warn('[UnoCSS Hybrid] Watch mode not available:', (err as Error).message);\n }\n }\n });\n }\n\n // 构建完成后的日志\n api.onAfterBuild(() => {\n if (isProd && fs.existsSync(currentCssPath)) {\n const stats = fs.statSync(currentCssPath);\n const fileName = path.basename(currentCssPath);\n console.log(\n `[UnoCSS Hybrid] Final CSS: ${fileName} (${(stats.size / 1024).toFixed(2)} KB)`,\n );\n }\n });\n\n // 关闭 dev server 时清理 WebSocket 服务器\n api.onCloseDevServer(async () => {\n if (wss) {\n console.log('[UnoCSS Hybrid] Closing WebSocket server...');\n wss.close();\n wss = null;\n }\n });\n },\n };\n}\n\nexport default pluginUnocss;\n"]}
@@ -5,7 +5,7 @@ import { createHash } from 'crypto';
5
5
 
6
6
  // plugin-unocss.ts
7
7
  var __filename$1 = fileURLToPath(import.meta.url);
8
- var __dirname$1 = path.dirname(__filename$1);
8
+ path.dirname(__filename$1);
9
9
  function pluginUnocss(options = {}) {
10
10
  const {
11
11
  unocssConfig = "./uno.config.ts",
@@ -29,16 +29,24 @@ function pluginUnocss(options = {}) {
29
29
  fullRegenerationDelay = 2e3,
30
30
  verbose = false
31
31
  } = options;
32
- const pluginDir = __dirname$1;
33
32
  let resolvedOutputPath;
34
33
  if (!outputPath) {
35
- resolvedOutputPath = path.resolve(pluginDir, "./generated/uno.css");
34
+ resolvedOutputPath = path.resolve(rootContext, "./generated/uno.css");
36
35
  } else if (path.isAbsolute(outputPath)) {
37
36
  resolvedOutputPath = outputPath;
38
37
  } else if (outputPath.startsWith("./")) {
39
38
  resolvedOutputPath = path.resolve(rootContext, outputPath);
40
39
  } else {
41
- resolvedOutputPath = path.resolve(pluginDir, outputPath);
40
+ resolvedOutputPath = path.resolve(rootContext, outputPath);
41
+ }
42
+ const outputDir = path.dirname(resolvedOutputPath);
43
+ if (!fs.existsSync(outputDir)) {
44
+ try {
45
+ fs.mkdirSync(outputDir, { recursive: true });
46
+ console.log("[UnoCSS Hybrid] Created output directory:", outputDir);
47
+ } catch (err) {
48
+ console.error("[UnoCSS Hybrid] Failed to create output directory:", err);
49
+ }
42
50
  }
43
51
  let currentCssPath = resolvedOutputPath;
44
52
  const getCssOutputPaths = (fileName) => {
@@ -96,14 +104,19 @@ function pluginUnocss(options = {}) {
96
104
  } else {
97
105
  cssPath = "/uno.css";
98
106
  }
99
- tags.headTags.unshift({
100
- tag: "link",
101
- attrs: {
102
- rel: "stylesheet",
103
- href: cssPath
104
- }
105
- });
106
- console.log(`[UnoCSS Hybrid] Auto-injected CSS link: ${cssPath}`);
107
+ const isLinkInjected = tags.headTags.some(
108
+ (tag) => tag.tag === "link" && tag.attrs && tag.attrs.href === cssPath
109
+ );
110
+ if (!isLinkInjected) {
111
+ tags.headTags.unshift({
112
+ tag: "link",
113
+ attrs: {
114
+ rel: "stylesheet",
115
+ href: cssPath
116
+ }
117
+ });
118
+ console.log(`[UnoCSS Hybrid] Auto-injected CSS link: ${cssPath}`);
119
+ }
107
120
  if (!isProd) {
108
121
  const hotReloadScript = `
109
122
  (function() {
@@ -184,21 +197,32 @@ function pluginUnocss(options = {}) {
184
197
  connect();
185
198
  })();
186
199
  `;
187
- tags.bodyTags.push({
188
- tag: "script",
189
- children: hotReloadScript
190
- });
191
- console.log("[UnoCSS Hybrid] Hot reload script injected");
200
+ const isScriptInjected = tags.bodyTags.some(
201
+ (tag) => tag.tag === "script" && tag.attrs && tag.attrs["data-unocss-hmr"]
202
+ );
203
+ if (!isScriptInjected) {
204
+ tags.bodyTags.push({
205
+ tag: "script",
206
+ attrs: { "data-unocss-hmr": "true" },
207
+ children: hotReloadScript
208
+ });
209
+ console.log("[UnoCSS Hybrid] Hot reload script injected");
210
+ }
192
211
  }
193
212
  return tags;
194
213
  });
195
214
  }
196
- const loadConfig = async () => {
215
+ let cachedConfig = null;
216
+ const loadConfig = async (reload = false) => {
217
+ if (cachedConfig && !reload) {
218
+ return cachedConfig;
219
+ }
197
220
  if (typeof unocssConfig === "string") {
198
221
  const configPath = path.resolve(rootContext, unocssConfig);
199
222
  try {
200
223
  const configModule = await import(`file:///${configPath.replace(/\\/g, "/")}`);
201
- return configModule.default || configModule;
224
+ cachedConfig = configModule.default || configModule;
225
+ return cachedConfig;
202
226
  } catch (err) {
203
227
  console.warn(
204
228
  `[UnoCSS Hybrid] Failed to load config from ${configPath}, using default config`
@@ -206,6 +230,7 @@ function pluginUnocss(options = {}) {
206
230
  return {};
207
231
  }
208
232
  }
233
+ cachedConfig = unocssConfig;
209
234
  return unocssConfig;
210
235
  };
211
236
  const getFileHash = (content) => {
@@ -231,18 +256,25 @@ function pluginUnocss(options = {}) {
231
256
  cwd: rootContext,
232
257
  absolute: true
233
258
  });
234
- const allContents = files.map((file) => {
235
- const content = fs.readFileSync(file, "utf-8");
236
- const hash = getFileHash(content);
237
- const relPath = path.relative(rootContext, file);
238
- fileContentCache.set(relPath, hash);
239
- return content;
240
- }).join("\n");
259
+ const contentPromises = files.map(async (file) => {
260
+ try {
261
+ const content = await fs.promises.readFile(file, "utf-8");
262
+ const hash = getFileHash(content);
263
+ const relPath = path.relative(rootContext, file);
264
+ fileContentCache.set(relPath, hash);
265
+ return content;
266
+ } catch (readErr) {
267
+ console.warn(`[UnoCSS Hybrid] Failed to read file ${file} during regeneration:`, readErr);
268
+ return "";
269
+ }
270
+ });
271
+ const contents = await Promise.all(contentPromises);
272
+ const allContents = contents.join("\n");
241
273
  const generator = await getGenerator(config);
242
274
  const result = await generator.generate(allContents);
243
275
  if (result.css && result.css.trim().length > 0) {
244
- fs.writeFileSync(resolvedOutputPath, result.css);
245
- const stats = fs.statSync(resolvedOutputPath);
276
+ await fs.promises.writeFile(resolvedOutputPath, result.css);
277
+ const stats = await fs.promises.stat(resolvedOutputPath);
246
278
  console.log(
247
279
  `[UnoCSS Hybrid] Full regeneration completed: ${resolvedOutputPath} (${(stats.size / 1024).toFixed(2)} KB)`
248
280
  );
@@ -277,15 +309,6 @@ function pluginUnocss(options = {}) {
277
309
  const generateCSS = async (changedFiles) => {
278
310
  try {
279
311
  const config = await loadConfig();
280
- const { globby } = await import('globby');
281
- const files = await globby(contentPatterns, {
282
- cwd: rootContext,
283
- absolute: true
284
- });
285
- if (files.length === 0) {
286
- console.warn("[UnoCSS Hybrid] No files found to scan");
287
- return resolvedOutputPath;
288
- }
289
312
  if (!isProd && changedFiles && fileContentCache.size > 0) {
290
313
  if (isFullRegenerationInProgress) {
291
314
  log("Skipping incremental update during full regeneration");
@@ -300,7 +323,7 @@ function pluginUnocss(options = {}) {
300
323
  log(`File removed: ${relPath2}`);
301
324
  continue;
302
325
  }
303
- const content = fs.readFileSync(file, "utf-8");
326
+ const content = await fs.promises.readFile(file, "utf-8");
304
327
  const hash = getFileHash(content);
305
328
  const relPath = path.relative(rootContext, file);
306
329
  if (fileContentCache.get(relPath) !== hash) {
@@ -315,7 +338,7 @@ function pluginUnocss(options = {}) {
315
338
  const changedContents = [];
316
339
  for (const file of changedFiles) {
317
340
  if (fs.existsSync(file)) {
318
- const content = fs.readFileSync(file, "utf-8");
341
+ const content = await fs.promises.readFile(file, "utf-8");
319
342
  changedContents.push(content);
320
343
  }
321
344
  }
@@ -323,12 +346,12 @@ function pluginUnocss(options = {}) {
323
346
  const result2 = await generator2.generate(changedContent);
324
347
  if (result2.css && result2.css.trim().length > 0) {
325
348
  if (fs.existsSync(resolvedOutputPath)) {
326
- fs.appendFileSync(resolvedOutputPath, "\n" + result2.css);
349
+ await fs.promises.appendFile(resolvedOutputPath, "\n" + result2.css);
327
350
  } else {
328
- fs.writeFileSync(resolvedOutputPath, result2.css);
351
+ await fs.promises.writeFile(resolvedOutputPath, result2.css);
329
352
  }
330
353
  incrementalUpdateCount++;
331
- const stats2 = fs.statSync(resolvedOutputPath);
354
+ const stats2 = await fs.promises.stat(resolvedOutputPath);
332
355
  console.log(
333
356
  `[UnoCSS Hybrid] Incremental update: ${resolvedOutputPath} (${(stats2.size / 1024).toFixed(2)} KB, update #${incrementalUpdateCount}/${incrementalThreshold})`
334
357
  );
@@ -344,14 +367,30 @@ function pluginUnocss(options = {}) {
344
367
  }
345
368
  }
346
369
  console.log("[UnoCSS Hybrid] Full CSS generation...");
370
+ const { globby } = await import('globby');
371
+ const files = await globby(contentPatterns, {
372
+ cwd: rootContext,
373
+ absolute: true
374
+ });
375
+ if (files.length === 0) {
376
+ console.warn("[UnoCSS Hybrid] No files found to scan");
377
+ return resolvedOutputPath;
378
+ }
347
379
  const generator = await getGenerator(config);
348
- const allContents = files.map((file) => {
349
- const content = fs.readFileSync(file, "utf-8");
350
- const hash = getFileHash(content);
351
- const relPath = path.relative(rootContext, file);
352
- fileContentCache.set(relPath, hash);
353
- return content;
354
- }).join("\n");
380
+ const contentPromises = files.map(async (file) => {
381
+ try {
382
+ const content = await fs.promises.readFile(file, "utf-8");
383
+ const hash = getFileHash(content);
384
+ const relPath = path.relative(rootContext, file);
385
+ fileContentCache.set(relPath, hash);
386
+ return content;
387
+ } catch (readErr) {
388
+ console.warn(`[UnoCSS Hybrid] Failed to read file ${file}:`, readErr);
389
+ return "";
390
+ }
391
+ });
392
+ const contents = await Promise.all(contentPromises);
393
+ const allContents = contents.join("\n");
355
394
  const result = await generator.generate(allContents);
356
395
  if (!result.css || result.css.trim().length === 0) {
357
396
  console.warn("[UnoCSS Hybrid] Generated CSS is empty");
@@ -368,12 +407,12 @@ function pluginUnocss(options = {}) {
368
407
  finalOutputPath = resolvedOutputPath;
369
408
  currentCssPath = resolvedOutputPath;
370
409
  }
371
- const outputDir = path.dirname(finalOutputPath);
372
- if (!fs.existsSync(outputDir)) {
373
- fs.mkdirSync(outputDir, { recursive: true });
410
+ const outputDir2 = path.dirname(finalOutputPath);
411
+ if (!fs.existsSync(outputDir2)) {
412
+ await fs.promises.mkdir(outputDir2, { recursive: true });
374
413
  }
375
- fs.writeFileSync(finalOutputPath, result.css);
376
- const stats = fs.statSync(finalOutputPath);
414
+ await fs.promises.writeFile(finalOutputPath, result.css);
415
+ const stats = await fs.promises.stat(finalOutputPath);
377
416
  console.log(
378
417
  `[UnoCSS Hybrid] CSS generated: ${finalOutputPath} (${(stats.size / 1024).toFixed(2)} KB)`
379
418
  );
@@ -402,24 +441,36 @@ function pluginUnocss(options = {}) {
402
441
  middlewares.unshift(async (req, res, next) => {
403
442
  if (req.url?.startsWith("/uno.css")) {
404
443
  try {
405
- if (!fs.existsSync(resolvedOutputPath)) {
406
- res.statusCode = 404;
407
- res.setHeader("Content-Type", "text/plain; charset=utf-8");
408
- res.end("CSS file not found. Please restart the dev server to generate it.");
409
- console.warn("[UnoCSS Hybrid] CSS file not found at:", resolvedOutputPath);
410
- return;
411
- }
412
444
  res.setHeader("Content-Type", "text/css; charset=utf-8");
413
445
  res.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
414
446
  res.setHeader("Pragma", "no-cache");
415
447
  res.setHeader("Expires", "0");
448
+ if (!fs.existsSync(resolvedOutputPath)) {
449
+ const outputDir2 = path.dirname(resolvedOutputPath);
450
+ if (!fs.existsSync(outputDir2)) {
451
+ try {
452
+ await fs.promises.mkdir(outputDir2, { recursive: true });
453
+ console.log("[UnoCSS Hybrid] Created output directory:", outputDir2);
454
+ } catch (mkdirErr) {
455
+ console.error("[UnoCSS Hybrid] Failed to create directory:", mkdirErr);
456
+ }
457
+ }
458
+ if (!fs.existsSync(resolvedOutputPath)) {
459
+ console.warn("[UnoCSS Hybrid] CSS file not found yet at:", resolvedOutputPath);
460
+ console.log("[UnoCSS Hybrid] Returning empty CSS, will try to regenerate...");
461
+ res.end("/* UnoCSS: CSS file will be generated shortly */");
462
+ generateCSS().catch((err) => {
463
+ console.error("[UnoCSS Hybrid] Background regeneration failed:", err);
464
+ });
465
+ return;
466
+ }
467
+ }
416
468
  const css = fs.readFileSync(resolvedOutputPath, "utf-8");
417
469
  res.end(css);
418
470
  } catch (err) {
419
471
  console.error("[UnoCSS Hybrid] Error serving CSS:", err);
420
- res.statusCode = 500;
421
- res.setHeader("Content-Type", "text/plain; charset=utf-8");
422
- res.end("Error loading CSS file. Check console for details.");
472
+ res.setHeader("Content-Type", "text/css; charset=utf-8");
473
+ res.end("/* UnoCSS: Error loading CSS file */");
423
474
  }
424
475
  } else {
425
476
  next();
@@ -1 +1 @@
1
- {"version":3,"sources":["../plugin-unocss.ts"],"names":["__filename","__dirname","relPath","generator","result","stats"],"mappings":"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","file":"plugin-unocss.mjs","sourcesContent":["import type { RsbuildPlugin } from '@rsbuild/core';\nimport type { UserConfig } from 'unocss';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport { fileURLToPath } from 'url';\nimport { createHash } from 'crypto';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\nexport interface PluginUnocssOptions {\n /** UnoCSS 配置文件路径或直接配置对象 (默认: './uno.config.ts') */\n unocssConfig?: string | UserConfig;\n\n /**\n * 生成的 CSS 文件输出路径\n *\n * 路径解析规则:\n * - 以 './' 开头: 相对于项目根目录 (推荐)\n * - 相对路径: 相对于插件目录\n * - 绝对路径: 直接使用\n * - 未配置: 默认为 'generated/uno.css' 相对于插件目录\n */\n outputPath?: string;\n\n /** 扫描的内容文件路径模式 (支持 glob 模式) */\n contentPatterns?: string[];\n\n /** 监听的目录路径 (用于开发环境的 watch 模式, 默认: 'src') */\n watchDirectory?: string;\n\n /** 是否自动在 HTML 中注入生成的 CSS link 标签 (默认: true) */\n autoInject?: boolean;\n\n /** 是否在开发环境启用文件监听模式 (默认: true) */\n watch?: boolean;\n\n /**\n * 是否在生产环境为 CSS 文件名添加 content hash\n *\n * 启用后, 文件名格式为 'uno.[hash].css', hash 基于 CSS 内容生成 (默认: true)\n */\n enableHash?: boolean;\n\n /**\n * 增量更新阈值:达到此次数后触发全量重建 (默认: 30)\n */\n incrementalThreshold?: number;\n\n /**\n * 文件变化防抖延迟,单位毫秒 (默认: 300)\n */\n debounceDelay?: number;\n\n /**\n * 全量重建前的等待延迟,单位毫秒 (默认: 2000)\n */\n fullRegenerationDelay?: number;\n\n /**\n * 是否启用详细日志 (默认: false)\n */\n verbose?: boolean;\n}\n\n/**\n * UnoCSS Plugin for Rsbuild\n *\n * 一个用于 Rsbuild 的 UnoCSS 插件,提供 CLI 预生成和自动注入功能.\n *\n * 特性:\n * - 扫描项目文件并生成独立的 CSS 文件\n * - 开发环境支持文件监听和热更新\n * - 生产环境支持 CSS 文件名 hash\n * - 自动在 HTML 中注入 CSS link 标签\n *\n * @param options - 插件配置选项\n * @returns Rsbuild 插件实例\n *\n * @example\n * ```ts\n * import { pluginUnocss } from '@ikkin/plugin-unocss';\n *\n * export default {\n * plugins: [\n * pluginUnocss({\n * outputPath: './src/generated/uno.css',\n * enableHash: true,\n * })\n * ]\n * };\n * ```\n */\nexport function pluginUnocss(\n options: PluginUnocssOptions = {},\n): RsbuildPlugin {\n const {\n unocssConfig = './uno.config.ts',\n outputPath = '',\n contentPatterns = [\n './src/**/*.{html,js,ts,jsx,tsx}',\n './index.html',\n ],\n watchDirectory = 'src',\n autoInject = true,\n watch = true,\n enableHash = true,\n } = options;\n\n return {\n name: 'unocss',\n\n setup(api) {\n const rootContext = api.context.rootPath;\n\n // 解析配置选项\n const {\n incrementalThreshold = 30,\n debounceDelay = 300,\n fullRegenerationDelay = 2000,\n verbose = false,\n } = options;\n\n // 解析输出路径\n const pluginDir = __dirname;\n let resolvedOutputPath: string;\n\n if (!outputPath) {\n // 未配置:使用默认路径(相对于插件目录)\n resolvedOutputPath = path.resolve(pluginDir, './generated/uno.css');\n } else if (path.isAbsolute(outputPath)) {\n // 绝对路径:直接使用\n resolvedOutputPath = outputPath;\n } else if (outputPath.startsWith('./')) {\n // 以 ./ 开头:相对于项目根目录(推荐,更明确)\n resolvedOutputPath = path.resolve(rootContext, outputPath);\n } else {\n // 相对路径(不带 ./):相对于插件目录(更简洁)\n resolvedOutputPath = path.resolve(pluginDir, outputPath);\n }\n\n // 用于保存当前生成的 CSS 文件路径(可能包含 hash)\n let currentCssPath = resolvedOutputPath;\n\n // 获取 rsbuild 的 CSS 输出路径配置\n const getCssOutputPaths = (fileName: string) => {\n try {\n const normalizedConfig = api.getNormalizedConfig();\n const distRoot = normalizedConfig.output.distPath.root || 'dist';\n const cssPath = normalizedConfig.output.distPath.css || 'static/css';\n // 获取 server.base 配置(用于部署到子目录)\n const serverBase = normalizedConfig.server?.base || '/';\n\n // 返回绝对路径和相对路径(用于 HTML 注入)\n const absoluteDir = path.isAbsolute(distRoot)\n ? distRoot\n : path.join(rootContext, distRoot);\n\n // 确保 base 路径以 / 开头和结尾\n const normalizedBase = serverBase.startsWith('/')\n ? serverBase\n : `/${serverBase}`;\n const baseWithTrailingSlash = normalizedBase.endsWith('/')\n ? normalizedBase\n : `${normalizedBase}/`;\n\n return {\n // CSS 文件的绝对输出目录\n absoluteDir: path.join(absoluteDir, cssPath),\n // CSS 文件的 URL 相对路径(用于 HTML 中引用)\n // 移除开头的 / 因为 base 已经包含了\n urlPath: `${baseWithTrailingSlash}${cssPath.startsWith('/') ? cssPath.slice(1) : cssPath}/${fileName}`,\n };\n } catch (err) {\n // 如果获取配置失败,使用默认值\n console.warn('[UnoCSS Hybrid] Failed to get rsbuild config, using default CSS path');\n return {\n absoluteDir: path.join(rootContext, 'dist', 'static', 'css'),\n urlPath: `/static/css/${fileName}`,\n };\n }\n };\n\n // WebSocket 类型定义\n type WebSocketServer = import('ws').WebSocketServer;\n\n // 用于保存 WebSocket 服务器实例和端口\n let wss: WebSocketServer | null = null;\n // 动态分配的 WebSocket 端口(避免端口冲突)\n let wsPort = 0;\n\n // 通过环境变量判断是否是生产环境\n const isProd = process.env.NODE_ENV === 'production';\n\n // 文件内容哈希缓存(用于增量生成)\n const fileContentCache = new Map<string, string>();\n // 增量更新计数器\n let incrementalUpdateCount = 0;\n // 全量重建锁(防止重复重建)\n let isFullRegenerationInProgress = false;\n // 全量重建的定时器\n let fullRegenerationTimer: NodeJS.Timeout | null = null;\n // 待处理的重建请求(在重建完成后再次触发)\n let pendingFullRegeneration = false;\n\n // Generator 实例复用\n let generatorInstance: any = null;\n\n // 日志辅助函数\n const log = (message: string, force = false) => {\n if (verbose || force) {\n console.log(`[UnoCSS Hybrid] ${message}`);\n }\n };\n\n // 初始化或获取 generator 实例\n const getGenerator = async (config: UserConfig): Promise<any> => {\n if (!generatorInstance) {\n const { createGenerator } = await import('unocss');\n generatorInstance = await createGenerator(config);\n }\n return generatorInstance;\n };\n\n // 自动注入:通过修改 HTML 标签来注入 CSS(不污染源码)\n if (autoInject) {\n api.modifyHTMLTags((tags) => {\n let cssPath: string;\n\n if (isProd && enableHash) {\n // 生产环境:使用 rsbuild 配置的 CSS 输出路径\n // 此时 currentCssPath 可能还未更新,所以使用占位符\n const cssFileName = path.basename(currentCssPath || 'uno.css');\n const { urlPath } = getCssOutputPaths(cssFileName);\n cssPath = urlPath;\n } else {\n // 开发环境或未启用 hash:使用固定文件名\n cssPath = '/uno.css';\n }\n\n tags.headTags.unshift({\n tag: 'link',\n attrs: {\n rel: 'stylesheet',\n href: cssPath,\n },\n });\n\n console.log(`[UnoCSS Hybrid] Auto-injected CSS link: ${cssPath}`);\n\n // 开发环境:注入热更新脚本和 WebSocket 端口\n if (!isProd) {\n const hotReloadScript = `\n (function() {\n function reloadCSS(version) {\n const oldLink = document.querySelector('link[href*=\"/uno.css\"]');\n if (oldLink && oldLink.parentNode) {\n const newLink = document.createElement('link');\n newLink.rel = 'stylesheet';\n newLink.href = '/uno.css?v=' + version;\n oldLink.parentNode.insertBefore(newLink, oldLink);\n\n newLink.onload = function() {\n if (oldLink.parentNode) {\n oldLink.parentNode.removeChild(oldLink);\n }\n };\n\n newLink.onerror = function() {\n console.error('[UnoCSS] Failed to reload CSS');\n if (newLink.parentNode) {\n newLink.parentNode.removeChild(newLink);\n }\n };\n }\n }\n\n const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';\n const host = window.location.hostname;\n const wsUrl = protocol + '//' + host + ':${wsPort}';\n\n let socket = null;\n let reconnectCount = 0;\n const maxReconnect = 10;\n\n function connect() {\n if (reconnectCount === 0) {\n console.log('[UnoCSS] WebSocket connecting to ' + wsUrl);\n }\n\n socket = new WebSocket(wsUrl);\n\n socket.onopen = function() {\n console.log('[UnoCSS] WebSocket connected.');\n reconnectCount = 0;\n };\n\n socket.onmessage = function(event) {\n try {\n const data = JSON.parse(event.data);\n if (data.type === 'css-update' && data.version) {\n reloadCSS(data.version);\n }\n } catch (e) {\n // 忽略解析错误\n }\n };\n\n socket.onclose = function() {\n if (reconnectCount >= maxReconnect) {\n console.warn('[UnoCSS] WebSocket connection failed after maximum retry attempts.');\n return;\n }\n\n if (reconnectCount === 0) {\n console.log('[UnoCSS] WebSocket connection lost. Reconnecting...');\n }\n\n reconnectCount++;\n const delay = Math.min(1000 * Math.pow(1.5, reconnectCount), 30000);\n setTimeout(connect, delay);\n };\n\n socket.onerror = function(error) {\n console.error('[UnoCSS] WebSocket error:', error);\n };\n }\n\n connect();\n })();\n `;\n tags.bodyTags.push({\n tag: 'script',\n children: hotReloadScript,\n });\n console.log('[UnoCSS Hybrid] Hot reload script injected');\n }\n\n return tags;\n });\n }\n\n // 读取 UnoCSS 配置\n const loadConfig = async (): Promise<UserConfig> => {\n if (typeof unocssConfig === 'string') {\n const configPath = path.resolve(rootContext, unocssConfig);\n try {\n const configModule = await import(\n `file:///${configPath.replace(/\\\\/g, '/')}`\n );\n return configModule.default || configModule;\n } catch (err) {\n console.warn(\n `[UnoCSS Hybrid] Failed to load config from ${configPath}, using default config`,\n );\n return {};\n }\n }\n return unocssConfig;\n };\n\n // 生成文件内容的哈希\n const getFileHash = (content: string): string => {\n return createHash('md5').update(content).digest('hex');\n };\n\n // 异步全量重建(可在后台执行,不阻塞)\n const scheduleFullRegeneration = () => {\n if (isFullRegenerationInProgress) {\n log('Full regeneration already in progress, will schedule after current finishes');\n pendingFullRegeneration = true;\n return;\n }\n\n // 清除旧的定时器\n if (fullRegenerationTimer) {\n clearTimeout(fullRegenerationTimer);\n }\n\n // 延迟执行(确保文件变化暂停)\n fullRegenerationTimer = setTimeout(async () => {\n log('Starting full regeneration in background...', true);\n isFullRegenerationInProgress = true;\n pendingFullRegeneration = false;\n\n try {\n const config = await loadConfig();\n const { globby } = await import('globby');\n\n const files = await globby(contentPatterns, {\n cwd: rootContext,\n absolute: true,\n });\n\n // 读取所有文件内容\n const allContents = files.map(file => {\n const content = fs.readFileSync(file, 'utf-8');\n const hash = getFileHash(content);\n const relPath = path.relative(rootContext, file);\n fileContentCache.set(relPath, hash);\n return content;\n }).join('\\n');\n\n const generator = await getGenerator(config);\n const result = await generator.generate(allContents);\n\n if (result.css && result.css.trim().length > 0) {\n fs.writeFileSync(resolvedOutputPath, result.css);\n\n const stats = fs.statSync(resolvedOutputPath);\n console.log(\n `[UnoCSS Hybrid] Full regeneration completed: ${resolvedOutputPath} (${(stats.size / 1024).toFixed(2)} KB)`,\n );\n\n // 重置计数器\n incrementalUpdateCount = 0;\n\n // 通知浏览器刷新\n if (wss) {\n const version = Date.now();\n const message = JSON.stringify({\n type: 'css-update',\n version: version,\n });\n\n wss.clients.forEach((client: any) => {\n if (client.readyState === 1) {\n client.send(message);\n }\n });\n\n console.log(`[UnoCSS Hybrid] Broadcasted full regeneration to ${wss.clients.size} client(s)`);\n }\n }\n } catch (err) {\n console.error('[UnoCSS Hybrid] Full regeneration failed:', err);\n } finally {\n isFullRegenerationInProgress = false;\n fullRegenerationTimer = null;\n\n // 如果在重建期间有新的文件变化,再次触发重建\n if (pendingFullRegeneration) {\n log('Pending regeneration detected, scheduling...');\n pendingFullRegeneration = false;\n scheduleFullRegeneration();\n }\n }\n }, fullRegenerationDelay);\n };\n\n // 生成 UnoCSS CSS(开发模式支持增量生成)\n const generateCSS = async (changedFiles?: string[]): Promise<string> => {\n try {\n const config = await loadConfig();\n\n // 扫描文件\n const { globby } = await import('globby');\n const files = await globby(contentPatterns, {\n cwd: rootContext,\n absolute: true,\n });\n\n if (files.length === 0) {\n console.warn('[UnoCSS Hybrid] No files found to scan');\n return resolvedOutputPath;\n }\n\n // 开发模式的增量生成逻辑\n if (!isProd && changedFiles && fileContentCache.size > 0) {\n // 全量重建期间,跳过增量更新\n if (isFullRegenerationInProgress) {\n log('Skipping incremental update during full regeneration');\n return resolvedOutputPath;\n }\n\n // 检测是否有真正的内容变化\n let hasRealChanges = false;\n\n for (const file of changedFiles) {\n if (!fs.existsSync(file)) {\n // 文件被删除,从缓存中移除\n const relPath = path.relative(rootContext, file);\n fileContentCache.delete(relPath);\n hasRealChanges = true;\n log(`File removed: ${relPath}`);\n continue;\n }\n\n const content = fs.readFileSync(file, 'utf-8');\n const hash = getFileHash(content);\n const relPath = path.relative(rootContext, file);\n\n if (fileContentCache.get(relPath) !== hash) {\n // 文件内容变化了\n fileContentCache.set(relPath, hash);\n hasRealChanges = true;\n log(`File changed: ${relPath} (hash: ${hash.substring(0, 8)})`);\n }\n }\n\n // 如果有真正的变化,进行增量生成\n if (hasRealChanges) {\n console.log(`[UnoCSS Hybrid] Files changed, performing incremental update...`);\n\n const generator = await getGenerator(config);\n\n // 只读取变化的文件内容\n const changedContents: string[] = [];\n for (const file of changedFiles) {\n if (fs.existsSync(file)) {\n const content = fs.readFileSync(file, 'utf-8');\n changedContents.push(content);\n }\n }\n\n // 生成变化文件的 CSS\n const changedContent = changedContents.join('\\n');\n const result = await generator.generate(changedContent);\n\n if (result.css && result.css.trim().length > 0) {\n // 直接追加新 CSS(简单快速)\n if (fs.existsSync(resolvedOutputPath)) {\n fs.appendFileSync(resolvedOutputPath, '\\n' + result.css);\n } else {\n fs.writeFileSync(resolvedOutputPath, result.css);\n }\n\n // 增加计数器\n incrementalUpdateCount++;\n\n const stats = fs.statSync(resolvedOutputPath);\n console.log(\n `[UnoCSS Hybrid] Incremental update: ${resolvedOutputPath} (${(stats.size / 1024).toFixed(2)} KB, update #${incrementalUpdateCount}/${incrementalThreshold})`,\n );\n\n // 检查是否需要触发全量重建\n if (incrementalUpdateCount >= incrementalThreshold) {\n console.log(`[UnoCSS Hybrid] Threshold reached (${incrementalUpdateCount} updates), scheduling full regeneration...`);\n scheduleFullRegeneration();\n }\n\n return resolvedOutputPath;\n }\n } else {\n log('No content changes detected, skipping generation');\n return resolvedOutputPath;\n }\n }\n\n // 全量生成(生产环境或首次生成)\n console.log('[UnoCSS Hybrid] Full CSS generation...');\n\n const generator = await getGenerator(config);\n\n // 读取所有文件内容并更新缓存\n const allContents = files.map(file => {\n const content = fs.readFileSync(file, 'utf-8');\n const hash = getFileHash(content);\n const relPath = path.relative(rootContext, file);\n fileContentCache.set(relPath, hash);\n return content;\n }).join('\\n');\n\n // 生成 CSS\n const result = await generator.generate(allContents);\n\n if (!result.css || result.css.trim().length === 0) {\n console.warn('[UnoCSS Hybrid] Generated CSS is empty');\n return resolvedOutputPath;\n }\n\n // 计算输出路径\n let finalOutputPath: string;\n if (isProd && enableHash) {\n // 生产环境:生成到 rsbuild 配置的 CSS 输出目录,文件名带 hash\n const hash = createHash('md5').update(result.css).digest('hex').substring(0, 8);\n const cssFileName = `uno.${hash}.css`;\n const { absoluteDir } = getCssOutputPaths(cssFileName);\n finalOutputPath = path.join(absoluteDir, cssFileName);\n currentCssPath = finalOutputPath;\n } else {\n // 开发环境:生成到插件目录的 generated 子目录,文件名固定\n finalOutputPath = resolvedOutputPath;\n currentCssPath = resolvedOutputPath;\n }\n\n // 确保输出目录存在\n const outputDir = path.dirname(finalOutputPath);\n if (!fs.existsSync(outputDir)) {\n fs.mkdirSync(outputDir, { recursive: true });\n }\n\n // 写入 CSS 文件\n fs.writeFileSync(finalOutputPath, result.css);\n\n const stats = fs.statSync(finalOutputPath);\n console.log(\n `[UnoCSS Hybrid] CSS generated: ${finalOutputPath} (${(stats.size / 1024).toFixed(2)} KB)`,\n );\n\n return finalOutputPath;\n } catch (err) {\n console.error('[UnoCSS Hybrid] Failed to generate CSS:', err);\n return resolvedOutputPath;\n }\n };\n\n // 生产环境:构建前生成 CSS\n if (isProd) {\n api.onBeforeBuild(async () => {\n await generateCSS();\n });\n }\n\n // 开发环境:配置静态文件服务和热更新\n if (!isProd) {\n\n api.modifyRsbuildConfig((config) => {\n const existingSetupMiddlewares = config.dev?.setupMiddlewares;\n const setupMiddlewaresArray = Array.isArray(existingSetupMiddlewares)\n ? existingSetupMiddlewares\n : existingSetupMiddlewares\n ? [existingSetupMiddlewares]\n : [];\n\n return {\n ...config,\n dev: {\n ...config.dev,\n setupMiddlewares: [\n ...setupMiddlewaresArray,\n (middlewares, _devServer) => {\n // 添加自定义中间件来提供 CSS 文件\n middlewares.unshift(async (req, res, next) => {\n // 处理带查询参数的请求 (如 /uno.css?v=123456)\n if (req.url?.startsWith('/uno.css')) {\n try {\n // 检查文件是否存在\n if (!fs.existsSync(resolvedOutputPath)) {\n res.statusCode = 404;\n res.setHeader('Content-Type', 'text/plain; charset=utf-8');\n res.end('CSS file not found. Please restart the dev server to generate it.');\n console.warn('[UnoCSS Hybrid] CSS file not found at:', resolvedOutputPath);\n return;\n }\n\n // 设置正确的 Content-Type 和缓存控制\n res.setHeader('Content-Type', 'text/css; charset=utf-8');\n // 禁用缓存,确保每次都获取最新内容\n res.setHeader('Cache-Control', 'no-cache, no-store, must-revalidate');\n res.setHeader('Pragma', 'no-cache');\n res.setHeader('Expires', '0');\n\n const css = fs.readFileSync(resolvedOutputPath, 'utf-8');\n res.end(css);\n } catch (err) {\n console.error('[UnoCSS Hybrid] Error serving CSS:', err);\n res.statusCode = 500;\n res.setHeader('Content-Type', 'text/plain; charset=utf-8');\n res.end('Error loading CSS file. Check console for details.');\n }\n } else {\n next();\n }\n });\n },\n ],\n },\n };\n });\n\n // 启动时生成 CSS 并创建 WebSocket 服务器\n api.onBeforeStartDevServer(async () => {\n console.log('[UnoCSS Hybrid] Development mode: CLI generation enabled');\n await generateCSS();\n\n // 提前创建 WebSocket 服务器,以便在 HTML 生成前获取端口\n try {\n const { WebSocketServer } = await import('ws');\n\n // 创建 WebSocket 服务器,使用 port: 0 让系统自动分配可用端口\n wss = new WebSocketServer({ port: 0 });\n wsPort = (wss.address() as any).port;\n\n console.log(`[UnoCSS Hybrid] WebSocket server created on port ${wsPort}`);\n\n // 当客户端连接时\n wss.on('connection', (ws: any) => {\n console.log('[UnoCSS Hybrid] Client connected to WebSocket');\n\n ws.on('close', () => {\n console.log('[UnoCSS Hybrid] Client disconnected from WebSocket');\n });\n });\n\n console.log('[UnoCSS Hybrid] UnoCSS HMR WebSocket server ready');\n } catch (err) {\n console.error('[UnoCSS Hybrid] Failed to create WebSocket server:', err);\n }\n });\n\n // 合并启动后的操作\n api.onAfterStartDevServer(async () => {\n console.log('[UnoCSS Hybrid] Dev server started, CSS available at /uno.css');\n\n // Watch 模式\n if (watch) {\n try {\n log('Initializing watch mode...', true);\n\n // 动态导入 chokidar\n const chokidar = await import('chokidar');\n log('chokidar imported successfully');\n\n // 监听指定目录\n const watchDir = path.resolve(rootContext, watchDirectory);\n console.log(`[UnoCSS Hybrid] Watching directory: ${watchDir}`);\n\n // 监听内容文件变化\n const watcher = chokidar.watch(watchDir, {\n ignored: /(^|[\\/\\\\])\\../, // ignore dotfiles\n ignoreInitial: true,\n persistent: true,\n });\n\n log('Watcher created, setting up event handlers...');\n\n watcher.on('ready', () => {\n log('Watcher ready, scanning for files...');\n });\n\n watcher.on('error', (error) => {\n console.error('[UnoCSS Hybrid] Watcher error:', error);\n });\n\n // 防抖:避免频繁重新生成\n let regenerateTimer: NodeJS.Timeout | null = null;\n // 收集本次防抖周期内的变化文件\n let changedFilesInBatch: string[] = [];\n\n watcher.on('all', async (event: string, filePath: string) => {\n log(`Watcher event: ${event} on ${path.relative(rootContext, filePath)}`);\n\n // 检查文件扩展名\n const ext = path.extname(filePath);\n const shouldWatch = ['.html', '.js', '.ts', '.jsx', '.tsx'].includes(ext);\n\n log(`File extension: ${ext}, shouldWatch: ${shouldWatch}`);\n\n // 监听文件添加、修改和删除\n if (shouldWatch && (event === 'change' || event === 'add' || event === 'unlink')) {\n log(`File ${event}: ${path.relative(rootContext, filePath)} - queuing`);\n\n // 将变化的文件添加到批次中\n changedFilesInBatch.push(filePath);\n\n if (regenerateTimer) {\n clearTimeout(regenerateTimer);\n }\n\n regenerateTimer = setTimeout(async () => {\n console.log(`[UnoCSS Hybrid] Regenerating CSS... (${changedFilesInBatch.length} file(s) changed)`);\n\n // 传递变化文件列表,启用增量生成\n await generateCSS(changedFilesInBatch);\n\n const version = Date.now();\n console.log('[UnoCSS Hybrid] Broadcasting CSS update via WebSocket, version:', version);\n\n // 通过我们自己的 WebSocket 广播更新\n if (wss) {\n const message = JSON.stringify({\n type: 'css-update',\n version: version,\n });\n\n wss.clients.forEach((client: any) => {\n if (client.readyState === 1) { // WebSocket.OPEN\n client.send(message);\n }\n });\n\n console.log(`[UnoCSS Hybrid] Broadcasted to ${wss.clients.size} client(s)`);\n } else {\n console.warn('[UnoCSS Hybrid] WebSocket server not available');\n }\n\n // 清空批次\n changedFilesInBatch = [];\n }, debounceDelay);\n } else {\n log(`Event ignored - ext: ${ext}, event: ${event}`);\n }\n });\n\n console.log('[UnoCSS Hybrid] Watch mode: enabled');\n } catch (err) {\n console.warn('[UnoCSS Hybrid] Watch mode not available:', (err as Error).message);\n }\n }\n });\n }\n\n // 构建完成后的日志\n api.onAfterBuild(() => {\n if (isProd && fs.existsSync(currentCssPath)) {\n const stats = fs.statSync(currentCssPath);\n const fileName = path.basename(currentCssPath);\n console.log(\n `[UnoCSS Hybrid] Final CSS: ${fileName} (${(stats.size / 1024).toFixed(2)} KB)`,\n );\n }\n });\n\n // 关闭 dev server 时清理 WebSocket 服务器\n api.onCloseDevServer(async () => {\n if (wss) {\n console.log('[UnoCSS Hybrid] Closing WebSocket server...');\n wss.close();\n wss = null;\n }\n });\n },\n };\n}\n\nexport default pluginUnocss;\n"]}
1
+ {"version":3,"sources":["../plugin-unocss.ts"],"names":["__filename","relPath","generator","result","stats","outputDir"],"mappings":"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","file":"plugin-unocss.mjs","sourcesContent":["import type { RsbuildPlugin } from '@rsbuild/core';\nimport type { UserConfig } from 'unocss';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport { fileURLToPath } from 'url';\nimport { createHash } from 'crypto';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\nexport interface PluginUnocssOptions {\n /** UnoCSS 配置文件路径或直接配置对象 (默认: './uno.config.ts') */\n unocssConfig?: string | UserConfig;\n\n /**\n * 生成的 CSS 文件输出路径\n *\n * 路径解析规则:\n * - 以 './' 开头: 相对于项目根目录 (推荐)\n * - 相对路径: 相对于插件目录\n * - 绝对路径: 直接使用\n * - 未配置: 默认为 'generated/uno.css' 相对于插件目录\n */\n outputPath?: string;\n\n /** 扫描的内容文件路径模式 (支持 glob 模式) */\n contentPatterns?: string[];\n\n /** 监听的目录路径 (用于开发环境的 watch 模式, 默认: 'src') */\n watchDirectory?: string;\n\n /** 是否自动在 HTML 中注入生成的 CSS link 标签 (默认: true) */\n autoInject?: boolean;\n\n /** 是否在开发环境启用文件监听模式 (默认: true) */\n watch?: boolean;\n\n /**\n * 是否在生产环境为 CSS 文件名添加 content hash\n *\n * 启用后, 文件名格式为 'uno.[hash].css', hash 基于 CSS 内容生成 (默认: true)\n */\n enableHash?: boolean;\n\n /**\n * 增量更新阈值:达到此次数后触发全量重建 (默认: 30)\n */\n incrementalThreshold?: number;\n\n /**\n * 文件变化防抖延迟,单位毫秒 (默认: 300)\n */\n debounceDelay?: number;\n\n /**\n * 全量重建前的等待延迟,单位毫秒 (默认: 2000)\n */\n fullRegenerationDelay?: number;\n\n /**\n * 是否启用详细日志 (默认: false)\n */\n verbose?: boolean;\n}\n\n/**\n * UnoCSS Plugin for Rsbuild\n *\n * 一个用于 Rsbuild 的 UnoCSS 插件,提供 CLI 预生成和自动注入功能.\n *\n * 特性:\n * - 扫描项目文件并生成独立的 CSS 文件\n * - 开发环境支持文件监听和热更新\n * - 生产环境支持 CSS 文件名 hash\n * - 自动在 HTML 中注入 CSS link 标签\n *\n * @param options - 插件配置选项\n * @returns Rsbuild 插件实例\n *\n * @example\n * ```ts\n * import { pluginUnocss } from '@ikkin/plugin-unocss';\n *\n * export default {\n * plugins: [\n * pluginUnocss({\n * outputPath: './src/generated/uno.css',\n * enableHash: true,\n * })\n * ]\n * };\n * ```\n */\nexport function pluginUnocss(\n options: PluginUnocssOptions = {},\n): RsbuildPlugin {\n const {\n unocssConfig = './uno.config.ts',\n outputPath = '',\n contentPatterns = [\n './src/**/*.{html,js,ts,jsx,tsx}',\n './index.html',\n ],\n watchDirectory = 'src',\n autoInject = true,\n watch = true,\n enableHash = true,\n } = options;\n\n return {\n name: 'unocss',\n\n setup(api) {\n const rootContext = api.context.rootPath;\n\n // 解析配置选项\n const {\n incrementalThreshold = 30,\n debounceDelay = 300,\n fullRegenerationDelay = 2000,\n verbose = false,\n } = options;\n\n // 解析输出路径\n const pluginDir = __dirname;\n let resolvedOutputPath: string;\n\n if (!outputPath) {\n // 未配置:使用默认路径(相对于项目根目录)\n // 修复:改为项目根目录,避免跨电脑路径问题\n resolvedOutputPath = path.resolve(rootContext, './generated/uno.css');\n } else if (path.isAbsolute(outputPath)) {\n // 绝对路径:直接使用\n resolvedOutputPath = outputPath;\n } else if (outputPath.startsWith('./')) {\n // 以 ./ 开头:相对于项目根目录(推荐,更明确)\n resolvedOutputPath = path.resolve(rootContext, outputPath);\n } else {\n // 相对路径(不带 ./):相对于项目根目录(保持一致性)\n resolvedOutputPath = path.resolve(rootContext, outputPath);\n }\n\n // 确保输出目录存在(在初始化时就创建,避免时序问题)\n const outputDir = path.dirname(resolvedOutputPath);\n if (!fs.existsSync(outputDir)) {\n try {\n fs.mkdirSync(outputDir, { recursive: true });\n console.log('[UnoCSS Hybrid] Created output directory:', outputDir);\n } catch (err) {\n console.error('[UnoCSS Hybrid] Failed to create output directory:', err);\n }\n }\n\n // 用于保存当前生成的 CSS 文件路径(可能包含 hash)\n let currentCssPath = resolvedOutputPath;\n\n // 获取 rsbuild 的 CSS 输出路径配置\n const getCssOutputPaths = (fileName: string) => {\n try {\n const normalizedConfig = api.getNormalizedConfig();\n const distRoot = normalizedConfig.output.distPath.root || 'dist';\n const cssPath = normalizedConfig.output.distPath.css || 'static/css';\n // 获取 server.base 配置(用于部署到子目录)\n const serverBase = normalizedConfig.server?.base || '/';\n\n // 返回绝对路径和相对路径(用于 HTML 注入)\n const absoluteDir = path.isAbsolute(distRoot)\n ? distRoot\n : path.join(rootContext, distRoot);\n\n // 确保 base 路径以 / 开头和结尾\n const normalizedBase = serverBase.startsWith('/')\n ? serverBase\n : `/${serverBase}`;\n const baseWithTrailingSlash = normalizedBase.endsWith('/')\n ? normalizedBase\n : `${normalizedBase}/`;\n\n return {\n // CSS 文件的绝对输出目录\n absoluteDir: path.join(absoluteDir, cssPath),\n // CSS 文件的 URL 相对路径(用于 HTML 中引用)\n // 移除开头的 / 因为 base 已经包含了\n urlPath: `${baseWithTrailingSlash}${cssPath.startsWith('/') ? cssPath.slice(1) : cssPath}/${fileName}`,\n };\n } catch (err) {\n // 如果获取配置失败,使用默认值\n console.warn('[UnoCSS Hybrid] Failed to get rsbuild config, using default CSS path');\n return {\n absoluteDir: path.join(rootContext, 'dist', 'static', 'css'),\n urlPath: `/static/css/${fileName}`,\n };\n }\n };\n\n // WebSocket 类型定义\n type WebSocketServer = import('ws').WebSocketServer;\n\n // 用于保存 WebSocket 服务器实例和端口\n let wss: WebSocketServer | null = null;\n // 动态分配的 WebSocket 端口(避免端口冲突)\n let wsPort = 0;\n\n // 通过环境变量判断是否是生产环境\n const isProd = process.env.NODE_ENV === 'production';\n\n // 文件内容哈希缓存(用于增量生成)\n const fileContentCache = new Map<string, string>();\n // 增量更新计数器\n let incrementalUpdateCount = 0;\n // 全量重建锁(防止重复重建)\n let isFullRegenerationInProgress = false;\n // 全量重建的定时器\n let fullRegenerationTimer: NodeJS.Timeout | null = null;\n // 待处理的重建请求(在重建完成后再次触发)\n let pendingFullRegeneration = false;\n\n // Generator 实例复用\n let generatorInstance: any = null;\n\n // 日志辅助函数\n const log = (message: string, force = false) => {\n if (verbose || force) {\n console.log(`[UnoCSS Hybrid] ${message}`);\n }\n };\n\n // 初始化或获取 generator 实例\n const getGenerator = async (config: UserConfig): Promise<any> => {\n if (!generatorInstance) {\n const { createGenerator } = await import('unocss');\n generatorInstance = await createGenerator(config);\n }\n return generatorInstance;\n };\n\n // 自动注入:通过修改 HTML 标签来注入 CSS(不污染源码)\n if (autoInject) {\n api.modifyHTMLTags((tags) => {\n let cssPath: string;\n\n if (isProd && enableHash) {\n // 生产环境:使用 rsbuild 配置的 CSS 输出路径\n // 此时 currentCssPath 可能还未更新,所以使用占位符\n const cssFileName = path.basename(currentCssPath || 'uno.css');\n const { urlPath } = getCssOutputPaths(cssFileName);\n cssPath = urlPath;\n } else {\n // 开发环境或未启用 hash:使用固定文件名\n cssPath = '/uno.css';\n }\n\n // 检查是否已注入 CSS link\n const isLinkInjected = tags.headTags.some(\n (tag) => tag.tag === 'link' && tag.attrs && tag.attrs.href === cssPath\n );\n\n if (!isLinkInjected) {\n tags.headTags.unshift({\n tag: 'link',\n attrs: {\n rel: 'stylesheet',\n href: cssPath,\n },\n });\n\n console.log(`[UnoCSS Hybrid] Auto-injected CSS link: ${cssPath}`);\n }\n\n // 开发环境:注入热更新脚本和 WebSocket 端口\n if (!isProd) {\n const hotReloadScript = `\n (function() {\n function reloadCSS(version) {\n const oldLink = document.querySelector('link[href*=\"/uno.css\"]');\n if (oldLink && oldLink.parentNode) {\n const newLink = document.createElement('link');\n newLink.rel = 'stylesheet';\n newLink.href = '/uno.css?v=' + version;\n oldLink.parentNode.insertBefore(newLink, oldLink);\n\n newLink.onload = function() {\n if (oldLink.parentNode) {\n oldLink.parentNode.removeChild(oldLink);\n }\n };\n\n newLink.onerror = function() {\n console.error('[UnoCSS] Failed to reload CSS');\n if (newLink.parentNode) {\n newLink.parentNode.removeChild(newLink);\n }\n };\n }\n }\n\n const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';\n const host = window.location.hostname;\n const wsUrl = protocol + '//' + host + ':${wsPort}';\n\n let socket = null;\n let reconnectCount = 0;\n const maxReconnect = 10;\n\n function connect() {\n if (reconnectCount === 0) {\n console.log('[UnoCSS] WebSocket connecting to ' + wsUrl);\n }\n\n socket = new WebSocket(wsUrl);\n\n socket.onopen = function() {\n console.log('[UnoCSS] WebSocket connected.');\n reconnectCount = 0;\n };\n\n socket.onmessage = function(event) {\n try {\n const data = JSON.parse(event.data);\n if (data.type === 'css-update' && data.version) {\n reloadCSS(data.version);\n }\n } catch (e) {\n // 忽略解析错误\n }\n };\n\n socket.onclose = function() {\n if (reconnectCount >= maxReconnect) {\n console.warn('[UnoCSS] WebSocket connection failed after maximum retry attempts.');\n return;\n }\n\n if (reconnectCount === 0) {\n console.log('[UnoCSS] WebSocket connection lost. Reconnecting...');\n }\n\n reconnectCount++;\n const delay = Math.min(1000 * Math.pow(1.5, reconnectCount), 30000);\n setTimeout(connect, delay);\n };\n\n socket.onerror = function(error) {\n console.error('[UnoCSS] WebSocket error:', error);\n };\n }\n\n connect();\n })();\n `;\n\n // 检查是否已注入热更新脚本\n const isScriptInjected = tags.bodyTags.some(\n (tag) => tag.tag === 'script' && tag.attrs && tag.attrs['data-unocss-hmr']\n );\n\n if (!isScriptInjected) {\n tags.bodyTags.push({\n tag: 'script',\n attrs: { 'data-unocss-hmr': 'true' },\n children: hotReloadScript,\n });\n console.log('[UnoCSS Hybrid] Hot reload script injected');\n }\n }\n\n return tags;\n });\n }\n\n // 缓存配置对象\n let cachedConfig: UserConfig | null = null;\n\n // 读取 UnoCSS 配置 (带缓存)\n const loadConfig = async (reload = false): Promise<UserConfig> => {\n if (cachedConfig && !reload) {\n return cachedConfig;\n }\n\n if (typeof unocssConfig === 'string') {\n const configPath = path.resolve(rootContext, unocssConfig);\n try {\n // 添加时间戳查询参数以绕过可能的模块缓存(仅在强制 reload 时有用,但常规使用 import 缓存即可)\n const configModule = await import(\n `file:///${configPath.replace(/\\\\/g, '/')}`\n );\n cachedConfig = configModule.default || configModule;\n return cachedConfig as UserConfig;\n } catch (err) {\n console.warn(\n `[UnoCSS Hybrid] Failed to load config from ${configPath}, using default config`,\n );\n return {};\n }\n }\n cachedConfig = unocssConfig;\n return unocssConfig;\n };\n\n // 生成文件内容的哈希\n const getFileHash = (content: string): string => {\n return createHash('md5').update(content).digest('hex');\n };\n\n // 异步全量重建(可在后台执行,不阻塞)\n const scheduleFullRegeneration = () => {\n if (isFullRegenerationInProgress) {\n log('Full regeneration already in progress, will schedule after current finishes');\n pendingFullRegeneration = true;\n return;\n }\n\n // 清除旧的定时器\n if (fullRegenerationTimer) {\n clearTimeout(fullRegenerationTimer);\n }\n\n // 延迟执行(确保文件变化暂停)\n fullRegenerationTimer = setTimeout(async () => {\n log('Starting full regeneration in background...', true);\n isFullRegenerationInProgress = true;\n pendingFullRegeneration = false;\n\n try {\n const config = await loadConfig();\n const { globby } = await import('globby');\n\n const files = await globby(contentPatterns, {\n cwd: rootContext,\n absolute: true,\n });\n\n // 并发读取所有文件内容 (优化点:异步并发)\n const contentPromises = files.map(async (file) => {\n try {\n const content = await fs.promises.readFile(file, 'utf-8');\n const hash = getFileHash(content);\n const relPath = path.relative(rootContext, file);\n fileContentCache.set(relPath, hash);\n return content;\n } catch (readErr) {\n console.warn(`[UnoCSS Hybrid] Failed to read file ${file} during regeneration:`, readErr);\n return '';\n }\n });\n\n const contents = await Promise.all(contentPromises);\n const allContents = contents.join('\\n');\n\n const generator = await getGenerator(config);\n const result = await generator.generate(allContents);\n\n if (result.css && result.css.trim().length > 0) {\n await fs.promises.writeFile(resolvedOutputPath, result.css);\n\n const stats = await fs.promises.stat(resolvedOutputPath);\n console.log(\n `[UnoCSS Hybrid] Full regeneration completed: ${resolvedOutputPath} (${(stats.size / 1024).toFixed(2)} KB)`,\n );\n\n // 重置计数器\n incrementalUpdateCount = 0;\n\n // 通知浏览器刷新\n if (wss) {\n const version = Date.now();\n const message = JSON.stringify({\n type: 'css-update',\n version: version,\n });\n\n wss.clients.forEach((client: any) => {\n if (client.readyState === 1) {\n client.send(message);\n }\n });\n\n console.log(`[UnoCSS Hybrid] Broadcasted full regeneration to ${wss.clients.size} client(s)`);\n }\n }\n } catch (err) {\n console.error('[UnoCSS Hybrid] Full regeneration failed:', err);\n } finally {\n isFullRegenerationInProgress = false;\n fullRegenerationTimer = null;\n\n // 如果在重建期间有新的文件变化,再次触发重建\n if (pendingFullRegeneration) {\n log('Pending regeneration detected, scheduling...');\n pendingFullRegeneration = false;\n scheduleFullRegeneration();\n }\n }\n }, fullRegenerationDelay);\n };\n\n // 生成 UnoCSS CSS(开发模式支持增量生成)\n const generateCSS = async (changedFiles?: string[]): Promise<string> => {\n try {\n const config = await loadConfig();\n\n // 开发模式的增量生成逻辑\n if (!isProd && changedFiles && fileContentCache.size > 0) {\n // 全量重建期间,跳过增量更新\n if (isFullRegenerationInProgress) {\n log('Skipping incremental update during full regeneration');\n return resolvedOutputPath;\n }\n\n // 检测是否有真正的内容变化\n let hasRealChanges = false;\n\n for (const file of changedFiles) {\n if (!fs.existsSync(file)) {\n // 文件被删除,从缓存中移除\n const relPath = path.relative(rootContext, file);\n fileContentCache.delete(relPath);\n hasRealChanges = true;\n log(`File removed: ${relPath}`);\n continue;\n }\n\n const content = await fs.promises.readFile(file, 'utf-8');\n const hash = getFileHash(content);\n const relPath = path.relative(rootContext, file);\n\n if (fileContentCache.get(relPath) !== hash) {\n // 文件内容变化了\n fileContentCache.set(relPath, hash);\n hasRealChanges = true;\n log(`File changed: ${relPath} (hash: ${hash.substring(0, 8)})`);\n }\n }\n\n // 如果有真正的变化,进行增量生成\n if (hasRealChanges) {\n console.log(`[UnoCSS Hybrid] Files changed, performing incremental update...`);\n\n const generator = await getGenerator(config);\n\n // 只读取变化的文件内容\n const changedContents: string[] = [];\n for (const file of changedFiles) {\n if (fs.existsSync(file)) {\n const content = await fs.promises.readFile(file, 'utf-8');\n changedContents.push(content);\n }\n }\n\n // 生成变化文件的 CSS\n const changedContent = changedContents.join('\\n');\n const result = await generator.generate(changedContent);\n\n if (result.css && result.css.trim().length > 0) {\n // 直接追加新 CSS(简单快速)\n if (fs.existsSync(resolvedOutputPath)) {\n await fs.promises.appendFile(resolvedOutputPath, '\\n' + result.css);\n } else {\n await fs.promises.writeFile(resolvedOutputPath, result.css);\n }\n\n // 增加计数器\n incrementalUpdateCount++;\n\n const stats = await fs.promises.stat(resolvedOutputPath);\n console.log(\n `[UnoCSS Hybrid] Incremental update: ${resolvedOutputPath} (${(stats.size / 1024).toFixed(2)} KB, update #${incrementalUpdateCount}/${incrementalThreshold})`,\n );\n\n // 检查是否需要触发全量重建\n if (incrementalUpdateCount >= incrementalThreshold) {\n console.log(`[UnoCSS Hybrid] Threshold reached (${incrementalUpdateCount} updates), scheduling full regeneration...`);\n scheduleFullRegeneration();\n }\n\n return resolvedOutputPath;\n }\n } else {\n log('No content changes detected, skipping generation');\n return resolvedOutputPath;\n }\n }\n\n // 全量生成(生产环境或首次生成或全量重建)\n console.log('[UnoCSS Hybrid] Full CSS generation...');\n\n // 扫描文件 (移到这里,仅在全量生成时执行)\n const { globby } = await import('globby');\n const files = await globby(contentPatterns, {\n cwd: rootContext,\n absolute: true,\n });\n\n if (files.length === 0) {\n console.warn('[UnoCSS Hybrid] No files found to scan');\n return resolvedOutputPath;\n }\n\n const generator = await getGenerator(config);\n\n // 并发读取所有文件内容并更新缓存 (优化点:使用 Promise.all 并发读取)\n const contentPromises = files.map(async (file) => {\n try {\n const content = await fs.promises.readFile(file, 'utf-8');\n const hash = getFileHash(content);\n const relPath = path.relative(rootContext, file);\n fileContentCache.set(relPath, hash);\n return content;\n } catch (readErr) {\n console.warn(`[UnoCSS Hybrid] Failed to read file ${file}:`, readErr);\n return '';\n }\n });\n\n const contents = await Promise.all(contentPromises);\n const allContents = contents.join('\\n');\n\n // 生成 CSS\n const result = await generator.generate(allContents);\n\n if (!result.css || result.css.trim().length === 0) {\n console.warn('[UnoCSS Hybrid] Generated CSS is empty');\n return resolvedOutputPath;\n }\n\n // 计算输出路径\n let finalOutputPath: string;\n if (isProd && enableHash) {\n // 生产环境:生成到 rsbuild 配置的 CSS 输出目录,文件名带 hash\n const hash = createHash('md5').update(result.css).digest('hex').substring(0, 8);\n const cssFileName = `uno.${hash}.css`;\n const { absoluteDir } = getCssOutputPaths(cssFileName);\n finalOutputPath = path.join(absoluteDir, cssFileName);\n currentCssPath = finalOutputPath;\n } else {\n // 开发环境:生成到插件目录的 generated 子目录,文件名固定\n finalOutputPath = resolvedOutputPath;\n currentCssPath = resolvedOutputPath;\n }\n\n // 确保输出目录存在\n const outputDir = path.dirname(finalOutputPath);\n if (!fs.existsSync(outputDir)) {\n await fs.promises.mkdir(outputDir, { recursive: true });\n }\n\n // 写入 CSS 文件\n await fs.promises.writeFile(finalOutputPath, result.css);\n\n const stats = await fs.promises.stat(finalOutputPath);\n console.log(\n `[UnoCSS Hybrid] CSS generated: ${finalOutputPath} (${(stats.size / 1024).toFixed(2)} KB)`,\n );\n\n return finalOutputPath;\n } catch (err) {\n console.error('[UnoCSS Hybrid] Failed to generate CSS:', err);\n return resolvedOutputPath;\n }\n };\n\n // 生产环境:构建前生成 CSS\n if (isProd) {\n api.onBeforeBuild(async () => {\n await generateCSS();\n });\n }\n\n // 开发环境:配置静态文件服务和热更新\n if (!isProd) {\n\n api.modifyRsbuildConfig((config) => {\n const existingSetupMiddlewares = config.dev?.setupMiddlewares;\n const setupMiddlewaresArray = Array.isArray(existingSetupMiddlewares)\n ? existingSetupMiddlewares\n : existingSetupMiddlewares\n ? [existingSetupMiddlewares]\n : [];\n\n return {\n ...config,\n dev: {\n ...config.dev,\n setupMiddlewares: [\n ...setupMiddlewaresArray,\n (middlewares, _devServer) => {\n // 添加自定义中间件来提供 CSS 文件\n middlewares.unshift(async (req, res, next) => {\n // 处理带查询参数的请求 (如 /uno.css?v=123456)\n if (req.url?.startsWith('/uno.css')) {\n try {\n // 设置正确的 Content-Type 和缓存控制\n res.setHeader('Content-Type', 'text/css; charset=utf-8');\n // 禁用缓存,确保每次都获取最新内容\n res.setHeader('Cache-Control', 'no-cache, no-store, must-revalidate');\n res.setHeader('Pragma', 'no-cache');\n res.setHeader('Expires', '0');\n\n // 检查文件是否存在\n if (!fs.existsSync(resolvedOutputPath)) {\n // 文件不存在:确保目录存在,并尝试读取(可能刚刚生成)\n const outputDir = path.dirname(resolvedOutputPath);\n if (!fs.existsSync(outputDir)) {\n try {\n await fs.promises.mkdir(outputDir, { recursive: true });\n console.log('[UnoCSS Hybrid] Created output directory:', outputDir);\n } catch (mkdirErr) {\n console.error('[UnoCSS Hybrid] Failed to create directory:', mkdirErr);\n }\n }\n\n // 再次检查文件(可能刚刚生成)\n if (!fs.existsSync(resolvedOutputPath)) {\n // 文件仍然不存在:返回空 CSS 而不是 404\n // 这样可以避免页面加载错误,等待 CSS 生成后重新请求\n console.warn('[UnoCSS Hybrid] CSS file not found yet at:', resolvedOutputPath);\n console.log('[UnoCSS Hybrid] Returning empty CSS, will try to regenerate...');\n res.end('/* UnoCSS: CSS file will be generated shortly */');\n\n // 触发异步生成(不阻塞响应)\n generateCSS().catch(err => {\n console.error('[UnoCSS Hybrid] Background regeneration failed:', err);\n });\n return;\n }\n }\n\n const css = fs.readFileSync(resolvedOutputPath, 'utf-8');\n res.end(css);\n } catch (err) {\n console.error('[UnoCSS Hybrid] Error serving CSS:', err);\n // 出错时也返回空 CSS,避免页面崩溃\n res.setHeader('Content-Type', 'text/css; charset=utf-8');\n res.end('/* UnoCSS: Error loading CSS file */');\n }\n } else {\n next();\n }\n });\n },\n ],\n },\n };\n });\n\n // 启动时生成 CSS 并创建 WebSocket 服务器\n api.onBeforeStartDevServer(async () => {\n console.log('[UnoCSS Hybrid] Development mode: CLI generation enabled');\n await generateCSS();\n\n // 提前创建 WebSocket 服务器,以便在 HTML 生成前获取端口\n try {\n const { WebSocketServer } = await import('ws');\n\n // 创建 WebSocket 服务器,使用 port: 0 让系统自动分配可用端口\n wss = new WebSocketServer({ port: 0 });\n wsPort = (wss.address() as any).port;\n\n console.log(`[UnoCSS Hybrid] WebSocket server created on port ${wsPort}`);\n\n // 当客户端连接时\n wss.on('connection', (ws: any) => {\n console.log('[UnoCSS Hybrid] Client connected to WebSocket');\n\n ws.on('close', () => {\n console.log('[UnoCSS Hybrid] Client disconnected from WebSocket');\n });\n });\n\n console.log('[UnoCSS Hybrid] UnoCSS HMR WebSocket server ready');\n } catch (err) {\n console.error('[UnoCSS Hybrid] Failed to create WebSocket server:', err);\n }\n });\n\n // 合并启动后的操作\n api.onAfterStartDevServer(async () => {\n console.log('[UnoCSS Hybrid] Dev server started, CSS available at /uno.css');\n\n // Watch 模式\n if (watch) {\n try {\n log('Initializing watch mode...', true);\n\n // 动态导入 chokidar\n const chokidar = await import('chokidar');\n log('chokidar imported successfully');\n\n // 监听指定目录\n const watchDir = path.resolve(rootContext, watchDirectory);\n console.log(`[UnoCSS Hybrid] Watching directory: ${watchDir}`);\n\n // 监听内容文件变化\n const watcher = chokidar.watch(watchDir, {\n ignored: /(^|[\\/\\\\])\\../, // ignore dotfiles\n ignoreInitial: true,\n persistent: true,\n });\n\n log('Watcher created, setting up event handlers...');\n\n watcher.on('ready', () => {\n log('Watcher ready, scanning for files...');\n });\n\n watcher.on('error', (error) => {\n console.error('[UnoCSS Hybrid] Watcher error:', error);\n });\n\n // 防抖:避免频繁重新生成\n let regenerateTimer: NodeJS.Timeout | null = null;\n // 收集本次防抖周期内的变化文件\n let changedFilesInBatch: string[] = [];\n\n watcher.on('all', async (event: string, filePath: string) => {\n log(`Watcher event: ${event} on ${path.relative(rootContext, filePath)}`);\n\n // 检查文件扩展名\n const ext = path.extname(filePath);\n const shouldWatch = ['.html', '.js', '.ts', '.jsx', '.tsx'].includes(ext);\n\n log(`File extension: ${ext}, shouldWatch: ${shouldWatch}`);\n\n // 监听文件添加、修改和删除\n if (shouldWatch && (event === 'change' || event === 'add' || event === 'unlink')) {\n log(`File ${event}: ${path.relative(rootContext, filePath)} - queuing`);\n\n // 将变化的文件添加到批次中\n changedFilesInBatch.push(filePath);\n\n if (regenerateTimer) {\n clearTimeout(regenerateTimer);\n }\n\n regenerateTimer = setTimeout(async () => {\n console.log(`[UnoCSS Hybrid] Regenerating CSS... (${changedFilesInBatch.length} file(s) changed)`);\n\n // 传递变化文件列表,启用增量生成\n await generateCSS(changedFilesInBatch);\n\n const version = Date.now();\n console.log('[UnoCSS Hybrid] Broadcasting CSS update via WebSocket, version:', version);\n\n // 通过我们自己的 WebSocket 广播更新\n if (wss) {\n const message = JSON.stringify({\n type: 'css-update',\n version: version,\n });\n\n wss.clients.forEach((client: any) => {\n if (client.readyState === 1) { // WebSocket.OPEN\n client.send(message);\n }\n });\n\n console.log(`[UnoCSS Hybrid] Broadcasted to ${wss.clients.size} client(s)`);\n } else {\n console.warn('[UnoCSS Hybrid] WebSocket server not available');\n }\n\n // 清空批次\n changedFilesInBatch = [];\n }, debounceDelay);\n } else {\n log(`Event ignored - ext: ${ext}, event: ${event}`);\n }\n });\n\n console.log('[UnoCSS Hybrid] Watch mode: enabled');\n } catch (err) {\n console.warn('[UnoCSS Hybrid] Watch mode not available:', (err as Error).message);\n }\n }\n });\n }\n\n // 构建完成后的日志\n api.onAfterBuild(() => {\n if (isProd && fs.existsSync(currentCssPath)) {\n const stats = fs.statSync(currentCssPath);\n const fileName = path.basename(currentCssPath);\n console.log(\n `[UnoCSS Hybrid] Final CSS: ${fileName} (${(stats.size / 1024).toFixed(2)} KB)`,\n );\n }\n });\n\n // 关闭 dev server 时清理 WebSocket 服务器\n api.onCloseDevServer(async () => {\n if (wss) {\n console.log('[UnoCSS Hybrid] Closing WebSocket server...');\n wss.close();\n wss = null;\n }\n });\n },\n };\n}\n\nexport default pluginUnocss;\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ikkin/plugin-unocss",
3
- "version": "1.1.1",
3
+ "version": "1.1.3",
4
4
  "description": "UnoCSS plugin for Rsbuild with CLI pre-generation and automatic injection",
5
5
  "main": "./dist/plugin-unocss.js",
6
6
  "module": "./dist/plugin-unocss.mjs",