befly 3.9.38 → 3.9.40

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 (155) hide show
  1. package/README.md +37 -38
  2. package/befly.config.ts +62 -40
  3. package/checks/checkApi.ts +16 -16
  4. package/checks/checkApp.ts +19 -25
  5. package/checks/checkTable.ts +42 -42
  6. package/docs/README.md +42 -35
  7. package/docs/{api.md → api/api.md} +223 -231
  8. package/docs/cipher.md +71 -69
  9. package/docs/database.md +143 -141
  10. package/docs/{examples.md → guide/examples.md} +181 -181
  11. package/docs/guide/quickstart.md +331 -0
  12. package/docs/hooks/auth.md +38 -0
  13. package/docs/hooks/cors.md +28 -0
  14. package/docs/{hook.md → hooks/hook.md} +140 -57
  15. package/docs/hooks/parser.md +19 -0
  16. package/docs/hooks/rateLimit.md +47 -0
  17. package/docs/{redis.md → infra/redis.md} +84 -93
  18. package/docs/plugins/cipher.md +61 -0
  19. package/docs/plugins/database.md +128 -0
  20. package/docs/{plugin.md → plugins/plugin.md} +83 -81
  21. package/docs/quickstart.md +26 -26
  22. package/docs/{addon.md → reference/addon.md} +46 -46
  23. package/docs/{config.md → reference/config.md} +32 -80
  24. package/docs/{logger.md → reference/logger.md} +52 -52
  25. package/docs/{sync.md → reference/sync.md} +32 -35
  26. package/docs/{table.md → reference/table.md} +1 -1
  27. package/docs/{validator.md → reference/validator.md} +57 -57
  28. package/hooks/auth.ts +8 -4
  29. package/hooks/cors.ts +13 -13
  30. package/hooks/parser.ts +37 -17
  31. package/hooks/permission.ts +26 -14
  32. package/hooks/rateLimit.ts +276 -0
  33. package/hooks/validator.ts +8 -8
  34. package/lib/asyncContext.ts +43 -0
  35. package/lib/cacheHelper.ts +212 -77
  36. package/lib/cacheKeys.ts +38 -0
  37. package/lib/cipher.ts +30 -30
  38. package/lib/connect.ts +28 -28
  39. package/lib/dbHelper.ts +183 -102
  40. package/lib/jwt.ts +16 -16
  41. package/lib/logger.ts +610 -19
  42. package/lib/redisHelper.ts +185 -44
  43. package/lib/sqlBuilder.ts +90 -91
  44. package/lib/validator.ts +59 -39
  45. package/loader/loadApis.ts +48 -44
  46. package/loader/loadHooks.ts +40 -14
  47. package/loader/loadPlugins.ts +16 -17
  48. package/main.ts +57 -47
  49. package/package.json +47 -45
  50. package/paths.ts +15 -14
  51. package/plugins/cache.ts +5 -4
  52. package/plugins/cipher.ts +3 -3
  53. package/plugins/config.ts +2 -2
  54. package/plugins/db.ts +9 -9
  55. package/plugins/jwt.ts +3 -3
  56. package/plugins/logger.ts +8 -12
  57. package/plugins/redis.ts +8 -8
  58. package/plugins/tool.ts +6 -6
  59. package/router/api.ts +85 -56
  60. package/router/static.ts +12 -12
  61. package/sync/syncAll.ts +12 -12
  62. package/sync/syncApi.ts +55 -52
  63. package/sync/syncDb/apply.ts +20 -19
  64. package/sync/syncDb/constants.ts +25 -23
  65. package/sync/syncDb/ddl.ts +35 -36
  66. package/sync/syncDb/helpers.ts +6 -9
  67. package/sync/syncDb/schema.ts +10 -9
  68. package/sync/syncDb/sqlite.ts +7 -8
  69. package/sync/syncDb/table.ts +37 -35
  70. package/sync/syncDb/tableCreate.ts +21 -20
  71. package/sync/syncDb/types.ts +23 -20
  72. package/sync/syncDb/version.ts +10 -10
  73. package/sync/syncDb.ts +43 -36
  74. package/sync/syncDev.ts +74 -65
  75. package/sync/syncMenu.ts +190 -55
  76. package/tests/api-integration-array-number.test.ts +282 -0
  77. package/tests/befly-config-env.test.ts +78 -0
  78. package/tests/cacheHelper.test.ts +135 -104
  79. package/tests/cacheKeys.test.ts +41 -0
  80. package/tests/cipher.test.ts +90 -89
  81. package/tests/dbHelper-advanced.test.ts +140 -134
  82. package/tests/dbHelper-all-array-types.test.ts +316 -0
  83. package/tests/dbHelper-array-serialization.test.ts +258 -0
  84. package/tests/dbHelper-columns.test.ts +56 -55
  85. package/tests/dbHelper-execute.test.ts +45 -44
  86. package/tests/dbHelper-joins.test.ts +124 -119
  87. package/tests/fields-redis-cache.test.ts +29 -27
  88. package/tests/fields-validate.test.ts +38 -38
  89. package/tests/getClientIp.test.ts +54 -0
  90. package/tests/integration.test.ts +69 -67
  91. package/tests/jwt.test.ts +27 -26
  92. package/tests/logger.test.ts +267 -34
  93. package/tests/rateLimit-hook.test.ts +477 -0
  94. package/tests/redisHelper.test.ts +187 -188
  95. package/tests/redisKeys.test.ts +6 -73
  96. package/tests/scanConfig.test.ts +144 -0
  97. package/tests/sqlBuilder-advanced.test.ts +217 -215
  98. package/tests/sqlBuilder.test.ts +92 -91
  99. package/tests/sync-connection.test.ts +29 -29
  100. package/tests/syncDb-apply.test.ts +97 -96
  101. package/tests/syncDb-array-number.test.ts +160 -0
  102. package/tests/syncDb-constants.test.ts +48 -47
  103. package/tests/syncDb-ddl.test.ts +99 -98
  104. package/tests/syncDb-helpers.test.ts +29 -28
  105. package/tests/syncDb-schema.test.ts +61 -60
  106. package/tests/syncDb-types.test.ts +60 -59
  107. package/tests/syncMenu-paths.test.ts +68 -0
  108. package/tests/util.test.ts +42 -41
  109. package/tests/validator-array-number.test.ts +310 -0
  110. package/tests/validator-default.test.ts +373 -0
  111. package/tests/validator.test.ts +271 -266
  112. package/tsconfig.json +4 -5
  113. package/types/api.d.ts +7 -12
  114. package/types/befly.d.ts +60 -13
  115. package/types/cache.d.ts +8 -4
  116. package/types/common.d.ts +17 -9
  117. package/types/context.d.ts +2 -2
  118. package/types/crypto.d.ts +23 -0
  119. package/types/database.d.ts +19 -19
  120. package/types/hook.d.ts +2 -2
  121. package/types/jwt.d.ts +118 -0
  122. package/types/logger.d.ts +30 -0
  123. package/types/plugin.d.ts +4 -4
  124. package/types/redis.d.ts +7 -3
  125. package/types/roleApisCache.ts +23 -0
  126. package/types/sync.d.ts +10 -10
  127. package/types/table.d.ts +50 -9
  128. package/types/validate.d.ts +69 -0
  129. package/utils/addonHelper.ts +90 -0
  130. package/utils/arrayKeysToCamel.ts +18 -0
  131. package/utils/calcPerfTime.ts +13 -0
  132. package/utils/configTypes.ts +3 -0
  133. package/utils/cors.ts +19 -0
  134. package/utils/fieldClear.ts +75 -0
  135. package/utils/genShortId.ts +12 -0
  136. package/utils/getClientIp.ts +45 -0
  137. package/utils/keysToCamel.ts +22 -0
  138. package/utils/keysToSnake.ts +22 -0
  139. package/utils/modules.ts +98 -0
  140. package/utils/pickFields.ts +19 -0
  141. package/utils/process.ts +56 -0
  142. package/utils/regex.ts +225 -0
  143. package/utils/response.ts +115 -0
  144. package/utils/route.ts +23 -0
  145. package/utils/scanConfig.ts +142 -0
  146. package/utils/scanFiles.ts +48 -0
  147. package/.prettierignore +0 -2
  148. package/.prettierrc +0 -12
  149. package/docs/1-/345/237/272/346/234/254/344/273/213/347/273/215.md +0 -35
  150. package/docs/2-/345/210/235/346/255/245/344/275/223/351/252/214.md +0 -64
  151. package/docs/3-/347/254/254/344/270/200/344/270/252/346/216/245/345/217/243.md +0 -46
  152. package/docs/4-/346/223/215/344/275/234/346/225/260/346/215/256/345/272/223.md +0 -172
  153. package/hooks/requestLogger.ts +0 -84
  154. package/types/index.ts +0 -24
  155. package/util.ts +0 -283
