refactor: 重构项目为分层架构#1
Conversation
将整个项目从扁平结构重构为严格的分层架构 (Presentation → Application → Domain → Core ← Infrastructure), 涵盖以下主要变更: ## 架构重构 - 引入分层架构:Core / Domain / Application / Infrastructure / Presentation - 实现依赖注入容器 (ServiceContainer) 和服务令牌 (SERVICE_TOKENS) - 引入 EventBus 事件总线实现跨层通信 - 统一使用接口 (I-prefix) 进行依赖反转 ## 构建系统 - 从 npm 迁移到 pnpm - 引入 esbuild 替代 tsc 进行生产构建 - 引入 Vitest 替代原有测试框架 - 新增 CI/CD 工作流 (CodeQL, 安全审计, 类型检查, 测试覆盖率, Schema 验证, 基准测试) ## 核心层 (Core) - 定义所有接口 (ITemplateService, ISchemaService, ILogger 等) - 定义类型系统 (ConfigTypes, DomainEvents, EditorTypes, JsonSchemaTypes 等) - 定义常量 (DiagnosticCodes, ServiceTokens, ExtensionConstants) - 定义错误类型 (ExtensionErrors) - 通用工具 (LRUCache, Debouncer, AsyncInitializer, IdGenerator) ## 领域层 (Domain) - Template 实体和值对象 - DataStoreService 统一存储服务 - TemplateService 模板业务逻辑 - 各类 Store (CategoryStore, ItemStore, TemplateStore, TranslationStore 等) - MiniMessage 解析器 - Minecraft 物品模型系统 (ItemModel, ModelGenerator, Registry 等) ## 应用层 (Application) - ExtensionService 扩展生命周期管理 - SchemaService 及其子服务 (SchemaCache, SchemaLoader, SchemaDynamicGenerator 等) - ModelPreviewService 模型预览服务 - 扩展子服务 (DataCacheInitializer, DocumentChangeTracker, WorkspaceDiagnosticManager 等) ## 基础设施层 (Infrastructure) - DI 容器和注册器 (DependencyContainer, ApplicationRegistrar, DomainRegistrar 等) - YAML 处理 (YamlParser, YamlPathParser, YamlScanner) - 日志系统 (Logger, FileLogTarget, OutputChannelLogTarget) - 文件系统 (FileWatcher, NamespaceDiscoveryService, ResourcePackDiscovery) - 缓存系统 (DiagnosticCache, DocumentParseCache, IncrementalAnalyzer) - 数据加载 (MinecraftDataService, MinecraftVersionService, DataConfigLoader) - 渲染器 (MinecraftModelRenderer, WorkerPool, Scene, Camera) - Schema 验证 (SchemaLoader, SchemaValidator) - 配置管理 (ConfigurationManager, DiagnosticSeverityConfig) - 性能监控 (PerformanceMonitor) ## 表现层 (Presentation) - 统一补全系统 (UnifiedCompletionProvider, CompletionManager) - 策略模式补全 (SchemaAwareCompletionStrategy, 各类 DelegateStrategy) - 诊断提供者 (Template, Translation, Schema, Category, ItemId, FilePath 等) - 代码操作提供者 (QuickFix: EnumValueFix, RequiredFieldFix, TypeMismatchFix 等) - 定义跳转 (CategoryDefinitionProvider, ItemIdDefinitionProvider, TemplateDefinitionProvider) - 悬停提示 (SchemaKeyHoverProvider, TemplateHoverProvider) - WebView 模型预览 (ModelPreviewPanel) - 命令注册 (ModelPreviewCommands, SchemaCommands, NewTemplateCommands) ## 数据与配置 - 外部化配置数据到 data/ 目录 (constants, minecraft, network, schema) - JSON Schema 定义到 schemas/ 目录 - 新增 Minecraft 模型属性和版本数据 ## 测试 - 全面的单元测试覆盖 (60+ 测试文件) - 基准测试 (DI 容器, EventBus, Schema, Template, YAML 解析器) - Vitest 配置和 VS Code mock
📊 Test Coverage Report
|
|
This pull request sets up GitHub code scanning for this repository. Once the scans have completed and the checks have passed, the analysis results for this pull request branch will appear on this overview. Once you merge this pull request, the 'Security' tab will show more code scanning analysis results (for example, for the default branch). Depending on your configuration and choice of analysis tool, future pull requests will be annotated with code scanning analysis results. For more information about GitHub code scanning, check out the documentation. |
- 修复 translations.schema.json 的 $id 域名不一致问题 (craftengine.xiao-momi.com → craftengine.dev) - 修改 ajv 验证步骤,加载所有引用的 schema 文件 (-r 参数) 以支持跨文件 $ref 解析
- 移除冗余条件检查 (js/trivial-conditional) - 修复重复操作 (js/redundant-operation) - 消费无效表达式结果 (js/useless-expression) - 修复正则表达式字符类中的重复字符 (js/regex/duplicate-in-character-class) - 移除未使用的导入和变量 (js/unused-local-variable) - 修复构造函数属性覆盖 (js/useless-assignment-to-property) - 消除文件系统竞态条件 (js/file-system-race) - 添加 CodeQL 配置排除 scripts 目录 (js/file-access-to-http)
master 分支缺少 pnpm-lock.yaml,导致 --frozen-lockfile 失败, 改用 --no-frozen-lockfile 安装 base 分支依赖。
⚡ Benchmark ResultsNo benchmark results to compare. ✅ No significant performance regression |
移除 package job 的事件类型限制,使 VSIX 打包和 artifact 上传在所有触发事件(push、PR、workflow_dispatch)中都执行,便于在 PR 阶段验证打包流程。
🔒 Security Audit Report
Run |
package script 仅执行了 esbuild 编译,未调用 vsce package 生成 .vsix 文件, 导致 CI 中 upload-artifact 找不到 .vsix 文件。
CI 环境中 vsce 命令不可用,将 @vscode/vsce 加入 devDependencies, 并将 script 中的裸 vsce 调用改为 pnpm exec vsce。
将 vscode:prepublish 改为只执行编译(clean + esbuild --production), package script 改为只调用 vsce package,由 vsce 自动触发 prepublish 完成编译, 避免 package → vsce package → prepublish → package 的循环调用。
vsce 内部调用 npm list --production 检查依赖树, 与 pnpm 的 node_modules 结构不兼容。 添加 --no-dependencies 跳过检查,esbuild 已将依赖打包进 bundle。
- 升级 ajv 8.17.1 → 8.18.0(修复 ReDoS) - 升级 glob 11.1.0 → 13.0.6(修复 minimatch ReDoS) - 添加 pnpm overrides 修复间接依赖漏洞: minimatch、@isaacs/brace-expansion、diff - 剩余 1 个 moderate(eslint 内部 ajv@6,上游问题)
🔒 Security Audit Report
Run |
minimatch@<10.2.1 的 override 将 vsce 依赖的 minimatch@^3 (CJS) 强制升级到 v10+ (ESM-only),导致 CJS require() 调用失败
🔒 Security Audit Report
Run |
…ture schema services - Add prettier, eslint-config-prettier, editorconfig and format CI check - Enhance eslint config with stricter type-safety rules - Rewrite README with modern layout and badges - Add core interfaces: IExtensionRegistry, IFileWatcherFactory, INotificationService, ISchemaFileLoader - Add SafeRegex utility for safe regex compilation - Add infrastructure implementations: VscodeExtensionRegistry, NotificationService, VscodeFileWatcherFactory - Move SchemaFileLoader from application to infrastructure layer - Remove SchemaDeploymentService (responsibilities redistributed) - Register new services in DI container - Cache compiled version condition regex pattern - Use ISchemaFileLoader interface in SchemaLoaderService
… layers - Core: ExtensionErrors, AsyncInitializer, Debouncer, deepFreeze, LRUCache, SafeRegex, StringSimilarityUtils - Domain: ExtendedTypeService, DataStoreStatisticsCollector, DocumentProcessor, TemplateSearchService, TemplateSuggestionService, TemplateUsageService - Infrastructure: DiagnosticCache, IncrementalAnalyzer, CompositeSubscription, PerformanceMonitor, SchemaFileLoader, SchemaTransformer, ValidationErrorFormatter, YamlDocument, YamlHelper - Application: DocumentChangeTracker, YamlExtensionIntegrator
🔒 Security Audit Report
Run |
Consolidate all changes since v0.0.3 into the CHANGELOG entry, including build pipeline fixes, CI improvements, Prettier toolchain, sub-module extractions, security fixes, and new unit tests.
🔒 Security Audit Report
Run |
| export const createBuildConfig = (options = {}) => { | ||
| const { | ||
| production = false, | ||
| watch = false, |
Check notice
Code scanning / CodeQL
Unused variable, import, function or class Note
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 28 days ago
In general, to fix unused variable issues, either remove the unused binding or start using it meaningfully. Here the simplest fix that does not change existing behavior is to stop destructuring watch from options, since it is never read. That preserves the current semantics (the function still ignores any watch option the caller may pass) while eliminating the unused variable warning.
Concretely, in esbuild.config.mjs, inside createBuildConfig, edit the destructuring at lines 21–25 to remove watch. The rest of the function, including production and sourcemap, remains unchanged. No imports, methods, or additional definitions are needed.
| @@ -20,7 +20,6 @@ | ||
| export const createBuildConfig = (options = {}) => { | ||
| const { | ||
| production = false, | ||
| watch = false, | ||
| sourcemap = !production ? 'inline' : 'external', | ||
| } = options; | ||
|
|
| import { copy } from 'esbuild-plugin-copy'; | ||
| import { cpSync, mkdirSync, existsSync, readdirSync, readFileSync } from 'fs'; | ||
| import { execSync } from 'child_process'; | ||
| import { resolve, dirname, join } from 'path'; |
Check notice
Code scanning / CodeQL
Unused variable, import, function or class Note
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 28 days ago
In general, unused imports should be removed from the import list so that only actually used symbols are imported. This keeps the codebase cleaner and avoids confusion about whether an unused symbol is part of some incomplete implementation.
For this specific case, in esbuild.mjs on line 5, the named import list from 'path' includes resolve, dirname, and join. Only dirname and join are used (at lines 16 and 131 respectively). The best fix that does not alter any runtime behavior is to remove resolve from this destructuring import while leaving dirname and join intact. No additional code changes or imports are needed, and no logic elsewhere needs to be updated as a result.
Concretely:
- Edit
esbuild.mjs. - Locate the line
import { resolve, dirname, join } from 'path';. - Change it to
import { dirname, join } from 'path';.
| @@ -2,7 +2,7 @@ | ||
| import { copy } from 'esbuild-plugin-copy'; | ||
| import { cpSync, mkdirSync, existsSync, readdirSync, readFileSync } from 'fs'; | ||
| import { execSync } from 'child_process'; | ||
| import { resolve, dirname, join } from 'path'; | ||
| import { dirname, join } from 'path'; | ||
| import { fileURLToPath } from 'url'; | ||
| import { createBuildConfig, paths } from './esbuild.config.mjs'; | ||
| import { logger } from './scripts/logger.js'; |
| import { execSync } from 'child_process'; | ||
| import { resolve, dirname, join } from 'path'; | ||
| import { fileURLToPath } from 'url'; | ||
| import { createBuildConfig, paths } from './esbuild.config.mjs'; |
Check notice
Code scanning / CodeQL
Unused variable, import, function or class Note
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 28 days ago
To fix the problem, remove the unused named import createBuildConfig and keep only paths from ./esbuild.config.mjs. This eliminates the unused binding while preserving all existing functionality, since module side effects are preserved as long as the module is imported at least once (which it still will be, via paths).
Concretely, in esbuild.mjs, at the import on line 7, change:
import { createBuildConfig, paths } from './esbuild.config.mjs';to:
import { paths } from './esbuild.config.mjs';No additional methods, imports, or definitions are required; we are only removing an unused symbol from an existing import.
| @@ -4,7 +4,7 @@ | ||
| import { execSync } from 'child_process'; | ||
| import { resolve, dirname, join } from 'path'; | ||
| import { fileURLToPath } from 'url'; | ||
| import { createBuildConfig, paths } from './esbuild.config.mjs'; | ||
| import { paths } from './esbuild.config.mjs'; | ||
| import { logger } from './scripts/logger.js'; | ||
| import { | ||
| shouldCopyDependencies, |
- Upgrade yaml to ^2.8.3 and add security overrides for minimatch, rollup, serialize-javascript, flatted, undici, picomatch, ajv, brace-expansion - Apply prettier formatting across source and test files - Fix Debouncer to use console.error instead of rethrowing when no logger is available - Fix async test assertions with vi.waitFor and vi.advanceTimersByTimeAsync - Exclude interface and type-only files from coverage reports
概述
将 CraftEngine VS Code 扩展从扁平结构全面重构为严格的分层架构,提升代码可维护性、可测试性和可扩展性。
架构变更
分层架构
关键设计模式
构建系统变更
CI/CD 新增工作流
新增功能模块
Minecraft 模型系统
Schema 系统增强
诊断与代码操作
数据外部化
data/目录 (constants, minecraft, network, schema)schemas/目录测试
变更统计
检查清单