0%

biu:biu biu 一下,一键生成企业级前端基座

谨以此文向教员致敬,纪念教员逝世 50 周年。缅怀伟人!对我们这一代而言,学习不仅是回望,更是把认真、独立和长期主义落实到每天的生活中。雄关漫道真如铁,而今迈步从头越。

写在前面

  有些影响并不总是以宏大的声音抵达普通人的生活。它更像一盏放在远处的灯:让许多人第一次知道,出身并不能替一个人写完一生,平凡的日子也可以有自己的方向;让人愿意在困顿里保留一点清醒,在选择面前多问一句“为什么”,在无人注视的地方仍把手上的事情认真做完。这样的分量,未必需要被反复说明,却会在一代又一代人的生活里留下回声。

  谨记这份朴素而持久的力量。做前端项目的时间越久,越容易遇到一个共同问题:每个业务项目都在重复搭建登录、菜单、权限、路由、标签页、国际化、主题、错误页和发布脚本。团队规模变大以后,不同项目还会形成不同的控制方式,页面体验和工程规范很难真正统一。

  biu 就是为解决这类问题而设计的企业级前端基座。它把稳定、通用的基础能力沉淀为可复用的包,把项目差异留给业务开发者:项目只需要维护页面、菜单配置、环境配置和业务逻辑,就可以获得一套完整的应用外壳与交付流程。

biu 是什么

  biu 是一个基于 Node.js、pnpm、TypeScript、Rsbuild/Rspack 的模块化前端基座。它不绑定单一业务领域,也不要求所有历史项目重写成同一种技术栈,而是通过清晰的运行时协议和适配器,让新项目与旧项目都能接入同一套基础规范。

它的核心目标可以概括为一句话:

让团队用一套可理解、可扩展、可审计的基座能力,持续交付不同技术栈的前端应用。

四种项目形态

biu 将应用边界和基座能力分开,支持四种实际开发形态:

  1. Portal A:Sidebar 门户。适合左侧多级目录、面包屑、多标签页和远程 APP 的企业后台。
  2. Portal B:Topbar 门户。适合顶部多目录横向布局、工具栏插槽和门户切换场景。
  3. 独立 APP。使用官方 preset 的独立子应用,可独立启动、构建、部署和绑定域名,支持 React、Vue、HTML 等技术栈。
  4. React Custom。由业务项目完全定义页面和外壳,只复用登录开关、错误兜底、路由、事件、更新检查以及 Modal、Drawer、Tooltip 等基座能力。

Portal 与 APP 是同级项目,不把子应用源码编译进门户。它们可以独立开发、独立发布、独立回滚,也可以通过环境配置组成完整的企业应用网络。

生产 Demo:一套基座,六个独立交付单元

下面这套 Demo 展示了 biu 的真实部署边界:两个门户负责导航和业务编排,React/Vue/HTML/Custom 应用分别作为独立项目交付。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
flowchart TB
Dev[开发者] --> CLI[biu CLI]
CLI --> PortalA[Portal A\nSidebar\nbiu-a.biugle.cn]
CLI --> PortalB[Portal B\nTopbar\nbiu-b.biugle.cn]
PortalA --> React[React APP\nbiu-s.biugle.cn]
PortalA --> Vue[Vue APP\nbiu-vue.biugle.cn]
PortalB --> React
PortalB --> Vue
Dev --> CI[GitHub Actions\nCI / Changesets / npm]
Dev --> Vercel[Vercel Native Git]
Vercel --> PortalA
Vercel --> PortalB
Vercel --> React
Vercel --> Vue
Vercel --> HTML[HTML APP\nbiu-html.biugle.cn]
Vercel --> Custom[React Custom\nbiu-custom.biugle.cn]

Portal A:侧栏门户

Portal A 侧栏门户

Portal A 负责展示完整的企业后台体验:多级目录、菜单选中态、面包屑、多标签页、收藏、新开标签页、主题和语言切换都由基座统一管理。业务页面只通过菜单 Code 和路由配置接入,不需要重复实现这些基础交互。

Portal B:顶部多目录门户

Portal B 顶部多目录门户

Portal B 使用另一种布局表达同一套能力:多个目录可以横向平铺,菜单按照内容自适应,在空间不足时使用统一的省略和滚动策略;窄屏则切换为多级下拉选择。两种门户视觉布局不同,但登录、权限、路由、标签页、工具栏、弹窗和错误兜底仍然来自同一个基座。

统一的基础能力

1. 菜单、路由与权限边界

菜单路径与 URL 路径保持一致,目录层级也会体现在 URL 中。这让页面分享、刷新恢复和后端权限判断都有稳定依据:

1
/enterprise-operations-center/security-compliance/ComplianceReport

