@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.
- package/README.md +12 -8
- package/README.zh-CN.md +16 -0
- package/assets/.changeset/ledger.yaml +25 -0
- package/assets/.github/ISSUE_TEMPLATE/config.yml +1 -1
- package/assets/AGENTS.md +4 -3
- package/assets/CONTRIBUTING.md +27 -2
- package/assets/SECURITY.md +12 -14
- package/assets/package.json +13 -4
- package/package.json +6 -4
- package/templates/cli/package.json +11 -4
- package/templates/client/package.json +17 -1
- package/templates/server/package.json +11 -4
- package/templates/tsdown/package.json +11 -4
- package/templates/vitepress/.vitepress/config.ts +146 -165
- package/templates/vitepress/ai/index.md +12 -23
- package/templates/vitepress/ai/llms-txt.md +13 -31
- package/templates/vitepress/getting-started.md +3 -32
- package/templates/vitepress/index.md +27 -30
- package/templates/vitepress/knowledge/index.md +17 -41
- package/templates/vitepress/monorepo/commands.md +13 -18
- package/templates/vitepress/monorepo/index.md +22 -100
- package/templates/vitepress/monorepo/manage.md +15 -227
- package/templates/vitepress/monorepo/publish.md +15 -70
- package/templates/vitepress/monorepo/templates.md +10 -17
- package/templates/vitepress/monorepo/troubleshooting.md +13 -16
- package/templates/vitepress/package.json +10 -4
- package/templates/vitepress/public/_redirects +3 -0
- package/templates/vitepress/repoctl/adopt-existing.md +51 -53
- package/templates/vitepress/repoctl/aliases.md +18 -18
- package/templates/vitepress/repoctl/checks.md +21 -68
- package/templates/vitepress/repoctl/commands.md +16 -64
- package/templates/vitepress/repoctl/config.md +14 -35
- package/templates/vitepress/repoctl/doctor.md +20 -60
- package/templates/vitepress/repoctl/execution-model.md +16 -69
- package/templates/vitepress/repoctl/getting-started.md +34 -40
- package/templates/vitepress/repoctl/index.md +33 -61
- package/templates/vitepress/repoctl/reports.md +20 -74
- package/templates/vitepress/repoctl/scenarios.md +26 -28
- package/templates/vitepress/repoctl/template-assets.md +19 -88
- package/templates/vitepress/repoctl/templates.md +50 -81
- package/templates/vitepress/repoctl/troubleshooting.md +32 -46
- package/templates/vitepress/repoctl/workflows.md +38 -67
- package/templates/vitepress/thinking.md +4 -85
- package/templates/vitepress/tools/changeset.md +9 -59
- package/templates/vitepress/tools/husky.md +6 -124
- package/templates/vitepress/tools/index.md +13 -32
- package/templates/vitepress/tools/lint-staged.md +5 -96
- package/templates/vitepress/tools/llms-txt.md +4 -6
- package/templates/vitepress/tools/pnpm.md +7 -119
- package/templates/vitepress/tools/renovate.md +3 -87
- package/templates/vitepress/tools/turborepo.md +5 -157
- package/templates/vitepress/why/how-to-reuse-js-code.md +6 -247
- package/templates/vitepress/why/index.md +14 -1
- package/templates/vitepress/why/js-cjs-mjs.md +9 -96
- package/templates/vitepress/why/js-keywords.md +4 -129
- package/templates/vitepress/why/modern/bundlers.md +3 -50
- package/templates/vitepress/why/modern/dts.md +4 -90
- package/templates/vitepress/why/modern/esm-vs-cjs.md +4 -81
- package/templates/vitepress/why/modern/index.md +10 -51
- package/templates/vitepress/why/modern/package-entry-points.md +6 -117
- package/templates/vitepress/why/modern/typescript.md +4 -152
- package/templates/vitepress/why/publish-basic-npm-package.md +17 -144
- package/templates/vitepress/why/what-is-npm-package.md +4 -159
- package/templates/vitepress/zh/ai/index.md +33 -0
- package/templates/vitepress/zh/ai/llms-txt.md +42 -0
- package/templates/vitepress/zh/getting-started.md +40 -0
- package/templates/vitepress/zh/index.md +66 -0
- package/templates/vitepress/zh/knowledge/index.md +50 -0
- package/templates/vitepress/zh/monorepo/commands.md +21 -0
- package/templates/vitepress/zh/monorepo/index.md +115 -0
- package/templates/vitepress/zh/monorepo/manage.md +243 -0
- package/templates/vitepress/zh/monorepo/publish.md +87 -0
- package/templates/vitepress/zh/monorepo/templates.md +21 -0
- package/templates/vitepress/zh/monorepo/troubleshooting.md +20 -0
- package/templates/vitepress/zh/repoctl/adopt-existing.md +135 -0
- package/templates/vitepress/{en → zh}/repoctl/aliases.md +18 -18
- package/templates/vitepress/zh/repoctl/checks.md +86 -0
- package/templates/vitepress/zh/repoctl/commands.md +168 -0
- package/templates/vitepress/zh/repoctl/config.md +90 -0
- package/templates/vitepress/zh/repoctl/doctor.md +86 -0
- package/templates/vitepress/zh/repoctl/execution-model.md +81 -0
- package/templates/vitepress/zh/repoctl/getting-started.md +122 -0
- package/templates/vitepress/zh/repoctl/index.md +102 -0
- package/templates/vitepress/zh/repoctl/reports.md +94 -0
- package/templates/vitepress/{en → zh}/repoctl/scenarios.md +28 -26
- package/templates/vitepress/zh/repoctl/template-assets.md +116 -0
- package/templates/vitepress/zh/repoctl/templates.md +159 -0
- package/templates/vitepress/zh/repoctl/troubleshooting.md +110 -0
- package/templates/vitepress/zh/repoctl/workflows.md +118 -0
- package/templates/vitepress/zh/thinking.md +88 -0
- package/templates/vitepress/zh/tools/changeset.md +75 -0
- package/templates/vitepress/zh/tools/husky.md +130 -0
- package/templates/vitepress/zh/tools/index.md +38 -0
- package/templates/vitepress/zh/tools/lint-staged.md +103 -0
- package/templates/vitepress/zh/tools/llms-txt.md +9 -0
- package/templates/vitepress/zh/tools/pnpm.md +127 -0
- package/templates/vitepress/zh/tools/renovate.md +91 -0
- package/templates/vitepress/zh/tools/turborepo.md +166 -0
- package/templates/vitepress/zh/why/assets/npm-dt.svg +15 -0
- package/templates/vitepress/zh/why/assets/npm-ts.svg +19 -0
- package/templates/vitepress/zh/why/examples/0.npm-basic-package/index.js +10 -0
- package/templates/vitepress/zh/why/examples/0.npm-basic-package/package.json +11 -0
- package/templates/vitepress/zh/why/examples/1.npm-basic-package/index.cjs +12 -0
- package/templates/vitepress/zh/why/examples/1.npm-basic-package/index.d.ts +1 -0
- package/templates/vitepress/zh/why/examples/1.npm-basic-package/index.js +8 -0
- package/templates/vitepress/zh/why/examples/1.npm-basic-package/package.json +19 -0
- package/templates/vitepress/zh/why/examples/2.npm-basic-package/README.md +1 -0
- package/templates/vitepress/zh/why/examples/2.npm-basic-package/package-lock.json +30 -0
- package/templates/vitepress/zh/why/examples/2.npm-basic-package/package.json +35 -0
- package/templates/vitepress/zh/why/examples/2.npm-basic-package/rename-ext.js +24 -0
- package/templates/vitepress/zh/why/examples/2.npm-basic-package/src/index.ts +8 -0
- package/templates/vitepress/zh/why/examples/2.npm-basic-package/tsconfig.cjs.json +8 -0
- package/templates/vitepress/zh/why/examples/2.npm-basic-package/tsconfig.esm.json +7 -0
- package/templates/vitepress/zh/why/examples/2.npm-basic-package/tsconfig.json +18 -0
- package/templates/vitepress/zh/why/examples/3.npm-basic-package/README.md +1 -0
- package/templates/vitepress/zh/why/examples/3.npm-basic-package/package-lock.json +1496 -0
- package/templates/vitepress/zh/why/examples/3.npm-basic-package/package.json +31 -0
- package/templates/vitepress/zh/why/examples/3.npm-basic-package/src/index.ts +8 -0
- package/templates/vitepress/zh/why/examples/3.npm-basic-package/tsconfig.json +16 -0
- package/templates/vitepress/zh/why/examples/3.npm-basic-package/tsdown.config.ts +16 -0
- package/templates/vitepress/zh/why/examples/usage-cjs/cjs.cjs +4 -0
- package/templates/vitepress/zh/why/examples/usage-cjs/esm.mjs +4 -0
- package/templates/vitepress/zh/why/examples/usage-cjs/index.js +8 -0
- package/templates/vitepress/zh/why/examples/usage-cjs/package-lock.json +36 -0
- package/templates/vitepress/zh/why/examples/usage-cjs/package.json +20 -0
- package/templates/vitepress/zh/why/examples/usage-esm/cjs.cjs +4 -0
- package/templates/vitepress/zh/why/examples/usage-esm/createRequire.js +7 -0
- package/templates/vitepress/zh/why/examples/usage-esm/esm.mjs +4 -0
- package/templates/vitepress/zh/why/examples/usage-esm/index.js +8 -0
- package/templates/vitepress/zh/why/examples/usage-esm/package-lock.json +36 -0
- package/templates/vitepress/zh/why/examples/usage-esm/package.json +21 -0
- package/templates/vitepress/zh/why/how-to-reuse-js-code.md +250 -0
- package/templates/vitepress/zh/why/index.md +1 -0
- package/templates/vitepress/zh/why/js-cjs-mjs.md +99 -0
- package/templates/vitepress/zh/why/js-keywords.md +132 -0
- package/templates/vitepress/zh/why/modern/bundlers.md +52 -0
- package/templates/vitepress/zh/why/modern/dts.md +93 -0
- package/templates/vitepress/zh/why/modern/esm-vs-cjs.md +84 -0
- package/templates/vitepress/zh/why/modern/index.md +55 -0
- package/templates/vitepress/zh/why/modern/package-entry-points.md +128 -0
- package/templates/vitepress/zh/why/modern/typescript.md +155 -0
- package/templates/vitepress/zh/why/publish-basic-npm-package.md +146 -0
- package/templates/vitepress/zh/why/what-is-npm-package.md +162 -0
- package/templates/vue-lib/package.json +12 -5
- package/templates/vitepress/en/index.md +0 -63
- package/templates/vitepress/en/knowledge/monorepo.md +0 -37
- package/templates/vitepress/en/repoctl/adopt-existing.md +0 -133
- package/templates/vitepress/en/repoctl/commands.md +0 -120
- package/templates/vitepress/en/repoctl/config.md +0 -69
- package/templates/vitepress/en/repoctl/getting-started.md +0 -116
- package/templates/vitepress/en/repoctl/index.md +0 -74
- package/templates/vitepress/en/repoctl/templates.md +0 -128
- package/templates/vitepress/en/repoctl/troubleshooting.md +0 -96
- package/templates/vitepress/en/repoctl/workflows.md +0 -89
|
@@ -1,127 +1,15 @@
|
|
|
1
1
|
# pnpm
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
- `pnpm-workspace.yaml` 决定哪些目录属于 workspace。
|
|
6
|
-
- `pnpm install` 会把 workspace 包链接起来。
|
|
7
|
-
- 根脚本,例如 `pnpm doctor`、`pnpm new`、`pnpm check`,最终会调用 repoctl 的 `repo` CLI。
|
|
8
|
-
|
|
9
|
-
## 在 repoctl 项目里怎么用 pnpm
|
|
3
|
+
pnpm owns workspace discovery, dependency installation, script execution, and versioning configuration.
|
|
10
4
|
|
|
11
5
|
```bash
|
|
12
6
|
pnpm install
|
|
13
|
-
pnpm
|
|
14
|
-
pnpm
|
|
15
|
-
pnpm
|
|
16
|
-
pnpm
|
|
7
|
+
pnpm --filter <package> build
|
|
8
|
+
pnpm -r test
|
|
9
|
+
pnpm change
|
|
10
|
+
pnpm change status
|
|
17
11
|
```
|
|
18
12
|
|
|
19
|
-
|
|
20
|
-
| --------------------- | ----------------------------- |
|
|
21
|
-
| `pnpm install` | 安装依赖并创建 workspace link |
|
|
22
|
-
| `pnpm add -D repoctl` | 给已有仓库接入 repoctl CLI |
|
|
23
|
-
| `pnpm doctor` | 通过根脚本运行 `repo doctor` |
|
|
24
|
-
| `pnpm new` | 通过根脚本运行 `repo new` |
|
|
25
|
-
| `pnpm check` | 通过根脚本运行 `repo check` |
|
|
26
|
-
|
|
27
|
-
继续看:[repoctl 快速开始](../repoctl/getting-started.md)。
|
|
28
|
-
|
|
29
|
-
## 1. 什么是 pnpm?
|
|
30
|
-
|
|
31
|
-
**pnpm** 是一种 Node.js 的包管理器(类似于 **npm** 和 **yarn**)。
|
|
32
|
-
名字里的 **p** 代表 **Performant(高性能)**,也有人说是 **“poor man's npm”** 😂。
|
|
33
|
-
|
|
34
|
-
它的核心特点是:
|
|
35
|
-
|
|
36
|
-
- 使用 **硬链接 + 符号链接** 的方式来存储依赖。
|
|
37
|
-
- 避免不同项目重复下载相同的依赖,大大节省磁盘空间。
|
|
38
|
-
- 更快的安装速度。
|
|
39
|
-
|
|
40
|
-
## 2. pnpm 有什么用?
|
|
41
|
-
|
|
42
|
-
### 🚀 性能和空间优势
|
|
43
|
-
|
|
44
|
-
- **npm/yarn**:每个项目都要复制一份完整的依赖到 `node_modules`。
|
|
45
|
-
- **pnpm**:把所有依赖放在一个全局的 **内容可寻址存储(content-addressable store)**,项目里只是通过符号链接指向。
|
|
46
|
-
|
|
47
|
-
结果就是:
|
|
48
|
-
|
|
49
|
-
- 相同的依赖只会存一份。
|
|
50
|
-
- 安装速度更快,磁盘占用更小。
|
|
51
|
-
|
|
52
|
-
### 📦 严格的依赖隔离
|
|
53
|
-
|
|
54
|
-
- 在 `npm` 或 `yarn` 中,`node_modules` 会形成一个“扁平化”结构,有时可能让项目误依赖到不是自己声明的包(幽灵依赖问题)。
|
|
55
|
-
- **pnpm** 使用符号链接保持严格的依赖树,避免隐式依赖。
|
|
56
|
-
👉 如果你的 `package.json` 里没声明,就无法直接引用。
|
|
57
|
-
|
|
58
|
-
### 🛠 Monorepo 支持更好
|
|
59
|
-
|
|
60
|
-
- `pnpm` 原生支持 monorepo 管理(工作空间 `pnpm-workspace.yaml`)。
|
|
61
|
-
- 比如在一个仓库里有多个子包,`pnpm` 可以高效地安装和链接它们,代替 Lerna、Yarn workspaces 等工具。
|
|
62
|
-
|
|
63
|
-
### 🌍 与 npm 生态完全兼容
|
|
64
|
-
|
|
65
|
-
- `pnpm` 底层还是调用 npm registry,所以和 npm 包生态 **100%兼容**。
|
|
66
|
-
- 使用方式也和 `npm` 很接近,学习成本低。
|
|
67
|
-
|
|
68
|
-
## 3. 如何使用 pnpm?
|
|
69
|
-
|
|
70
|
-
### 安装 pnpm
|
|
71
|
-
|
|
72
|
-
```bash
|
|
73
|
-
npm install -g pnpm
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
### 常用命令对照
|
|
77
|
-
|
|
78
|
-
| 操作 | npm | pnpm |
|
|
79
|
-
| ---------- | ------------------ | ---------------- |
|
|
80
|
-
| 安装依赖 | `npm install` | `pnpm install` |
|
|
81
|
-
| 安装某个包 | `npm install xx` | `pnpm add xx` |
|
|
82
|
-
| 移除某个包 | `npm uninstall xx` | `pnpm remove xx` |
|
|
83
|
-
| 更新依赖 | `npm update` | `pnpm update` |
|
|
84
|
-
| 初始化项目 | `npm init` | `pnpm init` |
|
|
85
|
-
|
|
86
|
-
### Monorepo 示例
|
|
87
|
-
|
|
88
|
-
创建 `pnpm-workspace.yaml`:
|
|
89
|
-
|
|
90
|
-
```yaml
|
|
91
|
-
packages:
|
|
92
|
-
- 'packages/*'
|
|
93
|
-
- 'apps/*'
|
|
94
|
-
- 'templates/*'
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
这样 `pnpm` 会自动管理多个子项目的依赖和链接。
|
|
98
|
-
|
|
99
|
-
## 总结
|
|
100
|
-
|
|
101
|
-
- **pnpm 是一种更快、更省空间、更严格的包管理器**。
|
|
102
|
-
- 核心优势:
|
|
103
|
-
1. **磁盘节省**(共享依赖存储)。
|
|
104
|
-
2. **安装速度快**。
|
|
105
|
-
3. **严格依赖管理**,避免幽灵依赖。
|
|
106
|
-
4. **原生支持 monorepo**。
|
|
107
|
-
|
|
108
|
-
## npm vs Yarn vs pnpm 对比表
|
|
109
|
-
|
|
110
|
-
| 特性 / 工具 | **npm** | **Yarn** | **pnpm** |
|
|
111
|
-
| ----------------- | -------------------------------- | ----------------------------- | -------------------------------------- |
|
|
112
|
-
| **生态兼容性** | ✅ 官方,100% 兼容 npm registry | ✅ 兼容 npm registry | ✅ 兼容 npm registry |
|
|
113
|
-
| **安装速度** | ⏳ 较慢(尤其是全量安装时) | 🚀 比 npm 快,缓存优化 | ⚡ 非常快(硬链接 + 全局存储机制) |
|
|
114
|
-
| **磁盘空间占用** | 📦 高,每个项目一份完整依赖 | 📦 中等,有缓存但依赖重复存储 | 🪶 很低,共享依赖存储,节省大量空间 |
|
|
115
|
-
| **依赖结构** | 扁平化,可能产生“幽灵依赖” | 扁平化,依旧可能有幽灵依赖 | 严格隔离,避免幽灵依赖 |
|
|
116
|
-
| **Monorepo 支持** | 🚫 无原生支持,需要 Lerna 等工具 | ⚠️ Yarn Workspaces 支持 | ✅ 原生支持 Workspaces,管理更高效 |
|
|
117
|
-
| **命令兼容性** | 标准 npm 命令 | 大部分与 npm 相似 | 基本兼容,部分命令略有不同(如 `add`) |
|
|
118
|
-
| **锁文件** | `package-lock.json` | `yarn.lock` | `pnpm-lock.yaml` |
|
|
119
|
-
| **稳定性** | ✅ 官方维护,稳定性高 | ✅ 较成熟,社区维护 | ✅ 越来越流行,性能最佳 |
|
|
120
|
-
| **学习成本** | ⭐⭐ 最低 | ⭐⭐ 略有差异(命令相似) | ⭐⭐⭐ 略高,但上手简单 |
|
|
121
|
-
| **适用场景** | 小型项目,或默认环境 | 中大型项目,需要更快安装 | 中大型/Monorepo 项目,重视性能和空间 |
|
|
122
|
-
|
|
123
|
-
## 对比总结
|
|
13
|
+
`pnpm-workspace.yaml` is the source of truth for package patterns and release groups. repoctl can diagnose missing patterns and synchronize recommended defaults, but pnpm remains the package manager.
|
|
124
14
|
|
|
125
|
-
|
|
126
|
-
- **Yarn**:性能较优,适合需要加快依赖安装的团队。
|
|
127
|
-
- **pnpm**:性能最好、磁盘最省、依赖最严格,特别适合 **大型项目** 和 **monorepo** 场景。
|
|
15
|
+
Prefer exact workspace filters in automation and keep `packageManager` plus `engines.node` declared at the repository root.
|
|
@@ -1,91 +1,7 @@
|
|
|
1
1
|
# Renovate
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Renovate opens dependency update pull requests according to repository policy.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
它能帮你在项目中自动检测过期的依赖,并通过 PR(Pull Request)的形式提交更新建议。
|
|
5
|
+
Group related tooling updates, respect pnpm workspace constraints, and let the normal build, lint, typecheck, tsd, and test matrix validate each update. Avoid combining unrelated runtime and tooling upgrades when separate review makes regressions easier to isolate.
|
|
7
6
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
- 你不需要手动检查 `package.json`、`requirements.txt` 等文件里的依赖是否过期。
|
|
11
|
-
- Renovate 会帮你自动发现并发起更新。
|
|
12
|
-
|
|
13
|
-
## 2. Renovate 有什么用?
|
|
14
|
-
|
|
15
|
-
### 🚀 核心价值
|
|
16
|
-
|
|
17
|
-
1. **自动化依赖升级**
|
|
18
|
-
- 自动扫描项目依赖(支持 Node.js、Python、Java、Go、Docker 等)。
|
|
19
|
-
- 自动检测新版本。
|
|
20
|
-
- 自动提交 PR。
|
|
21
|
-
|
|
22
|
-
2. **降低维护成本**
|
|
23
|
-
- 避免依赖长期不升级,导致一次性大版本升级困难。
|
|
24
|
-
- 减少安全漏洞(及时更新安全补丁版本)。
|
|
25
|
-
|
|
26
|
-
3. **可控性强**
|
|
27
|
-
- 你可以配置哪些依赖自动升级,哪些只做提醒。
|
|
28
|
-
- 可以选择自动合并 **patch/minor** 版本更新,而 **major** 版本需要人工 review。
|
|
29
|
-
|
|
30
|
-
4. **支持 Monorepo**
|
|
31
|
-
- 非常适合 monorepo 项目,能分别更新各个子包的依赖。
|
|
32
|
-
|
|
33
|
-
## 3. Renovate 怎么用?
|
|
34
|
-
|
|
35
|
-
### 方式一:作为 GitHub App
|
|
36
|
-
|
|
37
|
-
1. 打开 [Renovate GitHub App](https://github.com/apps/renovate) 并安装到你的仓库。
|
|
38
|
-
2. 它会自动在项目根目录生成一个配置文件 `renovate.json`(或 `renovate.json5`)。
|
|
39
|
-
3. Renovate 就会定期检查依赖,并创建 PR。
|
|
40
|
-
|
|
41
|
-
### 方式二:自托管
|
|
42
|
-
|
|
43
|
-
如果你不想用 GitHub App,可以自己部署 Renovate(适用于 GitLab、Bitbucket 等环境)。
|
|
44
|
-
|
|
45
|
-
```bash
|
|
46
|
-
npx renovate
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
### 配置示例
|
|
50
|
-
|
|
51
|
-
在项目根目录添加 `renovate.json`:
|
|
52
|
-
|
|
53
|
-
```json
|
|
54
|
-
{
|
|
55
|
-
"extends": ["config:base"],
|
|
56
|
-
"packageRules": [
|
|
57
|
-
{
|
|
58
|
-
"matchUpdateTypes": ["minor", "patch"],
|
|
59
|
-
"automerge": true
|
|
60
|
-
},
|
|
61
|
-
{
|
|
62
|
-
"matchUpdateTypes": ["major"],
|
|
63
|
-
"automerge": false
|
|
64
|
-
}
|
|
65
|
-
]
|
|
66
|
-
}
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
解释:
|
|
70
|
-
|
|
71
|
-
- 使用基础配置 `"extends": ["config:base"]`。
|
|
72
|
-
- **minor/patch 更新** 自动合并。
|
|
73
|
-
- **major 更新** 需要人工 review。
|
|
74
|
-
|
|
75
|
-
### 实际效果
|
|
76
|
-
|
|
77
|
-
- Renovate 会创建类似这样的 PR:
|
|
78
|
-
- `chore(deps): update dependency react from 18.2.0 to 18.3.0`
|
|
79
|
-
- `fix(deps): update dependency lodash from 4.17.20 to 4.17.21`
|
|
80
|
-
|
|
81
|
-
- 你可以选择直接合并,或者再测试后手动处理。
|
|
82
|
-
|
|
83
|
-
## 4. 总结
|
|
84
|
-
|
|
85
|
-
- **Renovate = 自动依赖升级管家**。
|
|
86
|
-
- 主要用途:**自动检测依赖更新、自动生成 PR、降低维护成本**。
|
|
87
|
-
- 使用方式:安装 GitHub App(最简单),或者自托管运行。
|
|
88
|
-
- 适用场景:
|
|
89
|
-
- 需要长期维护的项目。
|
|
90
|
-
- 对安全性敏感的项目(及时更新补丁)。
|
|
91
|
-
- Monorepo 项目,依赖多而复杂。
|
|
7
|
+
repoctl does not replace Renovate. It provides the diagnostic and verification commands that Renovate pull requests can run consistently.
|
|
@@ -1,166 +1,14 @@
|
|
|
1
1
|
# Turborepo
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Turborepo runs the monorepo task graph and caches repeatable work.
|
|
4
4
|
|
|
5
5
|
```bash
|
|
6
6
|
pnpm build
|
|
7
|
+
pnpm lint
|
|
8
|
+
pnpm typecheck
|
|
7
9
|
pnpm test
|
|
8
|
-
pnpm exec repo check --full
|
|
9
|
-
pnpm exec repo check --json --out reports/check-plan.json
|
|
10
10
|
```
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
| --------------------------------- | ----------------------------------------- |
|
|
14
|
-
| `repo check` | 决定校验模式,输出可读或可保存的计划 |
|
|
15
|
-
| 根脚本 `pnpm build` / `pnpm test` | 调用 `turbo run build` / `turbo run test` |
|
|
16
|
-
| `turbo.json` | 定义任务依赖、缓存输出和执行策略 |
|
|
12
|
+
Root scripts delegate to `turbo run`. Package scripts define the actual build, lint, typecheck, and test commands; `turbo.json` defines dependencies, inputs, outputs, and cache behavior.
|
|
17
13
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
## 1. 什么是 Turborepo?
|
|
21
|
-
|
|
22
|
-
**Turborepo** 是由 **Vercel** 推出的一个 **高性能 JavaScript/TypeScript monorepo 构建系统**。
|
|
23
|
-
|
|
24
|
-
它的定位类似于 **NX / Bazel**,但更轻量、更贴合前端生态。
|
|
25
|
-
主要解决 **monorepo(多包/多项目仓库)** 下的构建、缓存和任务调度问题。
|
|
26
|
-
|
|
27
|
-
👉 通俗说:
|
|
28
|
-
在一个仓库里有多个应用和包,**Turborepo 可以帮你高效管理它们的依赖、构建、测试和发布**。
|
|
29
|
-
|
|
30
|
-
## 2. Turborepo 有什么用?
|
|
31
|
-
|
|
32
|
-
### 🚀 性能优化
|
|
33
|
-
|
|
34
|
-
- **增量构建**:只重新构建改动过的包,而不是全量重建。
|
|
35
|
-
- **智能缓存**:构建结果会缓存,本地和 CI/CD 环境可以共享(比如用远程缓存)。
|
|
36
|
-
- **任务并行化**:最大化利用 CPU 核心,减少构建时间。
|
|
37
|
-
|
|
38
|
-
### 📦 Monorepo 管理
|
|
39
|
-
|
|
40
|
-
- 可以在一个仓库中维护多个项目(比如 `templates/` 下是模板,`packages/` 下是共享组件或工具)。
|
|
41
|
-
- 内置工作区(workspace)支持,自动管理依赖关系。
|
|
42
|
-
|
|
43
|
-
### 🛠 灵活的任务编排
|
|
44
|
-
|
|
45
|
-
- 你可以定义 `build`、`test`、`lint` 等任务,Turborepo 会根据依赖关系和缓存情况决定执行策略。
|
|
46
|
-
|
|
47
|
-
### 🌍 和 Vercel 深度集成
|
|
48
|
-
|
|
49
|
-
- 在 Vercel 平台上可以直接利用远程缓存,加速 CI/CD。
|
|
50
|
-
|
|
51
|
-
## 3. Turborepo 怎么用?
|
|
52
|
-
|
|
53
|
-
### 安装
|
|
54
|
-
|
|
55
|
-
全局安装(可选):
|
|
56
|
-
|
|
57
|
-
```bash
|
|
58
|
-
npm install turbo --global
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
在项目中初始化:
|
|
62
|
-
|
|
63
|
-
```bash
|
|
64
|
-
npx create-turbo@latest
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
这会生成一个 monorepo 结构,比如:
|
|
68
|
-
|
|
69
|
-
```txt
|
|
70
|
-
.
|
|
71
|
-
├── apps
|
|
72
|
-
│ ├── web # 前端应用
|
|
73
|
-
│ └── docs # 文档应用
|
|
74
|
-
└── packages
|
|
75
|
-
├── ui # UI 组件库
|
|
76
|
-
└── config # 配置共享包
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
### 配置 `turbo.json`
|
|
80
|
-
|
|
81
|
-
核心配置文件,放在仓库根目录:
|
|
82
|
-
|
|
83
|
-
```json
|
|
84
|
-
{
|
|
85
|
-
"$schema": "https://turbo.build/schema.json",
|
|
86
|
-
"pipeline": {
|
|
87
|
-
"build": {
|
|
88
|
-
"dependsOn": ["^build"],
|
|
89
|
-
"outputs": ["dist/**", ".next/**"]
|
|
90
|
-
},
|
|
91
|
-
"lint": {},
|
|
92
|
-
"test": {
|
|
93
|
-
"dependsOn": ["build"]
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
解释:
|
|
100
|
-
|
|
101
|
-
- `build` 任务依赖于上游包的 `build`。
|
|
102
|
-
- 缓存 `dist/**` 或 `.next/**` 输出目录。
|
|
103
|
-
- `test` 依赖于 `build`。
|
|
104
|
-
|
|
105
|
-
### 运行命令
|
|
106
|
-
|
|
107
|
-
在根目录执行:
|
|
108
|
-
|
|
109
|
-
```bash
|
|
110
|
-
turbo run build
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
👉 Turborepo 会:
|
|
114
|
-
|
|
115
|
-
- 找到所有定义了 `build` 脚本的项目。
|
|
116
|
-
- 根据依赖关系决定执行顺序。
|
|
117
|
-
- 如果缓存可用,直接跳过执行,秒完成。
|
|
118
|
-
|
|
119
|
-
同理:
|
|
120
|
-
|
|
121
|
-
```bash
|
|
122
|
-
turbo run lint
|
|
123
|
-
turbo run test
|
|
124
|
-
```
|
|
125
|
-
|
|
126
|
-
### 远程缓存(可选)
|
|
127
|
-
|
|
128
|
-
如果团队协作或 CI/CD,需要共享缓存:
|
|
129
|
-
|
|
130
|
-
```bash
|
|
131
|
-
npx turbo login
|
|
132
|
-
npx turbo link
|
|
133
|
-
```
|
|
134
|
-
|
|
135
|
-
这样不同开发者、CI 都可以复用缓存,进一步加速。
|
|
136
|
-
|
|
137
|
-
## 4. 总结
|
|
138
|
-
|
|
139
|
-
- **Turborepo = 高性能 monorepo 构建工具**。
|
|
140
|
-
- **核心优势**:缓存、增量构建、并行执行、依赖感知。
|
|
141
|
-
- **适用场景**:
|
|
142
|
-
- 大型 monorepo(多个应用 + 包)。
|
|
143
|
-
- 需要快速构建和测试的团队。
|
|
144
|
-
- 想用 Vercel 部署的项目。
|
|
145
|
-
|
|
146
|
-
好的 👍,我来帮你把 **Turborepo、Lerna、Nx** 三个常见 **Monorepo 管理工具**做一个对比表。
|
|
147
|
-
|
|
148
|
-
## Turborepo vs Lerna vs Nx
|
|
149
|
-
|
|
150
|
-
| 特性 / 工具 | **Turborepo** | **Lerna** | **Nx** |
|
|
151
|
-
| ----------------- | ---------------------------------------- | ------------------------------------------- | ----------------------------------------------- |
|
|
152
|
-
| **定位** | 高性能构建系统,专注缓存、并行和增量构建 | 最早的 JS monorepo 工具,专注版本管理和发布 | 企业级开发平台,集成构建、测试、代码生成等功能 |
|
|
153
|
-
| **核心优势** | ⚡ 高速缓存(本地 & 远程)、并行任务执行 | 📦 包版本管理(独立/统一模式)、发布到 npm | 🛠 丰富的插件生态、代码生成器、强大的依赖图分析 |
|
|
154
|
-
| **依赖管理** | 基于 pnpm/yarn/npm workspaces | 基于 npm/yarn workspaces | 内置强依赖图(project graph)管理 |
|
|
155
|
-
| **构建/缓存机制** | ✅ 智能缓存 & 增量构建 | ❌ 无缓存机制 | ✅ 强大缓存 & 增量构建(类似 Bazel) |
|
|
156
|
-
| **任务编排** | pipeline 模式(`turbo.json`) | 简单顺序执行 | 高度可配置任务调度器(依赖感知) |
|
|
157
|
-
| **语言支持** | 主要是 JS/TS 生态 | 主要是 JS/TS 生态 | 多语言支持(JS/TS/Go/Rust/Python 等) |
|
|
158
|
-
| **学习成本** | ⭐⭐ 低(配置简洁,前端友好) | ⭐⭐ 低(老牌工具,功能单一) | ⭐⭐⭐ 高(功能多,配置复杂) |
|
|
159
|
-
| **社区活跃度** | 🚀 高(Vercel 维护,发展迅速) | ⚠️ 中等(已过巅峰,更多用于发布流程) | 🚀 高(企业应用广泛,社区和插件丰富) |
|
|
160
|
-
| **适合场景** | 前端/全栈项目,追求构建速度 & CI/CD 效率 | 多包库发布(如 npm 包集合项目) | 大型企业级 monorepo,跨语言/跨团队复杂项目 |
|
|
161
|
-
|
|
162
|
-
## 对比总结
|
|
163
|
-
|
|
164
|
-
- **Turborepo**:主打 **快**,缓存和增量构建体验非常好,适合前端/全栈团队。
|
|
165
|
-
- **Lerna**:更像是 **版本管理/发包工具**,现在多和 pnpm/Yarn Workspaces 搭配,用于管理 npm 包版本和发布。
|
|
166
|
-
- **Nx**:功能最全,适合大型团队,有可视化依赖图、代码生成、跨语言支持,但学习曲线较陡。
|
|
14
|
+
Mark generated artifacts as task outputs and declare upstream dependencies such as `build` before tests that consume built packages.
|
|
@@ -1,250 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
outline: [2, 4]
|
|
3
|
-
---
|
|
1
|
+
# Reusing JavaScript Code
|
|
4
2
|
|
|
5
|
-
|
|
3
|
+
JavaScript code can be shared through source modules, workspace packages, or published npm packages. The right boundary depends on ownership and consumers.
|
|
6
4
|
|
|
7
|
-
|
|
5
|
+
- Use a local module for code owned by one package.
|
|
6
|
+
- Use a workspace package when multiple projects in the same repository share versioned behavior.
|
|
7
|
+
- Publish an npm package when external repositories need a stable public API.
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
假如人人写代码都复制粘贴,这会造成一个工程化的地狱,后期维护成本急剧升高。
|
|
12
|
-
|
|
13
|
-
为此我们需要有效利用 `模块化` 的思路,去提炼,拆分,复用我们写的代码。
|
|
14
|
-
|
|
15
|
-
## **代码的模块化**
|
|
16
|
-
|
|
17
|
-
在现代 `JavaScript` 开发中,**模块化**不仅是一种组织代码的结构化方式,更是实现高效代码复用的核心前提。
|
|
18
|
-
|
|
19
|
-
### 模块化是复用的基础
|
|
20
|
-
|
|
21
|
-
1. **明确边界,职责单一**
|
|
22
|
-
模块化将一个大程序拆分为职责清晰、相互独立的功能块(模块)。每个模块完成一个单一任务,这种**高内聚、低耦合**的结构,为复用提供了天然的土壤。
|
|
23
|
-
|
|
24
|
-
2. **清晰的导入导出机制**
|
|
25
|
-
通过标准的 `export` 和 `import`(或 `CommonJS` 的 `module.exports` / `require`),开发者可以在不同文件、不同项目中复用相同模块,而无需复制粘贴代码。
|
|
26
|
-
|
|
27
|
-
3. **便于维护与测试**
|
|
28
|
-
模块是可单独测试、维护的最小单元。模块化设计使得一个功能变化不会影响其他模块,增强了系统的稳定性和可扩展性。
|
|
29
|
-
|
|
30
|
-
4. **为构建通用库打下基础**
|
|
31
|
-
工具函数库(如 `lodash/es-toolkit`)、业务中间件、配置模块、数据处理逻辑等,都是基于模块化原则设计的。只有当代码被封装为模块,它才可能被提取、封装、共享、发布。
|
|
32
|
-
|
|
33
|
-
### 模块化让复用从被动到主动
|
|
34
|
-
|
|
35
|
-
非模块化时代的“复用”往往是:
|
|
36
|
-
|
|
37
|
-
- 复制粘贴代码
|
|
38
|
-
- 修改适配不同上下文
|
|
39
|
-
|
|
40
|
-
而模块化之后,“复用”变成了:
|
|
41
|
-
|
|
42
|
-
- 明确接口,按需引入
|
|
43
|
-
- 参数化、配置化、可扩展
|
|
44
|
-
|
|
45
|
-
这不仅是形式上的进步,更是软件工程层面的范式跃迁。
|
|
46
|
-
|
|
47
|
-
### js 模块的典型格式
|
|
48
|
-
|
|
49
|
-
- **ES Modules(现代浏览器/现代 Node.js)**:标准、推荐,使用 `import` / `export`
|
|
50
|
-
- **CommonJS(传统 Node.js)**:使用 `require` / `module.exports`
|
|
51
|
-
- **UMD / IIFE / SystemJS / AMD**:一些老式模块化兼容方案,仍用于一些库的打包格式
|
|
52
|
-
|
|
53
|
-
#### ES Modules (ESM)
|
|
54
|
-
|
|
55
|
-
目前大部分新的 `npm` 包都使用这个格式发包,
|
|
56
|
-
|
|
57
|
-
它最大的特点是,使用 `export` / `import` 将功能函数、类、常量等分别放入独立 `.js` 文件中,动态引入的使用 `import()` 进行引入
|
|
58
|
-
|
|
59
|
-
```js
|
|
60
|
-
// utils/math.js
|
|
61
|
-
export function add(a, b) {
|
|
62
|
-
return a + b
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
export function multiply(a, b) {
|
|
66
|
-
return a * b
|
|
67
|
-
}
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
```js
|
|
71
|
-
// main.js
|
|
72
|
-
import { add, multiply } from './utils/math'
|
|
73
|
-
|
|
74
|
-
console.log(add(2, 3)) // 5
|
|
75
|
-
console.log(multiply(2, 3)) // 6
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
**这是目前的主流,也是未来的方向**
|
|
79
|
-
|
|
80
|
-
注意事项:
|
|
81
|
-
|
|
82
|
-
- 在浏览器中引入,需要使用 `<script type="module">`
|
|
83
|
-
- 在 `Node.js` 中需要 `package.json` 设置 `"type": "module"`
|
|
84
|
-
|
|
85
|
-
---
|
|
86
|
-
|
|
87
|
-
#### CommonJS (CJS)
|
|
88
|
-
|
|
89
|
-
在 `ESM` 规范没有被确立之前的社区模块化方案,低版本 `Node.js` 环境使用,高版本 `Node.js` 同时兼容 `CJS` 和 `ESM` 2 种模块化方案和加载策略
|
|
90
|
-
|
|
91
|
-
最大的特点为,使用 `require` / `module.exports`(`commonjs2`) / `exports`(`commonjs`) 进行模块化
|
|
92
|
-
|
|
93
|
-
```js
|
|
94
|
-
// utils/math.js
|
|
95
|
-
function add(a, b) {
|
|
96
|
-
return a + b
|
|
97
|
-
}
|
|
98
|
-
module.exports = { add }
|
|
99
|
-
```
|
|
100
|
-
|
|
101
|
-
```js
|
|
102
|
-
// app.js
|
|
103
|
-
const { add } = require('./utils/math.js')
|
|
104
|
-
|
|
105
|
-
console.log(add(5, 10))
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
新的包不会使用这个格式,目前这个格式的 `npm` 包,也正在逐步向 `ESM` 格式进行迁移
|
|
109
|
-
|
|
110
|
-
#### AMD (Asynchronous Module Definition)
|
|
111
|
-
|
|
112
|
-
AMD 是 RequireJS 推广的模块格式,支持异步加载模块,适用于浏览器。
|
|
113
|
-
|
|
114
|
-
```js
|
|
115
|
-
define('myLib', [], () => {
|
|
116
|
-
function hello() {
|
|
117
|
-
return 'Hello from AMD'
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
return {
|
|
121
|
-
hello
|
|
122
|
-
}
|
|
123
|
-
})
|
|
124
|
-
```
|
|
125
|
-
|
|
126
|
-
**已经过时,不要使用!**
|
|
127
|
-
|
|
128
|
-
#### UMD (Universal Module Definition)
|
|
129
|
-
|
|
130
|
-
UMD 是为了同时兼容 CommonJS、AMD 和浏览器环境而设计的模块格式。
|
|
131
|
-
|
|
132
|
-
```js
|
|
133
|
-
(function (root, factory) {
|
|
134
|
-
if (typeof define === 'function' && define.amd) {
|
|
135
|
-
// AMD
|
|
136
|
-
define([], factory)
|
|
137
|
-
}
|
|
138
|
-
else if (typeof module === 'object' && module.exports) {
|
|
139
|
-
// CommonJS
|
|
140
|
-
module.exports = factory()
|
|
141
|
-
}
|
|
142
|
-
else {
|
|
143
|
-
// Browser global
|
|
144
|
-
root.myLib = factory()
|
|
145
|
-
}
|
|
146
|
-
}(this, () => {
|
|
147
|
-
// 模块内容
|
|
148
|
-
function hello() {
|
|
149
|
-
return 'Hello from UMD'
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
return {
|
|
153
|
-
hello
|
|
154
|
-
}
|
|
155
|
-
}))
|
|
156
|
-
```
|
|
157
|
-
|
|
158
|
-
通常在你使用 `vite` 的 `lib` 模式的时候,除了会打一个 `ESM` 包之外,也会打一个 `UMD` 的包,用于 `CDN` + `SSR` 场景下使用。
|
|
159
|
-
|
|
160
|
-
#### IIFE (Immediately Invoked Function Expression)
|
|
161
|
-
|
|
162
|
-
IIFE 是立即执行函数表达式,常用于浏览器中,通常暴露到 `window` 上(无模块系统时的“模拟模块”方式)。
|
|
163
|
-
|
|
164
|
-
https://developer.mozilla.org/en-US/docs/Glossary/IIFE
|
|
165
|
-
|
|
166
|
-
```js
|
|
167
|
-
(function () {
|
|
168
|
-
function hello() {
|
|
169
|
-
console.log('Hello from IIFE')
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
// 暴露到全局
|
|
173
|
-
window.myLib = {
|
|
174
|
-
hello
|
|
175
|
-
}
|
|
176
|
-
})()
|
|
177
|
-
```
|
|
178
|
-
|
|
179
|
-
#### SystemJS / System.register
|
|
180
|
-
|
|
181
|
-
`System` 是由 `ES6 Module Loader` 提出的一种格式,现代打包工具(如 `Rollup`)可以输出此格式,用于运行时动态加载 `ES Modules`。
|
|
182
|
-
|
|
183
|
-
`SystemJS` 就是帮助你在不支持原生 `ESM` 格式的浏览器上(比如IE11),使用 `ESM` 格式
|
|
184
|
-
|
|
185
|
-
```js
|
|
186
|
-
System.register(['./constants'], (exports) => {
|
|
187
|
-
return {
|
|
188
|
-
execute() {
|
|
189
|
-
function hello() {
|
|
190
|
-
console.log('Hello from System')
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
exports('hello', hello)
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
})
|
|
197
|
-
```
|
|
198
|
-
|
|
199
|
-
加载方式(需要 `SystemJS` 库):
|
|
200
|
-
|
|
201
|
-
```html
|
|
202
|
-
<script src="https://cdn.jsdelivr.net/npm/systemjs/dist/system.js"></script>
|
|
203
|
-
<script>
|
|
204
|
-
System.import('/path/to/your-module.js').then(({ hello }) => hello())
|
|
205
|
-
</script>
|
|
206
|
-
```
|
|
207
|
-
|
|
208
|
-
比如 `@vitejs/plugin-legacy` 这个浏览器降级兼容方案,就是使用 `SystemJS` 在老旧的浏览器里面,加载 `ESM` 格式,从而进行兼容的。
|
|
209
|
-
|
|
210
|
-
#### 参考链接
|
|
211
|
-
|
|
212
|
-
- [rollupjs](https://rollupjs.org/configuration-options/#output-format)
|
|
213
|
-
- [webpackjs](https://webpack.js.org/configuration/output/#module-definition-systems-1)
|
|
214
|
-
- [esbuild](https://esbuild.github.io/api/#format)
|
|
215
|
-
- [swc](https://swc.rs/docs/configuration/modules)
|
|
216
|
-
- [babel](https://babeljs.io/docs/babel-preset-env#modules)
|
|
217
|
-
- [typescript](https://www.typescriptlang.org/tsconfig/#module)
|
|
218
|
-
|
|
219
|
-
## 一些复用方式
|
|
220
|
-
|
|
221
|
-
### **利用路径 alias 复用代码**
|
|
222
|
-
|
|
223
|
-
在纯 JS 工程中,如果使用构建工具如 Vite / Webpack,可以配置别名路径:
|
|
224
|
-
|
|
225
|
-
```js
|
|
226
|
-
// vite.config.js
|
|
227
|
-
export default {
|
|
228
|
-
resolve: {
|
|
229
|
-
alias: {
|
|
230
|
-
'@utils': path.resolve(__dirname, 'src/utils')
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
```
|
|
235
|
-
|
|
236
|
-
然后在代码中:
|
|
237
|
-
|
|
238
|
-
```js
|
|
239
|
-
import { add } from '@utils/math.js'
|
|
240
|
-
```
|
|
241
|
-
|
|
242
|
-
但是这种方式,仅在构建工具中生效,假如一个项目不用任何的构建工具,这个方案就不行了。
|
|
243
|
-
|
|
244
|
-
### **发布为 npm 本地包 / 私有包 / 公共包**
|
|
245
|
-
|
|
246
|
-
绝大部的场景都应该使用这个方案,来达到跨项目复用代码的目的。
|
|
247
|
-
|
|
248
|
-
这也是官方和社区推荐的方案。
|
|
249
|
-
|
|
250
|
-
接下来让我们开始 `npm` 包发布的旅程吧!
|
|
9
|
+
In a pnpm workspace, declare internal dependencies with the `workspace:` protocol and let the package build produce explicit runtime and type entrypoints.
|
|
@@ -1 +1,14 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Building A Modern npm Package
|
|
2
|
+
|
|
3
|
+
A modern package needs a deliberate module format, export map, declaration strategy, build pipeline, and compatibility policy.
|
|
4
|
+
|
|
5
|
+
## Guide
|
|
6
|
+
|
|
7
|
+
- [Modern Package Overview](./modern/index.md)
|
|
8
|
+
- [ESM vs CommonJS](./modern/esm-vs-cjs.md)
|
|
9
|
+
- [Type Declarations](./modern/dts.md)
|
|
10
|
+
- [Package Entry Points](./modern/package-entry-points.md)
|
|
11
|
+
- [Bundlers](./modern/bundlers.md)
|
|
12
|
+
- [TypeScript](./modern/typescript.md)
|
|
13
|
+
|
|
14
|
+
Runnable evolution examples remain under `why/examples/` and are intentionally excluded from the generated AI documentation index.
|