diff --git a/.npmrc b/.npmrc index 8b02f75..38ff6ba 100644 --- a/.npmrc +++ b/.npmrc @@ -1 +1,2 @@ -registry = https://registry.npmmirror.com/ \ No newline at end of file +registry = https://registry.npmmirror.com/ +hoist=false \ No newline at end of file diff --git a/templates/vite-react-template/.npmrc b/apps/ui-site/.npmrc similarity index 100% rename from templates/vite-react-template/.npmrc rename to apps/ui-site/.npmrc diff --git a/templates/vite-react-template/.vscode/settings.json b/apps/ui-site/.vscode/settings.json similarity index 100% rename from templates/vite-react-template/.vscode/settings.json rename to apps/ui-site/.vscode/settings.json diff --git a/apps/ui-site/index.html b/apps/ui-site/index.html new file mode 100644 index 0000000..cffe571 --- /dev/null +++ b/apps/ui-site/index.html @@ -0,0 +1,11 @@ + + + + + DefGov UI Web + + +
+ + + diff --git a/templates/vite-react-template/package.json b/apps/ui-site/package.json similarity index 55% rename from templates/vite-react-template/package.json rename to apps/ui-site/package.json index 2e61490..3cf287d 100644 --- a/templates/vite-react-template/package.json +++ b/apps/ui-site/package.json @@ -1,34 +1,43 @@ { - "name": "vite-react-template", + "name": "ui-site", "version": "0.0.0", "private": true, "type": "module", - "sideEffects": ["*.css"], + "sideEffects": [ + "*.css" + ], "module": "./dist/index.es.js", "main": "./dist/index.cjs.js", "types": "./dist/index.d.ts", "style": "./dist/index.css", "exports": { ".": { + "types": "./dist/index.d.ts", "import": "./dist/index.es.js", - "require": "./dist/index.cjs.js", - "types": "./dist/index.d.ts" + "require": "./dist/index.cjs.js" }, "./index.css": "./dist/index.css" }, - "files": ["dist"], + "files": [ + "dist" + ], "scripts": { "dev": "vite", - "build": "vite build --tsconfig tsconfig.build.json" + "build": "tsc -p tsconfig.build.json && vite build" }, "devDependencies": { "@types/node": "^25.6.0", "@types/react": "^19.2.14", "@types/react-dom": "^19.2.3", - "@vitejs/plugin-react": "^6.0.1", + "@vitejs/plugin-react": "~5.2.0", "glob": "^13.0.6", - "typescript": "^6.0.3", - "vite": "^8.0.9", + "typescript": "~6.0.3", + "vite": "~7.3.2", "vite-plugin-dts": "^4.5.4" + }, + "dependencies": { + "@defgov/ui-web": "workspace:*", + "react": "^19.2.5", + "react-dom": "^19.2.5" } } diff --git a/packages/ui-web/scripts-plugin/vite-plugin-gen-index-css.ts b/apps/ui-site/scripts-plugin/vite-plugin-gen-index-css.ts similarity index 100% rename from packages/ui-web/scripts-plugin/vite-plugin-gen-index-css.ts rename to apps/ui-site/scripts-plugin/vite-plugin-gen-index-css.ts diff --git a/packages/ui-web/scripts-plugin/vite-plugin-gen-index-ts.ts b/apps/ui-site/scripts-plugin/vite-plugin-gen-index-ts.ts similarity index 100% rename from packages/ui-web/scripts-plugin/vite-plugin-gen-index-ts.ts rename to apps/ui-site/scripts-plugin/vite-plugin-gen-index-ts.ts diff --git a/apps/ui-site/src/App.tsx b/apps/ui-site/src/App.tsx new file mode 100644 index 0000000..a0dd46d --- /dev/null +++ b/apps/ui-site/src/App.tsx @@ -0,0 +1,9 @@ +import { ButtonGallery } from "./gallery/ButtonGallery"; + +export default function App() { + return ( + <> + + + ); +} diff --git a/apps/ui-site/src/common/CommonProps.ts b/apps/ui-site/src/common/CommonProps.ts new file mode 100644 index 0000000..c78338a --- /dev/null +++ b/apps/ui-site/src/common/CommonProps.ts @@ -0,0 +1,9 @@ +import { type CSSProperties, type ReactNode } from "react"; + +export type CommonProps = { + className?: string; + style?: CSSProperties; + children?: ReactNode; + disabled?: boolean; + key?: string; +}; diff --git a/apps/ui-site/src/common/InnerWrapper.tsx b/apps/ui-site/src/common/InnerWrapper.tsx new file mode 100644 index 0000000..19fbc02 --- /dev/null +++ b/apps/ui-site/src/common/InnerWrapper.tsx @@ -0,0 +1,17 @@ +import { ReactNode } from "react"; + +export const InnerWrapper = ({ children }: { children: ReactNode }) => { + return ( +
+ {children} +
+ ); +}; diff --git a/apps/ui-site/src/common/OuterWrapper.tsx b/apps/ui-site/src/common/OuterWrapper.tsx new file mode 100644 index 0000000..69cc8c8 --- /dev/null +++ b/apps/ui-site/src/common/OuterWrapper.tsx @@ -0,0 +1,16 @@ +import { ReactNode } from "react"; + +export const OuterWrapper = ({ children }: { children: ReactNode }) => { + return ( +
+ {children} +
+ ); +}; diff --git a/apps/ui-site/src/gallery/ButtonGallery.tsx b/apps/ui-site/src/gallery/ButtonGallery.tsx new file mode 100644 index 0000000..9efcf5e --- /dev/null +++ b/apps/ui-site/src/gallery/ButtonGallery.tsx @@ -0,0 +1,22 @@ +import { Button, DownloadSvg } from "@defgov/ui-web"; +import { InnerWrapper } from "../common/InnerWrapper"; +import { OuterWrapper } from "../common/OuterWrapper"; + +export const ButtonGallery = () => { + return ( + + + + + + + + + + + ); +}; diff --git a/apps/ui-site/src/main.tsx b/apps/ui-site/src/main.tsx new file mode 100644 index 0000000..d1fea26 --- /dev/null +++ b/apps/ui-site/src/main.tsx @@ -0,0 +1,8 @@ +import { createRoot } from "react-dom/client"; +import App from "./App"; +import "@defgov/ui-web/index.css"; + +const container = document.getElementById("root")!; +const root = createRoot(container); + +root.render(); diff --git a/templates/vite-react-template/src/types/css.d.ts b/apps/ui-site/src/types/css.d.ts similarity index 100% rename from templates/vite-react-template/src/types/css.d.ts rename to apps/ui-site/src/types/css.d.ts diff --git a/templates/vite-react-template/src/types/env.d.ts b/apps/ui-site/src/types/env.d.ts similarity index 100% rename from templates/vite-react-template/src/types/env.d.ts rename to apps/ui-site/src/types/env.d.ts diff --git a/apps/ui-site/tsconfig.base.json b/apps/ui-site/tsconfig.base.json new file mode 100644 index 0000000..d1b2a98 --- /dev/null +++ b/apps/ui-site/tsconfig.base.json @@ -0,0 +1,26 @@ +{ + // tsconfig.base.json,用于被 tesconfig.json 和 tesconfig.build.json 继承 + "compilerOptions": { + // 输出模块语法,使用版本号最新的那个,而不是实验性语法 ESNext + "module": "es2022", + + // 模块解析策略,模拟 Vite / Rollup / webpack,支持 exports / imports,不强制 Node ESM 的严格规则 + "moduleResolution": "bundler", + + // 显式声明使用的类型包 + "types": ["node", "react", "react-dom"], + + // 允许 ESM 导入 CJS + "esModuleInterop": true, + + // 跳过 node_modules 类型检查,加快构建,避免第三方类型污染 + "skipLibCheck": true, + + /** + * 只做类型检查,不生成 JS 输出 + * - 适用于 Vite / Next / Nuxt 等 bundler 场景 + * - 防止 tsc 与构建工具重复 emit + */ + "noEmit": true + } +} diff --git a/apps/ui-site/tsconfig.build.json b/apps/ui-site/tsconfig.build.json new file mode 100644 index 0000000..4b4367f --- /dev/null +++ b/apps/ui-site/tsconfig.build.json @@ -0,0 +1,108 @@ +{ + // 此文件仅用于类型检查,不用于类型检查,构建时会指定使用 tsconfig.build.json + "extends": "./tsconfig.base.json", + "compilerOptions": { + // Browser api,需要加 "DOM","DOM.Iterable" + // Node api,需要加 "ES2025",始终使用带版本号的最新版本 + // NextJs api,属于同构,server 端会预处理 DOM,计算url,三个都需要 "ES2025", "DOM", "DOM.Iterable" + "lib": ["ES2025", "DOM", "DOM.Iterable"], + + /** + * 显式声明使用的类型包 + * - node:Node.js API + * - react:JSX / React 类型 + * - vite/client:import.meta / env + */ + "types": ["node", "react", "react-dom"], + + /** + * React JSX 编译模式 + * - 使用 React 17+ 新 JSX Transform + * - 不需要手动 import React + */ + "jsx": "react-jsx", + + /** + * 编译输出目录 + * - tsc / tsc -b 都会用到 + */ + "outDir": "./dist", + + /** + * 源码根目录 + * - 确保 dist 结构与 src 一致 + * - 对 declaration 路径至关重要 + */ + "rootDir": "./src", + + /** + * 生成 .d.ts 类型声明文件 + * - 组件库 / npm 包发布必需 + * - 对应用项目无害,仅影响类型输出 + */ + "declaration": true, + + /** + * 强制单文件可独立编译 + * - 适配 esbuild / SWC / bundler 编译模型 + * - 禁止依赖跨文件类型推断(enum / namespace 等) + */ + "isolatedModules": true + }, + /** + * 参与类型检查和编译的文件 + * - 只扫描 src + * - 其它目录通过 exclude 排除 + */ + "include": ["src"], + + /** + * 明确排除非源码内容 + * - 避免污染类型系统 + * - 防止误入 dist / test / config + * - 保证发布包干净 + */ + "exclude": [ + "node_modules", + "dist", + + // ---------- build / cache ---------- + ".turbo/**/*", + ".cache/**/*", + ".vite/**/*", + + // ---------- 配置文件 ---------- + "vite.config.ts", + "*.config.ts", + "*.config.js", + "tsconfig.*.json", + + // ---------- 测试相关 ---------- + "__tests__/**/*", + "test/**/*", + "tests/**/*", + "**/*.test.ts", + "**/*.test.tsx", + "**/*.spec.ts", + "**/*.spec.tsx", + + // ---------- Storybook ---------- + ".storybook/**/*", + "stories/**/*", + + // ---------- 示例 / 脚本 ---------- + "example/**/*", + "examples/**/*", + "scripts/**/*", + + // ---------- 环境与静态资源 ---------- + ".env", + ".env.*", + "public/**/*", + + // ---------- 文档 ---------- + "docs/**/*", + "README.md", + "LICENSE" + ] +} diff --git a/templates/vite-react-template/tsconfig.json b/apps/ui-site/tsconfig.json similarity index 91% rename from templates/vite-react-template/tsconfig.json rename to apps/ui-site/tsconfig.json index a28554e..cf58f48 100644 --- a/templates/vite-react-template/tsconfig.json +++ b/apps/ui-site/tsconfig.json @@ -6,11 +6,12 @@ "lib": ["ES2025", "DOM", "DOM.Iterable"], //显式声明使用的类型包,避免找不到模块 - "types": ["node", "react", "vite/client"], + "types": ["node", "react", "react-dom"], // React JSX 编译模式 "jsx": "react-jsx" }, // 将类型检查范围扩大至整个子项目,而不只是 src 文件夹, "include": ["**/*"] + } diff --git a/apps/ui-site/vite.config.ts b/apps/ui-site/vite.config.ts new file mode 100644 index 0000000..ee0396d --- /dev/null +++ b/apps/ui-site/vite.config.ts @@ -0,0 +1,16 @@ +import { defineConfig } from "vite" +import react from "@vitejs/plugin-react" +import dts from "vite-plugin-dts" +import { genIndexTsPlugin } from "./scripts-plugin/vite-plugin-gen-index-ts" +import { genIndexCssPlugin } from "./scripts-plugin/vite-plugin-gen-index-css" + +export default defineConfig({ + plugins: [ + genIndexTsPlugin(), + genIndexCssPlugin(), + react(), + dts({ + insertTypesEntry: true, + }), + ], +}) \ No newline at end of file diff --git a/package.json b/package.json index a5e3eb6..345db59 100644 --- a/package.json +++ b/package.json @@ -12,9 +12,5 @@ "engines": { "node": ">=20" }, - "workspaces": [ - "packages/*", - "app/*" - ], "packageManager": "pnpm@11.0.0-rc.5+sha512.c469fb6aa13a99e57aec935cd7b86ff422701f4602ecac2231d3dc20910586ebfb6b50a7b455d0778ec22ae56912d8d8e88e9f9e0a03c0875a6a41783a94a1bd" } diff --git a/packages/ui-web/package.json b/packages/ui-web/package.json index 0a188d7..eb98b8a 100644 --- a/packages/ui-web/package.json +++ b/packages/ui-web/package.json @@ -12,9 +12,9 @@ "style": "./dist/index.css", "exports": { ".": { + "types": "./dist/index.d.ts", "import": "./dist/index.es.js", - "require": "./dist/index.cjs.js", - "types": "./dist/index.d.ts" + "require": "./dist/index.cjs.js" }, "./index.css": "./dist/index.css" }, @@ -22,19 +22,22 @@ "dist" ], "scripts": { - "dev": "vite", - "build": "vite build --tsconfig tsconfig.build.json" + "gen-css": "ts-node scripts/gen-index-css.ts", + "gen-ts": "ts-node scripts/gen-index-ts.ts", + "gen-index": "pnpm run gen-css && pnpm run gen-ts", + "dev": "pnpm run gen-index && vite build --watch", + "build": "pnpm run gen-index && tsc -p tsconfig.build.json && vite build" }, "devDependencies": { "@tailwindcss/vite": "^4.2.4", "@types/node": "^25.6.0", "@types/react": "^19.2.14", "@types/react-dom": "^19.2.3", - "@vitejs/plugin-react": "^6.0.1", + "@vitejs/plugin-react": "~5.2.0", "glob": "^13.0.6", "ts-node": "^10.9.2", - "typescript": "^6.0.3", - "vite": "^8.0.9", + "typescript": "~6.0.3", + "vite": "~7.3.2", "vite-plugin-dts": "^4.5.4" }, "dependencies": { diff --git a/templates/vite-react-template/scripts-plugin/vite-plugin-gen-index-ts.ts b/packages/ui-web/scripts/gen-index-css.ts similarity index 72% rename from templates/vite-react-template/scripts-plugin/vite-plugin-gen-index-ts.ts rename to packages/ui-web/scripts/gen-index-css.ts index 17c5d84..fdddef4 100644 --- a/templates/vite-react-template/scripts-plugin/vite-plugin-gen-index-ts.ts +++ b/packages/ui-web/scripts/gen-index-css.ts @@ -1,5 +1,3 @@ -// plugins/vite-plugin-gen-index-ts.ts -import type { Plugin } from "vite"; import fs from "fs"; import path from "path"; import { globSync } from "glob"; @@ -68,7 +66,10 @@ function generateIndexFile(dirPath: string) { }); const validFiles = allFiles.filter(isValidFile); - if (validFiles.length === 0) return; + if (validFiles.length === 0) { + console.log("⚠️ 未找到符合条件的文件,跳过生成 index.ts"); + return; + } validFiles.sort(); @@ -88,42 +89,33 @@ ${exportStatements.join("\n")} const indexFilePath = path.resolve(dirPath, "index.ts"); - // ✅ 内容比对,避免无限 rebuild + // ✅ 内容比对,避免重复写入 if (fs.existsSync(indexFilePath)) { const old = fs.readFileSync(indexFilePath, "utf8"); - if (old === indexContent) return; + if (old === indexContent) { + console.log("✅ index.ts 内容无变化,无需重新生成"); + return; + } } fs.writeFileSync(indexFilePath, indexContent, "utf8"); + console.log(`✅ 成功生成 index.ts: ${indexFilePath}`); } -export function genIndexTsPlugin(): Plugin { - return { - name: "vite-plugin-gen-index-ts", - apply: "build", - - buildStart() { - const [targetDir] = CONFIG.targetDirs; - if (!targetDir) { - this.error("CONFIG.targetDirs is empty"); - return; - } - - const absTargetDir = path.resolve(process.cwd(), targetDir); - - try { - generateIndexFile(absTargetDir); - } catch (err) { - const msg = err instanceof Error ? err.message : String(err); - this.error(`[gen-index-ts] failed: ${msg}`); - throw err; - } - }, - - handleHotUpdate({ file }) { - if (file.replace(/\\/g, "/").endsWith("/src/index.ts")) { - return []; - } - }, - }; +// 脚本入口 +const [targetDir] = CONFIG.targetDirs; +if (!targetDir) { + console.error("❌ CONFIG.targetDirs 不能为空"); + process.exit(1); +} + +const absTargetDir = path.resolve(process.cwd(), targetDir); + +try { + console.log(`🚀 开始扫描目录: ${absTargetDir}`); + generateIndexFile(absTargetDir); +} catch (err) { + const msg = err instanceof Error ? err.message : String(err); + console.error(`❌ [gen-index-ts] 执行失败: ${msg}`); + process.exit(1); } diff --git a/packages/ui-web/scripts/gen-index-ts.ts b/packages/ui-web/scripts/gen-index-ts.ts new file mode 100644 index 0000000..fdddef4 --- /dev/null +++ b/packages/ui-web/scripts/gen-index-ts.ts @@ -0,0 +1,121 @@ +import fs from "fs"; +import path from "path"; +import { globSync } from "glob"; + +interface Config { + targetDirs: string[]; + includeExtensions: string[]; + excludeKeywords: { + dirs: string[]; + fileSuffixes: string[]; + filePatterns: RegExp[]; + }; +} + +const CONFIG: Config = { + targetDirs: ["src"], + includeExtensions: [".ts", ".tsx", ".vue"], + excludeKeywords: { + dirs: ["__tests__", "tests", "story", "stories", "types"], + fileSuffixes: [".d.ts"], + filePatterns: [ + /^index\.(ts|tsx|js|jsx)$/, + /\.(test|spec)\./, + /\.(story|stories)\./, + ], + }, +}; + +const normalizePath = (p: string) => p.replace(/\\/g, "/"); + +const isInExcludeDir = (filePath: string) => { + const normalized = normalizePath(filePath); + return CONFIG.excludeKeywords.dirs.some((dir) => + normalized.includes(`/${dir}/`), + ); +}; + +const isExcludeSuffix = (filePath: string) => + CONFIG.excludeKeywords.fileSuffixes.some((suffix) => + filePath.endsWith(suffix), + ); + +const isMatchExcludePattern = (fileName: string) => + CONFIG.excludeKeywords.filePatterns.some((pattern) => pattern.test(fileName)); + +function isValidFile(filePath: string): boolean { + const fileName = filePath.split(/[\\/]/).pop()!; + + if (isInExcludeDir(filePath)) return false; + if (isExcludeSuffix(filePath)) return false; + if (isMatchExcludePattern(fileName)) return false; + + const ext = path.extname(filePath); + return CONFIG.includeExtensions.includes(ext); +} + +function generateIndexFile(dirPath: string) { + const searchPattern = path.resolve(dirPath, "**", "*.*"); + + const allFiles = globSync(searchPattern, { + nodir: true, + absolute: true, + windowsPathsNoEscape: true, + dot: false, + follow: true, + }); + + const validFiles = allFiles.filter(isValidFile); + if (validFiles.length === 0) { + console.log("⚠️ 未找到符合条件的文件,跳过生成 index.ts"); + return; + } + + validFiles.sort(); + + const exportStatements = validFiles.map((file) => { + const relPath = path.relative(dirPath, file); + const importPath = `./${relPath + .replace(/\.[^.]+$/, "") + .replace(/\\/g, "/")}`; + return `export * from '${importPath}';`; + }); + + const indexContent = ` +import './index.css'; + +${exportStatements.join("\n")} +`.trim(); + + const indexFilePath = path.resolve(dirPath, "index.ts"); + + // ✅ 内容比对,避免重复写入 + if (fs.existsSync(indexFilePath)) { + const old = fs.readFileSync(indexFilePath, "utf8"); + if (old === indexContent) { + console.log("✅ index.ts 内容无变化,无需重新生成"); + return; + } + } + + fs.writeFileSync(indexFilePath, indexContent, "utf8"); + console.log(`✅ 成功生成 index.ts: ${indexFilePath}`); +} + +// 脚本入口 +const [targetDir] = CONFIG.targetDirs; +if (!targetDir) { + console.error("❌ CONFIG.targetDirs 不能为空"); + process.exit(1); +} + +const absTargetDir = path.resolve(process.cwd(), targetDir); + +try { + console.log(`🚀 开始扫描目录: ${absTargetDir}`); + generateIndexFile(absTargetDir); +} catch (err) { + const msg = err instanceof Error ? err.message : String(err); + console.error(`❌ [gen-index-ts] 执行失败: ${msg}`); + process.exit(1); +} diff --git a/packages/ui-web/src/common/Box.tsx b/packages/ui-web/src/common/Box.tsx index 553d81e..b282c87 100644 --- a/packages/ui-web/src/common/Box.tsx +++ b/packages/ui-web/src/common/Box.tsx @@ -1,6 +1,6 @@ import React from "react"; import { cn } from "tailwind-variants"; -import { CommonProps } from "./CommonProps"; +import { type CommonProps } from "./CommonProps"; // 别名<约束>=值 // 千万不要 C = As extend React.ElementType,这样子连等号,会切断推导 @@ -22,8 +22,7 @@ const Box = ( ) => { const { as: Component = "div", children, className, ...rest } = props; - - const boxRootClass = cn( className); + const boxRootClass = cn(className); return ( diff --git a/packages/ui-web/src/common/CommonProps.ts b/packages/ui-web/src/common/CommonProps.ts index 395df95..c78338a 100644 --- a/packages/ui-web/src/common/CommonProps.ts +++ b/packages/ui-web/src/common/CommonProps.ts @@ -1,4 +1,4 @@ -import { CSSProperties, ReactNode } from "react"; +import { type CSSProperties, type ReactNode } from "react"; export type CommonProps = { className?: string; diff --git a/packages/ui-web/src/component/button/Button.tsx b/packages/ui-web/src/component/button/Button.tsx index 9244fa7..bb9ee64 100644 --- a/packages/ui-web/src/component/button/Button.tsx +++ b/packages/ui-web/src/component/button/Button.tsx @@ -48,10 +48,10 @@ export const Button = (props: ButtonProps) => { {iconSvg ? ( hideIcon ? ( iconOnly ? ( - + ) : null ) : ( - + ) ) : null} {!iconOnly && children} diff --git a/packages/ui-web/src/index.ts b/packages/ui-web/src/index.ts index 74b0046..e26f8cf 100644 --- a/packages/ui-web/src/index.ts +++ b/packages/ui-web/src/index.ts @@ -1,6 +1,4 @@ - - -import './index.css'; +import './index.css'; export * from './assets/svg/BoldSvg'; export * from './assets/svg/CheckIndicatorSvg'; @@ -42,4 +40,4 @@ export * from './component/username-field/UsernameField'; export * from './styles/recipe/IinlineSize.recipe'; export * from './styles/recipe/ItemSize.recipe'; export * from './styles/recipe/brand.recipe'; -export * from './styles/recipe/variant.recipe'; +export * from './styles/recipe/variant.recipe'; \ No newline at end of file diff --git a/packages/ui-web/tsconfig.base.json b/packages/ui-web/tsconfig.base.json index b134137..6df5e7c 100644 --- a/packages/ui-web/tsconfig.base.json +++ b/packages/ui-web/tsconfig.base.json @@ -17,24 +17,6 @@ "esModuleInterop": true, // 跳过 node_modules 类型检查,加快构建,避免第三方类型污染 - "skipLibCheck": true, - - // 模块检测策略,不会影响 node_modules 中的第三方 CommonJS 依赖,Vite 会在预构建阶段自动将其转换为 ESM。 - "moduleDetection": "force", - - // 保留源码中的 import / export 语句原样输出,不进行自动转换(如 import → require),通常与 moduleDetection: "force" 搭配使用 - "verbatimModuleSyntax": true, - - // 是否检查“未使用的局部变量” - "noUnusedLocals": true, - - // 是否检查“未使用的函数参数” - "noUnusedParameters": true, - - // 是否只允许“可擦除的语法(Erasable Syntax),确保 TypeScript 语法在编译后可完全移除 - "erasableSyntaxOnly": true, - - // 是否禁止 switch 语句中的 case 贯穿(fallthrough),如果 case 没有 break / return,会报错 - "noFallthroughCasesInSwitch": true + "skipLibCheck": true } } diff --git a/packages/ui-web/tsconfig.build.json b/packages/ui-web/tsconfig.build.json index f3b4b99..cbaa3e1 100644 --- a/packages/ui-web/tsconfig.build.json +++ b/packages/ui-web/tsconfig.build.json @@ -42,33 +42,19 @@ */ "declaration": true, - /** - * 只做类型检查,不生成 JS 输出 - * - 适用于 Vite / Next / Nuxt 等 bundler 场景 - * - 防止 tsc 与构建工具重复 emit - */ - "noEmit": true, - /** * 强制单文件可独立编译 * - 适配 esbuild / SWC / bundler 编译模型 * - 禁止依赖跨文件类型推断(enum / namespace 等) */ - "isolatedModules": true, - - /** - * 允许在 import 中显式使用 .ts / .tsx 后缀 - * - 兼容 Node ESM / bundler 对文件扩展名的严格要求 - * - 避免 `import './foo'` 在 TS + ESM 下歧义 - */ - "allowImportingTsExtensions": true + "isolatedModules": true }, /** * 参与类型检查和编译的文件 * - 只扫描 src * - 其它目录通过 exclude 排除 */ - "include": ["src", "scripts"], + "include": ["src"], /** * 明确排除非源码内容 diff --git a/packages/ui-web/tsconfig.json b/packages/ui-web/tsconfig.json index a28554e..f0cc359 100644 --- a/packages/ui-web/tsconfig.json +++ b/packages/ui-web/tsconfig.json @@ -9,7 +9,14 @@ "types": ["node", "react", "vite/client"], // React JSX 编译模式 - "jsx": "react-jsx" + "jsx": "react-jsx", + + /** + * 只做类型检查,不生成 JS 输出 + * - 适用于 Vite / Next / Nuxt 等 bundler 场景 + * - 防止 tsc 与构建工具重复 emit + */ + "noEmit": true }, // 将类型检查范围扩大至整个子项目,而不只是 src 文件夹, "include": ["**/*"] diff --git a/packages/ui-web/vite.config.ts b/packages/ui-web/vite.config.ts index 12b8568..00c62a3 100644 --- a/packages/ui-web/vite.config.ts +++ b/packages/ui-web/vite.config.ts @@ -3,13 +3,9 @@ import react from "@vitejs/plugin-react"; import dts from "vite-plugin-dts"; import path from "path"; import tailwindcss from "@tailwindcss/vite"; -import { genIndexTsPlugin } from "./scripts-plugin/vite-plugin-gen-index-ts"; -import { genIndexCssPlugin } from "./scripts-plugin/vite-plugin-gen-index-css"; export default defineConfig({ plugins: [ - genIndexTsPlugin(), - genIndexCssPlugin(), react(), tailwindcss(), dts({ diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3db8565..f14dd73 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -25,7 +25,7 @@ importers: version: 19.2.3(@types/react@19.2.14) '@vitejs/plugin-react': specifier: ^6.0.1 - version: 6.0.1(vite@8.0.10(@types/node@25.6.0)(jiti@2.6.1)) + version: 6.0.1(vite@8.0.10(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)) glob: specifier: ^13.0.6 version: 13.0.6 @@ -34,10 +34,47 @@ importers: version: 6.0.3 vite: specifier: ^8.0.9 - version: 8.0.10(@types/node@25.6.0)(jiti@2.6.1) + version: 8.0.10(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1) vite-plugin-dts: specifier: ^4.5.4 - version: 4.5.4(@types/node@25.6.0)(typescript@6.0.3)(vite@8.0.10(@types/node@25.6.0)(jiti@2.6.1)) + version: 4.5.4(@types/node@25.6.0)(rollup@4.60.2)(typescript@6.0.3)(vite@8.0.10(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)) + + apps/ui-site: + dependencies: + '@defgov/ui-web': + specifier: workspace:* + version: link:../../packages/ui-web + react: + specifier: ^19.2.5 + version: 19.2.5 + react-dom: + specifier: ^19.2.5 + version: 19.2.5(react@19.2.5) + devDependencies: + '@types/node': + specifier: ^25.6.0 + version: 25.6.0 + '@types/react': + specifier: ^19.2.14 + version: 19.2.14 + '@types/react-dom': + specifier: ^19.2.3 + version: 19.2.3(@types/react@19.2.14) + '@vitejs/plugin-react': + specifier: ~5.2.0 + version: 5.2.0(vite@7.3.2(@types/node@25.6.0)(jiti@2.6.1)(lightningcss@1.32.0)) + glob: + specifier: ^13.0.6 + version: 13.0.6 + typescript: + specifier: ~6.0.3 + version: 6.0.3 + vite: + specifier: ~7.3.2 + version: 7.3.2(@types/node@25.6.0)(jiti@2.6.1)(lightningcss@1.32.0) + vite-plugin-dts: + specifier: ^4.5.4 + version: 4.5.4(@types/node@25.6.0)(rollup@4.60.2)(typescript@6.0.3)(vite@7.3.2(@types/node@25.6.0)(jiti@2.6.1)(lightningcss@1.32.0)) packages/bookmark-sync: dependencies: @@ -84,7 +121,7 @@ importers: devDependencies: '@tailwindcss/vite': specifier: ^4.2.4 - version: 4.2.4(vite@8.0.10(@types/node@25.6.0)(jiti@2.6.1)) + version: 4.2.4(vite@7.3.2(@types/node@25.6.0)(jiti@2.6.1)(lightningcss@1.32.0)) '@types/node': specifier: ^25.6.0 version: 25.6.0 @@ -95,8 +132,8 @@ importers: specifier: ^19.2.3 version: 19.2.3(@types/react@19.2.14) '@vitejs/plugin-react': - specifier: ^6.0.1 - version: 6.0.1(vite@8.0.10(@types/node@25.6.0)(jiti@2.6.1)) + specifier: ~5.2.0 + version: 5.2.0(vite@7.3.2(@types/node@25.6.0)(jiti@2.6.1)(lightningcss@1.32.0)) glob: specifier: ^13.0.6 version: 13.0.6 @@ -104,16 +141,23 @@ importers: specifier: ^10.9.2 version: 10.9.2(@types/node@25.6.0)(typescript@6.0.3) typescript: - specifier: ^6.0.3 + specifier: ~6.0.3 version: 6.0.3 vite: - specifier: ^8.0.9 - version: 8.0.10(@types/node@25.6.0)(jiti@2.6.1) + specifier: ~7.3.2 + version: 7.3.2(@types/node@25.6.0)(jiti@2.6.1)(lightningcss@1.32.0) vite-plugin-dts: specifier: ^4.5.4 - version: 4.5.4(@types/node@25.6.0)(typescript@6.0.3)(vite@8.0.10(@types/node@25.6.0)(jiti@2.6.1)) + version: 4.5.4(@types/node@25.6.0)(rollup@4.60.2)(typescript@6.0.3)(vite@7.3.2(@types/node@25.6.0)(jiti@2.6.1)(lightningcss@1.32.0)) - templates/vite-react-template: + templates/vite-react-app: + dependencies: + react: + specifier: ^19.2.5 + version: 19.2.5 + react-dom: + specifier: ^19.2.5 + version: 19.2.5(react@19.2.5) devDependencies: '@types/node': specifier: ^25.6.0 @@ -125,23 +169,101 @@ importers: specifier: ^19.2.3 version: 19.2.3(@types/react@19.2.14) '@vitejs/plugin-react': - specifier: ^6.0.1 - version: 6.0.1(vite@8.0.10(@types/node@25.6.0)(jiti@2.6.1)) + specifier: ~5.2.0 + version: 5.2.0(vite@7.3.2(@types/node@25.6.0)(jiti@2.6.1)(lightningcss@1.32.0)) glob: specifier: ^13.0.6 version: 13.0.6 + ts-node: + specifier: ^10.9.2 + version: 10.9.2(@types/node@25.6.0)(typescript@6.0.3) typescript: - specifier: ^6.0.3 + specifier: ~6.0.3 version: 6.0.3 vite: - specifier: ^8.0.9 - version: 8.0.10(@types/node@25.6.0)(jiti@2.6.1) + specifier: ~7.3.2 + version: 7.3.2(@types/node@25.6.0)(jiti@2.6.1)(lightningcss@1.32.0) vite-plugin-dts: specifier: ^4.5.4 - version: 4.5.4(@types/node@25.6.0)(typescript@6.0.3)(vite@8.0.10(@types/node@25.6.0)(jiti@2.6.1)) + version: 4.5.4(@types/node@25.6.0)(rollup@4.60.2)(typescript@6.0.3)(vite@7.3.2(@types/node@25.6.0)(jiti@2.6.1)(lightningcss@1.32.0)) + + templates/vite-react-lib: + dependencies: + react: + specifier: ^19 + version: 19.2.5 + react-dom: + specifier: ^19 + version: 19.2.5(react@19.2.5) + devDependencies: + '@types/node': + specifier: ^25.6.0 + version: 25.6.0 + '@types/react': + specifier: ^19.2.14 + version: 19.2.14 + '@types/react-dom': + specifier: ^19.2.3 + version: 19.2.3(@types/react@19.2.14) + '@vitejs/plugin-react': + specifier: ~5.2.0 + version: 5.2.0(vite@7.3.2(@types/node@25.6.0)(jiti@2.6.1)(lightningcss@1.32.0)) + glob: + specifier: ^13.0.6 + version: 13.0.6 + ts-node: + specifier: ^10.9.2 + version: 10.9.2(@types/node@25.6.0)(typescript@6.0.3) + typescript: + specifier: ~6.0.3 + version: 6.0.3 + vite: + specifier: ~7.3.2 + version: 7.3.2(@types/node@25.6.0)(jiti@2.6.1)(lightningcss@1.32.0) + vite-plugin-dts: + specifier: ^4.5.4 + version: 4.5.4(@types/node@25.6.0)(rollup@4.60.2)(typescript@6.0.3)(vite@7.3.2(@types/node@25.6.0)(jiti@2.6.1)(lightningcss@1.32.0)) packages: + '@babel/code-frame@7.29.0': + resolution: {integrity: sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==} + engines: {node: '>=6.9.0'} + + '@babel/compat-data@7.29.3': + resolution: {integrity: sha512-LIVqM46zQWZhj17qA8wb4nW/ixr2y1Nw+r1etiAWgRM6U1IqP+LNhL1yg440jYZR72jCWcWbLWzIosH+uP1fqg==} + engines: {node: '>=6.9.0'} + + '@babel/core@7.29.0': + resolution: {integrity: sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==} + engines: {node: '>=6.9.0'} + + '@babel/generator@7.29.1': + resolution: {integrity: sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-compilation-targets@7.28.6': + resolution: {integrity: sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-globals@7.28.0': + resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-imports@7.28.6': + resolution: {integrity: sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-transforms@7.28.6': + resolution: {integrity: sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-plugin-utils@7.28.6': + resolution: {integrity: sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==} + engines: {node: '>=6.9.0'} + '@babel/helper-string-parser@7.27.1': resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} engines: {node: '>=6.9.0'} @@ -150,15 +272,43 @@ packages: resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} engines: {node: '>=6.9.0'} + '@babel/helper-validator-option@7.27.1': + resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} + engines: {node: '>=6.9.0'} + + '@babel/helpers@7.29.2': + resolution: {integrity: sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==} + engines: {node: '>=6.9.0'} + '@babel/parser@7.29.3': resolution: {integrity: sha512-b3ctpQwp+PROvU/cttc4OYl4MzfJUWy6FZg+PMXfzmt/+39iHVF0sDfqay8TQM3JA2EUOyKcFZt75jWriQijsA==} engines: {node: '>=6.0.0'} hasBin: true + '@babel/plugin-transform-react-jsx-self@7.27.1': + resolution: {integrity: sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-react-jsx-source@7.27.1': + resolution: {integrity: sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/runtime@7.29.2': resolution: {integrity: sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==} engines: {node: '>=6.9.0'} + '@babel/template@7.28.6': + resolution: {integrity: sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==} + engines: {node: '>=6.9.0'} + + '@babel/traverse@7.29.0': + resolution: {integrity: sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==} + engines: {node: '>=6.9.0'} + '@babel/types@7.29.0': resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==} engines: {node: '>=6.9.0'} @@ -203,6 +353,162 @@ packages: '@emnapi/wasi-threads@1.2.1': resolution: {integrity: sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==} + '@esbuild/aix-ppc64@0.27.7': + resolution: {integrity: sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.27.7': + resolution: {integrity: sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.27.7': + resolution: {integrity: sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.27.7': + resolution: {integrity: sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.27.7': + resolution: {integrity: sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.27.7': + resolution: {integrity: sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.27.7': + resolution: {integrity: sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.27.7': + resolution: {integrity: sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.27.7': + resolution: {integrity: sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.27.7': + resolution: {integrity: sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.27.7': + resolution: {integrity: sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.27.7': + resolution: {integrity: sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.27.7': + resolution: {integrity: sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.27.7': + resolution: {integrity: sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.27.7': + resolution: {integrity: sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.27.7': + resolution: {integrity: sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.27.7': + resolution: {integrity: sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-arm64@0.27.7': + resolution: {integrity: sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.27.7': + resolution: {integrity: sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.27.7': + resolution: {integrity: sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.27.7': + resolution: {integrity: sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openharmony-arm64@0.27.7': + resolution: {integrity: sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + + '@esbuild/sunos-x64@0.27.7': + resolution: {integrity: sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.27.7': + resolution: {integrity: sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.27.7': + resolution: {integrity: sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.27.7': + resolution: {integrity: sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + '@floating-ui/core@1.7.5': resolution: {integrity: sha512-1Ih4WTWyw0+lKyFMcBHGbb5U5FtuHJuujoyyr5zTaWS5EYMeT6Jb2AuDeftsCsEuchO+mM2ij5+q9crhydzLhQ==} @@ -357,6 +663,9 @@ packages: '@rolldown/pluginutils@1.0.0-rc.17': resolution: {integrity: sha512-n8iosDOt6Ig1UhJ2AYqoIhHWh/isz0xpicHTzpKBeotdVsTEcxsSA/i3EVM7gQAj0rU27OLAxCjzlj15IWY7bg==} + '@rolldown/pluginutils@1.0.0-rc.3': + resolution: {integrity: sha512-eybk3TjzzzV97Dlj5c+XrBFW57eTNhzod66y9HrBlzJ6NsCrWCp/2kaPS3K9wJmurBC0Tdw4yPjXKZqlznim3Q==} + '@rolldown/pluginutils@1.0.0-rc.7': resolution: {integrity: sha512-qujRfC8sFVInYSPPMLQByRh7zhwkGFS4+tyMQ83srV1qrxL4g8E2tyxVVyxd0+8QeBM1mIk9KbWxkegRr76XzA==} @@ -369,6 +678,144 @@ packages: rollup: optional: true + '@rollup/rollup-android-arm-eabi@4.60.2': + resolution: {integrity: sha512-dnlp69efPPg6Uaw2dVqzWRfAWRnYVb1XJ8CyyhIbZeaq4CA5/mLeZ1IEt9QqQxmbdvagjLIm2ZL8BxXv5lH4Yw==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.60.2': + resolution: {integrity: sha512-OqZTwDRDchGRHHm/hwLOL7uVPB9aUvI0am/eQuWMNyFHf5PSEQmyEeYYheA0EPPKUO/l0uigCp+iaTjoLjVoHg==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.60.2': + resolution: {integrity: sha512-UwRE7CGpvSVEQS8gUMBe1uADWjNnVgP3Iusyda1nSRwNDCsRjnGc7w6El6WLQsXmZTbLZx9cecegumcitNfpmA==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.60.2': + resolution: {integrity: sha512-gjEtURKLCC5VXm1I+2i1u9OhxFsKAQJKTVB8WvDAHF+oZlq0GTVFOlTlO1q3AlCTE/DF32c16ESvfgqR7343/g==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-freebsd-arm64@4.60.2': + resolution: {integrity: sha512-Bcl6CYDeAgE70cqZaMojOi/eK63h5Me97ZqAQoh77VPjMysA/4ORQBRGo3rRy45x4MzVlU9uZxs8Uwy7ZaKnBw==} + cpu: [arm64] + os: [freebsd] + + '@rollup/rollup-freebsd-x64@4.60.2': + resolution: {integrity: sha512-LU+TPda3mAE2QB0/Hp5VyeKJivpC6+tlOXd1VMoXV/YFMvk/MNk5iXeBfB4MQGRWyOYVJ01625vjkr0Az98OJQ==} + cpu: [x64] + os: [freebsd] + + '@rollup/rollup-linux-arm-gnueabihf@4.60.2': + resolution: {integrity: sha512-2QxQrM+KQ7DAW4o22j+XZ6RKdxjLD7BOWTP0Bv0tmjdyhXSsr2Ul1oJDQqh9Zf5qOwTuTc7Ek83mOFaKnodPjg==} + cpu: [arm] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-arm-musleabihf@4.60.2': + resolution: {integrity: sha512-TbziEu2DVsTEOPif2mKWkMeDMLoYjx95oESa9fkQQK7r/Orta0gnkcDpzwufEcAO2BLBsD7mZkXGFqEdMRRwfw==} + cpu: [arm] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-arm64-gnu@4.60.2': + resolution: {integrity: sha512-bO/rVDiDUuM2YfuCUwZ1t1cP+/yqjqz+Xf2VtkdppefuOFS2OSeAfgafaHNkFn0t02hEyXngZkxtGqXcXwO8Rg==} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-arm64-musl@4.60.2': + resolution: {integrity: sha512-hr26p7e93Rl0Za+JwW7EAnwAvKkehh12BU1Llm9Ykiibg4uIr2rbpxG9WCf56GuvidlTG9KiiQT/TXT1yAWxTA==} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-loong64-gnu@4.60.2': + resolution: {integrity: sha512-pOjB/uSIyDt+ow3k/RcLvUAOGpysT2phDn7TTUB3n75SlIgZzM6NKAqlErPhoFU+npgY3/n+2HYIQVbF70P9/A==} + cpu: [loong64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-loong64-musl@4.60.2': + resolution: {integrity: sha512-2/w+q8jszv9Ww1c+6uJT3OwqhdmGP2/4T17cu8WuwyUuuaCDDJ2ojdyYwZzCxx0GcsZBhzi3HmH+J5pZNXnd+Q==} + cpu: [loong64] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-ppc64-gnu@4.60.2': + resolution: {integrity: sha512-11+aL5vKheYgczxtPVVRhdptAM2H7fcDR5Gw4/bTcteuZBlH4oP9f5s9zYO9aGZvoGeBpqXI/9TZZihZ609wKw==} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-ppc64-musl@4.60.2': + resolution: {integrity: sha512-i16fokAGK46IVZuV8LIIwMdtqhin9hfYkCh8pf8iC3QU3LpwL+1FSFGej+O7l3E/AoknL6Dclh2oTdnRMpTzFQ==} + cpu: [ppc64] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-riscv64-gnu@4.60.2': + resolution: {integrity: sha512-49FkKS6RGQoriDSK/6E2GkAsAuU5kETFCh7pG4yD/ylj9rKhTmO3elsnmBvRD4PgJPds5W2PkhC82aVwmUcJ7A==} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-riscv64-musl@4.60.2': + resolution: {integrity: sha512-mjYNkHPfGpUR00DuM1ZZIgs64Hpf4bWcz9Z41+4Q+pgDx73UwWdAYyf6EG/lRFldmdHHzgrYyge5akFUW0D3mQ==} + cpu: [riscv64] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-s390x-gnu@4.60.2': + resolution: {integrity: sha512-ALyvJz965BQk8E9Al/JDKKDLH2kfKFLTGMlgkAbbYtZuJt9LU8DW3ZoDMCtQpXAltZxwBHevXz5u+gf0yA0YoA==} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-x64-gnu@4.60.2': + resolution: {integrity: sha512-UQjrkIdWrKI626Du8lCQ6MJp/6V1LAo2bOK9OTu4mSn8GGXIkPXk/Vsp4bLHCd9Z9Iz2OTEaokUE90VweJgIYQ==} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-x64-musl@4.60.2': + resolution: {integrity: sha512-bTsRGj6VlSdn/XD4CGyzMnzaBs9bsRxy79eTqTCBsA8TMIEky7qg48aPkvJvFe1HyzQ5oMZdg7AnVlWQSKLTnw==} + cpu: [x64] + os: [linux] + libc: [musl] + + '@rollup/rollup-openbsd-x64@4.60.2': + resolution: {integrity: sha512-6d4Z3534xitaA1FcMWP7mQPq5zGwBmGbhphh2DwaA1aNIXUu3KTOfwrWpbwI4/Gr0uANo7NTtaykFyO2hPuFLg==} + cpu: [x64] + os: [openbsd] + + '@rollup/rollup-openharmony-arm64@4.60.2': + resolution: {integrity: sha512-NetAg5iO2uN7eB8zE5qrZ3CSil+7IJt4WDFLcC75Ymywq1VZVD6qJ6EvNLjZ3rEm6gB7XW5JdT60c6MN35Z85Q==} + cpu: [arm64] + os: [openharmony] + + '@rollup/rollup-win32-arm64-msvc@4.60.2': + resolution: {integrity: sha512-NCYhOotpgWZ5kdxCZsv6Iudx0wX8980Q/oW4pNFNihpBKsDbEA1zpkfxJGC0yugsUuyDZ7gL37dbzwhR0VI7pQ==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.60.2': + resolution: {integrity: sha512-RXsaOqXxfoUBQoOgvmmijVxJnW2IGB0eoMO7F8FAjaj0UTywUO/luSqimWBJn04WNgUkeNhh7fs7pESXajWmkg==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-gnu@4.60.2': + resolution: {integrity: sha512-qdAzEULD+/hzObedtmV6iBpdL5TIbKVztGiK7O3/KYSf+HIzU257+MX1EXJcyIiDbMAqmbwaufcYPvyRryeZtA==} + cpu: [x64] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.60.2': + resolution: {integrity: sha512-Nd/SgG27WoA9e+/TdK74KnHz852TLa94ovOYySo/yMPuTmpckK/jIF2jSwS3g7ELSKXK13/cVdmg1Z/DaCWKxA==} + cpu: [x64] + os: [win32] + '@rushstack/node-core-library@5.23.1': resolution: {integrity: sha512-wlKmIKIYCKuCASbITvOxLZXepPbwXvrv7S6ig6XNWFchSyhL/E2txmVXspHY49Wu2dzf7nI27a2k/yV5BA3EiA==} peerDependencies: @@ -541,6 +988,18 @@ packages: '@types/argparse@1.0.38': resolution: {integrity: sha512-ebDJ9b0e702Yr7pWgB0jzm+CX4Srzz8RcXtLJDJB+BSccqMa36uyH/zUsSYao5+BD1ytv3k3rPYCq4mAE1hsXA==} + '@types/babel__core@7.20.5': + resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} + + '@types/babel__generator@7.27.0': + resolution: {integrity: sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==} + + '@types/babel__template@7.4.4': + resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} + + '@types/babel__traverse@7.28.0': + resolution: {integrity: sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==} + '@types/chrome@0.1.40': resolution: {integrity: sha512-UnfyRAe8ORu9HSuTH0EqyOEUin3JrWW9Nl/gDXezNfTUrfIoxw+WRZgKOxGz0t5BnjbfXBnS2eCYfW2PxH1wcA==} @@ -573,6 +1032,12 @@ packages: '@types/webextension-polyfill@0.12.5': resolution: {integrity: sha512-uKSAv6LgcVdINmxXMKBuVIcg/2m5JZugoZO8x20g7j2bXJkPIl/lVGQcDlbV+aXAiTyXT2RA5U5mI4IGCDMQeg==} + '@vitejs/plugin-react@5.2.0': + resolution: {integrity: sha512-YmKkfhOAi3wsB1PhJq5Scj3GXMn3WvtQ/JC0xoopuHoXSdmtdStOpFrYaT1kie2YgFBcIe64ROzMYRjCrYOdYw==} + engines: {node: ^20.19.0 || >=22.12.0} + peerDependencies: + vite: ^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 + '@vitejs/plugin-react@6.0.1': resolution: {integrity: sha512-l9X/E3cDb+xY3SWzlG1MOGt2usfEHGMNIaegaUGFsLkb3RCn/k8/TOXBcab+OndDI4TBtktT8/9BwwW8Vi9KUQ==} engines: {node: ^20.19.0 || >=22.12.0} @@ -659,6 +1124,11 @@ packages: resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} engines: {node: 18 || 20 || >=22} + baseline-browser-mapping@2.10.25: + resolution: {integrity: sha512-QO/VHsXCQdnzADMfmkeOPvHdIAkoB7i0/rGjINPJEetLx75hNttVWGQ/jycHUDP9zZ9rupbm60WRxcwViB0MiA==} + engines: {node: '>=6.0.0'} + hasBin: true + brace-expansion@2.1.0: resolution: {integrity: sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w==} @@ -666,6 +1136,14 @@ packages: resolution: {integrity: sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==} engines: {node: 18 || 20 || >=22} + browserslist@4.28.2: + resolution: {integrity: sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + + caniuse-lite@1.0.30001791: + resolution: {integrity: sha512-yk0l/YSrOnFZk3UROpDLQD9+kC1l4meK/wed583AXrzoarMGJcbRi2Q4RaUYbKxYAsZ8sWmaSa/DsLmdBeI1vQ==} + compare-versions@6.1.1: resolution: {integrity: sha512-4hm4VPpIecmlg59CHXnRDnqGplJFrbLG4aFEl5vl6cK1u76ws3LLvX7ikFnTDl5vo39sjWD6AaDPYodJp/NNHg==} @@ -675,6 +1153,9 @@ packages: confbox@0.2.4: resolution: {integrity: sha512-ysOGlgTFbN2/Y6Cg3Iye8YKulHw+R2fNXHrgSmXISQdMnomY6eNDprVdW9R5xBguEqI954+S6709UyiO7B+6OQ==} + convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + create-require@1.1.1: resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} @@ -705,6 +1186,9 @@ packages: resolution: {integrity: sha512-DPi0FmjiSU5EvQV0++GFDOJ9ASQUVFh5kD+OzOnYdi7n3Wpm9hWWGfB/O2blfHcMVTL5WkQXSnRiK9makhrcnw==} engines: {node: '>=0.3.1'} + electron-to-chromium@1.5.349: + resolution: {integrity: sha512-QsWVGyRuY07Aqb234QytTfwd5d9AJlfNIQ5wIOl1L+PZDzI9d9+Fn0FRale/QYlFxt/bUnB0/nLd1jFPGxGK1A==} + enhanced-resolve@5.21.0: resolution: {integrity: sha512-otxSQPw4lkOZWkHpB3zaEQs6gWYEsmX4xQF68ElXC/TWvGxGMSGOvoNbaLXm6/cS/fSfHtsEdw90y20PCd+sCA==} engines: {node: '>=10.13.0'} @@ -717,6 +1201,15 @@ packages: resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} engines: {node: '>= 0.4'} + esbuild@0.27.7: + resolution: {integrity: sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==} + engines: {node: '>=18'} + hasBin: true + + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + estree-walker@2.0.2: resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} @@ -750,6 +1243,10 @@ packages: function-bind@1.1.2: resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + glob@13.0.6: resolution: {integrity: sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==} engines: {node: 18 || 20 || >=22} @@ -784,9 +1281,22 @@ packages: jju@1.4.0: resolution: {integrity: sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==} + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + jsesc@3.1.0: + resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} + engines: {node: '>=6'} + hasBin: true + json-schema-traverse@1.0.0: resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + jsonfile@6.2.1: resolution: {integrity: sha512-zwOTdL3rFQ/lRdBnntKVOX6k5cKJwEc1HdilT71BWEu7J41gXIB2MRp+vxduPSwZJPWBxEzv4yH1wYLJGUHX4Q==} @@ -875,6 +1385,9 @@ packages: resolution: {integrity: sha512-NxVFwLAnrd9i7KUBxC4DrUhmgjzOs+1Qm50D3oF1/oL+r1NpZ4gA7xvG0/zJ8evR7zIKn4vLf7qTNduWFtCrRw==} engines: {node: 20 || >=22} + lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + magic-string@0.30.21: resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} @@ -911,6 +1424,9 @@ packages: engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true + node-releases@2.0.38: + resolution: {integrity: sha512-3qT/88Y3FbH/Kx4szpQQ4HzUbVrHPKTLVpVocKiLfoYvw9XSGOX2FmD2d6DrXbVYyAQTF2HeF6My8jmzx7/CRw==} + path-browserify@1.0.1: resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} @@ -949,6 +1465,10 @@ packages: peerDependencies: react: ^19.2.5 + react-refresh@0.18.0: + resolution: {integrity: sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw==} + engines: {node: '>=0.10.0'} + react@19.2.5: resolution: {integrity: sha512-llUJLzz1zTUBrskt2pwZgLq59AemifIftw4aB7JxOqf1HY2FDaGDxgwpAPVzHU1kdWabH7FauP4i1oEeer2WCA==} engines: {node: '>=0.10.0'} @@ -970,9 +1490,18 @@ packages: engines: {node: ^20.19.0 || >=22.12.0} hasBin: true + rollup@4.60.2: + resolution: {integrity: sha512-J9qZyW++QK/09NyN/zeO0dG/1GdGfyp9lV8ajHnRVLfo/uFsbji5mHnDgn/qYdUHyCkM2N+8VyspgZclfAh0eQ==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + scheduler@0.27.0: resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==} + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + semver@7.7.4: resolution: {integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==} engines: {node: '>=10'} @@ -1066,6 +1595,12 @@ packages: resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} engines: {node: '>= 10.0.0'} + update-browserslist-db@1.2.3: + resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + use-sync-external-store@1.6.0: resolution: {integrity: sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==} peerDependencies: @@ -1083,6 +1618,46 @@ packages: vite: optional: true + vite@7.3.2: + resolution: {integrity: sha512-Bby3NOsna2jsjfLVOHKes8sGwgl4TT0E6vvpYgnAYDIF/tie7MRaFthmKuHx1NSXjiTueXH3do80FMQgvEktRg==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + '@types/node': ^20.19.0 || >=22.12.0 + jiti: '>=1.21.0' + less: ^4.0.0 + lightningcss: ^1.21.0 + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: '>=0.54.8' + sugarss: ^5.0.0 + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + '@types/node': + optional: true + jiti: + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + vite@8.0.10: resolution: {integrity: sha512-rZuUu9j6J5uotLDs+cAA4O5H4K1SfPliUlQwqa6YEwSrWDZzP4rhm00oJR5snMewjxF5V/K3D4kctsUTsIU9Mw==} engines: {node: ^20.19.0 || >=22.12.0} @@ -1132,22 +1707,124 @@ packages: webextension-polyfill@0.12.0: resolution: {integrity: sha512-97TBmpoWJEE+3nFBQ4VocyCdLKfw54rFaJ6EVQYLBCXqCIpLSZkwGgASpv4oPt9gdKCJ80RJlcmNzNn008Ag6Q==} + yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + yn@3.1.1: resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} engines: {node: '>=6'} snapshots: + '@babel/code-frame@7.29.0': + dependencies: + '@babel/helper-validator-identifier': 7.28.5 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + '@babel/compat-data@7.29.3': {} + + '@babel/core@7.29.0': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/generator': 7.29.1 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) + '@babel/helpers': 7.29.2 + '@babel/parser': 7.29.3 + '@babel/template': 7.28.6 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + '@jridgewell/remapping': 2.3.5 + convert-source-map: 2.0.0 + debug: 4.4.3 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/generator@7.29.1': + dependencies: + '@babel/parser': 7.29.3 + '@babel/types': 7.29.0 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + jsesc: 3.1.0 + + '@babel/helper-compilation-targets@7.28.6': + dependencies: + '@babel/compat-data': 7.29.3 + '@babel/helper-validator-option': 7.27.1 + browserslist: 4.28.2 + lru-cache: 5.1.1 + semver: 6.3.1 + + '@babel/helper-globals@7.28.0': {} + + '@babel/helper-module-imports@7.28.6': + dependencies: + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-transforms@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-module-imports': 7.28.6 + '@babel/helper-validator-identifier': 7.28.5 + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-plugin-utils@7.28.6': {} + '@babel/helper-string-parser@7.27.1': {} '@babel/helper-validator-identifier@7.28.5': {} + '@babel/helper-validator-option@7.27.1': {} + + '@babel/helpers@7.29.2': + dependencies: + '@babel/template': 7.28.6 + '@babel/types': 7.29.0 + '@babel/parser@7.29.3': dependencies: '@babel/types': 7.29.0 + '@babel/plugin-transform-react-jsx-self@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-react-jsx-source@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/runtime@7.29.2': {} + '@babel/template@7.28.6': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/parser': 7.29.3 + '@babel/types': 7.29.0 + + '@babel/traverse@7.29.0': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/generator': 7.29.1 + '@babel/helper-globals': 7.28.0 + '@babel/parser': 7.29.3 + '@babel/template': 7.28.6 + '@babel/types': 7.29.0 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + '@babel/types@7.29.0': dependencies: '@babel/helper-string-parser': 7.27.1 @@ -1196,6 +1873,84 @@ snapshots: tslib: 2.8.1 optional: true + '@esbuild/aix-ppc64@0.27.7': + optional: true + + '@esbuild/android-arm64@0.27.7': + optional: true + + '@esbuild/android-arm@0.27.7': + optional: true + + '@esbuild/android-x64@0.27.7': + optional: true + + '@esbuild/darwin-arm64@0.27.7': + optional: true + + '@esbuild/darwin-x64@0.27.7': + optional: true + + '@esbuild/freebsd-arm64@0.27.7': + optional: true + + '@esbuild/freebsd-x64@0.27.7': + optional: true + + '@esbuild/linux-arm64@0.27.7': + optional: true + + '@esbuild/linux-arm@0.27.7': + optional: true + + '@esbuild/linux-ia32@0.27.7': + optional: true + + '@esbuild/linux-loong64@0.27.7': + optional: true + + '@esbuild/linux-mips64el@0.27.7': + optional: true + + '@esbuild/linux-ppc64@0.27.7': + optional: true + + '@esbuild/linux-riscv64@0.27.7': + optional: true + + '@esbuild/linux-s390x@0.27.7': + optional: true + + '@esbuild/linux-x64@0.27.7': + optional: true + + '@esbuild/netbsd-arm64@0.27.7': + optional: true + + '@esbuild/netbsd-x64@0.27.7': + optional: true + + '@esbuild/openbsd-arm64@0.27.7': + optional: true + + '@esbuild/openbsd-x64@0.27.7': + optional: true + + '@esbuild/openharmony-arm64@0.27.7': + optional: true + + '@esbuild/sunos-x64@0.27.7': + optional: true + + '@esbuild/win32-arm64@0.27.7': + optional: true + + '@esbuild/win32-ia32@0.27.7': + optional: true + + '@esbuild/win32-x64@0.27.7': + optional: true + '@floating-ui/core@1.7.5': dependencies: '@floating-ui/utils': 0.2.11 @@ -1332,13 +2087,92 @@ snapshots: '@rolldown/pluginutils@1.0.0-rc.17': {} + '@rolldown/pluginutils@1.0.0-rc.3': {} + '@rolldown/pluginutils@1.0.0-rc.7': {} - '@rollup/pluginutils@5.3.0': + '@rollup/pluginutils@5.3.0(rollup@4.60.2)': dependencies: '@types/estree': 1.0.8 estree-walker: 2.0.2 picomatch: 4.0.4 + optionalDependencies: + rollup: 4.60.2 + + '@rollup/rollup-android-arm-eabi@4.60.2': + optional: true + + '@rollup/rollup-android-arm64@4.60.2': + optional: true + + '@rollup/rollup-darwin-arm64@4.60.2': + optional: true + + '@rollup/rollup-darwin-x64@4.60.2': + optional: true + + '@rollup/rollup-freebsd-arm64@4.60.2': + optional: true + + '@rollup/rollup-freebsd-x64@4.60.2': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.60.2': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.60.2': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.60.2': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.60.2': + optional: true + + '@rollup/rollup-linux-loong64-gnu@4.60.2': + optional: true + + '@rollup/rollup-linux-loong64-musl@4.60.2': + optional: true + + '@rollup/rollup-linux-ppc64-gnu@4.60.2': + optional: true + + '@rollup/rollup-linux-ppc64-musl@4.60.2': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.60.2': + optional: true + + '@rollup/rollup-linux-riscv64-musl@4.60.2': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.60.2': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.60.2': + optional: true + + '@rollup/rollup-linux-x64-musl@4.60.2': + optional: true + + '@rollup/rollup-openbsd-x64@4.60.2': + optional: true + + '@rollup/rollup-openharmony-arm64@4.60.2': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.60.2': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.60.2': + optional: true + + '@rollup/rollup-win32-x64-gnu@4.60.2': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.60.2': + optional: true '@rushstack/node-core-library@5.23.1(@types/node@25.6.0)': dependencies: @@ -1440,12 +2274,12 @@ snapshots: '@tailwindcss/oxide-win32-arm64-msvc': 4.2.4 '@tailwindcss/oxide-win32-x64-msvc': 4.2.4 - '@tailwindcss/vite@4.2.4(vite@8.0.10(@types/node@25.6.0)(jiti@2.6.1))': + '@tailwindcss/vite@4.2.4(vite@7.3.2(@types/node@25.6.0)(jiti@2.6.1)(lightningcss@1.32.0))': dependencies: '@tailwindcss/node': 4.2.4 '@tailwindcss/oxide': 4.2.4 tailwindcss: 4.2.4 - vite: 8.0.10(@types/node@25.6.0)(jiti@2.6.1) + vite: 7.3.2(@types/node@25.6.0)(jiti@2.6.1)(lightningcss@1.32.0) '@tsconfig/node10@1.0.12': {} @@ -1480,6 +2314,27 @@ snapshots: '@types/argparse@1.0.38': {} + '@types/babel__core@7.20.5': + dependencies: + '@babel/parser': 7.29.3 + '@babel/types': 7.29.0 + '@types/babel__generator': 7.27.0 + '@types/babel__template': 7.4.4 + '@types/babel__traverse': 7.28.0 + + '@types/babel__generator@7.27.0': + dependencies: + '@babel/types': 7.29.0 + + '@types/babel__template@7.4.4': + dependencies: + '@babel/parser': 7.29.3 + '@babel/types': 7.29.0 + + '@types/babel__traverse@7.28.0': + dependencies: + '@babel/types': 7.29.0 + '@types/chrome@0.1.40': dependencies: '@types/filesystem': 0.0.36 @@ -1511,10 +2366,22 @@ snapshots: '@types/webextension-polyfill@0.12.5': {} - '@vitejs/plugin-react@6.0.1(vite@8.0.10(@types/node@25.6.0)(jiti@2.6.1))': + '@vitejs/plugin-react@5.2.0(vite@7.3.2(@types/node@25.6.0)(jiti@2.6.1)(lightningcss@1.32.0))': + dependencies: + '@babel/core': 7.29.0 + '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-react-jsx-source': 7.27.1(@babel/core@7.29.0) + '@rolldown/pluginutils': 1.0.0-rc.3 + '@types/babel__core': 7.20.5 + react-refresh: 0.18.0 + vite: 7.3.2(@types/node@25.6.0)(jiti@2.6.1)(lightningcss@1.32.0) + transitivePeerDependencies: + - supports-color + + '@vitejs/plugin-react@6.0.1(vite@8.0.10(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1))': dependencies: '@rolldown/pluginutils': 1.0.0-rc.7 - vite: 8.0.10(@types/node@25.6.0)(jiti@2.6.1) + vite: 8.0.10(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1) '@volar/language-core@2.4.28': dependencies: @@ -1594,6 +2461,8 @@ snapshots: balanced-match@4.0.4: {} + baseline-browser-mapping@2.10.25: {} + brace-expansion@2.1.0: dependencies: balanced-match: 1.0.0 @@ -1602,12 +2471,24 @@ snapshots: dependencies: balanced-match: 4.0.4 + browserslist@4.28.2: + dependencies: + baseline-browser-mapping: 2.10.25 + caniuse-lite: 1.0.30001791 + electron-to-chromium: 1.5.349 + node-releases: 2.0.38 + update-browserslist-db: 1.2.3(browserslist@4.28.2) + + caniuse-lite@1.0.30001791: {} + compare-versions@6.1.1: {} confbox@0.1.8: {} confbox@0.2.4: {} + convert-source-map@2.0.0: {} + create-require@1.1.1: {} csstype@3.2.3: {} @@ -1624,6 +2505,8 @@ snapshots: diff@8.0.4: {} + electron-to-chromium@1.5.349: {} + enhanced-resolve@5.21.0: dependencies: graceful-fs: 4.2.11 @@ -1633,6 +2516,37 @@ snapshots: es-errors@1.3.0: {} + esbuild@0.27.7: + optionalDependencies: + '@esbuild/aix-ppc64': 0.27.7 + '@esbuild/android-arm': 0.27.7 + '@esbuild/android-arm64': 0.27.7 + '@esbuild/android-x64': 0.27.7 + '@esbuild/darwin-arm64': 0.27.7 + '@esbuild/darwin-x64': 0.27.7 + '@esbuild/freebsd-arm64': 0.27.7 + '@esbuild/freebsd-x64': 0.27.7 + '@esbuild/linux-arm': 0.27.7 + '@esbuild/linux-arm64': 0.27.7 + '@esbuild/linux-ia32': 0.27.7 + '@esbuild/linux-loong64': 0.27.7 + '@esbuild/linux-mips64el': 0.27.7 + '@esbuild/linux-ppc64': 0.27.7 + '@esbuild/linux-riscv64': 0.27.7 + '@esbuild/linux-s390x': 0.27.7 + '@esbuild/linux-x64': 0.27.7 + '@esbuild/netbsd-arm64': 0.27.7 + '@esbuild/netbsd-x64': 0.27.7 + '@esbuild/openbsd-arm64': 0.27.7 + '@esbuild/openbsd-x64': 0.27.7 + '@esbuild/openharmony-arm64': 0.27.7 + '@esbuild/sunos-x64': 0.27.7 + '@esbuild/win32-arm64': 0.27.7 + '@esbuild/win32-ia32': 0.27.7 + '@esbuild/win32-x64': 0.27.7 + + escalade@3.2.0: {} + estree-walker@2.0.2: {} exsolve@1.0.8: {} @@ -1656,6 +2570,8 @@ snapshots: function-bind@1.1.2: {} + gensync@1.0.0-beta.2: {} + glob@13.0.6: dependencies: minimatch: 10.2.5 @@ -1682,8 +2598,14 @@ snapshots: jju@1.4.0: {} + js-tokens@4.0.0: {} + + jsesc@3.1.0: {} + json-schema-traverse@1.0.0: {} + json5@2.2.3: {} + jsonfile@6.2.1: dependencies: universalify: 2.0.1 @@ -1749,6 +2671,10 @@ snapshots: lru-cache@11.3.5: {} + lru-cache@5.1.1: + dependencies: + yallist: 3.1.1 + magic-string@0.30.21: dependencies: '@jridgewell/sourcemap-codec': 1.5.5 @@ -1782,6 +2708,8 @@ snapshots: nanoid@3.3.12: {} + node-releases@2.0.38: {} + path-browserify@1.0.1: {} path-parse@1.0.7: {} @@ -1822,6 +2750,8 @@ snapshots: react: 19.2.5 scheduler: 0.27.0 + react-refresh@0.18.0: {} + react@19.2.5: {} require-from-string@2.0.2: {} @@ -1856,8 +2786,41 @@ snapshots: '@rolldown/binding-win32-arm64-msvc': 1.0.0-rc.17 '@rolldown/binding-win32-x64-msvc': 1.0.0-rc.17 + rollup@4.60.2: + dependencies: + '@types/estree': 1.0.8 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.60.2 + '@rollup/rollup-android-arm64': 4.60.2 + '@rollup/rollup-darwin-arm64': 4.60.2 + '@rollup/rollup-darwin-x64': 4.60.2 + '@rollup/rollup-freebsd-arm64': 4.60.2 + '@rollup/rollup-freebsd-x64': 4.60.2 + '@rollup/rollup-linux-arm-gnueabihf': 4.60.2 + '@rollup/rollup-linux-arm-musleabihf': 4.60.2 + '@rollup/rollup-linux-arm64-gnu': 4.60.2 + '@rollup/rollup-linux-arm64-musl': 4.60.2 + '@rollup/rollup-linux-loong64-gnu': 4.60.2 + '@rollup/rollup-linux-loong64-musl': 4.60.2 + '@rollup/rollup-linux-ppc64-gnu': 4.60.2 + '@rollup/rollup-linux-ppc64-musl': 4.60.2 + '@rollup/rollup-linux-riscv64-gnu': 4.60.2 + '@rollup/rollup-linux-riscv64-musl': 4.60.2 + '@rollup/rollup-linux-s390x-gnu': 4.60.2 + '@rollup/rollup-linux-x64-gnu': 4.60.2 + '@rollup/rollup-linux-x64-musl': 4.60.2 + '@rollup/rollup-openbsd-x64': 4.60.2 + '@rollup/rollup-openharmony-arm64': 4.60.2 + '@rollup/rollup-win32-arm64-msvc': 4.60.2 + '@rollup/rollup-win32-ia32-msvc': 4.60.2 + '@rollup/rollup-win32-x64-gnu': 4.60.2 + '@rollup/rollup-win32-x64-msvc': 4.60.2 + fsevents: 2.3.3 + scheduler@0.27.0: {} + semver@6.3.1: {} + semver@7.7.4: {} source-map-js@1.2.1: {} @@ -1931,16 +2894,22 @@ snapshots: universalify@2.0.1: {} + update-browserslist-db@1.2.3(browserslist@4.28.2): + dependencies: + browserslist: 4.28.2 + escalade: 3.2.0 + picocolors: 1.1.1 + use-sync-external-store@1.6.0(react@19.2.5): dependencies: react: 19.2.5 v8-compile-cache-lib@3.0.1: {} - vite-plugin-dts@4.5.4(@types/node@25.6.0)(typescript@6.0.3)(vite@8.0.10(@types/node@25.6.0)(jiti@2.6.1)): + vite-plugin-dts@4.5.4(@types/node@25.6.0)(rollup@4.60.2)(typescript@6.0.3)(vite@7.3.2(@types/node@25.6.0)(jiti@2.6.1)(lightningcss@1.32.0)): dependencies: '@microsoft/api-extractor': 7.58.7(@types/node@25.6.0) - '@rollup/pluginutils': 5.3.0 + '@rollup/pluginutils': 5.3.0(rollup@4.60.2) '@volar/typescript': 2.4.28 '@vue/language-core': 2.2.0(typescript@6.0.3) compare-versions: 6.1.1 @@ -1950,13 +2919,46 @@ snapshots: magic-string: 0.30.21 typescript: 6.0.3 optionalDependencies: - vite: 8.0.10(@types/node@25.6.0)(jiti@2.6.1) + vite: 7.3.2(@types/node@25.6.0)(jiti@2.6.1)(lightningcss@1.32.0) transitivePeerDependencies: - '@types/node' - rollup - supports-color - vite@8.0.10(@types/node@25.6.0)(jiti@2.6.1): + vite-plugin-dts@4.5.4(@types/node@25.6.0)(rollup@4.60.2)(typescript@6.0.3)(vite@8.0.10(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)): + dependencies: + '@microsoft/api-extractor': 7.58.7(@types/node@25.6.0) + '@rollup/pluginutils': 5.3.0(rollup@4.60.2) + '@volar/typescript': 2.4.28 + '@vue/language-core': 2.2.0(typescript@6.0.3) + compare-versions: 6.1.1 + debug: 4.4.3 + kolorist: 1.8.0 + local-pkg: 1.1.2 + magic-string: 0.30.21 + typescript: 6.0.3 + optionalDependencies: + vite: 8.0.10(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1) + transitivePeerDependencies: + - '@types/node' + - rollup + - supports-color + + vite@7.3.2(@types/node@25.6.0)(jiti@2.6.1)(lightningcss@1.32.0): + dependencies: + esbuild: 0.27.7 + fdir: 6.5.0(picomatch@4.0.4) + picomatch: 4.0.4 + postcss: 8.5.13 + rollup: 4.60.2 + tinyglobby: 0.2.16 + optionalDependencies: + '@types/node': 25.6.0 + fsevents: 2.3.3 + jiti: 2.6.1 + lightningcss: 1.32.0 + + vite@8.0.10(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1): dependencies: lightningcss: 1.32.0 picomatch: 4.0.4 @@ -1965,6 +2967,7 @@ snapshots: tinyglobby: 0.2.16 optionalDependencies: '@types/node': 25.6.0 + esbuild: 0.27.7 fsevents: 2.3.3 jiti: 2.6.1 @@ -1972,4 +2975,6 @@ snapshots: webextension-polyfill@0.12.0: {} + yallist@3.1.1: {} + yn@3.1.1: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 4cc172b..ea14cf7 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -3,4 +3,5 @@ packages: - "apps/*" - "templates/*" allowBuilds: + esbuild: false sharp: false diff --git a/templates/vite-react-app/.npmrc b/templates/vite-react-app/.npmrc new file mode 100644 index 0000000..8b02f75 --- /dev/null +++ b/templates/vite-react-app/.npmrc @@ -0,0 +1 @@ +registry = https://registry.npmmirror.com/ \ No newline at end of file diff --git a/templates/vite-react-app/.vscode/settings.json b/templates/vite-react-app/.vscode/settings.json new file mode 100644 index 0000000..772343c --- /dev/null +++ b/templates/vite-react-app/.vscode/settings.json @@ -0,0 +1,8 @@ +{ + "json.schemas": [ + { + "fileMatch": ["/tsconfig.build.json", "/tsconfig.base.json"], + "schema": {} + } + ] +} diff --git a/templates/vite-react-app/index.html b/templates/vite-react-app/index.html new file mode 100644 index 0000000..cffe571 --- /dev/null +++ b/templates/vite-react-app/index.html @@ -0,0 +1,11 @@ + + + + + DefGov UI Web + + +
+ + + diff --git a/templates/vite-react-app/package.json b/templates/vite-react-app/package.json new file mode 100644 index 0000000..7fb755b --- /dev/null +++ b/templates/vite-react-app/package.json @@ -0,0 +1,46 @@ +{ + "name": "vite-react-app", + "version": "0.0.0", + "private": true, + "type": "module", + "sideEffects": [ + "*.css" + ], + "module": "./dist/index.es.js", + "main": "./dist/index.cjs.js", + "types": "./dist/index.d.ts", + "style": "./dist/index.css", + "exports": { + ".": { + "import": "./dist/index.es.js", + "require": "./dist/index.cjs.js", + "types": "./dist/index.d.ts" + }, + "./index.css": "./dist/index.css" + }, + "files": [ + "dist" + ], + "scripts": { + "gen-css": "ts-node scripts/gen-index-css.ts", + "gen-ts": "ts-node scripts/gen-index-ts.ts", + "gen-index": "pnpm run gen-css && pnpm run gen-ts", + "dev": "pnpm run gen-index && vite build --watch", + "build": "pnpm run gen-index && tsc -p tsconfig.build.json && vite build" + }, + "devDependencies": { + "@types/node": "^25.6.0", + "@types/react": "^19.2.14", + "@types/react-dom": "^19.2.3", + "@vitejs/plugin-react": "~5.2.0", + "glob": "^13.0.6", + "typescript": "~6.0.3", + "vite": "~7.3.2", + "vite-plugin-dts": "^4.5.4", + "ts-node": "^10.9.2" + }, + "dependencies": { + "react": "^19.2.5", + "react-dom": "^19.2.5" + } +} diff --git a/templates/vite-react-app/scripts/gen-index-css.ts b/templates/vite-react-app/scripts/gen-index-css.ts new file mode 100644 index 0000000..fdddef4 --- /dev/null +++ b/templates/vite-react-app/scripts/gen-index-css.ts @@ -0,0 +1,121 @@ +import fs from "fs"; +import path from "path"; +import { globSync } from "glob"; + +interface Config { + targetDirs: string[]; + includeExtensions: string[]; + excludeKeywords: { + dirs: string[]; + fileSuffixes: string[]; + filePatterns: RegExp[]; + }; +} + +const CONFIG: Config = { + targetDirs: ["src"], + includeExtensions: [".ts", ".tsx", ".vue"], + excludeKeywords: { + dirs: ["__tests__", "tests", "story", "stories", "types"], + fileSuffixes: [".d.ts"], + filePatterns: [ + /^index\.(ts|tsx|js|jsx)$/, + /\.(test|spec)\./, + /\.(story|stories)\./, + ], + }, +}; + +const normalizePath = (p: string) => p.replace(/\\/g, "/"); + +const isInExcludeDir = (filePath: string) => { + const normalized = normalizePath(filePath); + return CONFIG.excludeKeywords.dirs.some((dir) => + normalized.includes(`/${dir}/`), + ); +}; + +const isExcludeSuffix = (filePath: string) => + CONFIG.excludeKeywords.fileSuffixes.some((suffix) => + filePath.endsWith(suffix), + ); + +const isMatchExcludePattern = (fileName: string) => + CONFIG.excludeKeywords.filePatterns.some((pattern) => pattern.test(fileName)); + +function isValidFile(filePath: string): boolean { + const fileName = filePath.split(/[\\/]/).pop()!; + + if (isInExcludeDir(filePath)) return false; + if (isExcludeSuffix(filePath)) return false; + if (isMatchExcludePattern(fileName)) return false; + + const ext = path.extname(filePath); + return CONFIG.includeExtensions.includes(ext); +} + +function generateIndexFile(dirPath: string) { + const searchPattern = path.resolve(dirPath, "**", "*.*"); + + const allFiles = globSync(searchPattern, { + nodir: true, + absolute: true, + windowsPathsNoEscape: true, + dot: false, + follow: true, + }); + + const validFiles = allFiles.filter(isValidFile); + if (validFiles.length === 0) { + console.log("⚠️ 未找到符合条件的文件,跳过生成 index.ts"); + return; + } + + validFiles.sort(); + + const exportStatements = validFiles.map((file) => { + const relPath = path.relative(dirPath, file); + const importPath = `./${relPath + .replace(/\.[^.]+$/, "") + .replace(/\\/g, "/")}`; + return `export * from '${importPath}';`; + }); + + const indexContent = ` +import './index.css'; + +${exportStatements.join("\n")} +`.trim(); + + const indexFilePath = path.resolve(dirPath, "index.ts"); + + // ✅ 内容比对,避免重复写入 + if (fs.existsSync(indexFilePath)) { + const old = fs.readFileSync(indexFilePath, "utf8"); + if (old === indexContent) { + console.log("✅ index.ts 内容无变化,无需重新生成"); + return; + } + } + + fs.writeFileSync(indexFilePath, indexContent, "utf8"); + console.log(`✅ 成功生成 index.ts: ${indexFilePath}`); +} + +// 脚本入口 +const [targetDir] = CONFIG.targetDirs; +if (!targetDir) { + console.error("❌ CONFIG.targetDirs 不能为空"); + process.exit(1); +} + +const absTargetDir = path.resolve(process.cwd(), targetDir); + +try { + console.log(`🚀 开始扫描目录: ${absTargetDir}`); + generateIndexFile(absTargetDir); +} catch (err) { + const msg = err instanceof Error ? err.message : String(err); + console.error(`❌ [gen-index-ts] 执行失败: ${msg}`); + process.exit(1); +} diff --git a/templates/vite-react-app/scripts/gen-index-ts.ts b/templates/vite-react-app/scripts/gen-index-ts.ts new file mode 100644 index 0000000..fdddef4 --- /dev/null +++ b/templates/vite-react-app/scripts/gen-index-ts.ts @@ -0,0 +1,121 @@ +import fs from "fs"; +import path from "path"; +import { globSync } from "glob"; + +interface Config { + targetDirs: string[]; + includeExtensions: string[]; + excludeKeywords: { + dirs: string[]; + fileSuffixes: string[]; + filePatterns: RegExp[]; + }; +} + +const CONFIG: Config = { + targetDirs: ["src"], + includeExtensions: [".ts", ".tsx", ".vue"], + excludeKeywords: { + dirs: ["__tests__", "tests", "story", "stories", "types"], + fileSuffixes: [".d.ts"], + filePatterns: [ + /^index\.(ts|tsx|js|jsx)$/, + /\.(test|spec)\./, + /\.(story|stories)\./, + ], + }, +}; + +const normalizePath = (p: string) => p.replace(/\\/g, "/"); + +const isInExcludeDir = (filePath: string) => { + const normalized = normalizePath(filePath); + return CONFIG.excludeKeywords.dirs.some((dir) => + normalized.includes(`/${dir}/`), + ); +}; + +const isExcludeSuffix = (filePath: string) => + CONFIG.excludeKeywords.fileSuffixes.some((suffix) => + filePath.endsWith(suffix), + ); + +const isMatchExcludePattern = (fileName: string) => + CONFIG.excludeKeywords.filePatterns.some((pattern) => pattern.test(fileName)); + +function isValidFile(filePath: string): boolean { + const fileName = filePath.split(/[\\/]/).pop()!; + + if (isInExcludeDir(filePath)) return false; + if (isExcludeSuffix(filePath)) return false; + if (isMatchExcludePattern(fileName)) return false; + + const ext = path.extname(filePath); + return CONFIG.includeExtensions.includes(ext); +} + +function generateIndexFile(dirPath: string) { + const searchPattern = path.resolve(dirPath, "**", "*.*"); + + const allFiles = globSync(searchPattern, { + nodir: true, + absolute: true, + windowsPathsNoEscape: true, + dot: false, + follow: true, + }); + + const validFiles = allFiles.filter(isValidFile); + if (validFiles.length === 0) { + console.log("⚠️ 未找到符合条件的文件,跳过生成 index.ts"); + return; + } + + validFiles.sort(); + + const exportStatements = validFiles.map((file) => { + const relPath = path.relative(dirPath, file); + const importPath = `./${relPath + .replace(/\.[^.]+$/, "") + .replace(/\\/g, "/")}`; + return `export * from '${importPath}';`; + }); + + const indexContent = ` +import './index.css'; + +${exportStatements.join("\n")} +`.trim(); + + const indexFilePath = path.resolve(dirPath, "index.ts"); + + // ✅ 内容比对,避免重复写入 + if (fs.existsSync(indexFilePath)) { + const old = fs.readFileSync(indexFilePath, "utf8"); + if (old === indexContent) { + console.log("✅ index.ts 内容无变化,无需重新生成"); + return; + } + } + + fs.writeFileSync(indexFilePath, indexContent, "utf8"); + console.log(`✅ 成功生成 index.ts: ${indexFilePath}`); +} + +// 脚本入口 +const [targetDir] = CONFIG.targetDirs; +if (!targetDir) { + console.error("❌ CONFIG.targetDirs 不能为空"); + process.exit(1); +} + +const absTargetDir = path.resolve(process.cwd(), targetDir); + +try { + console.log(`🚀 开始扫描目录: ${absTargetDir}`); + generateIndexFile(absTargetDir); +} catch (err) { + const msg = err instanceof Error ? err.message : String(err); + console.error(`❌ [gen-index-ts] 执行失败: ${msg}`); + process.exit(1); +} diff --git a/templates/vite-react-app/src/App.tsx b/templates/vite-react-app/src/App.tsx new file mode 100644 index 0000000..97e63ad --- /dev/null +++ b/templates/vite-react-app/src/App.tsx @@ -0,0 +1,3 @@ +export default function App() { + return <>; +} diff --git a/templates/vite-react-app/src/main.tsx b/templates/vite-react-app/src/main.tsx new file mode 100644 index 0000000..4930e42 --- /dev/null +++ b/templates/vite-react-app/src/main.tsx @@ -0,0 +1,7 @@ +import { createRoot } from "react-dom/client"; +import App from "./App"; + +const container = document.getElementById("root")!; +const root = createRoot(container); + +root.render(); diff --git a/templates/vite-react-app/src/types/css.d.ts b/templates/vite-react-app/src/types/css.d.ts new file mode 100644 index 0000000..d535de2 --- /dev/null +++ b/templates/vite-react-app/src/types/css.d.ts @@ -0,0 +1,4 @@ +declare module '*.css' { + const content: { [className: string]: string }; + export default content; +} \ No newline at end of file diff --git a/templates/vite-react-app/src/types/env.d.ts b/templates/vite-react-app/src/types/env.d.ts new file mode 100644 index 0000000..7ba6254 --- /dev/null +++ b/templates/vite-react-app/src/types/env.d.ts @@ -0,0 +1,51 @@ +/// + +declare module "*.svg" { + import * as React from "react"; + export const ReactComponent: React.FC>; + const src: string; + export default src; +} + +declare module "*.png" { + const src: string; + export default src; +} + +declare module "*.jpg" { + const src: string; + export default src; +} + +declare module "*.jpeg" { + const src: string; + export default src; +} + +declare module "*.gif" { + const src: string; + export default src; +} + +declare module "*.webp" { + const src: string; + export default src; +} + +interface ImportMetaEnv { + readonly MODE: "development" | "production" | "test"; + readonly BASE_URL: string; + readonly PROD: boolean; + readonly DEV: boolean; + readonly SSR: boolean; + + // ===== 业务环境变量 ===== + readonly VITE_API_BASE: string; + readonly VITE_UPLOAD_URL?: string; + readonly VITE_ENABLE_MOCK?: "true" | "false"; + readonly VITE_SENTRY_DSN?: string; +} + +interface ImportMeta { + readonly env: ImportMetaEnv; +} diff --git a/templates/vite-react-app/tsconfig.base.json b/templates/vite-react-app/tsconfig.base.json new file mode 100644 index 0000000..145f36e --- /dev/null +++ b/templates/vite-react-app/tsconfig.base.json @@ -0,0 +1,26 @@ +{ + // tsconfig.base.json,用于被 tesconfig.json 和 tesconfig.build.json 继承 + "compilerOptions": { + // 输出模块语法,使用版本号最新的那个,而不是实验性语法 ESNext + "module": "es2022", + + // 模块解析策略,模拟 Vite / Rollup / webpack,支持 exports / imports,不强制 Node ESM 的严格规则 + "moduleResolution": "bundler", + + // 显式声明使用的类型包 + "types": ["node", "react"], + + // 允许 ESM 导入 CJS + "esModuleInterop": true, + + // 跳过 node_modules 类型检查,加快构建,避免第三方类型污染 + "skipLibCheck": true, + + /** + * 只做类型检查,不生成 JS 输出 + * - 适用于 Vite / Next / Nuxt 等 bundler 场景 + * - 防止 tsc 与构建工具重复 emit + */ + "noEmit": true + } +} diff --git a/templates/vite-react-template/tsconfig.build.json b/templates/vite-react-app/tsconfig.build.json similarity index 88% rename from templates/vite-react-template/tsconfig.build.json rename to templates/vite-react-app/tsconfig.build.json index f3b4b99..d38b63b 100644 --- a/templates/vite-react-template/tsconfig.build.json +++ b/templates/vite-react-app/tsconfig.build.json @@ -13,7 +13,7 @@ * - react:JSX / React 类型 * - vite/client:import.meta / env */ - "types": ["node", "react", "vite/client"], + "types": ["node", "react"], /** * React JSX 编译模式 @@ -54,21 +54,14 @@ * - 适配 esbuild / SWC / bundler 编译模型 * - 禁止依赖跨文件类型推断(enum / namespace 等) */ - "isolatedModules": true, - - /** - * 允许在 import 中显式使用 .ts / .tsx 后缀 - * - 兼容 Node ESM / bundler 对文件扩展名的严格要求 - * - 避免 `import './foo'` 在 TS + ESM 下歧义 - */ - "allowImportingTsExtensions": true + "isolatedModules": true }, /** * 参与类型检查和编译的文件 * - 只扫描 src * - 其它目录通过 exclude 排除 */ - "include": ["src", "scripts"], + "include": ["src"], /** * 明确排除非源码内容 diff --git a/templates/vite-react-app/tsconfig.json b/templates/vite-react-app/tsconfig.json new file mode 100644 index 0000000..e5bdf16 --- /dev/null +++ b/templates/vite-react-app/tsconfig.json @@ -0,0 +1,16 @@ +{ + // 此文件仅用于类型检查,不用于构建,构建时会指定使用 tsconfig.build.json + "extends": "./tsconfig.base.json", + "compilerOptions": { + // node api 使用最新版本号的 "ESxxxx",browser api 使用 "DOM" 和 "DOM.Iterable" + "lib": ["ES2025", "DOM", "DOM.Iterable"], + + //显式声明使用的类型包,避免找不到模块 + "types": ["node", "react"], + + // React JSX 编译模式 + "jsx": "react-jsx" + }, + // 将类型检查范围扩大至整个子项目,而不只是 src 文件夹, + "include": ["**/*"] +} diff --git a/templates/vite-react-app/vite.config.ts b/templates/vite-react-app/vite.config.ts new file mode 100644 index 0000000..78a623a --- /dev/null +++ b/templates/vite-react-app/vite.config.ts @@ -0,0 +1,12 @@ +import { defineConfig } from "vite"; +import react from "@vitejs/plugin-react"; +import dts from "vite-plugin-dts"; + +export default defineConfig({ + plugins: [ + react(), + dts({ + insertTypesEntry: true, + }), + ], +}); diff --git a/templates/vite-react-lib/.npmrc b/templates/vite-react-lib/.npmrc new file mode 100644 index 0000000..8b02f75 --- /dev/null +++ b/templates/vite-react-lib/.npmrc @@ -0,0 +1 @@ +registry = https://registry.npmmirror.com/ \ No newline at end of file diff --git a/templates/vite-react-lib/.vscode/settings.json b/templates/vite-react-lib/.vscode/settings.json new file mode 100644 index 0000000..772343c --- /dev/null +++ b/templates/vite-react-lib/.vscode/settings.json @@ -0,0 +1,8 @@ +{ + "json.schemas": [ + { + "fileMatch": ["/tsconfig.build.json", "/tsconfig.base.json"], + "schema": {} + } + ] +} diff --git a/templates/vite-react-lib/package.json b/templates/vite-react-lib/package.json new file mode 100644 index 0000000..529994e --- /dev/null +++ b/templates/vite-react-lib/package.json @@ -0,0 +1,46 @@ +{ + "name": "vite-react-lib", + "version": "0.0.0", + "private": true, + "type": "module", + "sideEffects": [ + "*.css" + ], + "module": "./dist/index.es.js", + "main": "./dist/index.cjs.js", + "types": "./dist/index.d.ts", + "style": "./dist/index.css", + "exports": { + ".": { + "import": "./dist/index.es.js", + "require": "./dist/index.cjs.js", + "types": "./dist/index.d.ts" + }, + "./index.css": "./dist/index.css" + }, + "files": [ + "dist" + ], + "scripts": { + "gen-css": "ts-node scripts/gen-index-css.ts", + "gen-ts": "ts-node scripts/gen-index-ts.ts", + "gen-index": "pnpm run gen-css && pnpm run gen-ts", + "dev": "pnpm run gen-index && vite build --watch", + "build": "pnpm run gen-index && tsc -p tsconfig.build.json && vite build" + }, + "devDependencies": { + "@types/node": "^25.6.0", + "@types/react": "^19.2.14", + "@types/react-dom": "^19.2.3", + "@vitejs/plugin-react": "~5.2.0", + "glob": "^13.0.6", + "typescript": "~6.0.3", + "vite": "~7.3.2", + "vite-plugin-dts": "^4.5.4", + "ts-node": "^10.9.2" + }, + "peerDependencies": { + "react": "^19", + "react-dom": "^19" + } +} diff --git a/templates/vite-react-lib/scripts/gen-index-css.ts b/templates/vite-react-lib/scripts/gen-index-css.ts new file mode 100644 index 0000000..fdddef4 --- /dev/null +++ b/templates/vite-react-lib/scripts/gen-index-css.ts @@ -0,0 +1,121 @@ +import fs from "fs"; +import path from "path"; +import { globSync } from "glob"; + +interface Config { + targetDirs: string[]; + includeExtensions: string[]; + excludeKeywords: { + dirs: string[]; + fileSuffixes: string[]; + filePatterns: RegExp[]; + }; +} + +const CONFIG: Config = { + targetDirs: ["src"], + includeExtensions: [".ts", ".tsx", ".vue"], + excludeKeywords: { + dirs: ["__tests__", "tests", "story", "stories", "types"], + fileSuffixes: [".d.ts"], + filePatterns: [ + /^index\.(ts|tsx|js|jsx)$/, + /\.(test|spec)\./, + /\.(story|stories)\./, + ], + }, +}; + +const normalizePath = (p: string) => p.replace(/\\/g, "/"); + +const isInExcludeDir = (filePath: string) => { + const normalized = normalizePath(filePath); + return CONFIG.excludeKeywords.dirs.some((dir) => + normalized.includes(`/${dir}/`), + ); +}; + +const isExcludeSuffix = (filePath: string) => + CONFIG.excludeKeywords.fileSuffixes.some((suffix) => + filePath.endsWith(suffix), + ); + +const isMatchExcludePattern = (fileName: string) => + CONFIG.excludeKeywords.filePatterns.some((pattern) => pattern.test(fileName)); + +function isValidFile(filePath: string): boolean { + const fileName = filePath.split(/[\\/]/).pop()!; + + if (isInExcludeDir(filePath)) return false; + if (isExcludeSuffix(filePath)) return false; + if (isMatchExcludePattern(fileName)) return false; + + const ext = path.extname(filePath); + return CONFIG.includeExtensions.includes(ext); +} + +function generateIndexFile(dirPath: string) { + const searchPattern = path.resolve(dirPath, "**", "*.*"); + + const allFiles = globSync(searchPattern, { + nodir: true, + absolute: true, + windowsPathsNoEscape: true, + dot: false, + follow: true, + }); + + const validFiles = allFiles.filter(isValidFile); + if (validFiles.length === 0) { + console.log("⚠️ 未找到符合条件的文件,跳过生成 index.ts"); + return; + } + + validFiles.sort(); + + const exportStatements = validFiles.map((file) => { + const relPath = path.relative(dirPath, file); + const importPath = `./${relPath + .replace(/\.[^.]+$/, "") + .replace(/\\/g, "/")}`; + return `export * from '${importPath}';`; + }); + + const indexContent = ` +import './index.css'; + +${exportStatements.join("\n")} +`.trim(); + + const indexFilePath = path.resolve(dirPath, "index.ts"); + + // ✅ 内容比对,避免重复写入 + if (fs.existsSync(indexFilePath)) { + const old = fs.readFileSync(indexFilePath, "utf8"); + if (old === indexContent) { + console.log("✅ index.ts 内容无变化,无需重新生成"); + return; + } + } + + fs.writeFileSync(indexFilePath, indexContent, "utf8"); + console.log(`✅ 成功生成 index.ts: ${indexFilePath}`); +} + +// 脚本入口 +const [targetDir] = CONFIG.targetDirs; +if (!targetDir) { + console.error("❌ CONFIG.targetDirs 不能为空"); + process.exit(1); +} + +const absTargetDir = path.resolve(process.cwd(), targetDir); + +try { + console.log(`🚀 开始扫描目录: ${absTargetDir}`); + generateIndexFile(absTargetDir); +} catch (err) { + const msg = err instanceof Error ? err.message : String(err); + console.error(`❌ [gen-index-ts] 执行失败: ${msg}`); + process.exit(1); +} diff --git a/templates/vite-react-lib/scripts/gen-index-ts.ts b/templates/vite-react-lib/scripts/gen-index-ts.ts new file mode 100644 index 0000000..fdddef4 --- /dev/null +++ b/templates/vite-react-lib/scripts/gen-index-ts.ts @@ -0,0 +1,121 @@ +import fs from "fs"; +import path from "path"; +import { globSync } from "glob"; + +interface Config { + targetDirs: string[]; + includeExtensions: string[]; + excludeKeywords: { + dirs: string[]; + fileSuffixes: string[]; + filePatterns: RegExp[]; + }; +} + +const CONFIG: Config = { + targetDirs: ["src"], + includeExtensions: [".ts", ".tsx", ".vue"], + excludeKeywords: { + dirs: ["__tests__", "tests", "story", "stories", "types"], + fileSuffixes: [".d.ts"], + filePatterns: [ + /^index\.(ts|tsx|js|jsx)$/, + /\.(test|spec)\./, + /\.(story|stories)\./, + ], + }, +}; + +const normalizePath = (p: string) => p.replace(/\\/g, "/"); + +const isInExcludeDir = (filePath: string) => { + const normalized = normalizePath(filePath); + return CONFIG.excludeKeywords.dirs.some((dir) => + normalized.includes(`/${dir}/`), + ); +}; + +const isExcludeSuffix = (filePath: string) => + CONFIG.excludeKeywords.fileSuffixes.some((suffix) => + filePath.endsWith(suffix), + ); + +const isMatchExcludePattern = (fileName: string) => + CONFIG.excludeKeywords.filePatterns.some((pattern) => pattern.test(fileName)); + +function isValidFile(filePath: string): boolean { + const fileName = filePath.split(/[\\/]/).pop()!; + + if (isInExcludeDir(filePath)) return false; + if (isExcludeSuffix(filePath)) return false; + if (isMatchExcludePattern(fileName)) return false; + + const ext = path.extname(filePath); + return CONFIG.includeExtensions.includes(ext); +} + +function generateIndexFile(dirPath: string) { + const searchPattern = path.resolve(dirPath, "**", "*.*"); + + const allFiles = globSync(searchPattern, { + nodir: true, + absolute: true, + windowsPathsNoEscape: true, + dot: false, + follow: true, + }); + + const validFiles = allFiles.filter(isValidFile); + if (validFiles.length === 0) { + console.log("⚠️ 未找到符合条件的文件,跳过生成 index.ts"); + return; + } + + validFiles.sort(); + + const exportStatements = validFiles.map((file) => { + const relPath = path.relative(dirPath, file); + const importPath = `./${relPath + .replace(/\.[^.]+$/, "") + .replace(/\\/g, "/")}`; + return `export * from '${importPath}';`; + }); + + const indexContent = ` +import './index.css'; + +${exportStatements.join("\n")} +`.trim(); + + const indexFilePath = path.resolve(dirPath, "index.ts"); + + // ✅ 内容比对,避免重复写入 + if (fs.existsSync(indexFilePath)) { + const old = fs.readFileSync(indexFilePath, "utf8"); + if (old === indexContent) { + console.log("✅ index.ts 内容无变化,无需重新生成"); + return; + } + } + + fs.writeFileSync(indexFilePath, indexContent, "utf8"); + console.log(`✅ 成功生成 index.ts: ${indexFilePath}`); +} + +// 脚本入口 +const [targetDir] = CONFIG.targetDirs; +if (!targetDir) { + console.error("❌ CONFIG.targetDirs 不能为空"); + process.exit(1); +} + +const absTargetDir = path.resolve(process.cwd(), targetDir); + +try { + console.log(`🚀 开始扫描目录: ${absTargetDir}`); + generateIndexFile(absTargetDir); +} catch (err) { + const msg = err instanceof Error ? err.message : String(err); + console.error(`❌ [gen-index-ts] 执行失败: ${msg}`); + process.exit(1); +} diff --git a/templates/vite-react-lib/src/types/css.d.ts b/templates/vite-react-lib/src/types/css.d.ts new file mode 100644 index 0000000..d535de2 --- /dev/null +++ b/templates/vite-react-lib/src/types/css.d.ts @@ -0,0 +1,4 @@ +declare module '*.css' { + const content: { [className: string]: string }; + export default content; +} \ No newline at end of file diff --git a/templates/vite-react-lib/src/types/env.d.ts b/templates/vite-react-lib/src/types/env.d.ts new file mode 100644 index 0000000..7ba6254 --- /dev/null +++ b/templates/vite-react-lib/src/types/env.d.ts @@ -0,0 +1,51 @@ +/// + +declare module "*.svg" { + import * as React from "react"; + export const ReactComponent: React.FC>; + const src: string; + export default src; +} + +declare module "*.png" { + const src: string; + export default src; +} + +declare module "*.jpg" { + const src: string; + export default src; +} + +declare module "*.jpeg" { + const src: string; + export default src; +} + +declare module "*.gif" { + const src: string; + export default src; +} + +declare module "*.webp" { + const src: string; + export default src; +} + +interface ImportMetaEnv { + readonly MODE: "development" | "production" | "test"; + readonly BASE_URL: string; + readonly PROD: boolean; + readonly DEV: boolean; + readonly SSR: boolean; + + // ===== 业务环境变量 ===== + readonly VITE_API_BASE: string; + readonly VITE_UPLOAD_URL?: string; + readonly VITE_ENABLE_MOCK?: "true" | "false"; + readonly VITE_SENTRY_DSN?: string; +} + +interface ImportMeta { + readonly env: ImportMetaEnv; +} diff --git a/templates/vite-react-lib/tsconfig.base.json b/templates/vite-react-lib/tsconfig.base.json new file mode 100644 index 0000000..2a66330 --- /dev/null +++ b/templates/vite-react-lib/tsconfig.base.json @@ -0,0 +1,22 @@ +{ + // tsconfig.base.json,用于被 tesconfig.json 和 tesconfig.build.json 继承 + "compilerOptions": { + // 输出模块语法,使用版本号最新的那个,而不是实验性语法 ESNext + "module": "es2022", + + // 模块解析策略,模拟 Vite / Rollup / webpack,支持 exports / imports,不强制 Node ESM 的严格规则 + "moduleResolution": "bundler", + + // 显式声明使用的类型包 + "types": ["node", "react"], + + // 开启所有严格类型检查,防止 any / 隐式 any 扩散 + "strict": true, + + // 允许 ESM 导入 CJS + "esModuleInterop": true, + + // 跳过 node_modules 类型检查,加快构建,避免第三方类型污染 + "skipLibCheck": true + } +} diff --git a/templates/vite-react-lib/tsconfig.build.json b/templates/vite-react-lib/tsconfig.build.json new file mode 100644 index 0000000..d38b63b --- /dev/null +++ b/templates/vite-react-lib/tsconfig.build.json @@ -0,0 +1,115 @@ +{ + // 此文件仅用于类型检查,不用于类型检查,构建时会指定使用 tsconfig.build.json + "extends": "./tsconfig.base.json", + "compilerOptions": { + // Browser api,需要加 "DOM","DOM.Iterable" + // Node api,需要加 "ES2025",始终使用带版本号的最新版本 + // NextJs api,属于同构,server 端会预处理 DOM,计算url,三个都需要 "ES2025", "DOM", "DOM.Iterable" + "lib": ["ES2025", "DOM", "DOM.Iterable"], + + /** + * 显式声明使用的类型包 + * - node:Node.js API + * - react:JSX / React 类型 + * - vite/client:import.meta / env + */ + "types": ["node", "react"], + + /** + * React JSX 编译模式 + * - 使用 React 17+ 新 JSX Transform + * - 不需要手动 import React + */ + "jsx": "react-jsx", + + /** + * 编译输出目录 + * - tsc / tsc -b 都会用到 + */ + "outDir": "./dist", + + /** + * 源码根目录 + * - 确保 dist 结构与 src 一致 + * - 对 declaration 路径至关重要 + */ + "rootDir": "./src", + + /** + * 生成 .d.ts 类型声明文件 + * - 组件库 / npm 包发布必需 + * - 对应用项目无害,仅影响类型输出 + */ + "declaration": true, + + /** + * 只做类型检查,不生成 JS 输出 + * - 适用于 Vite / Next / Nuxt 等 bundler 场景 + * - 防止 tsc 与构建工具重复 emit + */ + "noEmit": true, + + /** + * 强制单文件可独立编译 + * - 适配 esbuild / SWC / bundler 编译模型 + * - 禁止依赖跨文件类型推断(enum / namespace 等) + */ + "isolatedModules": true + }, + /** + * 参与类型检查和编译的文件 + * - 只扫描 src + * - 其它目录通过 exclude 排除 + */ + "include": ["src"], + + /** + * 明确排除非源码内容 + * - 避免污染类型系统 + * - 防止误入 dist / test / config + * - 保证发布包干净 + */ + "exclude": [ + "node_modules", + "dist", + + // ---------- build / cache ---------- + ".turbo/**/*", + ".cache/**/*", + ".vite/**/*", + + // ---------- 配置文件 ---------- + "vite.config.ts", + "*.config.ts", + "*.config.js", + "tsconfig.*.json", + + // ---------- 测试相关 ---------- + "__tests__/**/*", + "test/**/*", + "tests/**/*", + "**/*.test.ts", + "**/*.test.tsx", + "**/*.spec.ts", + "**/*.spec.tsx", + + // ---------- Storybook ---------- + ".storybook/**/*", + "stories/**/*", + + // ---------- 示例 / 脚本 ---------- + "example/**/*", + "examples/**/*", + "scripts/**/*", + + // ---------- 环境与静态资源 ---------- + ".env", + ".env.*", + "public/**/*", + + // ---------- 文档 ---------- + "docs/**/*", + "README.md", + "LICENSE" + ] +} diff --git a/templates/vite-react-lib/tsconfig.json b/templates/vite-react-lib/tsconfig.json new file mode 100644 index 0000000..e5bdf16 --- /dev/null +++ b/templates/vite-react-lib/tsconfig.json @@ -0,0 +1,16 @@ +{ + // 此文件仅用于类型检查,不用于构建,构建时会指定使用 tsconfig.build.json + "extends": "./tsconfig.base.json", + "compilerOptions": { + // node api 使用最新版本号的 "ESxxxx",browser api 使用 "DOM" 和 "DOM.Iterable" + "lib": ["ES2025", "DOM", "DOM.Iterable"], + + //显式声明使用的类型包,避免找不到模块 + "types": ["node", "react"], + + // React JSX 编译模式 + "jsx": "react-jsx" + }, + // 将类型检查范围扩大至整个子项目,而不只是 src 文件夹, + "include": ["**/*"] +} diff --git a/templates/vite-react-template/vite.config.ts b/templates/vite-react-lib/vite.config.ts similarity index 78% rename from templates/vite-react-template/vite.config.ts rename to templates/vite-react-lib/vite.config.ts index a7b245d..b9a0317 100644 --- a/templates/vite-react-template/vite.config.ts +++ b/templates/vite-react-lib/vite.config.ts @@ -2,13 +2,9 @@ import { defineConfig } from "vite"; import react from "@vitejs/plugin-react"; import dts from "vite-plugin-dts"; import path from "path"; -import { genIndexTsPlugin } from "./scripts-plugin/vite-plugin-gen-index-ts"; -import { genIndexCssPlugin } from "./scripts-plugin/vite-plugin-gen-index-css"; export default defineConfig({ plugins: [ - genIndexTsPlugin(), - genIndexCssPlugin(), react(), dts({ insertTypesEntry: true, diff --git a/templates/vite-react-template/scripts-plugin/vite-plugin-gen-index-css.ts b/templates/vite-react-template/scripts-plugin/vite-plugin-gen-index-css.ts deleted file mode 100644 index 47af09c..0000000 --- a/templates/vite-react-template/scripts-plugin/vite-plugin-gen-index-css.ts +++ /dev/null @@ -1,137 +0,0 @@ -// plugins/vite-plugin-gen-index-css.ts -import type { Plugin } from "vite"; -import fs from "fs"; -import path from "path"; -import { globSync } from "glob"; - -interface Config { - targetDirs: string[]; - includeExtensions: string[]; - importSyntax: "@import"; - importSyntaxTail?: string; - excludeFilePattern: RegExp[]; - excludeDirs: string[]; - warnDuplicateTailwindImport: boolean; - indexFileName: string; -} - -const CONFIG: Config = { - targetDirs: ["src"], - includeExtensions: [".css"], - importSyntax: "@import", - excludeFilePattern: [/index\.css/, /index\.scss/, /\.(test|spec)\./], - excludeDirs: [ - "__tests__", - "tests", - "story", - "stories", - "types", - "node_modules", - "dist", - "build", - ], - warnDuplicateTailwindImport: true, - indexFileName: "index.css", -}; - -const normalizePath = (p: string) => p.replace(/\\/g, "/"); - -function isValidFile(filePath: string, config: Config): boolean { - const filenameWithExt = filePath.split(/[\\/]/).pop()!; - const shouldExcludeFile = config.excludeFilePattern.some((p) => - p.test(filenameWithExt), - ); - if (shouldExcludeFile) return false; - - const normalized = normalizePath(filePath); - const shouldExcludeDir = config.excludeDirs.some((dir) => - normalized.includes(`/${dir}/`), - ); - if (shouldExcludeDir) return false; - - const ext = path.extname(filePath); - if (!config.includeExtensions.includes(ext)) return false; - - if (config.warnDuplicateTailwindImport) { - try { - const content = fs.readFileSync(filePath, "utf-8"); - if ( - content.includes('@import "tailwindcss"') || - content.includes("@import 'tailwindcss'") - ) { - console.warn( - `[gen-index-css] ${filePath} 含有重复的 @import "tailwindcss",建议删除`, - ); - } - } catch { - // ignore - } - } - - return true; -} - -function generateIndexFile(config: Config) { - const [targetDir] = config.targetDirs; - const dirPath = path.resolve(process.cwd(), targetDir); - - const searchPattern = path.resolve(dirPath, "**", "*.*"); - - const allFiles = globSync(searchPattern, { - nodir: true, - absolute: true, - windowsPathsNoEscape: true, - dot: false, - follow: true, - }); - - const validFiles = allFiles.filter((f) => isValidFile(f, config)); - - console.log(`✅ 有效 CSS 文件数量: ${validFiles.length}`); - validFiles.sort(); - - const importStatements = validFiles.map((file) => { - const relPath = path.relative(dirPath, file); - const importPath = "./" + relPath.replace(/\\/g, "/"); - return `${config.importSyntax} '${importPath}';`; - }); - - const indexContent = ` -@import "tailwindcss"; -${importStatements.join("\n")} -`.trim(); - - const indexFilePath = path.resolve(dirPath, config.indexFileName); - - // ✅ 内容比对,防止无限 rebuild - if (fs.existsSync(indexFilePath)) { - const old = fs.readFileSync(indexFilePath, "utf8"); - if (old === indexContent) return; - } - - fs.writeFileSync(indexFilePath, indexContent, "utf8"); - console.log(`✅ 成功生成 ${config.indexFileName}: ${indexFilePath}`); -} - -export function genIndexCssPlugin(): Plugin { - return { - name: "vite-plugin-gen-index-css", - apply: "build", - - buildStart() { - try { - generateIndexFile(CONFIG); - } catch (err) { - const msg = err instanceof Error ? err.message : String(err); - this.error(`[gen-index-css] failed: ${msg}`); - throw err; - } - }, - - handleHotUpdate({ file }) { - if (normalizePath(file).endsWith(`/src/${CONFIG.indexFileName}`)) { - return []; - } - }, - }; -} diff --git a/templates/vite-react-template/tsconfig.base.json b/templates/vite-react-template/tsconfig.base.json deleted file mode 100644 index b134137..0000000 --- a/templates/vite-react-template/tsconfig.base.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - // tsconfig.base.json,用于被 tesconfig.json 和 tesconfig.build.json 继承 - "compilerOptions": { - // 输出模块语法,使用版本号最新的那个,而不是实验性语法 ESNext - "module": "es2022", - - // 模块解析策略,模拟 Vite / Rollup / webpack,支持 exports / imports,不强制 Node ESM 的严格规则 - "moduleResolution": "bundler", - - // 显式声明使用的类型包 - "types": ["node", "react", "vite/client"], - - // 开启所有严格类型检查,防止 any / 隐式 any 扩散 - "strict": true, - - // 允许 ESM 导入 CJS - "esModuleInterop": true, - - // 跳过 node_modules 类型检查,加快构建,避免第三方类型污染 - "skipLibCheck": true, - - // 模块检测策略,不会影响 node_modules 中的第三方 CommonJS 依赖,Vite 会在预构建阶段自动将其转换为 ESM。 - "moduleDetection": "force", - - // 保留源码中的 import / export 语句原样输出,不进行自动转换(如 import → require),通常与 moduleDetection: "force" 搭配使用 - "verbatimModuleSyntax": true, - - // 是否检查“未使用的局部变量” - "noUnusedLocals": true, - - // 是否检查“未使用的函数参数” - "noUnusedParameters": true, - - // 是否只允许“可擦除的语法(Erasable Syntax),确保 TypeScript 语法在编译后可完全移除 - "erasableSyntaxOnly": true, - - // 是否禁止 switch 语句中的 case 贯穿(fallthrough),如果 case 没有 break / return,会报错 - "noFallthroughCasesInSwitch": true - } -}