CLI 会根据菜单和权限白名单发现页面,并生成按页面拆分的动态入口。未被当前配置选中的页面不会进入依赖图,既减少产物体积,也让权限边界更容易审计。

业务项目只需要描述菜单和本地路由,不需要手工维护一套与菜单不同的前端路径:

1
2
3
4
5
6
7
8
9
10
11
12
13
// local-routes/index.ts
import type { MenuNode } from "@biugle/biu-router";

export const routes: MenuNode[] = [
{
code: "ComplianceReport",
type: "MENU",
path: "/enterprise-operations-center/security-compliance/ComplianceReport",
target: "PORTAL",
titleKey: "Enterprise Security Compliance Report Overview",
permissionCode: "security-compliance:report:view",
},
];

这种“菜单 Code、URL、页面注册、权限标识”相互可追踪的设计,特别适合需要审计和长期维护的企业后台。

2. 跨框架接入

业务团队可以继续使用现有技术栈。React、Vue 3、原生 HTML 和独立 React Custom Demo 都可以接入基座,不要求把历史项目一次性迁移。跨应用通信使用明确的 Bridge 和事件协议,基座不会把 Token、Cookie 或任意 DOM 内容塞进通信消息。

应用之间可以发布业务事件,而不必互相依赖组件实现:

1
2
3
4
5
6
7
8
import { biuEventBus } from "@biugle/biu-events";

const unsubscribe = biuEventBus.subscribe("order:created", (event) => {
console.log("刷新订单摘要", event.payload.orderId);
});

biuEventBus.publish("order:created", { orderId: "order-20260909-001" }, "order-service");
unsubscribe();

跨窗口场景再通过 Bridge 传递经过约束的消息,来源地址必须经过白名单校验。这样既能支持异构应用协作,也不会把业务页面绑死在某一个框架的状态管理实现上。

3. 布局能力可控制

应用可以通过 Context 和配置控制菜单、右侧工具区、多标签页、面包屑等基座区域。例如报表页面可以默认收起菜单,沉浸式页面可以隐藏面包屑;这些控制是页面级临时状态,离开页面后自动恢复,不会污染全局布局。

1
2
3
4
5
6
7
8
9
10
11
import { useBiuLayoutControl } from "@biugle/biu-runtime";

export function ReportPage() {
const { setLayoutOverrides } = useBiuLayoutControl();

useEffect(() => {
setLayoutOverrides({ hideSidebar: true, hideBreadcrumb: true });
}, [setLayoutOverrides]);

return <Report />;
}

4. 基座 UI 与 fire

Message、Tooltip、Drawer、Modal、复制文本、文本省略等高频能力由基座统一提供。fire 是独立的挂载方法,可以把 Modal、Drawer 或业务自定义内容直接挂载到 body,业务页面不必依赖某个门户的 DOM 层级:

1
2
3
4
5
6
7
8
9
import { fire, modal } from "@biugle/biu-ui";

const handle = fire(modal)({
title: "自定义确认",
children: <div>这里的内容完全由业务项目定义。</div>,
});

// 需要时关闭本次挂载
handle.close();

基座 UI 组件案例

5. 自定义工具栏和插槽

门户保留了稳定的默认布局工具栏,同时开放导航栏和内容区域插槽。自定义工具可以紧邻语言切换区域排列,也可以根据 Portal A/B 的布局策略只显示文本、只显示图标或同时显示两者。插槽内容由项目传入,基座负责位置、响应式和最大宽度控制。

门户工具栏和菜单案例

项目可以向门户插槽传入自己的操作,但默认布局仍由基座接管:

1
2
3
4
5
6
7
export default {
appId: "main-a",
projectType: "PORTAL",
portalSlots: { source: "./src/portal-slots.tsx" },
layout: { preset: "sidebar", tabs: true, breadcrumb: true },
menu: { fallback: true },
};

工程化:从创建到发布的一条链路

CLI 一键创建

新项目通过 CLI 选择 Portal、独立 APP 或 Custom 模式,按照引导完成项目数量、认证、菜单来源、端口和插槽配置。生成项目自带 TypeScript、ESLint、Prettier、EditorConfig、Husky/lint-staged 和 .gitignore,业务团队可以直接进入页面开发。

1
2
3
pnpm dlx @biugle/biu-cli init
pnpm install
pnpm start --filter main-a

Rsbuild/Rspack 构建

构建过程由 CLI 统一编排,Rsbuild/Rspack 负责开发服务、代码分割、内容 Hash 和生产产物。每个页面只生成自己的 chunk,静态资源具备可追踪的 manifest 和 buildId;HTML 与 manifest 使用短缓存或 no-cache,静态资源则使用内容 Hash,降低发布后服务器和 CDN 缓存造成的旧资源问题。

