Skip to content

Repository files navigation

frontend(@b1/frontend)

Biosan 前端公共资源库:基于 React + TypeScript + Antd 的组件库 Monorepo,统一管理 UI 组件、Hooks、工具函数与消息文案,并通过 dumi 自动生成在线文档。

本文档基于 2026-08 完成的一次大规模升级编写(工具链 dumi 2 / father 4 / lerna 8,运行时 React 18 + Antd 4.24)。


目录


技术栈

类别 选型
框架 React 18(^18.3.1
UI 库 Ant Design 4(^4.24.16,保持 4.x 稳定线)
语言 TypeScript
Monorepo Lerna 8(Nx 驱动)+ npm workspaces
组件/库构建 father 4(bundless + dts 生成)
文档站 dumi 2(.dumirc.ts 配置)
代码规范 ESLint(@umijs/fabric)+ Prettier + commitlint + lint-staged
提交规范 commitizen + cz-customizable

环境要求

工具 版本 说明
Node.js >=24 <25 必须 Node 24 LTS(当前推荐 24.19.0)
npm >=11 <12 Node 24 自带 npm 11

版本由 package.jsonengines 字段 + .npmrcengine-strict=true 双重强制,不满足会直接报错:

npm error notsup Required: {"node":">=24 <25","npm":">=11 <12"}

推荐用 nvm 管理

nvm install 24
nvm use 24
node -v   # v24.x

快速开始

# 1. 安装依赖(npm workspaces 会同时安装 4 个子包的依赖并建立本地软链)
npm install

# 2. 构建全部子包(lerna 编排,自动按依赖顺序:utils → components/hooks/msgs)
npm run build

# 3. 启动文档站(本地预览,默认 http://localhost:8000)
npm start

💡 若执行 npm install 时遇到 safe-delete 相关报错(WorkBuddy 等工具注入的删除保护),可临时禁用保护后执行:

env -u BASH_ENV -u CODEBUDDY_SAFE_DELETE_BIN_DIR -u CODEBUDDY_SAFE_DELETE_BULK_STATE_DIR npm install

项目结构

frontend/
├── package.json              # 根配置:workspaces、engines、scripts
├── lerna.json                # Lerna 8 配置(nx 构建编排)
├── .npmrc                    # engine-strict / legacy-peer-deps
├── .dumirc.ts                # dumi 2 文档站配置(含子包 alias)
├── docs/                     # 文档站源码(首页、指南、全局样式)
│   ├── index.md              #   首页(hero + features 支持 link 跳转)
│   ├── guide/                #   指南:快速上手 / 代码规范 / 组件开发 / 版本管理
│   └── styles/global.css     #   全局样式(苹果风 + 响应式,经 .dumirc.ts 内联注入)
├── public/                   # 静态资源(feature 背景图等,构建时拷贝到产物根)
├── packages/                 # 子包(npm workspaces)
│   ├── components/           # @b1/components   UI 组件
│   │   └── src/              #   组件源码 + index.md 文档(ColorPicker 等)
│   ├── hooks/                # @b1/hooks        React Hooks
│   ├── msgs/                 # @b1/msgs         提示用语文案
│   └── utils/                # @b1/utils        通用工具类
├── docs-dist/                # 文档站构建产物(gh-pages 部署)
└── .workbuddy/               # WorkBuddy 工作区数据(勿删,已 gitignore)

每个子包内部结构(以 utils 为例):

packages/utils/
├── package.json              # name/version/main/module/scripts
├── .fatherrc.ts              # father 4 构建配置(输出 lib/es)
├── tsconfig.json             # TS 编译配置
└── src/                      # 源码(目录即文档路由)
    ├── index.ts              # 入口
    └── common/format/        # 功能模块
        ├── index.ts
        └── index.md          # dumi 文档(frontmatter 控制路由)

子包说明

子包 npm 包名 版本 说明 构建产物
components @b1/components 1.1.28 通用公共组件(DragModal、ColorPicker、UnifiedLogin、SearchBar、SortDrag、ImageSecurity 等) lib/ + es/
hooks @b1/hooks 1.1.26 通用 React Hooks(debounce 等) lib/ + es/
msgs @b1/msgs 1.1.24 通用项目提示用语(文案常量) lib/ + es/
utils @b1/utils 1.1.25 通用工具类(format、deepClone、jsEncrypt 等) lib/ + es/

包间依赖componentshooks 依赖 @b1/utils(通过 dependencies 声明,workspaces 软链本地源码)。构建时 lerna 按 dependsOn: ^build 保证 utils 先构建。

新增组件(ColorPicker)

@b1/components 内置功能强大的颜色选择器 ColorPicker(零第三方依赖,颜色转换全手写):

  • HSV 取色面板:饱和度 × 亮度矩形 + 色相条,鼠标拖动取色(纯 CSS 渐变实现)
  • 预设色板(默认 36 色,可自定义)+ 最近使用(自动记录最近 8 个)
  • 透明度调节 + HEX / RGB / HSL 三格式输入切换 + 一键复制
  • 受控 / 非受控、allowClear(清除回传 null)、disabledsizepanelWidth
  • onChange 统一返回 { hex, rgb, hsl, alpha, rgba } 完整对象

使用示例:

import { ColorPicker } from '@b1/components';

<ColorPicker
  value={color}
  onChange={c => c && setColor(c.hex)}
  presets={['#f5222d', '#52c41a', '#1677ff']}
  showFormat="hex"
/>;

常用命令

开发

npm start              # 启动 dumi 文档站(热更新)
npm run docs:build     # 构建文档站到 docs-dist/
npm run docs:deploy    # 部署到 gh-pages(docs-dist 内容)
npm run deploy         # docs:build + docs:deploy

构建

npm run build          # 构建全部子包(lerna run build,按依赖顺序)
cd packages/utils && npx father build   # 构建单个子包
npm run clean          # 清理所有子包的 node_modules

子包 build 脚本为 father build --no-clean:跳过输出目录清理(增量覆盖),可避免 CI/工具链中 rimraf 被删除保护拦截,同时提升重复构建速度。

测试与代码规范

npm test               # 运行测试(umi-test)
npm run test:coverage  # 测试覆盖率
npm run lint           # ESLint 检查 packages/
npm run prettier       # 格式化全部代码

发布

npm run release        # 构建 + 发布全部子包到 npm(--access public)
npm run publish        # lerna publish(打 tag + 发布变更包)
npx lerna version      # 仅升级版本号 + 打 git tag

lerna.jsonversion: "independent":各子包独立版本号;command.version.exact: true:子包间依赖使用精确版本。


文档写作指南

文档采用 dumi 2 约定式路由:在子包 src/ 下写 index.md 即为该模块的文档页。

demo 直达源码(无需先构建).dumirc.tsalias@b1/components@b1/hooks@b1/utils@b1/msgs 指向各自 src/,文档里写 import { X } from '@b1/components' 会直接编译源码,新增/修改组件后刷新即可在文档站预览

首页(docs/index.md:hero + features 布局,feature 支持:

  • link 字段:点击卡片跳转对应页面(整卡可点由 global.css 的 stretched-link 实现)
  • 半透明背景图(public/ 下的 WebP,每张卡片不同,0.2 透明度水印效果)
  • 响应式:平板 2 列、手机单列(global.css 媒体查询)

frontmatter 控制页面归属(旧版 nav.path 写法已失效):

---
title: format
nav:
  path: /utils # 顶部导航(需与 .dumirc.ts 的 themeConfig.nav 对应)
group:
  title: common # 侧边栏分组
  path: /utils/common
---

# format 格式化

```js
import { formatFloat } from '@b1/utils';
console.log(formatFloat(1)); // 1.000
```

**代码块即演示**:带语言的代码块(`js`/`tsx`)会自动渲染为"示例 + 实时运行 + 可复制"的卡片,无需额外标记。

**组件 API 表格**(组件库文档用 mdx):

```mdx
<code src="./demos/basic.tsx" />

## API

<API id="Button" />

<API id="Button" /> 会自动从组件源码的 TS 类型定义提取 props 生成表格,注释即文档

⚠️ 文档配置变更点(dumi 1 → 2):

  • 配置文件:.umirc.ts.dumirc.ts
  • navsthemeConfig.nav(字段 pathlink
  • resolve.includesresolve.docDirs + resolve.atomDirs
  • locales[['zh-CN','中文']][{ id: 'zh-CN', name: '中文' }]
  • faviconfavicons(复数,数组)

工程配置说明

文件 作用
package.json workspaces: ["packages/*"] 声明子包;engines 强制 Node 24 / npm 11
.npmrc engine-strict=true 强制版本校验;legacy-peer-deps=true 跳过老包(react-captcha-code 等)的 peer 严格检查
lerna.json useNx: true 启用 Nx 编排;nx.targets.build.dependsOn: ["^build"] 保证子包按依赖顺序构建
.dumirc.ts dumi 2 文档站:title/logo/nav/atomDirs/extraBabelPlugins;alias$ 精确匹配让文档 demo 直接解析子包源码('@b1/components$': packages/components/src),改组件无需构建即可在文档站生效
public/ 静态资源目录(feature 背景图等),构建时拷贝到产物根路径,CSS 用绝对路径 /xxx.webp 引用
子包 .fatherrc.ts father 4 构建:cjs 输出 lib/esm 输出 es/、antd babel-plugin-import
子包 tsconfig.json TS 编译配置(4 个子包均已建)

💡 alias 精确匹配的原因@b1/utils 若用前缀匹配会连 less 里的 ~@b1/utils/es/styles/tokens.less 一起替换成不存在的 src/es/... 导致编译失败;$ 结尾只替换 JS 包名导入,带子路径的 less 导入仍走 node_modules 软链产物。


常见问题(FAQ)

Q1:npm installnotsup Required: {"node":">=24 <25"}
当前 Node 版本不对,用 nvm use 24 切到 Node 24。

Q2:npm install 报 peer 依赖冲突(react-captcha-code 等)?
已通过 .npmrclegacy-peer-deps=true 处理。若在 CI 中报错,确认 CI 也读取了项目 .npmrc

Q3:lerna bootstrap 不存在?
Lerna 8 已移除 bootstrap 命令(v7 起废弃),依赖管理改用 npm workspaces,直接 npm install 即可。

Q4:构建时提示 Cannot find module '@rollup/pluginutils' / esbuild 加载失败?
老锁文件导致的依赖缺失,删除 package-lock.jsonnode_modules 后重新 npm install(勿用历史遗留的 yarn.lock)。

Q5:文档站构建报 Invalid config keys: favicon/navs
这是 dumi 1 的配置写法,请按上方"文档配置变更点"迁移到 dumi 2 格式(.dumirc.ts)。

Q6:father buildDeclaration generation failed + TS 类型错误?
father 4 的 dts 生成比 father-build 1.x 严格,多为 React 18 类型差异:

  • useRef<T>()useRef<T | null>(null)
  • navigator.msSaveBlob(IE API)→ 类型断言
  • props 缺少 children → 在 interface 中补充 children?: React.ReactNode

Q7:文档站 dev 报 Element type is invalid ... got undefined
文档 demo 里 import { ColorPicker } from '@b1/components' 解析到了 lib/es 旧构建产物(新组件未构建)。已通过 .dumirc.tsalias($ 精确匹配)让 demo 直达源码解决;若仍出现,检查是否重启过 dev server。

Q8:改了 global.css / .dumirc.ts 但文档站没变化?
global.css 是在 dev server 启动时.dumirc.ts 读取内联的,修改后必须重启 npm start 才能生效(普通组件代码修改则热更新即时生效)。


升级记录

2026-08 · 大规模升级(Node 24 兼容)

说明
dumi 1.0.10 2.4.48 配置迁移至 .dumirc.ts
father-build 1.17.2 father 4.6.35 包名变更 + 子包独立配置
lerna 3.22.1 8.2.4 bootstrap 移除,改用 workspaces
react / react-dom 16.12 18.3.1 修复多处严格类型
antd 4.16.1 4.24.16 保持 4.x 稳定线(未升 5/6)
prettier 1.19.1 3.9.6
lint-staged 10.0.7 17.3.0
gh-pages 3.0.0 6.3.0

源码修复:DynamicGrid 大小写路径、DragModal children 类型、ImageSecurity/UnifiedLogin useRef、utils/download/excel IE API 类型、dynamicGrid 嵌套数组类型。

2026-08-12 · 体验升级

内容
新增组件 ColorPicker 颜色选择器(HSV 取色 / 预设色板 / 最近使用 / 透明度 / 三格式输入 / 复制,零依赖)
文档站 demo .dumirc.ts 增加 $ 精确匹配 alias,demo 直达源码免构建
首页 苹果风视觉 + 响应式(≤900px 平板 2 列 / ≤480px 手机单列)+ features 2×2 排版
首页背景 4 张哆啦A梦半透明背景图(WebP 700×300,每张 ~22KB,0.2 透明度水印效果)
首页交互 feature 卡片整卡可点击跳转(stretched-link)
全局样式 docs/styles/global.css(暗色模式、侧边栏、表格、代码块等打磨)
工程完善 测试 / lint / CI 全链路修复;public/ 静态资源目录;.workbuddy 加入 gitignore

License

MIT

About

基于umi, ts, lerna的react组件库

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages