@icebreakers/monorepo-templates 1.1.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (154) hide show
  1. package/README.md +12 -8
  2. package/README.zh-CN.md +16 -0
  3. package/assets/.changeset/ledger.yaml +25 -0
  4. package/assets/.github/ISSUE_TEMPLATE/config.yml +1 -1
  5. package/assets/AGENTS.md +4 -3
  6. package/assets/CONTRIBUTING.md +27 -2
  7. package/assets/SECURITY.md +12 -14
  8. package/assets/package.json +13 -4
  9. package/package.json +6 -4
  10. package/templates/cli/package.json +11 -4
  11. package/templates/client/package.json +17 -1
  12. package/templates/server/package.json +11 -4
  13. package/templates/tsdown/package.json +11 -4
  14. package/templates/vitepress/.vitepress/config.ts +146 -165
  15. package/templates/vitepress/ai/index.md +12 -23
  16. package/templates/vitepress/ai/llms-txt.md +13 -31
  17. package/templates/vitepress/getting-started.md +3 -32
  18. package/templates/vitepress/index.md +27 -30
  19. package/templates/vitepress/knowledge/index.md +17 -41
  20. package/templates/vitepress/monorepo/commands.md +13 -18
  21. package/templates/vitepress/monorepo/index.md +22 -100
  22. package/templates/vitepress/monorepo/manage.md +15 -227
  23. package/templates/vitepress/monorepo/publish.md +15 -70
  24. package/templates/vitepress/monorepo/templates.md +10 -17
  25. package/templates/vitepress/monorepo/troubleshooting.md +13 -16
  26. package/templates/vitepress/package.json +10 -4
  27. package/templates/vitepress/public/_redirects +3 -0
  28. package/templates/vitepress/repoctl/adopt-existing.md +51 -53
  29. package/templates/vitepress/repoctl/aliases.md +18 -18
  30. package/templates/vitepress/repoctl/checks.md +21 -68
  31. package/templates/vitepress/repoctl/commands.md +16 -64
  32. package/templates/vitepress/repoctl/config.md +14 -35
  33. package/templates/vitepress/repoctl/doctor.md +20 -60
  34. package/templates/vitepress/repoctl/execution-model.md +16 -69
  35. package/templates/vitepress/repoctl/getting-started.md +34 -40
  36. package/templates/vitepress/repoctl/index.md +33 -61
  37. package/templates/vitepress/repoctl/reports.md +20 -74
  38. package/templates/vitepress/repoctl/scenarios.md +26 -28
  39. package/templates/vitepress/repoctl/template-assets.md +19 -88
  40. package/templates/vitepress/repoctl/templates.md +50 -81
  41. package/templates/vitepress/repoctl/troubleshooting.md +32 -46
  42. package/templates/vitepress/repoctl/workflows.md +38 -67
  43. package/templates/vitepress/thinking.md +4 -85
  44. package/templates/vitepress/tools/changeset.md +9 -59
  45. package/templates/vitepress/tools/husky.md +6 -124
  46. package/templates/vitepress/tools/index.md +13 -32
  47. package/templates/vitepress/tools/lint-staged.md +5 -96
  48. package/templates/vitepress/tools/llms-txt.md +4 -6
  49. package/templates/vitepress/tools/pnpm.md +7 -119
  50. package/templates/vitepress/tools/renovate.md +3 -87
  51. package/templates/vitepress/tools/turborepo.md +5 -157
  52. package/templates/vitepress/why/how-to-reuse-js-code.md +6 -247
  53. package/templates/vitepress/why/index.md +14 -1
  54. package/templates/vitepress/why/js-cjs-mjs.md +9 -96
  55. package/templates/vitepress/why/js-keywords.md +4 -129
  56. package/templates/vitepress/why/modern/bundlers.md +3 -50
  57. package/templates/vitepress/why/modern/dts.md +4 -90
  58. package/templates/vitepress/why/modern/esm-vs-cjs.md +4 -81
  59. package/templates/vitepress/why/modern/index.md +10 -51
  60. package/templates/vitepress/why/modern/package-entry-points.md +6 -117
  61. package/templates/vitepress/why/modern/typescript.md +4 -152
  62. package/templates/vitepress/why/publish-basic-npm-package.md +17 -144
  63. package/templates/vitepress/why/what-is-npm-package.md +4 -159
  64. package/templates/vitepress/zh/ai/index.md +33 -0
  65. package/templates/vitepress/zh/ai/llms-txt.md +42 -0
  66. package/templates/vitepress/zh/getting-started.md +40 -0
  67. package/templates/vitepress/zh/index.md +66 -0
  68. package/templates/vitepress/zh/knowledge/index.md +50 -0
  69. package/templates/vitepress/zh/monorepo/commands.md +21 -0
  70. package/templates/vitepress/zh/monorepo/index.md +115 -0
  71. package/templates/vitepress/zh/monorepo/manage.md +243 -0
  72. package/templates/vitepress/zh/monorepo/publish.md +87 -0
  73. package/templates/vitepress/zh/monorepo/templates.md +21 -0
  74. package/templates/vitepress/zh/monorepo/troubleshooting.md +20 -0
  75. package/templates/vitepress/zh/repoctl/adopt-existing.md +135 -0
  76. package/templates/vitepress/{en → zh}/repoctl/aliases.md +18 -18
  77. package/templates/vitepress/zh/repoctl/checks.md +86 -0
  78. package/templates/vitepress/zh/repoctl/commands.md +168 -0
  79. package/templates/vitepress/zh/repoctl/config.md +90 -0
  80. package/templates/vitepress/zh/repoctl/doctor.md +86 -0
  81. package/templates/vitepress/zh/repoctl/execution-model.md +81 -0
  82. package/templates/vitepress/zh/repoctl/getting-started.md +122 -0
  83. package/templates/vitepress/zh/repoctl/index.md +102 -0
  84. package/templates/vitepress/zh/repoctl/reports.md +94 -0
  85. package/templates/vitepress/{en → zh}/repoctl/scenarios.md +28 -26
  86. package/templates/vitepress/zh/repoctl/template-assets.md +116 -0
  87. package/templates/vitepress/zh/repoctl/templates.md +159 -0
  88. package/templates/vitepress/zh/repoctl/troubleshooting.md +110 -0
  89. package/templates/vitepress/zh/repoctl/workflows.md +118 -0
  90. package/templates/vitepress/zh/thinking.md +88 -0
  91. package/templates/vitepress/zh/tools/changeset.md +75 -0
  92. package/templates/vitepress/zh/tools/husky.md +130 -0
  93. package/templates/vitepress/zh/tools/index.md +38 -0
  94. package/templates/vitepress/zh/tools/lint-staged.md +103 -0
  95. package/templates/vitepress/zh/tools/llms-txt.md +9 -0
  96. package/templates/vitepress/zh/tools/pnpm.md +127 -0
  97. package/templates/vitepress/zh/tools/renovate.md +91 -0
  98. package/templates/vitepress/zh/tools/turborepo.md +166 -0
  99. package/templates/vitepress/zh/why/assets/npm-dt.svg +15 -0
  100. package/templates/vitepress/zh/why/assets/npm-ts.svg +19 -0
  101. package/templates/vitepress/zh/why/examples/0.npm-basic-package/index.js +10 -0
  102. package/templates/vitepress/zh/why/examples/0.npm-basic-package/package.json +11 -0
  103. package/templates/vitepress/zh/why/examples/1.npm-basic-package/index.cjs +12 -0
  104. package/templates/vitepress/zh/why/examples/1.npm-basic-package/index.d.ts +1 -0
  105. package/templates/vitepress/zh/why/examples/1.npm-basic-package/index.js +8 -0
  106. package/templates/vitepress/zh/why/examples/1.npm-basic-package/package.json +19 -0
  107. package/templates/vitepress/zh/why/examples/2.npm-basic-package/README.md +1 -0
  108. package/templates/vitepress/zh/why/examples/2.npm-basic-package/package-lock.json +30 -0
  109. package/templates/vitepress/zh/why/examples/2.npm-basic-package/package.json +35 -0
  110. package/templates/vitepress/zh/why/examples/2.npm-basic-package/rename-ext.js +24 -0
  111. package/templates/vitepress/zh/why/examples/2.npm-basic-package/src/index.ts +8 -0
  112. package/templates/vitepress/zh/why/examples/2.npm-basic-package/tsconfig.cjs.json +8 -0
  113. package/templates/vitepress/zh/why/examples/2.npm-basic-package/tsconfig.esm.json +7 -0
  114. package/templates/vitepress/zh/why/examples/2.npm-basic-package/tsconfig.json +18 -0
  115. package/templates/vitepress/zh/why/examples/3.npm-basic-package/README.md +1 -0
  116. package/templates/vitepress/zh/why/examples/3.npm-basic-package/package-lock.json +1496 -0
  117. package/templates/vitepress/zh/why/examples/3.npm-basic-package/package.json +31 -0
  118. package/templates/vitepress/zh/why/examples/3.npm-basic-package/src/index.ts +8 -0
  119. package/templates/vitepress/zh/why/examples/3.npm-basic-package/tsconfig.json +16 -0
  120. package/templates/vitepress/zh/why/examples/3.npm-basic-package/tsdown.config.ts +16 -0
  121. package/templates/vitepress/zh/why/examples/usage-cjs/cjs.cjs +4 -0
  122. package/templates/vitepress/zh/why/examples/usage-cjs/esm.mjs +4 -0
  123. package/templates/vitepress/zh/why/examples/usage-cjs/index.js +8 -0
  124. package/templates/vitepress/zh/why/examples/usage-cjs/package-lock.json +36 -0
  125. package/templates/vitepress/zh/why/examples/usage-cjs/package.json +20 -0
  126. package/templates/vitepress/zh/why/examples/usage-esm/cjs.cjs +4 -0
  127. package/templates/vitepress/zh/why/examples/usage-esm/createRequire.js +7 -0
  128. package/templates/vitepress/zh/why/examples/usage-esm/esm.mjs +4 -0
  129. package/templates/vitepress/zh/why/examples/usage-esm/index.js +8 -0
  130. package/templates/vitepress/zh/why/examples/usage-esm/package-lock.json +36 -0
  131. package/templates/vitepress/zh/why/examples/usage-esm/package.json +21 -0
  132. package/templates/vitepress/zh/why/how-to-reuse-js-code.md +250 -0
  133. package/templates/vitepress/zh/why/index.md +1 -0
  134. package/templates/vitepress/zh/why/js-cjs-mjs.md +99 -0
  135. package/templates/vitepress/zh/why/js-keywords.md +132 -0
  136. package/templates/vitepress/zh/why/modern/bundlers.md +52 -0
  137. package/templates/vitepress/zh/why/modern/dts.md +93 -0
  138. package/templates/vitepress/zh/why/modern/esm-vs-cjs.md +84 -0
  139. package/templates/vitepress/zh/why/modern/index.md +55 -0
  140. package/templates/vitepress/zh/why/modern/package-entry-points.md +128 -0
  141. package/templates/vitepress/zh/why/modern/typescript.md +155 -0
  142. package/templates/vitepress/zh/why/publish-basic-npm-package.md +146 -0
  143. package/templates/vitepress/zh/why/what-is-npm-package.md +162 -0
  144. package/templates/vue-lib/package.json +12 -5
  145. package/templates/vitepress/en/index.md +0 -63
  146. package/templates/vitepress/en/knowledge/monorepo.md +0 -37
  147. package/templates/vitepress/en/repoctl/adopt-existing.md +0 -133
  148. package/templates/vitepress/en/repoctl/commands.md +0 -120
  149. package/templates/vitepress/en/repoctl/config.md +0 -69
  150. package/templates/vitepress/en/repoctl/getting-started.md +0 -116
  151. package/templates/vitepress/en/repoctl/index.md +0 -74
  152. package/templates/vitepress/en/repoctl/templates.md +0 -128
  153. package/templates/vitepress/en/repoctl/troubleshooting.md +0 -96
  154. package/templates/vitepress/en/repoctl/workflows.md +0 -89