@@ -1,4 +1,4 @@
1
- # Addon 插件包开发
1
+ # Addon 插件包开发
2
2
 
3
3
  > 可复用的功能模块,包含 API、表、插件、视图
4
4
 
@@ -59,11 +59,9 @@ Addon 是 Befly 的可复用功能模块,一个 Addon 可以包含:
59
59
  │ └── email.ts # 邮件插件
60
60
  ├── views/ # 前端视图
61
61
  │ ├── login_1/ # 登录页
62
- │ │ ├── login.vue
63
- │ │ └── meta.json
62
+ │ │ └── index.vue
64
63
  │ └── permission/ # 权限管理
65
- ├── permission.vue
66
- │ └── meta.json
64
+ └── index.vue
67
65
  ├── styles/ # 样式文件
68
66
  │ └── variables.scss
69
67
  ├── package.json # 包配置
@@ -92,7 +90,8 @@ Addon 是 Befly 的可复用功能模块,一个 Addon 可以包含:
92
90
  "files": ["apis", "plugins", "styles", "tables", "views", "package.json", "README.md"],
93
91
  "keywords": ["befly", "addon"],
94
92
  "dependencies": {
95
- "befly-shared": "^1.2.0"
93
+ "befly": "^3.9.0",
94
+ "befly-vite": "^1.1.0"
96
95
  }
