@bepack/cli 0.1.0-beta.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/reference.md ADDED
@@ -0,0 +1,822 @@
1
+ # BePack
2
+
3
+ BePack 是一个轻量级的构建工具,用于 Minecraft 基岩版脚本 API 项目。
4
+
5
+ 它管理常见的 BP/RP 项目任务:配置加载、清单修补、Minecraft 包版本解析、TypeScript 类型检查、Rolldown 构建、复制到游戏目录以及 mcpack/mcaddon 打包。
6
+
7
+ ## 已实现功能
8
+
9
+ ### CLI
10
+
11
+ 已实现的命令:
12
+
13
+ ```bash
14
+ bepack init
15
+ bepack install
16
+ bepack manifest
17
+ bepack build
18
+ bepack dev
19
+ bepack copy
20
+ bepack pack
21
+ bepack config
22
+ ```
23
+
24
+ 通用命令选项:
25
+
26
+ ```bash
27
+ --cwd <path>
28
+ --config <path>
29
+ --json
30
+ --dry-run
31
+ --silent
32
+ --verbose
33
+ ```
34
+
35
+ JSON 模式会抑制常规日志,并返回机器可读的成功/错误输出。
36
+
37
+ ### 配置加载
38
+
39
+ 支持的配置文件:
40
+
41
+ ```txt
42
+ bepack.config.ts
43
+ bepack.config.mjs
44
+ bepack.config.js
45
+ ```
46
+
47
+ 支持的导出方式:
48
+
49
+ ```ts
50
+ export default {
51
+ // config
52
+ };
53
+ ```
54
+
55
+ `defineConfig` 已导出并带有类型定义,以支持编辑器自动补全:
56
+
57
+ ```ts
58
+ import { defineConfig } from "@bepack/cli";
59
+
60
+ export default defineConfig({
61
+ root: ".",
62
+ target: "latest",
63
+
64
+ packs: {
65
+ bp: {
66
+ root: "bp",
67
+ uuid: "00000000-0000-0000-0000-000000000001",
68
+ moduleUuid: "00000000-0000-0000-0000-000000000002",
69
+ compile: {
70
+ entry: "src/main.ts",
71
+ },
72
+ dependencies: {
73
+ "@minecraft/server": "stable",
74
+ },
75
+ },
76
+ },
77
+
78
+ pack: {
79
+ outDir: "dist",
80
+ },
81
+ });
82
+ ```
83
+
84
+ 生成的包类型可通过以下方式使用:
85
+
86
+ ```json
87
+ {
88
+ "types": "dist/index.d.ts"
89
+ }
90
+ ```
91
+
92
+ ### 当前配置结构
93
+
94
+ 重要字段:
95
+
96
+ ```ts
97
+ type UserConfig = {
98
+ root?: string;
99
+ name: string;
100
+ version?: string;
101
+ description?: string;
102
+ target?: string;
103
+
104
+ /** Manifest format version: 2 (array versions, default) or 3 (SemVer string versions, Minecraft 1.21.110+ preview).
105
+ * Format 3 requires ALL version fields to be strings — arrays are rejected.
106
+ * Not set = auto-preserve existing manifest's format_version. New manifests default to 2. */
107
+ manifestFormat?: 2 | 3;
108
+
109
+ /** 编译配置移至 packs.bp.compile。顶层 build 只保留命令行为配置。 */
110
+ build?: {
111
+ copy?: false | true | string;
112
+ timing?: boolean;
113
+ };
114
+
115
+ packs?: {
116
+ bp?: {
117
+ root?: string;
118
+ uuid: string;
119
+ /** BP 的 moduleUuid 可选。只有配置了 compile 时才需要(用来管理 script 模块)。 */
120
+ moduleUuid?: string;
121
+ /** BP 编译配置(入口、TypeScript 检查、Rolldown 选项)。 */
122
+ compile?: {
123
+ entry: string;
124
+ tsconfig?: string;
125
+ typecheck?: boolean;
126
+ preserveModules?: boolean;
127
+ external?: (string | RegExp)[];
128
+ useNpx?: boolean;
129
+ minify?: boolean;
130
+ cache?: {
131
+ dev?: boolean; // 默认 true
132
+ build?: boolean; // 默认 false
133
+ file?: string; // 默认 "node_modules/.cache/bepack/tsconfig.tsbuildinfo"
134
+ };
135
+ /** 编译脚本输出目录,相对于 BP root。默认 "scripts"。 */
136
+ scriptOutputDir?: string;
137
+ };
138
+ /** 所有 BP 依赖都在此声明——包括清单依赖和纯代码依赖。 */
139
+ dependencies?: Record<string, "stable" | "beta" | "preview" | string>;
140
+ achievement?: boolean;
141
+ /** 额外的打包/复制文件列表(在默认 include 基础上追加)。 */
142
+ include?: string[];
143
+ };
144
+
145
+ rp?: {
146
+ root?: string;
147
+ uuid: string;
148
+ moduleUuid: string;
149
+ pbr?: boolean;
150
+ /** 额外的打包/复制文件列表。 */
151
+ include?: string[];
152
+ };
153
+ };
154
+
155
+ install?: {
156
+ registry?: string;
157
+ saveTo?: "dependencies" | "devDependencies";
158
+ packageManager?: "auto" | "npm" | "pnpm" | "yarn" | "bun";
159
+ runPackageManager?: boolean;
160
+ updatePackageJson?: boolean;
161
+ updateManifest?: boolean;
162
+ dependencyCatalog?: Record<string, DependencyCatalogEntry>;
163
+ dependencyResolvers?: DependencyResolverRule[];
164
+ };
165
+
166
+ copy?: {
167
+ defaultTarget?: string;
168
+ name?: string | { bp?: string; rp?: string };
169
+ /** RP 额外文件(BP 的额外文件请用 packs.bp.include)。 */
170
+ include?: { rp?: string[] };
171
+ targets?: Record<
172
+ string,
173
+ ({ type: "custom"; bp?: string; rp?: string } | { type: "gameRoot"; path: string }) & {
174
+ name?: string | { bp?: string; rp?: string };
175
+ }
176
+ >;
177
+ };
178
+
179
+ dev?: {
180
+ copy?: false | true | string;
181
+ watch?: {
182
+ include?: string[];
183
+ include?: string[];
184
+ };
185
+ };
186
+
187
+ pack?: {
188
+ name?: string;
189
+ outDir?: string;
190
+ };
191
+ };
192
+ ```
193
+
194
+ 路径约定:
195
+
196
+ - `root` 为项目根目录。
197
+ - `packs.bp.compile.entry` 为 Script API TypeScript 入口文件(仅 BP 配置了 compile 时)。
198
+ - `packs.bp.root` 为行为包根目录。
199
+ - `packs.rp.root` 为资源包根目录。
200
+ - `pack.outDir` 为 `.mcpack` / `.mcaddon` 的输出目录。
201
+
202
+ 对于 `bepack pack`,以下字段必须显式配置,且输入路径必须存在:
203
+
204
+ ```txt
205
+ packs.bp.root(如果配置了 BP)
206
+ packs.rp.root(如果配置了 RP)
207
+ pack.outDir
208
+ ```
209
+
210
+ > 注意:`bepack pack` 不再校验编译入口(`packs.bp.compile.entry`),
211
+ > 也不要求 BP 存在。仅 RP 项目也可以打包为 `.mcpack`。
212
+
213
+ ## 依赖安装与解析
214
+
215
+ `bepack install` 解析受管理的依赖、修补 `package.json`、可选地修补 `manifest.json`,并可选择运行包管理器。
216
+
217
+ 默认安装行为:
218
+
219
+ - 受管理的包写入 `dependencies`。
220
+ - 注册表默认为 `https://registry.npmjs.org/`。
221
+ - 包管理器默认为 `auto`。
222
+ - 默认会运行包管理器安装。
223
+ - 如果配置了 `install.registry`,包管理器安装会接收 `--registry <registry>`。
224
+
225
+ 所有 BP 依赖在 `packs.bp.dependencies` 中声明。依赖目录控制每个包的行为:
226
+
227
+ | 包 | 解析器 | package.json | manifest.json | 打包方式 |
228
+ | ---------------------------- | ------------------------- | ------------ | ------------- | -------- |
229
+ | `@minecraft/server` | `minecraft-script-api` | ✅ | ✅ | 外部 |
230
+ | `@minecraft/server-ui` | `minecraft-script-api` | ✅ | ✅ | 外部 |
231
+ | `@minecraft/server-net` | `minecraft-script-api-bp` | ✅ | ✅ | 外部 |
232
+ | `@minecraft/server-admin` | `minecraft-script-api-bp` | ✅ | ✅ | 外部 |
233
+ | `@minecraft/server-gametest` | `minecraft-script-api-bp` | ✅ | ✅ | 外部 |
234
+ | `@minecraft/vanilla-data` | `minecraft-vanilla-data` | ✅ | ❌ | 内联 |
235
+
236
+ ### 版本解析
237
+
238
+ 配置值:
239
+
240
+ ```ts
241
+ dependencies: {
242
+ "@minecraft/server": "stable",
243
+ "@minecraft/server-ui": "beta",
244
+ "@minecraft/vanilla-data": "preview",
245
+ }
246
+ ```
247
+
248
+ 受管理的 Minecraft 包在 `package.json` 中不会出现 `stable`、`beta`、`preview` 或 `latest` 字样。BePack 会从配置的注册表中解析具体的 npm 版本。
249
+
250
+ 每个包的解析器决定说明符(specifier)的规则:
251
+
252
+ #### `minecraft-script-api` — `@minecraft/server`、`@minecraft/server-ui`
253
+
254
+ | 说明符 | 目标 | package.json | manifest.json |
255
+ | --------- | -------- | ---------------------------------------------------------------- | ------------------------------ |
256
+ | `stable` | `latest` | 注册表中的最新稳定版 | 相同版本 |
257
+ | `stable` | 具体版本 | 查找匹配的 beta → 推断稳定版 `betaMajor.(betaMinor-1).betaPatch` | 相同版本 |
258
+ | `beta` | `latest` | 所有版本中最高的 beta 版(排除 preview) | `"beta"` |
259
+ | `beta` | 具体版本 | 匹配 `*-beta.*<target>-stable` 或 `*-beta-*<target>-stable` | `"beta"`(频道依赖)或具体版本 |
260
+ | `preview` | `latest` | 最高的 preview 版本(rc 或 beta) | 完整版本字符串 |
261
+ | `preview` | 具体版本 | 匹配 `*-{rc\|beta}.<target>-preview.*` | 完整版本字符串 |
262
+
263
+ #### `minecraft-script-api-bp` — `@minecraft/server-net`、`@minecraft/server-admin`、`@minecraft/server-gametest`
264
+
265
+ 这些包没有稳定版本。只接受 `beta` 和 `preview`。
266
+
267
+ | 说明符 | 行为 |
268
+ | --------- | --------------------------------------------- |
269
+ | `beta` | 同 `minecraft-script-api` 的 beta 解析方式 |
270
+ | `preview` | 同 `minecraft-script-api` 的 preview 解析方式 |
271
+ | `stable` | **拒绝** — `DEPENDENCY_VERSION_INVALID` |
272
+
273
+ #### `minecraft-vanilla-data` — `@minecraft/vanilla-data`
274
+
275
+ | 说明符 | 目标 | 行为 |
276
+ | --------- | ----------- | --------------------------------------------- |
277
+ | `stable` | `latest` | 最新稳定版(dist-tag `latest` 或最高 semver) |
278
+ | `stable` | `"1.26.32"` | 如果注册表中存在,则精确使用 `1.26.32` |
279
+ | `preview` | `latest` | 最高 `X.X.X-preview.N` 版本 |
280
+ | `preview` | `"1.26.40"` | 最高 `1.26.40-preview.N` 版本 |
281
+ | `beta` | — | **拒绝** — `DEPENDENCY_VERSION_INVALID` |
282
+
283
+ #### 稳定版推断示例
284
+
285
+ 对于 `minecraft-script-api` 解析器,稳定版从对应的 beta 版本推断:
286
+
287
+ ```txt
288
+ 2.7.0-beta.1.26.10-stable -> 2.6.0
289
+ 2.4.0-beta.1.21.120-stable -> 2.3.0
290
+ 2.1.0-beta.1.26.21-stable -> 2.0.0
291
+ ```
292
+
293
+ `target: "stable"` 和 `target: "beta"` 会被拒绝,因为 target 指的是 Minecraft 游戏版本,而非 Script API 频道。
294
+
295
+ 其他 target 字符串会传递给注册表解析。如果找不到匹配版本,安装失败并返回 `SAPI_VERSION_NOT_FOUND`。
296
+
297
+ 当清单依赖中使用 `preview` 或 `beta` 说明符而未先运行 `bepack install` 时,BePack 会抛出 `DEPENDENCY_REQUIRES_INSTALL`。这与 `stable` 的行为相同——说明符本身永远不会直接写入 `manifest.json`。
298
+
299
+ ### 安装日志
300
+
301
+ 常规安装日志显示简洁的进度:
302
+
303
+ ```txt
304
+ [Install] resolving dependencies for target 1.26.10
305
+ [Install] fetching @minecraft/server metadata from https://registry.npmjs.org/
306
+ [Install] @minecraft/server: stable -> package 2.6.0, manifest 2.6.0
307
+ ```
308
+
309
+ 使用 `--verbose` 可查看更底层的详细信息,如缓存命中、版本数量和推断过程。
310
+
311
+ ### 依赖目录与解析器扩展点
312
+
313
+ 安装解析分为依赖目录和解析器注册表两部分。
314
+
315
+ 依赖目录通过三个字段控制每个包的行为:
316
+
317
+ - `resolver`:处理此包的解析器组(例如 `"minecraft-script-api"`、`"minecraft-vanilla-data"`)。
318
+ - `packageJson`:是否写入 `package.json`(默认为 `true`)。
319
+ - `manifest`:是否写入 BP `manifest.json`(默认为 `false`)。当为 `true` 时,该包在构建时也会被外部化。
320
+ - `manifest: false`(例如 `@minecraft/vanilla-data`)的包不会写入清单,可以被内联打包。
321
+
322
+ 解析器将 `stable`、`beta`、`preview` 或精确版本号转换为具体的包版本和清单版本。
323
+ 解析器上下文包含 `ctx.npm`,这是一个可复用的 npm 注册表客户端,会自动使用 `install.registry` 并缓存元数据。
324
+
325
+ 自定义包和解析器可以在配置中提供:
326
+
327
+ ```ts
328
+ export default defineConfig({
329
+ install: {
330
+ dependencyCatalog: {
331
+ "my-package": {
332
+ resolver: "my-resolver",
333
+ packageJson: true,
334
+ manifest: true,
335
+ },
336
+ },
337
+ dependencyResolvers: [
338
+ {
339
+ name: "my-resolver",
340
+ resolver: "my-resolver",
341
+ match(ctx) {
342
+ return ctx.packageName === "my-package";
343
+ },
344
+ async resolve(ctx) {
345
+ const metadata = await ctx.npm.metadata(ctx.packageName);
346
+ const latest = ctx.npm.distTag(metadata, "latest") ?? "1.0.0";
347
+ return {
348
+ packageVersion: latest,
349
+ manifestVersion: latest,
350
+ };
351
+ },
352
+ },
353
+ ],
354
+ },
355
+ });
356
+ ```
357
+
358
+ 解析器顺序:
359
+
360
+ 1. 自定义 `install.dependencyResolvers`
361
+ 2. 内置 `minecraft-script-api` — `@minecraft/server` 和 `@minecraft/server-ui` 的 stable/beta/preview 解析
362
+ 3. 内置 `minecraft-script-api-bp` — `@minecraft/server-net`、`@minecraft/server-admin`、`@minecraft/server-gametest` 的 beta/preview 解析
363
+ 4. 内置 `minecraft-vanilla-data` — `@minecraft/vanilla-data` 的 stable/preview 解析
364
+ 5. 内置 `exact-version` — 任意精确版本说明符
365
+
366
+ ## 清单管理
367
+
368
+ `bepack manifest` 和 `bepack install` 可以创建和修补清单。
369
+
370
+ ### format_version 支持
371
+
372
+ BePack 同时支持 `format_version 2` 和 `format_version 3`(Minecraft 1.21.110+ preview):
373
+
374
+ | 特性 | format 2 | format 3 |
375
+ | -------------- | ---------------- | ----------------------------------------- |
376
+ | 版本格式 | 数组 `[1, 0, 0]` | SemVer 字符串 `"1.0.0"`(**不接受数组**) |
377
+ | 自定义设置面板 | 不支持 | 支持(预览) |
378
+ | 兼容性 | 高 | **不兼容** format 2 的数组版本 |
379
+
380
+ 版本字段适用范围:`header.version`、`header.min_engine_version`、`modules[].version`、dependencies 中 uuid 依赖的 `version`。Script API 的 `module_name` 依赖始终为字符串,不受影响。
381
+
382
+ **format 选择优先级**:
383
+
384
+ 1. 配置中显式设置 `manifestFormat: 2 | 3` → 强制使用
385
+ 2. 未设置时保留 existing manifest 的 `format_version`
386
+ 3. 全新 manifest 默认 `2`
387
+
388
+ **注意**:
389
+
390
+ - format 2 不兼容 format 3 的字符串版本。如果配置强制使用 format 2 但 existing manifest 是 format 3,BePack 会给出降级警告。
391
+ - `bepack init --from-bp/--from-rp` 会自动检测 manifest 的 `format_version` 和 `header.version` 实际格式是否一致。如果不一致(如 format=3 但 version 是数组),会按照 format 2 处理并给出警告。
392
+
393
+ BP 清单受控字段:
394
+
395
+ - `format_version`(根据配置或 existing 保留)
396
+ - `header.name`
397
+ - `header.description`(仅在配置时)
398
+ - `header.uuid`
399
+ - `header.version`
400
+ - `header.min_engine_version`
401
+ - 脚本模块
402
+ - BePack 管理的 `@minecraft/*` 依赖
403
+ - BP/RP 相互依赖
404
+ - `metadata.product_type`(仅在 `achievement: true` 时)
405
+
406
+ RP 清单受控字段:
407
+
408
+ - `format_version`
409
+ - `header.name`
410
+ - `header.description`(仅在配置时)
411
+ - `header.uuid`
412
+ - `header.version`
413
+ - `header.min_engine_version`
414
+ - 资源模块
415
+ - RP/BP 相互依赖
416
+ - `capabilities: ["pbr"]`(当 `pbr: true` 时)
417
+
418
+ 用户定义的清单字段会被保留。
419
+
420
+ 当同时配置了 BP 和 RP 时,BePack 会维护它们 header UUID 之间的相互依赖。
421
+
422
+ 成就元数据:
423
+
424
+ - `packs.bp.achievement: true` 添加 `metadata.product_type = "addon"`。
425
+ - 每个受管理的 Script API 依赖必须使用 `stable` 说明符。
426
+ - 如果在启用成就时使用了 `beta` 或 `preview` 依赖,BePack 会抛出 `ACHIEVEMENT_REQUIRES_STABLE_API`。
427
+
428
+ ## 构建
429
+
430
+ `bepack build` 执行以下步骤:
431
+
432
+ ```txt
433
+ 清单修补
434
+ hooks.beforeBuild
435
+ 类型检查
436
+ Rolldown 构建
437
+ hooks.afterBuild
438
+ 可选复制
439
+ 可选打包
440
+ ```
441
+
442
+ CLI 选项:
443
+
444
+ - `--mode <value>`:执行模式,透传给 Hook 上下文(`HookContext.mode`)。不设则为 `undefined`。Hook 内自行判断是否执行特定逻辑。
445
+
446
+ 类型检查行为:
447
+
448
+ - 默认:系统 `tsc --noEmit`。
449
+ - `build.useNpx: true` 或 `--use-npx`:`npx tsc --noEmit`。
450
+ - `packs.bp.compile.cache`:增量编译缓存配置。`cache.dev`(默认 `true`)控制 dev 模式;`cache.build`(默认 `false`)控制 build 模式。`cache.file` 指定 `.tsbuildinfo` 路径。`bepack build --cache` / `--no-cache` 可覆盖 build 模式。`dev` 命令默认启用缓存。
451
+ - 缺少 `tsconfig.json` 会提前失败,返回 `TYPECHECK_FAILED`。
452
+
453
+ Rolldown 行为:
454
+
455
+ - 默认 `preserveModules: true`(在 `packs.bp.compile.preserveModules` 中配置)。
456
+ - 输出到 `<packs.bp.root>/scripts`。
457
+ - 每次构建前会清空 `<packs.bp.root>/scripts` 目录。
458
+ - `packs.bp.compile.entry` 控制输入文件。
459
+ - `packs.bp.compile.scriptOutputDir` 控制编译脚本输出目录(相对于 BP root),默认 `"scripts"`。manifest 中的 script 模块 `entry` 路径也会随之更新为 `<scriptOutputDir>/<entry文件名>.js`。
460
+ - 外部包来自 `packs.bp.compile.external`,默认情况下也来自受管理的依赖目录。
461
+ - `packs.bp.compile.minify: true` 或 `--minify` 启用 Rolldown 代码压缩,输出更小的 JS 文件。
462
+ - 字符串替换通过顶层 `replace` 配置:`replace.values` 支持字面量或接收已解析 config 的函数;`replace.builtins` 可开启 `**VERSION**`、`**NAME**`、`**UUID**`、`**DESCRIPTION**`。未配置替换时不会创建 replace plugin。`**DESCRIPTION**` 优先使用 `packs.bp.description`,再回退到根 `description`。
463
+ - 构建完成后显示输出文件的大小统计(单文件显示路径和体积,多文件显示总文件数和总体积)。
464
+
465
+ > 注意:构建命令(`build` / `dev`)不再要求 BP 必须存在。如果项目只有 RP 或 BP 没有配置 `compile`,则跳过编译流程,只执行 manifest 修补和可选的文件复制/打包。
466
+
467
+ `packs.bp.compile.externalDependencies` 默认为 `true`,因此内置的 `manifest: true` 受管理包(例如 `@minecraft/server`、`@minecraft/server-ui`、`@minecraft/server-net`)不会被内联打包。`manifest: false` 的包(例如 `@minecraft/vanilla-data`)可以被内联打包。设置 `externalDependencies` 为 `false` 可自定义,或通过 `packs.bp.compile.external` 添加额外条目。
468
+
469
+ `build.timing: true` 或 `--timing` 可在构建时显示各步骤的耗时明细,便于排查性能瓶颈:
470
+
471
+ ```txt
472
+ timing manifest 12 ms
473
+ timing typecheck 856 ms
474
+ timing rolldown 45 ms
475
+ ```
476
+
477
+ `--timing` 同样支持 `bepack dev` 命令。
478
+
479
+ ## 开发模式
480
+
481
+ `bepack dev`:
482
+
483
+ - 在监视前先执行一次初始构建(manifest + 若有 compile 则编译)。
484
+ - 支持 `--skip-typecheck` 跳过类型检查(与 `build` 命令一致)。
485
+ - 支持 `--mode <value>`,用法与 `build` 命令相同,透传给 Hook 上下文。初始构建和后续增量重建均会传入该值。
486
+ - 默认监视的路径:
487
+ - `packs.bp.compile.entry` 所在目录(仅在 BP 配置了 compile 时,TypeScript 源码变化 → 触发编译)
488
+ - BP 的默认 include 列表 + `packs.bp.include` 中的文件/文件夹(不含 `scripts` 和 `manifest.json`)
489
+ - RP 的 include 列表中的文件/文件夹(如果配置了 `packs.rp.include`),否则监视整个 RP 目录
490
+ - 可通过 `dev.watch.include` 添加额外监听路径。
491
+ - 忽略以下目录:
492
+ - `node_modules`
493
+ - `.git`
494
+ - `pack.outDir`
495
+ - 每次更改时清空终端输出,显示每次更新的耗时。
496
+ - 构建锁:构建过程中来的其他文件变化会排队,构建结束后统一处理一次,不会并发构建。
497
+ - src 文件变化触发重建 + 复制,非 src 文件变化只触发复制。不涉及的文件不触发任何操作。
498
+
499
+ BP 的监听范围精确匹配 copy 的 include 规则,编辑不会被复制的文件不会触发重构建。
500
+ 可通过 `dev.watch.include` 添加额外监听路径:
501
+
502
+ ```ts
503
+ export default defineConfig({
504
+ dev: {
505
+ copy: true,
506
+ watch: {
507
+ include: ["docs", "tools/config.json"],
508
+ },
509
+ },
510
+ });
511
+ ```
512
+
513
+ ## 复制
514
+
515
+ `bepack copy` 将 BP/RP 复制到配置的目标路径。
516
+
517
+ **如果没有配置任何复制目标,`bepack copy` 会报错。** 复制前会验证目标目录是否存在,不存在则报错。
518
+
519
+ ### 内置目标
520
+
521
+ - `win`
522
+ - 新的 Windows Minecraft 基岩版路径:
523
+ - `%USERPROFILE%\AppData\Roaming\Minecraft Bedrock\Users\Shared\games\com.mojang`
524
+ - `winold`
525
+ - `%LOCALAPPDATA%\Packages\Microsoft.MinecraftUWP_8wekyb3d8bbwe` 下的旧 UWP Minecraft 路径
526
+
527
+ 内置目标本质上是预设路径的 `gameRoot` 类型,会自动追加 `development_behavior_packs` / `development_resource_packs` 子目录。
528
+
529
+ ### 目标类型
530
+
531
+ #### `custom` — 手动指定完整路径
532
+
533
+ ```ts
534
+ copy: {
535
+ defaultTarget: "server",
536
+ targets: {
537
+ server: {
538
+ type: "custom",
539
+ bp: "/server/world/development_behavior_packs",
540
+ rp: "/server/world/development_resource_packs",
541
+ },
542
+ },
543
+ }
544
+ ```
545
+
546
+ #### `gameRoot` — 指定游戏根目录,自动派生子目录
547
+
548
+ ```ts
549
+ copy: {
550
+ defaultTarget: "myServer",
551
+ targets: {
552
+ myServer: {
553
+ type: "gameRoot",
554
+ path: "/server/server1",
555
+ },
556
+ },
557
+ }
558
+ ```
559
+
560
+ 对于 `gameRoot` 类型,BePack 会自动拼接路径:
561
+
562
+ - BP → `<path>/development_behavior_packs`
563
+ - RP → `<path>/development_resource_packs`(仅当项目配置了 `packs.rp` 时)
564
+
565
+ ### 路径验证
566
+
567
+ 所有复制目标在复制前都会验证目录是否存在。如果目标目录不存在,命令会失败并返回 `COPY_FAILED`。这适用于所有目标类型(内置 `win`/`winold`、`custom`、`gameRoot`)。
568
+
569
+ ### 自定义复制文件夹名称
570
+
571
+ 复制到目标目录时,BP/RP 的文件夹名称默认为 `packs.bp.name` / `packs.rp.name`,即项目配置中的包名称。可以通过 `copy.name` 或目标级 `name` 覆盖:
572
+
573
+ `name` 可以是对象(分别指定 bp/rp),也可以是字符串(bp 和 rp 使用相同名称):
574
+
575
+ ```ts
576
+ copy: {
577
+ defaultTarget: "server",
578
+
579
+ // 全局名称覆盖(字符串:bp 和 rp 同名)
580
+ name: "MyPack",
581
+
582
+ targets: {
583
+ server: {
584
+ type: "gameRoot",
585
+ path: "/server/server1",
586
+ // 目标级名称覆盖(对象:分别指定 bp/rp)
587
+ name: {
588
+ bp: "behavior_packs_custom",
589
+ // rp 未设置,则回退到全局 copy.name 或 packs.rp.name
590
+ },
591
+ },
592
+
593
+ staging: {
594
+ type: "custom",
595
+ bp: "/staging/behavior_packs",
596
+ name: "StagingPack", // 字符串,bp 和 rp 都叫 StagingPack
597
+ },
598
+ },
599
+ }
600
+ ```
601
+
602
+ 优先级:**目标级 `name` > 全局 `copy.name` > 包配置 `packs.bp.name` / `packs.rp.name`**。
603
+
604
+ 各部分独立覆盖。例如只设置 `copy.name.bp`,则 RP 名称仍使用 `packs.rp.name` 的默认值。
605
+
606
+ ### 选择性复制
607
+
608
+ 复制 BP 时,默认只复制以下文件/文件夹:
609
+
610
+ ```
611
+ scripts manifest.json animation_controllers animations biomes
612
+ blocks entities functions items loot_tables pack_icon.png
613
+ recipes spawn_rules structures texts trading
614
+ feature_rules features worldgen
615
+ ```
616
+
617
+ BP 的额外文件/文件夹通过 `packs.bp.include` 配置(不会替换默认列表):
618
+
619
+ ```ts
620
+ packs: {
621
+ bp: {
622
+ root: "bp",
623
+ include: ["my_custom_data", "config.json"], // 额外复制/打包
624
+ },
625
+ }
626
+ ```
627
+
628
+ RP 的额外文件/文件夹通过 `packs.rp.include` 配置——一旦设置,RP 也变为选择性复制模式:
629
+
630
+ ```ts
631
+ packs: {
632
+ rp: {
633
+ root: "rp",
634
+ include: ["textures", "sounds", "models"], // 额外复制/打包
635
+ },
636
+ }
637
+ ```
638
+
639
+ 复制项不存在时会被静默跳过,不会报错。
640
+
641
+ Dev 模式使用相同的 include 规则来决定监听哪些文件,详见「开发模式」章节。
642
+
643
+ ### 复制与构建/开发联动
644
+
645
+ ```ts
646
+ build: {
647
+ copy: true, // 构建后复制到 copy.defaultTarget
648
+ // 或
649
+ copy: "myTarget", // 构建后复制到指定目标
650
+ }
651
+
652
+ dev: {
653
+ copy: true, // 文件变更后复制到 copy.defaultTarget
654
+ // 或
655
+ copy: "myTarget", // 文件变更后复制到指定目标
656
+ }
657
+ ```
658
+
659
+ `build.copy` 和 `dev.copy` 默认为 `false`(不复制)。`true` 表示使用 `copy.defaultTarget`,字符串表示使用指定目标。
660
+
661
+ ## 打包
662
+
663
+ `bepack pack` 创建:
664
+
665
+ - 仅配置 BP 时创建 `.mcpack`。
666
+ - 同时配置 BP 和 RP 时创建 `.mcaddon`。
667
+
668
+ **BP 始终使用选择性打包**:只打包默认 include 列表(`scripts`、`manifest.json`、`animation_controllers` 等)和 `packs.bp.include` 中配置的额外文件。即使 `bp.root = "."`(项目根目录即行为包),也不会将整个项目打包进去。
669
+
670
+ RP 默认打包整个目录;如果配置了 `packs.rp.include`,则改用选择性打包。
671
+
672
+ 输出文件名默认为:
673
+
674
+ ```txt
675
+ {name}-{version}
676
+ ```
677
+
678
+ 输出目录通过以下方式配置:
679
+
680
+ ```ts
681
+ pack: {
682
+ outDir: "dist",
683
+ }
684
+ ```
685
+
686
+ 打包输入配置必须显式指定,且输入路径必须存在。这可以防止意外打包猜测的默认目录。
687
+
688
+ ## 钩子
689
+
690
+ 支持的钩子:
691
+
692
+ ```ts
693
+ hooks: {
694
+ beforeInstall(ctx) {},
695
+ afterInstall(ctx) {},
696
+ beforeManifest(ctx) {},
697
+ afterManifest(ctx) {},
698
+ beforeBuild(ctx) {},
699
+ afterBuild(ctx) {},
700
+ beforeCopy(ctx) {},
701
+ afterCopy(ctx) {},
702
+ beforePack(ctx) {},
703
+ afterPack(ctx) {},
704
+ }
705
+ ```
706
+
707
+ 钩子上下文类型:
708
+
709
+ ```ts
710
+ type HookContext = {
711
+ command: CommandName; // "build" | "dev" | "install" | ...
712
+ cwd: string;
713
+ mode?: string; // 通过 --mode <value> 传入的执行模式
714
+ target: string;
715
+ config: ResolvedConfig;
716
+ paths: {
717
+ dist: string;
718
+ bpRoot?: string;
719
+ rpRoot?: string;
720
+ bpManifest?: string;
721
+ rpManifest?: string;
722
+ srcEntry?: string;
723
+ scriptOutFile?: string; // 编译输出文件路径
724
+ scriptOutDir?: string; // 编译输出目录路径
725
+ };
726
+ logger: LoggerLike;
727
+ };
728
+ ```
729
+
730
+ 钩子可以是同步或异步的。在钩子中抛出异常会导致命令失败,返回 `HOOK_FAILED`。
731
+
732
+ `mode` 来自 CLI `--mode <value>` 选项(目前 `build` 和 `dev` 命令支持),BEPack 不做语义判断,由用户在钩子内自行决定是否执行特定逻辑:
733
+
734
+ ```ts
735
+ hooks: {
736
+ async afterBuild({ mode }) {
737
+ if (mode === "template") return; // 模板构建跳过复制
738
+ await copyFilesToOutput();
739
+ },
740
+ }
741
+ ```
742
+
743
+ 未传入 `--mode` 时,`mode` 为 `undefined`,保持完全向后兼容。
744
+
745
+ ## 输出与错误
746
+
747
+ 常规模式下,CLI 输出使用彩色阶段标签和时间戳。
748
+
749
+ 示例:
750
+
751
+ ```txt
752
+ [17:30:02] [Install] resolving dependencies for target 1.26.10
753
+ [17:30:05] [Manifest] manifest.json updated
754
+ [17:30:05] [TypeScript] typecheck complete
755
+ [17:30:06] [Rolldown] preserve modules build complete
756
+ ```
757
+
758
+ `--json` 模式返回 JSON 并抑制常规日志。
759
+
760
+ 错误使用稳定的错误码,例如:
761
+
762
+ ```txt
763
+ CONFIG_NOT_FOUND
764
+ CONFIG_INVALID
765
+ TARGET_INVALID
766
+ UNSUPPORTED_DEPENDENCY
767
+ DEPENDENCY_VERSION_INVALID
768
+ DEPENDENCY_REQUIRES_INSTALL
769
+ SAPI_VERSION_NOT_FOUND
770
+ ACHIEVEMENT_REQUIRES_STABLE_API
771
+ TYPECHECK_FAILED
772
+ BUILD_FAILED
773
+ COPY_TARGET_NOT_FOUND
774
+ COPY_FAILED
775
+ PACK_FAILED
776
+ HOOK_FAILED
777
+ CLI_ARGUMENT_CONFLICT
778
+ ```
779
+
780
+ ## 初始化
781
+
782
+ `bepack init` 创建 `bepack.config.ts`。它不会创建项目目录。
783
+
784
+ ### 默认脚手架
785
+
786
+ ```bash
787
+ bepack init
788
+ ```
789
+
790
+ 生成标准配置模板,使用随机 UUID。
791
+
792
+ ### 从已有 manifest 反推
793
+
794
+ ```bash
795
+ # 只从 BP manifest 反推
796
+ bepack init --from-bp ./bp/manifest.json
797
+
798
+ # 只从 RP manifest 反推
799
+ bepack init --from-rp ./rp/manifest.json
800
+
801
+ # BP + RP 都传
802
+ bepack init --from-bp ./bp/manifest.json --from-rp ./rp/manifest.json
803
+ ```
804
+
805
+ 规则:
806
+
807
+ | 场景 | 行为 |
808
+ | -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
809
+ | 只传 BP | 顶层 `name`/`description` 设为 BP manifest 的值 |
810
+ | 只传 RP | 同上 |
811
+ | BP + RP 都传 | 顶层 `name`/`description` 从 BP 读取;同时分别设到 `packs.bp.name`/`packs.rp.name` |
812
+ | format_version | 自动检测原 manifest 的 `format_version`,写入生成的配置的 `manifestFormat` 字段。如果 `format_version` 与 `header.version` 的实际格式不符(如 format=3 但 version 是数组),降级为 format 2 并警告 |
813
+ | pack root | 根据 manifest 路径相对当前目录自动推导 |
814
+ | UUID | 直接读取 manifest 中的值,不重新生成 |
815
+ | 版本 | 从 manifest header 读取(支持数组 `[1,0,0]` 和字符串 `"1.0.0"`)。两个包版本不同时取最高者,并给出警告 |
816
+ | 依赖 | manifest 中的 `module_name` 依赖如果在 BePack 内置 catalog 中,自动写入配置 |
817
+ | 编译脚本 | manifest 中有 script 模块时自动开启 compile。根据模块 `entry` 推断源入口和输出目录:`"scripts/main.js"` → `entry: "src/main.ts"`;`"custom/app.js"` → `entry: "src/app.ts"`, `scriptOutputDir: "custom"` |
818
+ | Windows | 自动添加 `copy: { defaultTarget: "win" }" |
819
+
820
+ manifest 路径必须在当前目录内,否则报错。
821
+
822
+ 如果配置文件已存在,init 会报错提示使用 `--force` 覆盖。