@@ -0,0 +1,159 @@
1
+ # 模板与创建
2
+
3
+ repoctl 的模板由 `@icebreakers/monorepo-templates` 维护。CLI、脚手架和文档都复用同一份模板元数据。
4
+
5
+ 更偏维护者视角的模板元数据、健康检查和自定义模板说明见:[模板资产治理](./template-assets.md)。
6
+
7
+ ## 内置模板
8
+
9
+ | Key | Category | 默认目录 | 适合场景 |
10
+ | ------------- | -------- | ------------------ | --------------------------- |
11
+ | `tsdown` | library | `packages/tsdown` | TypeScript 库包 |
12
+ | `vue-lib` | library | `packages/vue-lib` | Vue 3 组件库 |
13
+ | `vue-hono` | app | `apps/client` | Vue 3 + Hono 前后端一体应用 |
14
+ | `hono-server` | service | `apps/server` | Hono API 服务 |
15
+ | `vitepress` | docs | `apps/website` | VitePress 文档站 |
16
+ | `cli` | tool | `apps/cli` | TypeScript 命令行工具 |
17
+
18
+ ## 查看模板
19
+
20
+ ```bash
21
+ repo templates
22
+ repo templates tsdown
23
+ repo templates --category library
24
+ repo templates --json
25
+ repo templates --markdown --out docs/templates.md
26
+ ```
27
+
28
+ ## 创建模板
29
+
30
+ ```bash
31
+ repo new sdk --template tsdown
32
+ repo new ui --template vue-lib
33
+ repo new api --template hono-server
34
+ repo new website --template vitepress
35
+ repo new toolbox --template cli
36
+ ```
37
+
38
+ 普通名字会自动放到模板约定的目录里,例如库包进入 `packages/`,应用进入 `apps/`。如果你传入带 `/` 的路径,例如 `packages/shared-utils`,repoctl 会尊重这个路径。
39
+
40
+ ## 按目标选择模板
41
+
42
+ ### 要发布 npm 库
43
+
44
+ ```bash
45
+ repo new sdk --template tsdown
46
+ ```
47
+
48
+ 生成后先检查:
49
+
50
+ - `package.json` 的 `name`、`exports`、`types`。
51
+ - `tsdown.config.ts` 是否符合产物格式。
52
+ - 是否需要补 `tsd` 类型测试。
53
+
54
+ ### 要沉淀 Vue 组件
55
+
56
+ ```bash
57
+ repo new ui --template vue-lib
58
+ ```
59
+
60
+ 生成后先检查:
61
+
62
+ - 组件入口是否只导出稳定 API。
63
+ - 样式是否能通过 Stylelint。
64
+ - 文档站或示例应用是否需要同步创建。
65
+
66
+ ### 要创建应用或服务
67
+
68
+ ```bash
69
+ repo new web --template vue-hono
70
+ repo new api --template hono-server
71
+ ```
72
+
73
+ 生成后先检查:
74
+
75
+ - 运行时环境变量和部署平台约束。
76
+ - `dev`、`build`、`typecheck` 脚本是否接入根任务。
77
+ - 是否需要在 CI 里加入 E2E 或集成测试。
78
+
79
+ ### 要创建文档站
80
+
81
+ ```bash
82
+ repo new docs --template vitepress
83
+ ```
84
+
85
+ 生成后先检查:
86
+
87
+ - 导航和 sidebar 是否围绕产品或包名组织。
88
+ - 是否需要中英文 locale。
89
+ - 是否需要把 `repo templates --markdown` 输出写进文档。
90
+
91
+ ### 要创建 CLI
92
+
93
+ ```bash
94
+ repo new toolbox --template cli
95
+ ```
96
+
97
+ 生成后先检查:
98
+
99
+ - `bin` 字段是否符合最终命令名。
100
+ - 参数解析、退出码和帮助信息是否可测试。
101
+ - 是否需要把命令用法写入 README。
102
+
103
+ ## 创建前预览
104
+
105
+ ```bash
106
+ repo new website --template vitepress --dry-run
107
+ repo new website --template vitepress --json
108
+ repo new website --template vitepress --json --out plans/website.json
109
+ ```
110
+
111
+ `--dry-run` 不写入磁盘,只展示模板、源目录、目标目录、package name 和输出文件。
112
+
113
+ `--json` 输出同一份创建计划的结构化数据,隐含 `--dry-run`。
114
+
115
+ `--out <file>` 可以把文本或 JSON 预览写入文件,也隐含 `--dry-run`。
116
+
117
+ ## 固化默认模板
118
+
119
+ ```ts
120
+ import { defineMonorepoConfig } from 'repoctl'
121
+
122
+ export default defineMonorepoConfig({
123
+ commands: {
124
+ create: {
125
+ defaultTemplate: 'tsdown',
126
+ },
127
+ },
128
+ })
129
+ ```
130
+
131
+ 之后:
132
+
133
+ ```bash
134
+ repo new utils
135
+ ```
136
+
137
+ 会直接创建 `tsdown` 库包。
138
+
139
+ ## 检查模板健康状态
140
+
141
+ ```bash
142
+ repo templates --check
143
+ repo templates --check --json
144
+ ```
145
+
146
+ 模板检查会确认:
147
+
148
+ - 模板 source 和 target 没有重复。
149
+ - 每个模板 source 目录都存在。
150
+ - 每个模板根目录都有 `package.json`。
151
+ - 每个模板都有 category 和 description。
152
+ - 模板源目录里没有会被脚手架过滤掉的临时或生成文件。
153
+
154
+ ## 继续阅读
155
+
156
+ - [接入已有仓库](./adopt-existing.md)
157
+ - [工作流与 CI](./workflows.md)
158
+ - [配置文件](./config.md)
159
+ - [模板资产治理](./template-assets.md)
@@ -0,0 +1,110 @@
1
+ # 排障与报告
2
+
3
+ repoctl 的排障重点不是让你猜错在哪里,而是尽量输出可以复现、可以保存、可以发给同事的报告。
4
+
5
+ ## 先跑 doctor
6
+
7
+ ```bash
8
+ repo doctor
9
+ repo doctor --strict
10
+ ```
11
+
12
+ `doctor` 主要检查:
13
+
14
+ - 当前目录是不是仓库根目录。
15
+ - Node 版本是否满足要求。
16
+ - `pnpm-workspace.yaml` 是否存在。
17
+ - `repoctl` 是否作为 CLI 依赖安装。
18
+ - 根脚本是否齐全。
19
+ - 是否仍残留已废弃的 `monorepo.config.ts`。
20
+ - Husky 与 lint-staged 是否都接上。
21
+
22
+ ## 保存诊断报告
23
+
24
+ ```bash
25
+ repo doctor --json --out reports/doctor.json
26
+ repo doctor --markdown --redact --out reports/doctor.md
27
+ ```
28
+
29
+ 推荐把 Markdown 报告贴到 issue 或 PR。`--redact` 会脱敏本机路径。
30
+
31
+ ## 查看校验计划
32
+
33
+ ```bash
34
+ repo check --dry-run
35
+ repo check --json --out reports/check-plan.json
36
+ repo check --markdown --redact --out reports/check-plan.md
37
+ ```
38
+
39
+ 当你不确定为什么某个文件触发了 workspace typecheck、pre-push 要跑哪些任务时,先看 check plan。
40
+
41
+ ## 收集环境信息
42
+
43
+ ```bash
44
+ repo env info
45
+ repo env support --markdown --redact --out reports/support.md
46
+ repo env snapshot --json --out reports/snapshot.json
47
+ repo env paths --markdown --redact --out reports/paths.md
48
+ ```
49
+
50
+ 这些命令适合排查 Node、pnpm、workspace、Git、路径和 CI 环境差异。
51
+
52
+ ## 先判断问题类型
53
+
54
+ | 现象 | 优先命令 | 继续阅读 |
55
+ | ------------------------------ | ----------------------------------------- | ------------------------------------ |
56
+ | 不确定当前目录是不是仓库根目录 | `repo doctor` | [doctor 诊断](./doctor.md) |
57
+ | 不知道 `repo check` 会跑什么 | `repo check --dry-run` | [校验链路](./checks.md) |
58
+ | CI 失败但日志不完整 | `repo env support --markdown --redact` | [报告与自动化输出](./reports.md) |
59
+ | 模板创建结果不符合预期 | `repo new <name> --template <key> --json` | [模板资产治理](./template-assets.md) |
60
+ | 模板列表或元数据异常 | `repo templates --check` | [模板资产治理](./template-assets.md) |
61
+
62
+ ## 常见问题
63
+
64
+ ### 当前目录不是仓库根目录
65
+
66
+ 切回包含 `pnpm-workspace.yaml` 和根 `package.json` 的目录,再运行:
67
+
68
+ ```bash
69
+ repo doctor
70
+ ```
71
+
72
+ ### 同时存在两个配置文件
73
+
74
+ 只保留一个:
75
+
76
+ ```txt
77
+ repoctl.config.ts
78
+ ```
79
+
80
+ `monorepo.config.ts` 已不再加载。旧项目需要改名为 `repoctl.config.ts`。
81
+
82
+ ### `repo new` 提示模板不存在
83
+
84
+ 先查看可用模板:
85
+
86
+ ```bash
87
+ repo templates
88
+ ```
89
+
90
+ 显式传入的 `--template` 会先校验。拼错时命令会失败并提示相近 key,不会静默回退。
91
+
92
+ ### 自动化里不希望出现交互
93
+
94
+ 使用非交互参数:
95
+
96
+ ```bash
97
+ repo init --yes
98
+ repo upgrade --no-overwrite
99
+ repo check --json --out reports/check-plan.json
100
+ ```
101
+
102
+ 非 TTY 环境下,repoctl 不会弹出交互选择框。
103
+
104
+ ## 继续阅读
105
+
106
+ - [工作流与 CI](./workflows.md)
107
+ - [命令速查](./commands.md)
108
+ - [doctor 诊断](./doctor.md)
109
+ - [报告与自动化输出](./reports.md)
110
+ - [命令别名](./aliases.md)
@@ -0,0 +1,118 @@
1
+ # 工作流与 CI
2
+
3
+ repoctl 的命令可以分成两类:给人用的日常入口,以及给 CI、脚本、编辑器用的可保存输出。
4
+
5
+ ## 本地日常工作流
6
+
7
+ ```bash
8
+ pnpm install
9
+ pnpm run repo:doctor
10
+ pnpm run repo:new -- sdk --template tsdown
11
+ pnpm run repo:check
12
+ pnpm build
13
+ ```
14
+
15
+ 这条链路适合新成员第一次进入仓库:
16
+
17
+ | 步骤 | 判断标准 |
18
+ | ---------------------- | ------------------------------------------------ |
19
+ | `pnpm install` | workspace 依赖和本地链接完整 |
20
+ | `pnpm run repo:doctor` | 仓库根目录、Node、脚本、配置和提交链路可用 |
21
+ | `pnpm run repo:new` | 新包由模板创建,目录和 package metadata 符合约定 |
22
+ | `pnpm run repo:check` | 提交前轻量校验可以复现 |
23
+ | `pnpm build` | 全仓构建链路没有明显断点 |
24
+
25
+ ## 存量仓库接入
26
+
27
+ ```bash
28
+ pnpm add -D repoctl
29
+ pnpm exec repo init --yes
30
+ pnpm exec repo doctor --markdown --out reports/doctor.md
31
+ pnpm exec repo upgrade --no-overwrite
32
+ pnpm exec repo doctor
33
+ ```
34
+
35
+ 推荐先用 `--no-overwrite` 保守接入。确认标准资产差异后,再决定是否使用 `--yes` 或 `--overwrite`。
36
+
37
+ ## CI 快速门禁
38
+
39
+ ```bash
40
+ pnpm install --frozen-lockfile
41
+ pnpm exec repo doctor --strict
42
+ pnpm exec repo check --full
43
+ ```
44
+
45
+ 适合小仓库或早期项目。`doctor --strict` 会把 warning 也当成失败,能避免配置漂移慢慢积累。
46
+
47
+ ## CI 报告模式
48
+
49
+ ```bash
50
+ pnpm exec repo doctor --json --out reports/doctor.json
51
+ pnpm exec repo check --json --out reports/check-plan.json
52
+ pnpm exec repo env support --markdown --redact --out reports/support.md
53
+ ```
54
+
55
+ 这组命令适合想保存构建上下文的 CI:
56
+
57
+ - `doctor.json` 给脚本判断仓库健康状态。
58
+ - `check-plan.json` 记录本次会跑哪些校验。
59
+ - `support.md` 适合上传为 artifact,或贴进 issue / PR。
60
+
61
+ ## pre-commit 与 pre-push
62
+
63
+ repoctl 暴露了底层 verify 命令,方便 hook 和脚本复用:
64
+
65
+ ```bash
66
+ repo verify pre-commit
67
+ repo verify staged-typecheck packages/app/src/main.ts
68
+ repo verify commit-msg .git/COMMIT_EDITMSG
69
+ repo verify pre-push
70
+ ```
71
+
72
+ 默认建议:
73
+
74
+ | 阶段 | 推荐行为 |
75
+ | ---------- | ------------------------------------------------------- |
76
+ | pre-commit | 聚焦 staged 文件,运行格式、lint 和 workspace typecheck |
77
+ | commit-msg | 校验 Conventional Commit 格式 |
78
+ | pre-push | 跑整仓 lint/typecheck,并按变更范围补 build/test/tsd |
79
+
80
+ ## 自动化创建预览
81
+
82
+ ```bash
83
+ repo new dashboard --template vue-hono --json --out plans/dashboard.json
84
+ repo templates --markdown --out docs/templates.md
85
+ repo ws ls --json --out reports/workspaces.json
86
+ ```
87
+
88
+ 这些命令都不会要求人工选择,适合编辑器插件、脚本和 CI bot。
89
+
90
+ ## 推荐流水线拆分
91
+
92
+ | 阶段 | 命令 | 失败后先看 |
93
+ | ---- | --------------------------------------------------------------- | ------------------------------------ |
94
+ | 安装 | `pnpm install --frozen-lockfile` | lockfile、Node、pnpm 版本 |
95
+ | 诊断 | `repo doctor --strict` | [doctor 诊断](./doctor.md) |
96
+ | 计划 | `repo check --full --json --out reports/check-plan.json` | [报告与自动化输出](./reports.md) |
97
+ | 执行 | `repo check --full` | 失败的 root script 或 workspace 任务 |
98
+ | 留证 | `repo env support --markdown --redact --out reports/support.md` | CI artifact |
99
+
100
+ 早期项目可以把计划和执行合并。成熟项目建议保留 `reports/`,方便失败时复盘实际执行路径。
101
+
102
+ ## 非交互参数选择
103
+
104
+ | 场景 | 推荐参数 |
105
+ | ------------------ | -------------------------------------------------- |
106
+ | 初始化时接受默认值 | `repo init --yes` |
107
+ | 同步时保留已有改动 | `repo upgrade --no-overwrite` |
108
+ | 明确覆盖标准资产 | `repo upgrade --yes` 或 `repo upgrade --overwrite` |
109
+ | 只看计划不执行 | `--dry-run` |
110
+ | 输出给脚本 | `--json --out <file>` |
111
+ | 输出给人看并脱敏 | `--markdown --redact --out <file>` |
112
+
113
+ ## 下一步
114
+
115
+ - 查所有参数:[命令速查](./commands.md)
116
+ - 理解校验链路:[校验链路](./checks.md)
117
+ - 生成排障包:[报告与自动化输出](./reports.md)
118
+ - 看短命令:[命令别名](./aliases.md)
@@ -0,0 +1,88 @@
1
+ # 我对 monorepo 的一些思考
2
+
3
+ ## 前言
4
+
5
+ 最近在自己的新项目中,我创建并使用了 [monorepo-template](https://github.com/sonofmagic/monorepo-template) 模板,并不断地做了不少改进。
6
+
7
+ 在此,我想借此机会分享一下这个模板的演变过程,以及我对 `monorepo` 的一些思考。
8
+
9
+ ## 它的由来
10
+
11
+ 为了应对越来越多的发包场景,我创建了 [npm-lib-template](https://github.com/sonofmagic/npm-lib-template) 模板
12
+
13
+ 这是一个 `git` 单仓单 `npm` 包模板,使用 `rollup` 进行打包,然后再发布到 `npm` 和 `github`
14
+
15
+ 然而,在后续开发中,我发现单仓库的模式在某些场景下难以应对。
16
+
17
+ 例如,当需要引用其他自己的包,进行单元测试并再次发包时,这时候往往要在多个项目之间进行来回的切换更改,管理复杂度会迅速上升。
18
+
19
+ `git submodule` 也是另外一条路子,但是我对每次都要同步 `hash` 感到深恶痛绝,遂放弃 (不过某些极其特殊场景的实现,还是只能利用这个功能)。
20
+
21
+ 因此,我决定要创建一个 [monorepo 项目模板](https://github.com/sonofmagic/monorepo-template) ,以应对这些需求。
22
+
23
+ ## 技术选型
24
+
25
+ ### 管理工具
26
+
27
+ 在 `monorepo` 的管理上,我选择了 `pnpm` 和 `turborepo` 这对组合,原因很简单:它们都非常快。
28
+
29
+ - `pnpm` 又可以节省磁盘空间,又能够链接自特定的内容寻址存储库,是为快也
30
+ - `turborepo` 有构建缓存,是为快也 `too`.
31
+
32
+ ### 语言与打包
33
+
34
+ 我选择使用纯 `TypeScript` 来编写所有类库项目,并统一使用 `tsdown` 进行打包,默认输出格式为 `cjs` 和 `esm`,并利用 `package.json` 中的 `exports` 字段进行分发。
35
+
36
+ ### 直接调试
37
+
38
+ 在直接调试时,我抛弃了 `dist` + `sourcemap` 的调试方式,使用了 `tsx`,它非常适合调试 `TypeScript` 编写的 `CLI` 项目。
39
+
40
+ ### 测试框架
41
+
42
+ 测试方面,我选择了 `vitest`。
43
+
44
+ 它不仅速度快,还很好地支持 `cjs`、`esm` 和 `TypeScript`,同时也适合 `monorepo` 项目。你可以利用 `turbo` 来执行单个的 `vitest` 任务,也可以利用 `vitest.workspace` 来进行多任务测试。
45
+
46
+ 最初我使用的是 `jest` + `ts-jest`,但它对多格式的混合模块的支持不够理想,最终我选择了 `vitest`。
47
+
48
+ ### 代码规范与质量控制
49
+
50
+ 为了保持代码质量,我使用了 `eslint` 和 `stylelint`,并基于自己的配置包 `@icebreakers/eslint-config` 和 `@icebreakers/stylelint-config` 来进行代码格式化和规范化。
51
+
52
+ 我还为 `.vscode` 配置了一些推荐插件和编辑器选项。
53
+
54
+ 此外,通过 `husky` 添加了 `git hook`,配合 `lint-staged` 对提交的代码进行校验。与 `commitlint` 结合使用,以确保 `git` 提交信息符合规范。
55
+
56
+ ### 本地引用与发包替换
57
+
58
+ 利用 `publishConfig` 会在发包的时候替换 `package.json` 字段的方式,在本地包相互引用的时候,都使用 `Typescript` 源文件的方式导出,在 `publishConfig` 里定义的导出为,真正在不同环境中,指向 `dist` 中不同格式的产物地址。
59
+
60
+ 通过这种方式,可以大大加速整个 `monorepo` 的开发测试速度,避免反复通过 `watch` 来构建 `dist` 和 `sourcemap`,也避免一构建出产物,对应的 `Typescript` 文件,就报错的问题。
61
+
62
+ ### 发包流程
63
+
64
+ 现在使用 pnpm 原生 versioning:用 `pnpm change` 记录意图,用 `pnpm version -r` 生成版本和 changelog,再用 `pnpm publish -r` 发布。版本计划保留在 `.changeset/ledger.yaml`,预发布则由 pnpm lanes 管理。
65
+
66
+ ### Github 相关配置
67
+
68
+ 在 `.github` 目录下,我提供了默认的 `CI/CD` 流程配置,以及用户提交 `issue` 时的模板。经过少量配置后,就可以实现自动发布 `npm` 包、创建 `git tag` 以及生成 `GitHub release`。
69
+
70
+ 此外,模板里还有许多为 `GitHub` 显示优化的 `md` 文档。
71
+
72
+ ## 部署
73
+
74
+ 文档网站通过 `netlify.toml` 配置部署在 `Netlify` 上。最初我使用的是 `Vercel`,但由于**国内**访问速度的原因,最终迁移到了 `Netlify`。
75
+
76
+ 而且由于我是开源项目贡献者的原因,`Netlify` 为我 `免费` 提供了 `Pro` 版本的计划 (通常这需要 `$19/per member/month`)
77
+
78
+ 感谢 `Netlify`! 爱你❤️😍。
79
+
80
+ 如果看到这里的哥们,你也有一定影响力的开源项目,也可以通过下方的链接申请。
81
+
82
+ https://www.netlify.com/legal/open-source-policy/
83
+
84
+ ## 总结
85
+
86
+ 从单仓到 `monorepo` 的转变不仅仅是对工具的选择,更是对项目管理模式的优化。通过采用合适的工具链,能够更高效地管理多包项目的同时,利用 `CI/CD` 确保代码的质量和发布的顺畅。
87
+
88
+ 希望这些思考对你有所帮助,也欢迎大家提出各种建议和意见。
@@ -0,0 +1,75 @@
1
+ # pnpm Versioning
2
+
3
+ 本模板使用 pnpm 11 原生 versioning 管理 monorepo 的变更意图、版本号、changelog 和发布。变更意图仍然使用 `.changeset/*.md` 格式,因此每次改动可以独立提交,不会直接修改包版本。
4
+
5
+ ## 日常开发
6
+
7
+ ```bash
8
+ pnpm change
9
+ pnpm change status
10
+ ```
11
+
12
+ `pnpm change` 会询问受影响的包、patch/minor/major 类型和 changelog 摘要。脚本或自动化场景可以直接指定:
13
+
14
+ ```bash
15
+ pnpm change --bump patch --summary "修复空输入崩溃" repoctl
16
+ ```
17
+
18
+ 变更意图会写入 `.changeset/`,与代码一起提交。`pnpm change status` 只预览计划,不会修改文件。
19
+
20
+ ## 版本与 changelog
21
+
22
+ 在 Release PR 中由 CI 消费变更意图:
23
+
24
+ ```bash
25
+ pnpm version -r --dry-run
26
+ pnpm version -r
27
+ ```
28
+
29
+ `pnpm version -r` 会更新受影响包、传播 workspace 依赖、生成 `CHANGELOG.md`,并把消费记录追加到 `.changeset/ledger.yaml`。仓库配置使用 `versioning.changelog.storage: repository`,所以 changelog 会和版本提交一起审查。
30
+
31
+ `@icebreakers/monorepo` 与 `repoctl` 属于 pnpm fixed group,任一包需要发布时两者始终使用同一个版本。
32
+
33
+ ## 发布
34
+
35
+ 正式发布由 Release PR 合并后的 main workflow 完成:
36
+
37
+ ```bash
38
+ pnpm publish -r --report-summary --provenance --no-git-checks
39
+ ```
40
+
41
+ pnpm 会跳过 registry 中已经存在的版本,并把新发布包写入 `pnpm-publish-summary.json`。CI 根据 summary 创建 `package@version` Git tag 和 GitHub Release,因此重复执行不会重新发布已存在版本。
42
+
43
+ 本地推荐使用 repoctl 包装命令:
44
+
45
+ ```bash
46
+ pnpm exec repo release stable prepare
47
+ pnpm exec repo release stable publish
48
+ ```
49
+
50
+ ## Prerelease lanes
51
+
52
+ alpha、beta、rc、next 是 pnpm lanes,而不是 Changesets pre 状态:
53
+
54
+ ```bash
55
+ pnpm exec repo release pre enter alpha
56
+ git add pnpm-workspace.yaml && git commit -m "chore(release): enter alpha lane"
57
+ git push
58
+
59
+ pnpm exec repo release pre publish
60
+ ```
61
+
62
+ 退出预发布轨道时执行 `pnpm exec repo release pre exit`,提交 `pnpm-workspace.yaml` 后合并回 main。lane 切换必须覆盖 fixed group 的全部包。
63
+
64
+ ## CI 约定
65
+
66
+ - 生成的 release workflow 只负责 checkout、安装依赖和权限声明,全部业务统一由 `pnpm exec repo release ci` 执行。
67
+ - main push 先生成或更新 Release PR;Release PR 合并后才发布 npm。
68
+ - alpha、beta、rc、next 分支要求所有可发布包位于对应 lane。
69
+ - npm 发布使用 GitHub OIDC provenance,不需要长期保存 `NPM_TOKEN`。
70
+ - 未发布版本恢复使用 workflow dispatch 的 `publish-unpublished` 模式,并按 package/version 校验后发布。
71
+ - repoctl 通过 GitHub REST API 幂等创建或更新 Release PR、package tag 和 GitHub Release,重复执行不会重复创建元数据。
72
+
73
+ 存量项目首次迁移运行 `pnpm dlx repoctl@latest upgrade --yes`。带有
74
+ `repoctl-managed: release/v2` 的 workflow 会自动升级;未标记的自定义
75
+ workflow 默认保留,可在确认后使用 `repo upgrade --overwrite-release`。
@@ -0,0 +1,130 @@
1
+ # Husky
2
+
3
+ 在 repoctl 体系里,Husky 是 Git hook 触发器;真正的校验逻辑尽量收口到 repoctl 命令,方便本地、CI 和手动复现使用同一套入口。
4
+
5
+ ```bash
6
+ repo verify pre-commit
7
+ repo verify commit-msg .git/COMMIT_EDITMSG
8
+ repo verify pre-push
9
+ ```
10
+
11
+ 如果你只想手动复现推荐校验,用:
12
+
13
+ ```bash
14
+ repo check --staged
15
+ repo check --full
16
+ ```
17
+
18
+ 继续看:[repoctl 工作流与 CI](../repoctl/workflows.md)。
19
+
20
+ ## 1. 什么是 Husky?
21
+
22
+ **Husky** 是一个用于在 **Git hooks**(如 `pre-commit`、`pre-push`、`commit-msg` 等)中运行脚本的工具。
23
+ 它的作用是让你在提交代码前或推送代码前,自动执行一些校验、格式化或测试,从而保证代码质量和团队规范。
24
+
25
+ > 简单来说:**Husky = Git hooks 的管理工具**。
26
+
27
+ ## 2. Husky 有什么用?
28
+
29
+ 常见用途:
30
+
31
+ 1. **代码格式化**
32
+ 在提交前运行 `prettier --write .`,确保代码风格一致。
33
+ 2. **Lint 检查**
34
+ 在 `pre-commit` 时执行 `eslint`,防止有 lint 错误的代码被提交。
35
+ 3. **推送前执行整仓校验**
36
+ 在 `pre-push` 时执行整仓 `lint`、`typecheck`,并按需补跑 `build`、`test`、`tsd`,防止未通过校验的代码被推送。
37
+ 4. **Commit 信息校验**
38
+ 在 `commit-msg` hook 中使用 [commitlint](https://github.com/conventional-changelog/commitlint) 强制提交信息符合规范(如 Conventional Commits)。
39
+
40
+ ## 3. 如何使用 Husky?
41
+
42
+ ### 安装
43
+
44
+ ```bash
45
+ npm install husky --save-dev
46
+ ```
47
+
48
+ ### 初始化
49
+
50
+ ```bash
51
+ npx husky init
52
+ ```
53
+
54
+ 这会生成一个 `.husky` 目录,并在里面创建 `pre-commit` 文件,默认内容可能是:
55
+
56
+ ```bash
57
+ #!/bin/sh
58
+ npm test
59
+ ```
60
+
61
+ ### 添加 Hook
62
+
63
+ 假设你想在提交前运行 ESLint,可以这样:
64
+
65
+ ```bash
66
+ npx husky add .husky/pre-commit "npm run lint"
67
+ ```
68
+
69
+ 生成的 `.husky/pre-commit` 文件类似:
70
+
71
+ ```bash
72
+ #!/bin/sh
73
+ npm run lint
74
+ ```
75
+
76
+ ### 使用 commit-msg 校验提交信息
77
+
78
+ 先装 commitlint:
79
+
80
+ ```bash
81
+ npm install @commitlint/{config-conventional,cli} --save-dev
82
+ ```
83
+
84
+ 创建配置文件 `commitlint.config.js`:
85
+
86
+ ```js
87
+ module.exports = { extends: ['@commitlint/config-conventional'] }
88
+ ```
89
+
90
+ 添加 hook:
91
+
92
+ ```bash
93
+ npx husky add .husky/commit-msg "npx --no-install commitlint --edit $1"
94
+ ```
95
+
96
+ 这样,若提交信息不符合规范,会被拦截。
97
+
98
+ ## 4. 和 lint-staged 搭配
99
+
100
+ 通常 Husky 会和 [lint-staged](https://github.com/okonet/lint-staged) 搭配使用:
101
+ 只检查本次改动的文件,而不是全量检查。
102
+
103
+ 示例:
104
+ `package.json` 里加:
105
+
106
+ ```json
107
+ {
108
+ "lint-staged": {
109
+ "*.js": "eslint --fix",
110
+ "*.ts": "eslint --fix"
111
+ }
112
+ }
113
+ ```
114
+
115
+ 然后在 `.husky/pre-commit` 文件中写:
116
+
117
+ ```bash
118
+ npx lint-staged
119
+ ```
120
+
121
+ 在本仓库默认实现里,`pre-commit` 和 `pre-push` 的职责拆分是:
122
+
123
+ - `pre-commit`:只针对 staged 文件执行 `eslint`、`stylelint` 和 workspace `typecheck`
124
+ - `pre-push`:强制执行整仓 `pnpm lint`、`pnpm typecheck`,并根据改动范围补跑 `build`、`test`、`tsd`
125
+
126
+ ## 总结
127
+
128
+ - **Husky** 是一个 Git hooks 工具,用来在 commit、push 等阶段运行脚本。
129
+ - 主要用于 **代码质量控制**:lint、格式化、测试、commit message 校验等。
130
+ - 使用方式:安装 → 初始化 → 添加 hooks → 编写脚本。