Initial commit: OneOS prototype workspace baseline.

Include weekly report and other prototype sources with project tooling config.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
王冕
2026-06-26 15:36:52 +08:00
commit 7ef8852919
1310 changed files with 282074 additions and 0 deletions

View File

@@ -0,0 +1,113 @@
import type { Plugin } from 'vite';
import { createHash } from 'crypto';
import path from 'path';
/**
* 为每个页面/组件文件注入稳定的唯一 ID
* 基于文件相对路径生成,保证构建间稳定不变
*
* 生成的 ID 格式:{项目名}-{目录类型}-{项目名称}-{16位哈希}
* 例如axhub-make-prototypes-demo-antd-a1b2c3d4e5f6g7h8
*
* 规则:
* - 忽略 index.tsx 中的 index 部分(因为都是同一个,没有意义)
* - 使用项目目录名(如 axhub-make
* - 根据 components 和 prototypes 目录区分
* - 加上文件项目名称
*/
export function injectStablePageIds(): Plugin {
const cwd = process.cwd();
// 从 cwd 获取项目目录名(如 axhub-make
const projectName = path.basename(cwd);
return {
name: 'inject-stable-page-ids',
enforce: 'pre',
transform(code, id) {
// 只处理 tsx/jsx 文件
if (!/\.(tsx|jsx)$/.test(id)) return null;
// 获取相对路径
const relativePath = path.relative(cwd, id).replace(/\\/g, '/');
// 生成长哈希16位 SHA-256极低重复风险
const longHash = createHash('sha256')
.update(relativePath)
.digest('hex')
.slice(0, 16);
// 解析路径src/prototypes/demo-antd/index.tsx 或 src/components/demo-button/index.tsx
// 目标格式axhub-make-prototypes-demo-antd 或 axhub-make-components-demo-button
// 规则:忽略 index.tsx 中的 index 部分,使用目录名作为项目名称
const pathParts = relativePath
.replace(/^src\//, '') // 移除 src/ 前缀
.replace(/\.(tsx|jsx)$/, '') // 移除文件扩展名
.split('/');
// 查找 prototypes 或 components 目录
const categoryIndex = pathParts.findIndex(part => part === 'prototypes' || part === 'components');
let readableId: string;
if (categoryIndex >= 0 && categoryIndex < pathParts.length - 1) {
// 找到目录类型prototypes 或 components
const category = pathParts[categoryIndex];
// 获取项目名称category 后面的第一个非 index 部分)
// 例如prototypes/demo-antd/index -> demo-antd
// prototypes/demo-antd/some-file -> demo-antd
// prototypes/index -> '' (空,使用降级方案)
let itemName = '';
// 从 category 后面开始查找项目名称
for (let i = categoryIndex + 1; i < pathParts.length; i++) {
const part = pathParts[i];
// 如果遇到 index跳过它继续查找下一级
if (part === 'index') {
continue;
}
// 找到第一个非 index 的部分,作为项目名称
itemName = part;
break;
}
// 组合:项目名-目录类型-项目名称
readableId = `${projectName}-${category}${itemName ? '-' + itemName : ''}`;
} else {
// 降级方案:如果路径不符合预期,使用原来的逻辑但移除 index
readableId = relativePath
.replace(/^src\//, '')
.replace(/\.(tsx|jsx)$/, '')
.replace(/\/index$/, '') // 移除末尾的 /index
.replace(/[\/\.]/g, '-')
.replace(/^-+|-+$/g, '') // 移除首尾的连字符
.slice(0, 48);
// 如果 readableId 不以项目名开头,则添加
if (!readableId.startsWith(projectName)) {
readableId = `${projectName}-${readableId}`;
}
}
// 组合 ID可读路径 + 哈希
const stableId = `${readableId}-${longHash}`;
// 注入全局常量,组件中可直接使用
const injectedCode = `
// Auto-injected by vite-plugin-inject-stable-page-ids
const __PAGE_ID__ = '${stableId}';
const __PAGE_PATH__ = '${readableId}';
const __PAGE_FULL_PATH__ = '${relativePath}';
const __PAGE_HASH__ = '${longHash}';
${code}
`.trim();
return {
code: injectedCode,
map: null
};
}
};
}