Vibe Coding学习(3)--Skills
一、Skills定义Skills 是一个封装了特定能力的可以复用的指令集。二、Skills 目录结构一个典型的 Skills 项目通常遵循以下目录结构skills-project/ ├── src/ │ ├── skills/ # 核心技能实现 │ │ ├── math/ # 数学相关技能 │ │ │ ├── __init__.py │ │ │ ├── calculator.py │ │ │ └── statistics.py │ │ ├── text/ # 文本处理技能 │ │ │ ├── __init__.py │ │ │ ├── summarizer.py │ │ │ └── translator.py │ │ └── __init__.py │ ├── utils/ # 工具函数 │ │ ├── __init__.py │ │ └── helpers.py │ └── main.py # 主入口文件 ├── tests/ # 测试目录 │ ├── test_math/ │ ├── test_text/ │ └── __init__.py ├── config/ # 配置文件 │ └── settings.yaml ├── docs/ # 文档 │ ├── api.md │ └── usage.md ├── requirements.txt # 依赖列表 ├── README.md # 项目说明 └── setup.py # 安装配置Python项目1、核心目录说明src/skills/技能实现的核心目录按功能模块组织子目录tests/单元测试和集成测试保持与 src 目录结构一致config/配置文件用于技能参数、API密钥等设置docs/技能使用文档和API说明utils/公共工具函数避免代码重复2、文件命名规范技能文件使用小写字母和下划线snake_case类名使用驼峰命名法CamelCase配置文件使用 .yaml 或 .json 格式测试文件以 test_ 开头3、扩展结构高级项目对于更复杂的 Skills 项目可能还会包含skills-project/ ├── api/ # REST API 接口 ├── cli/ # 命令行工具 ├── examples/ # 使用示例 ├── docker/ # Docker 配置 ├── .github/ # GitHub Actions 工作流 └── CHANGELOG.md # 版本变更记录三、Skills安装# 可以安装 Anthropic 官方全部 Skills全局安装 npx skills add anthropics/skills -g 如果网络不好可以采取手动安装 克隆官方仓库到本地 git clone http://github.com/anthropics/skills.git 将需要的 skill 目录安装到你的项目中 cp -r skills/skills/frontend-design .claude/skills/四、创建React组件生成Skill的步骤创建一个React组件生成Skill需要遵循统一的文件结构和编码规范。以下是完整的步骤指南1. 项目结构规划首先规划React组件Skill的目录结构react-component-skill/ ├── src/ │ ├── components/ # React组件目录 │ │ ├── ComponentTemplate.jsx # 组件模板 │ │ ├── ComponentValidator.js # 组件验证脚本 │ │ └── index.js # 组件导出文件 │ ├── utils/ │ │ ├── fileGenerator.js # 文件生成工具 │ │ └── configParser.js # 配置解析工具 │ └── main.js # 主入口文件 ├── templates/ # 模板文件 │ ├── component.jsx.template │ ├── test.js.template │ └── story.js.template ├── config/ │ └── skill-config.yaml # Skill配置文件 ├── tests/ │ └── test-component-generator.js ├── docs/ │ └── usage-guide.md └── package.json2. 创建组件模板定义标准的React组件模板确保所有生成的组件遵循相同的编码规范// ComponentTemplate.jsx import React from react; import PropTypes from prop-types; import ./ComponentName.css; /** ComponentName - 组件描述 param {Object} props - 组件属性 returns {JSX.Element} 渲染的组件 */ const ComponentName ({ className , children, ...restProps }) { return ( div className{component-name ${className}} {...restProps} {children} /div ); }; ComponentName.propTypes { /** 自定义类名 / className: PropTypes.string, /* 子元素 */ children: PropTypes.node, }; ComponentName.defaultProps { className: , }; export default ComponentName;3. 实现验证脚本创建验证脚本确保生成的组件符合规范// ComponentValidator.js const fs require(fs); const path require(path); class ComponentValidator { /** 验证组件文件结构 param {string} componentPath - 组件路径 returns {Object} 验证结果 */ static validateStructure(componentPath) { const requiredFiles [ index.js, ComponentName.jsx, ComponentName.css, ComponentName.test.js, ComponentName.stories.js ]; const missingFiles []; const existingFiles []; requiredFiles.forEach(file gt; { const filePath path.join(componentPath, file); if (!fs.existsSync(filePath)) { missingFiles.push(file); } else { existingFiles.push(file); } }); return { isValid: missingFiles.length 0, missingFiles, existingFiles, totalFiles: requiredFiles.length }; } /** 验证组件代码规范 param {string} filePath - 文件路径 returns {Object} 代码规范检查结果 */ static validateCodeStyle(filePath) { const content fs.readFileSync(filePath, utf8); const issues []; // 检查PropTypes定义 if (!content.includes(PropTypes)) { issues.push(缺少PropTypes类型定义); } // 检查默认导出 if (!content.includes(export default)) { issues.push(缺少默认导出); } // 检查组件注释 if (!content.includes(/**)) { issues.push(缺少JSDoc注释); } return { file: path.basename(filePath), issues, hasIssues: issues.length gt; 0 }; } } module.exports ComponentValidator;4. 创建生成脚本实现组件生成的主脚本// main.js const fs require(fs-extra); const path require(path); const ComponentValidator require(./utils/ComponentValidator); class ReactComponentGenerator { constructor(config) { this.config config; this.templateDir path.join(__dirname, templates); this.outputDir path.join(__dirname, output); } /** 生成React组件 param {string} componentName - 组件名称 param {Object} options - 生成选项 */ async generateComponent(componentName, options {}) { try { // 1. 验证组件名称 this.validateComponentName(componentName); // 2. 创建组件目录 const componentPath path.join(this.outputDir, componentName); await fs.ensureDir(componentPath); // 3. 读取模板文件 const templates await this.loadTemplates(); // 4. 渲染模板 const files this.renderTemplates(templates, componentName, options); // 5. 写入文件 await this.writeFiles(componentPath, files); // 6. 验证生成结果 const validationResult ComponentValidator.validateStructure(componentPath); if (!validationResult.isValid) { console.warn(⚠️ 组件结构不完整缺少文件:, validationResult.missingFiles); } console.log(✅ React组件 ${componentName} 生成成功); console.log( 位置: ${componentPath}); return { success: true, componentPath, validationResult }; } catch (error) { console.error(❌ 生成组件失败:, error.message); return { success: false, error: error.message }; } } validateComponentName(name) { // 组件名称验证逻辑 if (!name || typeof name ! string) { throw new Error(组件名称不能为空); } if (!/^[A-Z][a-zA-Z0-9]*$/.test(name)) { throw new Error(组件名称必须以大写字母开头且只能包含字母和数字); } } async loadTemplates() { const templateFiles await fs.readdir(this.templateDir); const templates {}; for (const file of templateFiles) { const content await fs.readFile( path.join(this.templateDir, file), utf8 ); templates[file] content; } return templates; } renderTemplates(templates, componentName, options) { const files {}; Object.entries(templates).forEach(([templateName, content]) gt; { let renderedContent content; // 替换占位符 renderedContent renderedContent .replace(/ComponentName/g, componentName) .replace(/component-name/g, componentName.toLowerCase()); // 根据选项调整内容 if (options.withTests false amp;amp; templateName.includes(.test.)) { return; // 跳过测试文件 } if (options.withStories false amp;amp; templateName.includes(.stories.)) { return; // 跳过Storybook文件 } // 生成输出文件名 const outputFileName templateName .replace(.template, ) .replace(ComponentName, componentName); files[outputFileName] renderedContent; }); return files; } async writeFiles(componentPath, files) { for (const [fileName, content] of Object.entries(files)) { const filePath path.join(componentPath, fileName); await fs.writeFile(filePath, content, utf8); } } } // 使用示例 if (require.main module) { const generator new ReactComponentGenerator(); const componentName process.argv[2] || Button; const options { withTests: true, withStories: true }; generator.generateComponent(componentName, options) .then(result { if (result.success) { console.log( 组件生成完成); } }) .catch(console.error); } module.exports ReactComponentGenerator;5. 配置文件示例创建Skill配置文件定义生成选项# skill-config.yaml skill: name: react-component-generator version: 1.0.0 description: React组件生成Skill generator: defaultOptions: withTests: true withStories: true withCssModule: false withPropTypes: true templates: component: templates/component.jsx.template test: templates/test.js.template story: templates/story.js.template css: templates/component.css.template validation: enabled: true validator: ./src/utils/ComponentValidator.js output: directory: ./output structure: flat # flat | nested rules: namingConvention: PascalCase fileExtension: .jsx indentSize: 2 quoteStyle: single6. 使用说明创建package.json脚本方便使用{ name: react-component-skill, version: 1.0.0, scripts: { generate: node src/main.js, generate:component: node src/main.js --name, validate: node src/utils/validate-all.js, test: jest, build: webpack --config webpack.config.js }, dependencies: { fs-extra: ^10.0.0, commander: ^8.3.0, chalk: ^4.1.2 }, devDependencies: { jest: ^27.0.0, webpack: ^5.0.0 } }使用方式# 安装依赖 npm install 生成组件 npm run generate -- Button 或直接使用 node src/main.js Button --withTests --withStories 验证生成的组件 npm run validate7. 最佳实践建议模板管理将模板文件单独存放便于维护和更新配置驱动通过配置文件管理生成选项避免硬编码验证机制生成后自动验证组件结构和代码规范错误处理完善的错误处理和用户反馈扩展性设计可扩展的架构支持自定义模板和规则文档生成自动生成组件使用文档和API文档通过以上步骤您可以创建一个完整的React组件生成Skill确保团队中的每个React组件都遵循统一的文件结构和编码规范提高代码质量和开发效率。