97
96
  }
98
97
  ```
@@ -127,14 +126,14 @@ bun init
127
126
  `apis/hello/world.ts`:
128
127
 
129
128
  ```typescript
130
- import type { ApiRoute } from 'befly/types/api.js';
129
+ import type { ApiRoute } from "befly/types/api";
131
130
 
132
131
  export default {
133
- name: 'Hello World',
134
- method: 'GET',
132
+ name: "Hello World",
133
+ method: "GET",
135
134
  auth: false,
136
135
  handler: async (befly, ctx) => {
137
- return Yes('Hello from my-addon!');
136
+ return Yes("Hello from my-addon!");
138
137
  }
139
138
  } as ApiRoute;
140
139
  ```
@@ -216,7 +215,7 @@ bun add @befly-addon/admin
216
215
 
217
216
  ```typescript
218
217
  // main.ts 或 vite.config.js
219
- import '@befly-addon/admin/styles/variables.scss';
218
+ import "@befly-addon/admin/styles/variables.scss";
220
219
  ```
221
220
 
222
221
  ---
@@ -267,29 +266,29 @@ apis/
267
266
  ### API 定义示例
268
267
 
269
268
  ```typescript
270
- import type { ApiRoute } from 'befly/types/api.js';
269
+ import type { ApiRoute } from "befly/types/api";
271
270
 
272
271
  export default {
273
- name: '管理员登录',
274
- method: 'POST',
272
+ name: "管理员登录",
273
+ method: "POST",
275
274
  auth: false,
276
- desc: '管理员邮箱密码登录',
275
+ desc: "管理员邮箱密码登录",
277
276
  fields: {
278
- email: { name: '邮箱', type: 'string', min: 5, max: 100, regexp: '@email' },
279
- password: { name: '密码', type: 'string', min: 6, max: 100 }
277
+ email: { name: "邮箱", type: "string", min: 5, max: 100, regexp: "@email" },
278
+ password: { name: "密码", type: "string", min: 6, max: 100 }
280
279
  },
281
- required: ['email', 'password'],
280
+ required: ["email", "password"],
282
281
  handler: async (befly, ctx) => {
283
282
  // 使用 addon 表时需要完整表名
284
283
  const admin = await befly.db.getDetail({
285
- table: 'addon_admin_admin',
286
- columns: ['id', 'email', 'password', 'nickname'],
284
+ table: "addon_admin_admin",
285
+ columns: ["id", "email", "password", "nickname"],
287
286
  where: { email: ctx.body.email }
288
287
  });
289
288
 
290
289
  // ... 业务逻辑
291
290
 
292
- return Yes('登录成功', { token: token });
291
+ return Yes("登录成功", { token: token });
293
292
  }
294
293
  } as ApiRoute;
