Skip to content

Commit 1eac140

Browse files
committed
chore: use qoder
1 parent d731890 commit 1eac140

File tree

21 files changed

+1209
-19
lines changed

21 files changed

+1209
-19
lines changed

.changeset/fancy-rice-divide.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
---
2+
"@icebreakers/monorepo": patch
3+
---
4+
5+
feat(clean): 自动删除 .qoder 文件夹
6+
7+
优化 `clean` 命令,现在执行清理操作时会自动删除项目根目录下的 `.qoder` 文件夹。
8+
9+
**变更内容**:
10+
- 在清理候选列表中添加 `.qoder` 目录
11+
- 更新相关测试用例以验证新功能
12+
13+
**影响范围**:
14+
- `monorepo clean` 命令
15+
- `pnpm script:clean` 命令
16+
17+
`.qoder` 文件夹通常用于存储 AI 助手生成的临时文件和设计文档,在清理项目模板时删除这些文件有助于保持项目的干净状态。

.dockerignore

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,44 @@
1+
# Dependencies
12
node_modules
3+
**/node_modules/
4+
5+
# Build outputs
6+
dist
7+
**/dist/
8+
9+
# Version control
210
.git
311
.gitignore
12+
.github
13+
14+
# Documentation
415
*.md
5-
dist
6-
**/node_modules/
16+
README*
17+
18+
# Testing
19+
coverage
20+
**/coverage/
21+
**/*.test.ts
22+
**/*.test.js
23+
**/*.spec.ts
24+
**/*.spec.js
25+
26+
# Build caches
27+
.turbo
28+
**/.turbo/
29+
.vitepress/cache
30+
**/.vitepress/cache
31+
32+
# Development
33+
.vscode
34+
.idea
35+
*.log
36+
.DS_Store
37+
38+
# CI/CD
39+
.github/workflows
40+
41+
# Environment
42+
.env
43+
.env.*
44+
!.env.example

.github/workflows/ci.yml

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@ jobs:
2020
os: [ubuntu-latest, windows-latest, macos-latest]
2121
node-version: [20, 22, 24]
2222
runs-on: ${{ matrix.os }}
23-
# To use Remote Caching, uncomment the next lines and follow the steps below.
24-
# env:
25-
# TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
26-
# TURBO_TEAM: ${{ vars.TURBO_TEAM }}
23+
# Remote Caching enabled - configure TURBO_TOKEN and TURBO_TEAM in repository settings
24+
env:
25+
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
26+
TURBO_TEAM: ${{ vars.TURBO_TEAM }}
2727

2828
steps:
2929
- name: Check out code
@@ -38,9 +38,17 @@ jobs:
3838
with:
3939
node-version: ${{ matrix.node-version }}
4040
cache: pnpm
41+
cache-dependency-path: pnpm-lock.yaml
4142

4243
- name: Install dependencies
43-
run: pnpm install
44+
run: pnpm install --frozen-lockfile
45+
46+
- name: Security Audit
47+
run: pnpm audit --audit-level=moderate
48+
continue-on-error: true
49+
50+
- name: Lint
51+
run: pnpm lint
4452

4553
- name: Build
4654
run: pnpm build