1
2
3
4
5
6
7
pnpm check
pnpm test
pnpm lint
pnpm format:check
pnpm audit:unused # Knip:无用文件、依赖、导出和引用审计
pnpm verify:scenarios # CLI 场景回归
pnpm build:demo:all

项目自身不需要维护复杂的 webpack 入口。CLI 会根据项目配置生成临时入口,基座包从统一出口导出,Rsbuild 只负责把业务页面和基础运行时编译成可部署的静态产物。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// biu.config.ts
export default {
appId: "main-a",
projectType: "PORTAL",
framework: "react",
portal: { code: "main-a", menuRootCode: "portal-main-a" },
layout: { preset: "sidebar", tabs: true, breadcrumb: true },
menu: { fallback: true },
remoteApps: {
"child-app": {
APP_URL: "https://biu-s.biugle.cn",
ALLOWED_ORIGINS: ["https://biu-s.biugle.cn"],
},
},
};

Changesets 与 GitHub Actions

公开包使用 Changesets 管理版本和 CHANGELOG。开发者提交 changeset 后,GitHub Actions 自动创建或更新 Release PR;合并后执行构建、测试和 npm 发布。当前公开包包括 CLI、i18n、events、bridge、router、store、ui、runtime、preset 和 React adapter。

1
2
3
pnpm changeset
pnpm version-packages
pnpm release

发布流程不要求把 npm Token 写进代码或 Vercel。npm granular token 只配置在 GitHub Actions Secret 中,Demo 则通过 Vercel Native Git 分别部署到自己的 Project 和域名。

更新检查与缓存策略

每次构建都会生成带内容 Hash 的静态资源和 build manifest。Runtime 首次启动建立当前版本基线,随后在用户导航等明确动作时最多检查一次;它不会轮询,也不会擅自刷新用户正在编辑的页面。发现新的 buildId 后,通过统一 Message 提示用户,由用户决定是否重新加载。

1
2
3
4
5
6
7
import { createBiuUpdateChecker } from "@biugle/biu-runtime";

const checker = createBiuUpdateChecker("/manifest/routes.json", () => {
showMessage("检测到新版本,请刷新页面");
});
await checker.initialize();
await checker.check();

这种设计把“npm 依赖升级”和“线上静态资源更新”分成两条链路:前者由 Changesets 管理,后者由 manifest/buildId 管理。HTML 和 manifest 使用短缓存或 no-cache,带 Hash 的 JS/CSS 保留长缓存,发布时保留上一版本静态资源以降低切换期间的 404 风险。

部署方案:从 Demo 到生产

biu 输出标准静态 dist 目录,因此可以按团队现有基础设施选择部署方式。门户和子应用建议分别构建、分别部署、分别绑定域名。

方案一:Vercel Native Git

适合 Demo、预览环境和轻量生产环境。将同一个 GitHub 仓库创建为多个 Vercel Project,每个 Project 指向一个应用:

1
2
3
4
5
6
Root Directory: ./
Framework Preset: Other
Node.js: 22
Install Command: pnpm install --frozen-lockfile
Build Command: pnpm build && pnpm --filter main-a biu build --all --env prod
Output Directory: examples/dev-demo/apps/main-a/dist

Portal A、Portal B、React、Vue、HTML 和 Custom 分别使用对应的 filter 和 dist 目录。配置完成后,Pull Request 自动生成 Preview,推送 main 自动生产部署;这种模式不需要 VERCEL_TOKENVERCEL_ORG_ID。详细配置见 Vercel 部署指南

方案二:GitHub Actions / GitLab CI

GitHub Actions 负责 CI 门禁、Changesets 和 npm 发布,也可以把构建后的 dist 上传到对象存储、CDN 或自有服务器。npm Token 只能保存为仓库 Secret;GitLab 使用同等作用的 CI/CD Variable,并设置为 Masked、Protected。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# .github/workflows/build-demo.yml
name: Build demo
on:
push:
branches: [main]

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
with: { version: 9.14.4 }
- uses: actions/setup-node@v4
with: { node-version: 22, cache: pnpm }
- run: pnpm install --frozen-lockfile
- run: pnpm --filter main-a biu build --all --env prod
- uses: actions/upload-artifact@v4
with:
name: portal-a-dist
path: examples/dev-demo/apps/main-a/dist

GitLab CI 可以使用同样的构建命令:

1
2
3
4
5
6
7
8
9
10
11
12
# .gitlab-ci.yml
build:portal-a:
image: node:22
before_script:
- corepack enable
- corepack prepare pnpm@9.14.4 --activate
- pnpm install --frozen-lockfile
script:
- pnpm --filter main-a biu build --all --env prod
artifacts:
paths:
- examples/dev-demo/apps/main-a/dist

