SuperAPI AI 工具集

fe-modularization

前端与建站

查看项目

更新于 10-16 00:29

技能介绍

用途:为 Metabase 前端代码确定“代码应该住在哪里”,并规范模块间依赖、迁移与副作用边界。核心目标是让文件位置真实反映概念归属与依赖方向。

分层模型:lib < basic < shared < feature < app,导入只能向下;feature 之间禁止互相导入;app 与 EE 可导入任意层。shared 细分为 shared-utils、shared-platform、shared-domain,各级内部再分 level,只允许导入严格更低的 level,同级禁止,从结构上避免循环依赖。

强制与配置:frontend/lint/module-boundaries.mjs 定义模块元素、层级、enforceSharedTiers、enforcePublicApi;shared-tiers.mjs 定义 shared 子层与 level。enforcePublicApi: true 的模块只能通过 metabase/<module> 从外部导入,模块内部用相对路径。新模块默认 enforcePublicApi: true 并带显式 index.ts。

公共 API 硬规则:不得在老路径保留 export … from 再导出,不得用 export * 桶导出;搬迁需在同一 PR 内移动代码、codemod 全部调用点、删除老路径。不得绕过模块 index.ts 直接深层导入;桶过重时应让模块无副作用,而不是深层导入。不得为通过 lint 而把消费者改写成更差写法。

副作用:SIDE_EFFECT_FREE_PATHS 中的目录被标记 sideEffects: false,代价是这些目录内不得在导入时执行任何工作,metabase/no-module-side-effects 规则会检查。必须在导入时运行的文件列入 SIDE_EFFECT_PATHS。库外观模块(metabase/router、metabase/ui、metabase/redux、metabase/dayjs)拥有 vendor 导入与注册,禁止在别处直接使用原始说明符。

扩展点与状态:接口由 socket 所有者定义,插件随扩展方放置;优先使用 props/注入,PLUGIN_* 注册表用于版本门控。有 redux state 的模块自己持有 store/(私有 reducer、selectors、actions),桶导出即状态 API;禁止裸 dispatch({ type: "…" })。端点通过 Api.injectEndpoints 迁到所属模块的 api/ 文件,消费者只经所有者导出访问。

迁移流程:先用 grep 枚举消费者并分类层级,做 consumer-tier 检查(目标必须在最低消费者同层或更低),记录 bun run module-boundaries 基线;然后 git mv、改所有导入、加具名导出、删老路径,再运行 lint、type-check、单测和 module-boundaries 验证并报告前后数量。

限制与陷阱:晚绑定(createSelector 输入数组中的裸函数引用、模块作用域读取 PLUGIN_*)会绕过 jest spy、EE 覆盖与懒加载;计划易过期,执行前须核对当前代码;linter 对再导出、裸说明符包、预置缓存有盲区,grep 老路径比通过 lint 更可靠;重桶在模块无副作用前是打包风险。文件路径变化会重置基于路径的基线。具体收费、价格与平台信息资料未提供。