.npmrc

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,17 @@
33
registry=https://registry.npmjs.org/
44
## 可使用国内镜像地址
55
# registry=http://registry.npmmirror.com/
6+
7+
## Git 配置
68
git-checks=false
9+
10+
## 包管理器配置
711
package-manager-strict=false
12+
13+
## 依赖处理
14+
auto-install-peers=true
15+
strict-peer-dependencies=false
16+
resolution-mode=highest
17+
818
## 部分场景可能需要开启此配置
919
# shamefully-hoist=true
Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
# TypeScript 类型问题修复 - clean.ts
2+
3+
## 问题描述
4+
5+
`packages/monorepo/src/commands/clean.ts` 文件中,由于启用了 `exactOptionalPropertyTypes: true` 这个严格的 TypeScript 编译选项,导致以下类型错误:
6+
7+
```
8+
不能将类型"string | undefined"分配给类型"string"。
9+
不能将类型"undefined"分配给类型"string"。
10+
```
11+
12+
**错误位置**: 第 53-62 行的 `choices` 数组映射
13+
14+
**根本原因**:
15+
16+
- `x.manifest.name` 的类型是 `string | undefined`
17+
- 当值为 `undefined` 时,直接赋值给 `description` 属性违反了 `exactOptionalPropertyTypes` 规则
18+
- 该规则要求可选属性只能显式设置为其定义的类型,不能通过 `undefined` 值来表示"未设置"
19+
20+
## 解决方案
21+
22+
### 修复前代码
23+
24+
```typescript
25+
cleanDirs = await checkbox<string>({
26+
message: '请选择需要清理的目录',
27+
choices: filteredPackages.map((x) => {
28+
return {
29+
name: path.relative(workspaceDir, x.rootDir),
30+
value: x.rootDir,
31+
checked: true,
32+
description: x.manifest.name, // ❌ 类型错误:可能是 undefined
33+
}
34+
}),
35+
})
36+
```
37+
38+
### 修复后代码
39+
40+
```typescript
41+
cleanDirs = await checkbox<string>({
42+
message: '请选择需要清理的目录',
43+
choices: filteredPackages.map((x) => {
44+
const baseChoice = {
45+
name: path.relative(workspaceDir, x.rootDir),
46+
value: x.rootDir,
47+
checked: true,
48+
}
49+
// ✅ 只在有值时才添加 description 属性
50+
return x.manifest.name
51+
? { ...baseChoice, description: x.manifest.name }
52+
: baseChoice
53+
}),
54+
})
55+
```
56+
57+
## 技术要点
58+
59+
### exactOptionalPropertyTypes 规则说明
60+
61+
这是 TypeScript 4.4+ 引入的严格类型检查选项,用于区分:
62+
63+
- **未设置的属性** (属性不存在)
64+
- **设置为 undefined 的属性** (属性存在但值为 undefined)
65+
66+
**示例**:
67+
68+
```typescript
69+
interface Person {
70+
name: string
71+
age?: number // 可选属性
72+
}
73+
74+
// 启用 exactOptionalPropertyTypes 前
75+
const p1: Person = { name: 'Alice', age: undefined } // ✅ 允许
76+
const p2: Person = { name: 'Bob' } // ✅ 允许
77+
78+
// 启用 exactOptionalPropertyTypes 后
79+
const p1: Person = { name: 'Alice', age: undefined } // ❌ 错误
80+
const p2: Person = { name: 'Bob' } // ✅ 允许
81+
```
82+
83+
### 修复策略
84+
85+
采用**条件对象展开**模式:
86+
87+
1. 创建基础对象(包含必需属性)
88+
2. 根据条件动态添加可选属性
89+
3. 使用对象展开运算符合并
90+
91+
**优点**:
92+
93+
- 类型安全
94+
- 代码简洁
95+
- 符合 TypeScript 严格模式最佳实践
96+
97+
## 验证结果
98+
99+
### 构建验证
100+
101+
```bash
102+
$ pnpm --filter @icebreakers/monorepo build
103+
✔ Build complete in 1791ms (CJS)
104+
✔ Build complete in 1794ms (ESM)
105+
```
106+
107+
### 测试验证
108+
109+
```bash
110+
$ pnpm --filter @icebreakers/monorepo test
111+
✓ 34 个测试文件通过
112+
✓ 102 个测试用例通过
113+
Duration: 4.32s
114+
```
115+
116+
### 类型检查
117+
118+
- ✅ 无 TypeScript 编译错误
119+
- ✅ 无 ESLint 错误
120+
- ✅ 所有严格类型检查通过
121+
122+
## 影响范围
123+
124+
**修改的文件**:
125+
126+
- `packages/monorepo/src/commands/clean.ts` (第 51-63 行)
127+
128+
**影响的功能**:
129+
130+
- `monorepo clean` 命令的交互式包选择功能
131+
- 清理时的包列表显示
132+
133+
**向后兼容性**:
134+
135+
- ✅ 完全兼容,无破坏性变更
136+
- ✅ 功能行为保持不变
137+
- ✅ API 接口保持不变
138+
139+
## 相关配置
140+
141+
**启用的 TypeScript 严格选项** (tsconfig.json):
142+
143+
```json
144+
{
145+
"compilerOptions": {
146+
"strict": true,
147+
"exactOptionalPropertyTypes": true,
148+
"noUncheckedIndexedAccess": true,
149+
"noPropertyAccessFromIndexSignature": true,
150+
"noImplicitOverride": true
151+
}
152+
}
153+
```
154+
155+
## 总结
156+
157+
通过采用条件对象展开模式,成功修复了 `exactOptionalPropertyTypes` 严格模式下的类型错误。修复后的代码更加类型安全,符合 TypeScript 最佳实践,同时保持了代码的可读性和简洁性。
158+
159+
这次修复也验证了项目在第一阶段优化中启用的严格 TypeScript 配置的有效性,确保了代码质量的提升。
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
# packages/monorepo clean 命令优化
2+
3+
## 变更说明
4+
5+
优化了 `@icebreakers/monorepo` 包的 `clean` 命令,现在执行清理操作时会自动删除项目根目录下的 `.qoder` 文件夹。
6+
7+
## 修改的文件
8+
9+
### 1. `packages/monorepo/src/commands/clean.ts`
10+
11+
**修改内容**:
12+
13+
-`candidates` 列表中添加了 `.qoder` 目录
14+
- 现在清理操作会同时删除:
15+
- 用户选择的包目录
16+
- `README.zh-CN.md` 文件
17+
- `.qoder` 文件夹 (新增)
18+
19+
**代码变更**:
20+
21+
```typescript
22+
const readmeZh = path.resolve(workspaceDir, 'README.zh-CN.md')
23+
const qoderDir = path.resolve(workspaceDir, '.qoder') // 新增
24+
const candidates = Array.from(new Set([
25+
...cleanDirs.filter(Boolean),
26+
readmeZh,
27+
qoderDir, // 新增
28+
]))
29+
```
30+
31+
### 2. `packages/monorepo/test/commands/clean.coverage.test.ts`
32+
33+
**修改内容**:
34+
35+
- 更新测试用例以验证 `.qoder` 目录会被删除
36+
- 添加断言确保 `fs.remove` 被正确调用
37+
38+
**代码变更**:
39+
40+
```typescript
41+
expect(removeMock).toHaveBeenCalledWith('/repo/.qoder')
42+
```
43+
44+
## 使用方式
45+
46+
执行清理命令时,`.qoder` 文件夹会自动被删除:
47+
48+
```bash
49+
# 交互式选择要清理的包
50+
pnpm script:clean
51+
52+
# 或使用 monorepo CLI
53+
monorepo clean
54+
55+
# 自动清理所有包(跳过交互)
56+
monorepo clean --yes
57+
```
58+
59+
## 验证
60+
61+
所有测试通过:
62+
63+
-`test/commands/clean.coverage.test.ts` - 单元测试通过
64+
- ✅ 全部 102 个测试通过
65+
- ✅ Lint 检查通过
66+
- ✅ 构建成功
67+
68+
## 影响范围
69+
70+
- **影响的命令**: `monorepo clean`, `pnpm script:clean`
71+
- **删除的内容**: `.qoder` 文件夹(如果存在)
72+
- **向后兼容**: 完全兼容,不影响现有功能
73+
- **副作用**: 无,`.qoder` 文件夹不存在时会被安全忽略
74+
75+
## 技术细节
76+
77+
`.qoder` 文件夹通常用于存储 AI 助手生成的设计文档、任务记录等临时文件。在清理项目模板时删除这些文件可以:
78+
79+
- 保持项目的干净状态
80+
- 避免将 AI 助手的临时文件带入新项目
81+
- 符合 clean 命令的预期行为
82+
83+
## 相关 Issue
84+
85+
该优化是基于用户反馈,确保项目清理时移除所有非必要的临时文件和缓存目录。

0 commit comments

Comments
 (0)