方案三:Docker + Nginx

如果部署环境是 Kubernetes、虚拟机或内网服务器,可以用多阶段构建生成静态产物,再交给 Nginx 提供服务。关键点是 SPA 深层路由必须回退到 index.html

1
2
3
4
5
6
7
8
9
10
FROM node:22-alpine AS builder
WORKDIR /workspace
RUN corepack enable && corepack prepare pnpm@9.14.4 --activate
COPY . .
RUN pnpm install --frozen-lockfile
RUN pnpm build && pnpm --filter main-a biu build --all --env prod

FROM nginx:alpine
COPY --from=builder /workspace/examples/dev-demo/apps/main-a/dist /usr/share/nginx/html
COPY deploy/nginx.conf /etc/nginx/conf.d/default.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
server {
listen 80;
root /usr/share/nginx/html;
index index.html;

location / {
try_files $uri $uri/ /index.html;
}

location ~* \.(js|css|png|svg|woff2)$ {
add_header Cache-Control "public, max-age=31536000, immutable";
}

location = /index.html {
add_header Cache-Control "no-cache";
}
}

生产环境还应补充 HTTPS、CSP、压缩、健康检查、灰度和回滚策略。无论采用哪种平台,都不要把 Token、Cookie、用户数据或内部接口密钥写入前端产物。

核心能力矩阵

能力层biu 提供什么业务项目负责什么
运行时登录注册、错误兜底、更新检查、生命周期认证接口、用户数据和业务页面
导航菜单、路由、权限标识、标签页、面包屑菜单 Code、页面路径和权限配置
布局Sidebar、Topbar、响应式、工具栏和插槽品牌信息和自定义工具
通信Event Bus、Bridge、路由参数和上下文业务事件名称与数据契约
UIMessage、Tooltip、Modal、Drawer、fire、复制和省略表单内容、业务交互和领域组件
工程CLI、Rsbuild、TypeScript、Knip、Changesets业务代码、环境变量和发布审批

这样的分层让“基座稳定”和“项目自由”同时成立:基座维护跨项目的一致性,项目维护真正属于自己的业务语义。

最小接入路径

从一个已有 React 项目接入 biu,不需要先重写全部页面。可以按下面的顺序渐进迁移:

1
2
3
4
5
6
1. 安装 @biugle/biu-cli 与所需运行时包
2. 生成 biu.config.ts 和 local-routes/index.ts
3. 将已有页面映射到菜单 Code 与完整 URL
4. 先启用默认 Layout,再逐个替换业务导航
5. 接入事件、UI 和错误兜底能力
6. 通过 check、test、build 完成首次交付

对于 Vue、HTML 和 Custom 项目,接入重点从 React 组件变为协议和运行时能力;这正是适配器层的意义:项目可以保留自己的渲染方式,团队仍然共享同一份导航、通信、发布和治理规范。

React Custom:不是 iframe,而是独立项目

React Custom 独立项目案例

React Custom 是一个独立 React 项目,不是把页面嵌套进门户的 iframe。它可以完全自定义页面、路由和布局,只按需引用 biu 的公共能力;登录、注册、首页、错误页等基础兜底能力可以启用,也可以由项目配置关闭并自行实现。

这种模式适合希望保留自身产品体验、但仍需要统一事件、路由、更新检查、弹窗和工程规范的团队。它把“技术栈自由”和“基础能力统一”放在了同一条交付链路上。

为什么值得使用

  • 兼容存量系统:React、Vue、HTML 和自定义项目都可以接入,渐进式迁移而不是推倒重来。
  • 统一用户体验:菜单、标签页、面包屑、主题、多语言和反馈组件保持一致。
  • 统一团队规范:CLI、TypeScript、Rsbuild、ESLint、Prettier、Husky、Knip 和 Changesets 形成可审计流程。
  • 独立交付:门户与子应用拥有独立端口、产物、域名、发布和回滚边界。
  • 可扩展但不绑死:官方 Layout 提供开箱即用体验,Custom 模式保留业务自主定义空间。
  • 面向企业治理:路由层级、权限 Code、buildId、manifest 和发布记录都可追踪,便于排查与回滚。

结语

  技术基座的价值,不只是少写几个组件,而是让团队在不断扩张、不断接入新旧系统的过程中,仍然保持清晰的边界和稳定的交付节奏。biu 希望把这些被反复验证的基础能力沉淀下来,让业务团队专注于真正有差异化的产品页面。

  从一条 CLI 命令开始,选择合适的项目形态,接入已有技术栈,按统一规则开发、构建和发布——biu biu 一下,一键生成企业级前端基座。

项目地址:github.com/biugle/biu

bulb