295
294
  ```
@@ -325,8 +324,8 @@ export default {
325
324
  ```typescript
326
325
  // 使用完整表名
327
326
  await befly.db.getList({
328
- table: 'addon_admin_role', // addon_{name}_{table}
329
- columns: ['id', 'name', 'code']
327
+ table: "addon_admin_role", // addon_{name}_{table}
328
+ columns: ["id", "name", "code"]
330
329
  });
331
330
  ```
332
331
 
@@ -339,7 +338,7 @@ await befly.db.getList({
339
338
  `plugins/email.ts`:
340
339
 
341
340
  ```typescript
342
- import type { Plugin } from 'befly/types/plugin.js';
341
+ import type { Plugin } from "befly/types/plugin";
343
342
 
344
343
  export interface EmailConfig {
345
344
  host: string;
@@ -349,9 +348,9 @@ export interface EmailConfig {
349
348
  }
350
349
 
351
350
  const emailPlugin: Plugin = {
352
- after: ['config'], // 依赖 config 插件
351
+ after: ["config"], // 依赖 config 插件
353
352
  async handler(befly) {
354
- const config = befly.config.get('email') as EmailConfig;
353
+ const config = befly.config.get("email") as EmailConfig;
355
354
 
356
355
  return {
357
356
  async send(to: string, subject: string, html: string) {
@@ -375,10 +374,10 @@ export default emailPlugin;
375
374
  ```typescript
376
375
  // 在 API 中使用
377
376
  export default {
378
- name: '发送邮件',
377
+ name: "发送邮件",
379
378
  handler: async (befly, ctx) => {
380
- await befly.email.send(ctx.body.to, '欢迎注册', '<h1>欢迎使用</h1>');
381
- return Yes('发送成功');
379
+ await befly.email.send(ctx.body.to, "欢迎注册", "<h1>欢迎使用</h1>");
380
+ return Yes("发送成功");
382
381
  }
383
382
  } as ApiRoute;
384
383
  ```
@@ -392,27 +391,28 @@ export default {
392
391
  ```
393
392
  views/
394
393
  ├── login_1/ # 使用 layout 1
395
- ├── login.vue # 页面组件
396
- │ └── meta.json # 菜单配置
394
+ └── index.vue # 页面组件(definePage 声明菜单元信息)
397
395
  ├── permission/
398
- │ ├── permission.vue
399
- │ ├── meta.json
396
+ │ ├── index.vue
400
397
  │ ├── role/ # 子菜单
401
- │ │ ├── role.vue
402
- │ │ └── meta.json
398
+ │ │ └── index.vue
403
399
  │ └── menu/
404
- ├── menu.vue
405
- │ └── meta.json
400
+ └── index.vue
406
401
  ```
407
402
 
408
- ### meta.json 配置
403
+ ### definePage(meta) 配置
409
404
 
410
- ```json
411
- {
412
- "name": "权限管理",
413
- "icon": "Shield",
414
- "sort": 10
415
- }
405
+ 在 `views/**/index.vue` 中使用 `definePage()` 声明菜单元信息:
406
+
407
+ ```vue
408
+ <script setup>
409
+ definePage({
410
+ meta: {
411
+ title: "权限管理",
412
+ order: 10
413
+ }
414
+ });
415
+ </script>
416
416
  ```
417
417
 
418
418
  ### 目录命名规则
@@ -474,8 +474,8 @@ A: 使用 `befly sync:db` 命令,会自动同步所有 Addon 的表定义。
474
474
  A: 通过 `befly.config` 访问:
475
475
 
476
476
  ```typescript
477
- const dbConfig = befly.config.get('db');
478
- const customConfig = befly.config.get('myAddon');
477
+ const dbConfig = befly.config.get("db");
478
+ const customConfig = befly.config.get("myAddon");
479
479
  ```
480
480
 
481
481
  ### Q: Addon 之间可以互相依赖吗?
@@ -24,9 +24,8 @@
24
24
  - [环境变量](#环境变量)
25
25
  - [完整配置示例](#完整配置示例)
26
26
  - [befly.common.json](#beflycmmonjson)
27
- - [befly.dev.json](#befldevjson)
28
- - [befly.prod.json](#beflprodjson)
29
- - [befly.local.json](#befllocaljson)
27
+ - [befly.development.json](#beflydevelopmentjson)
28
+ - [befly.production.json](#beflyproductionjson)
30
29
  - [访问配置](#访问配置)
31
30
  - [最佳实践](#最佳实践)
32
31
  - [常见问题](#常见问题)
@@ -54,16 +53,16 @@ Befly 配置系统采用分层配置设计,支持环境分离和本地覆盖
54
53
  配置文件存放在项目根目录的 `configs/` 目录下:
55
54
 
56
55
  ```
57
- 项目根目录/
56
+ // befly.development.json
58
57
  └── configs/
59
58
  ├── befly.common.json # 通用配置(所有环境共享)
60
- ├── befly.dev.json # 开发环境配置
61
- ├── befly.prod.json # 生产环境配置
62
- └── befly.local.json # 本地配置(不提交到 Git)
59
+ ├── befly.development.json # 开发环境配置
60
+ └── befly.production.json # 生产环境配置
63
61
  ```
64
62
 
65
63
  ### 加载优先级
66
64
 
65
+ // befly.production.json
67
66
  配置按以下顺序加载,后加载的覆盖先加载的:
68
67
 
69
68
  ```
@@ -71,15 +70,13 @@ Befly 配置系统采用分层配置设计,支持环境分离和本地覆盖
71
70
 
72
71
  befly.common.json(通用配置)
73
72
 
74
- befly.dev.json 或 befly.prod.json(环境配置)
75
-
76
- befly.local.json(本地配置,最高优先级)
73
+ befly.development.json 或 befly.production.json(环境配置)
77
74
  ```
78
75
 
79
76
  **环境判断**:
80
77
 
81
- - `NODE_ENV=production` → 加载 `befly.prod.json`
82
- - 其他情况 → 加载 `befly.dev.json`
78
+ - `NODE_ENV=production` → 加载 `befly.production.json`
79
+ - 其他情况 → 加载 `befly.development.json`
83
80
 
84
81
  ### 合并规则
85
82
 
@@ -95,7 +92,7 @@ befly.local.json(本地配置,最高优先级)
95
92
  }
96
93
  }
97
94
 
98
- // befly.local.json
95
+ // befly.development.json
99
96
  {
100
97
  "db": {
101
98
  "password": "local_password"
@@ -393,7 +390,7 @@ NODE_ENV=production bun run start
393
390
  }
394
391
  ```
395
392
 
396
- ### befly.dev.json
393
+ ### befly.development.json
397
394
 
398
395
  开发环境配置:
399
396
 
@@ -418,7 +415,7 @@ NODE_ENV=production bun run start
418
415
  }
419
416
  ```
420
417
 
421
- ### befly.prod.json
418
+ ### befly.production.json
422
419
 
423
420
  生产环境配置:
424
421
 
@@ -443,51 +440,13 @@ NODE_ENV=production bun run start
443
440
  }
444
441
  ```
445
442
 
446
- ### befly.local.json
447
-
448
- 本地配置(不提交到 Git):
449
-
450
- ```json
451
- {
452
- "db": {
453
- "password": "my_local_password"
454
- },
455
-
456
- "redis": {
457
- "password": "my_redis_password"
458
- },
459
-
460
- "auth": {
461
- "secret": "my-super-secret-key-for-local-development"
462
- },
463
-
464
- "addons": {
465
- "admin": {
466
- "email": {
467
- "user": "my-email@qq.com",
468
- "pass": "my-auth-code"
469
- }
470
- }
471
- }
472
- }
473
- ```
474
-
475
- **注意**:将 `befly.local.json` 添加到 `.gitignore`:
476
-
477
- ```gitignore
478
- # 本地配置
479
- configs/befly.local.json
480
- ```
481
-
482
- ---
483
-
484
443
  ## 访问配置
485
444
 
486
445
  ### 在 API 中访问
487
446
 
488
447
  ```typescript
489
448
  export default {
490
- name: '示例接口',
449
+ name: "示例接口",
491
450
  handler: async (befly, ctx) => {
492
451
  // 通过 befly.config 访问配置
493
452
  const appName = befly.config.appName;
@@ -497,7 +456,7 @@ export default {
497
456
  // 访问 Addon 配置
498
457
  const emailConfig = befly.config.addons?.admin?.email;
499
458
 
500
- return befly.tool.Yes('成功', { appName: appName });
459
+ return befly.tool.Yes("成功", { appName: appName });
501
460
  }
502
461
  };
503
462
  ```
@@ -505,7 +464,7 @@ export default {
505
464
  ### 在插件中访问
506
465
 
507
466
  ```typescript
508
- import { beflyConfig } from '../befly.config.js';
467
+ import { beflyConfig } from "../befly.config.js";
509
468
 
510
469
  const plugin: Plugin = {
511
470
  handler: () => {
@@ -516,10 +475,15 @@ const plugin: Plugin = {
516
475
  };
517
476
  ```
518
477
 
519
- ### 直接导入
478
+ ### 直接导入(仅 Befly 源码/单仓内)
479
+
480
+ > 说明:`befly` 包的 `exports` 仅暴露 `befly`、`befly/lib/*`、`befly/utils/*`、`befly/types/*`。
481
+ > 因此不支持 `befly/befly.config` 这种子路径导入。
482
+
483
+ 如果你在 Befly 源码/单仓内开发(例如编写内置插件/命令),可以使用相对路径导入:
520
484
 
521
485
  ```typescript
522
- import { beflyConfig } from 'befly/befly.config';
486
+ import { beflyConfig } from "../befly.config.js";
523
487
 
524
488
  console.log(beflyConfig.appName);
525
489
  ```
@@ -528,31 +492,21 @@ console.log(beflyConfig.appName);
528
492
 
529
493
  ## 最佳实践
530
494
 
531
- ### 1. 敏感信息放 local 配置
495
+ ### 1. 敏感信息使用环境变量
532
496
 
533
- ```json
534
- // ✅ befly.local.json(不提交)
535
- {
536
- "db": { "password": "real_password" },
537
- "auth": { "secret": "real_secret" },
538
- "redis": { "password": "real_password" }
539
- }
497
+ 不建议在 `configs/*.json` 中保存明文密码/密钥(这些文件通常会被提交)。
540
498
 
541
- // befly.common.json(会提交)
542
- {
543
- "db": { "password": "real_password" }
544
- }
545
- ```
499
+ 推荐做法:通过环境变量注入敏感信息(本地用 `.env`,部署用平台的 Secret/环境变量管理)。
546
500
 
547
501
  ### 2. 环境差异放环境配置
548
502
 
549
503
  ```json
550
- // befly.dev.json
504
+ // befly.development.json
551
505
  {
552
506
  "logger": { "debug": 1, "console": 1 }
553
507
  }
554
508
 
555
- // befly.prod.json
509
+ // befly.production.json
556
510
  {
557
511
  "logger": { "debug": 0, "console": 0 }
558
512
  }
@@ -583,7 +537,7 @@ console.log(beflyConfig.appName);
583
537
  ### 5. 生产环境关闭调试
584
538
 
585
539
  ```json
586
- // befly.prod.json
540
+ // befly.production.json
587
541
  {
588
542
  "logger": {
589
543
  "debug": 0,
@@ -607,16 +561,14 @@ console.log(beflyConfig.appName);
607
561
 
608
562
  ```typescript
609
563
  // 在 API 中打印
610
- befly.logger.info({ config: befly.config }, '当前配置');
564
+ befly.logger.info({ config: befly.config }, "当前配置");
611
565
  ```
612
566
 
613
567
  ### Q3: local 配置被提交了?
614
568
 
615
- 添加到 `.gitignore`:
569
+ 不再使用“本地覆盖配置文件”。
616
570
 
617
- ```gitignore
618
- configs/befly.local.json
619
- ```
571
+ 如果你发现敏感配置被提交:请改为环境变量注入,并在仓库层面避免提交 `.env`、密钥文件等。
620
572
 
621
573
  ### Q4: 如何动态修改配置?
622
574
 
@@ -630,7 +582,7 @@ configs/befly.local.json
630
582
  // befly.common.json
631
583
  { "disableHooks": ["hook1"] }
632
584
 
633
- // befly.local.json
585
+ // befly.production.json
634
586
  { "disableHooks": ["hook2"] }
635
587
 
636
588
  // 最终结果