@pt/cross-bridge
一个强大的跨域通信插件,支持独立标签页、iframe、完全跨域等多种通信场景。
📚 详细文档
为了帮助你更好地理解和使用 CrossBridge,我们准备了详细的文档指南。建议按以下顺序阅读:
- 📖 00_PROJECT_STATUS.md (项目总览) - 必读!了解项目当前的能力地图和状态。
- 🎯 01_REQUIREMENTS.md (需求规格) - 了解项目的背景、目标和核心需求。
- 🏗️ 02_ARCHITECTURE.md (架构设计) - 深入了解系统的分层架构和设计原理。
- 🔧 03_TECHNICAL_DESIGN.md (技术实现) - 查看具体的技术实现细节和代码结构。
- 💻 04_USAGE_EXAMPLES.md (全场景示例) - 核心!涵盖同域、跨域、iframe 等所有场景的代码示例。
- 📄 05_SINGLE_PAGE_GUIDE.md (单页指南) - 专为单页应用 (
index.html) 设计的快速上手指南。 - ⚡ 06_PERFORMANCE.md (性能优化) - 进阶阅读,了解如何进行性能调优。
✨ 特性
- 🚀 多种通信方式: 支持 SharedWorker、PostMessage、WebRTC P2P、WebSocket 中继等
- 🎯 智能路由: 根据通信场景和数据特征自动选择最优通信方式
- 📦 消息队列: 支持消息缓存和延迟消费,解决页面未加载问题
- 🔄 页面角色管理: 支持页面的多种角色(父页面、子页面、独立页面、混合角色)
- 🌐 完全跨域: 支持不同一级域名间的通信
- ⚡ 高性能: 同域通信延迟 < 1ms,跨域 P2P 延迟 < 50ms
- 🛠️ TypeScript: 完整的类型定义支持
- 🔧 易于集成: 与 mitt 等事件系统无缝集成
📦 安装
bash
# 使用 pnpm
pnpm add @pt/cross-bridge
# 使用 npm
npm install @pt/cross-bridge
# 使用 yarn
yarn add @pt/cross-bridge🚀 快速开始
基础使用
typescript
import { CrossBridge } from '@pt/cross-bridge';
// 创建 CrossBridge 实例
const bridge = new CrossBridge({
pageId: 'main-page',
role: 'parent',
adapters: ['shared-worker', 'post-message'],
debug: true,
});
// 连接
await bridge.connect();
// 监听消息
bridge.on('data-updated', (data, from) => {
console.log(`收到来自 ${from} 的数据:`, data);
});
// 发送消息
bridge.emit('user-action', { type: 'click', target: 'button' });
// 广播消息
bridge.broadcast('theme-changed', { theme: 'dark' });
// 发送给特定页面
bridge.sendTo('child-page', 'command', { action: 'refresh' });主页面(包含 iframe)
typescript
const mainBridge = new CrossBridge({
pageId: 'main-page',
role: 'parent',
adapters: ['shared-worker', 'post-message'],
});
await mainBridge.connect();
// 注册 iframe 页面
mainBridge.registerPage('data-analysis', {
role: 'child',
type: 'iframe',
origin: 'http://console-dev1.e-tudou.com',
domain: 'console-dev1.e-tudou.com',
element: document.getElementById('data-iframe'),
capabilities: ['data-processing'],
});
// 监听子页面消息
mainBridge.on('data-updated', (data, from) => {
console.log(`数据更新来自 ${from}:`, data);
// 转发给其他页面
mainBridge.sendTo('agent-chat', 'external-data-change', data);
});iframe 子页面
typescript
const childBridge = new CrossBridge({
pageId: 'data-analysis',
role: 'child',
adapters: ['post-message'],
});
await childBridge.connect();
// 监听父页面消息
childBridge.on('theme-changed', (themeData) => {
document.body.className = `theme-${themeData.theme}`;
});
// 向父页面发送数据
childBridge.emit('data-updated', {
type: 'analysis-result',
data: { result: 'success', count: 100 },
timestamp: Date.now(),
});独立标签页
typescript
const tabBridge = new CrossBridge({
pageId: 'standalone-tab-1',
role: 'standalone',
adapters: ['shared-worker'],
});
await tabBridge.connect();
// 监听其他标签页消息
tabBridge.on('user-login', (userInfo) => {
console.log('用户登录:', userInfo);
syncUserState(userInfo);
});
// 发送消息给主页面
tabBridge.sendTo('main-page', 'tab-action', {
action: 'file-selected',
fileId: '12345',
});单页应用使用
CrossBridge 完全支持在单个 HTML 页面中使用,特别适合以下场景:
1. 被 iframe 内嵌的子页面
html
<!DOCTYPE html>
<html>
<head>
<title>我的功能页面</title>
</head>
<body>
<h1>简单功能页面</h1>
<button id="action-btn">执行操作</button>
<!-- 引入 CrossBridge -->
<script src="./dist/cross-bridge.umd.js"></script>
<script>
// 初始化为子页面角色
const bridge = new CrossBridge({
pageId: 'my-feature-page',
role: 'child', // 子页面角色
adapters: ['post-message', 'shared-worker'],
debug: true,
});
// 连接
bridge.connect().then(() => {
console.log('子页面已连接到 CrossBridge');
});
// 监听来自父页面的消息
bridge.on('parent-message', (data) => {
console.log('收到父页面消息:', data);
});
// 向父页面发送消息
document.getElementById('action-btn').addEventListener('click', () => {
bridge.emit('child-action', {
action: 'button-click',
timestamp: Date.now(),
pageId: bridge.pageId,
});
});
</script>
</body>
</html>2. 独立部署的功能页面
html
<!DOCTYPE html>
<html>
<head>
<title>独立功能页面</title>
</head>
<body>
<h1>独立功能页面</h1>
<script src="./dist/cross-bridge.umd.js"></script>
<script>
// 初始化为独立页面角色
const bridge = new CrossBridge({
pageId: 'standalone-page',
role: 'standalone', // 独立页面角色
adapters: ['shared-worker'], // 可与同域其他页面通信
debug: true,
});
bridge.connect().then(() => {
console.log('独立页面已连接');
// 可以与同域的其他页面通信
bridge.broadcast('page-ready', {
pageType: 'feature-page',
capabilities: ['data-export', 'user-management'],
});
});
</script>
</body>
</html>3. URL 参数自动配置
支持通过 URL 参数自动配置页面角色和连接:
html
<!-- 自动设置为子页面角色并自动连接 -->
<iframe src="my-page.html?role=child&autoConnect=true"></iframe>
<!-- 自动设置为独立页面角色 -->
<a href="my-page.html?role=standalone" target="_blank">打开功能页面</a>在页面中检测 URL 参数:
javascript
// 检测 URL 参数并自动配置
const urlParams = new URLSearchParams(window.location.search);
const role = urlParams.get('role') || 'standalone';
const autoConnect = urlParams.get('autoConnect') === 'true';
const bridge = new CrossBridge({
pageId: `page-${Date.now()}`,
role: role,
adapters: ['post-message', 'shared-worker'],
debug: true,
});
if (autoConnect) {
bridge.connect();
}4. 使用场景示例
简单功能页面部署后作为 iframe 内嵌使用:
html
<!-- 父页面 -->
<!DOCTYPE html>
<html>
<body>
<h1>主应用</h1>
<iframe
src="https://my-domain.com/feature-page.html?role=child&autoConnect=true"
width="100%"
height="500px"
></iframe>
<script src="./dist/cross-bridge.umd.js"></script>
<script>
const parentBridge = new CrossBridge({
pageId: 'main-app',
role: 'parent',
adapters: ['post-message', 'shared-worker'],
debug: true,
});
parentBridge.connect().then(() => {
// 监听子页面消息
parentBridge.on('child-action', (data) => {
console.log('子页面操作:', data);
});
// 发送消息给子页面
parentBridge.broadcast('parent-message', {
type: 'config-update',
theme: 'dark',
});
});
</script>
</body>
</html>🎯 高级配置
完全跨域通信
typescript
const bridge = new CrossBridge({
pageId: 'cross-domain-page',
role: 'parent',
adapters: [
{
type: 'websocket-relay',
config: {
relayServer: 'wss://bridge.e-tudou.com/relay',
authentication: {
token: 'your-auth-token',
domain: 'example.com',
},
},
},
{
type: 'iframe-bridge',
config: {
bridgeUrl: 'https://bridge.e-tudou.com/bridge.html',
},
},
],
});消息队列配置
typescript
const bridge = new CrossBridge({
pageId: 'advanced-page',
role: 'parent',
adapters: ['shared-worker', 'post-message'],
queue: {
messageTypes: {
'critical-alert': {
ttl: 600000, // 10分钟
storage: 'local', // 持久化到 localStorage
priority: 0, // 最高优先级
persistent: true,
},
'user-interaction': {
ttl: 180000, // 3分钟
storage: 'session', // 会话存储
priority: 1,
persistent: true,
},
},
maxQueueSize: 1000,
cleanupInterval: 30000,
},
});性能优化配置
typescript
const bridge = new CrossBridge({
pageId: 'optimized-page',
role: 'parent',
adapters: ['shared-worker', 'post-message', 'webrtc-p2p'],
optimization: {
enableBatching: true, // 启用消息批处理
enableCompression: true, // 启用数据压缩
enableP2P: true, // 启用 P2P 直连
fallbackChain: [
// 降级链
'webrtc-p2p',
'shared-worker',
'post-message',
],
performanceMonitoring: true,
},
});与 mitt 集成
typescript
import mitt from 'mitt';
const globalEvents = mitt();
const bridge = new CrossBridge({
pageId: 'mitt-integration',
role: 'parent',
adapters: ['shared-worker'],
eventBus: globalEvents,
eventMapping: {
'cross-bridge:message': 'global:cross-message',
'cross-bridge:page-connected': 'global:page-online',
},
});
// mitt 事件会自动同步到 CrossBridge
globalEvents.on('user-action', (data) => {
bridge.broadcast('user-action', data);
});CrossBridge 类
构造函数
typescript
new CrossBridge(config: CrossBridgeConfig)方法
| 方法 | 描述 | 参数 | 返回值 |
|---|---|---|---|
connect() | 连接所有适配器 | - | Promise<void> |
disconnect() | 断开所有连接 | - | void |
emit(event, data, target?) | 发送事件消息 | event: string, data: any, target?: string | string[] | void |
broadcast(event, data) | 广播消息 | event: string, data: any | void |
sendTo(pageId, event, data) | 发送给特定页面 | pageId: string, event: string, data: any | void |
on(event, handler) | 监听事件 | event: string, handler: EventHandler | void |
off(event, handler?) | 移除事件监听器 | event: string, handler?: EventHandler | void |
once(event, handler) | 一次性事件监听器 | event: string, handler: EventHandler | void |
registerPage(id, info) | 注册页面信息 | id: string, info: PageInfo | void |
unregisterPage(id) | 注销页面 | id: string | void |
getConnectedPages() | 获取已连接页面列表 | - | PageInfo[] |
getPageInfo(id) | 获取页面信息 | id: string | PageInfo | null |
isConnected() | 检查是否已连接 | - | boolean |
getConnectionStatus() | 获取连接状态 | - | ConnectionStatus |
配置接口
CrossBridgeConfig
typescript
interface CrossBridgeConfig {
pageId: string; // 页面唯一标识
role: PageRole; // 页面角色
adapters: (AdapterType | AdapterConfig)[]; // 适配器配置
queue?: Partial<QueueConfig>; // 消息队列配置
storage?: Partial<StorageConfig>; // 存储配置
optimization?: Partial<OptimizationConfig>; // 性能优化配置
eventBus?: Emitter<any>; // 外部事件总线
eventMapping?: Record<string, string>; // 事件映射
debug?: boolean; // 调试模式
}PageRole
typescript
type PageRole = 'parent' | 'child' | 'standalone' | 'hybrid';parent: 父页面,包含 iframechild: 子页面,被嵌入的 iframestandalone: 独立页面,独立的浏览器标签页hybrid: 混合角色,既是父页面又是子页面
AdapterType
typescript
type AdapterType =
| 'shared-worker' // SharedWorker 适配器
| 'post-message' // PostMessage 适配器
| 'broadcast-channel' // BroadcastChannel 适配器
| 'webrtc-p2p' // WebRTC P2P 适配器
| 'iframe-bridge' // iframe 桥接适配器
| 'websocket-relay'; // WebSocket 中继适配器🏗️ 架构设计
分层架构
┌─────────────────────────────────────────┐
│ 应用层 │
│ (用户代码,事件处理,业务逻辑) │
└─────────────────────────────────────────┘
┌─────────────────────────────────────────┐
│ API 层 │
│ (CrossBridge 主类,统一接口) │
└─────────────────────────────────────────┘
┌─────────────────────────────────────────┐
│ 核心层 │
│ (消息路由,队列管理,生命周期管理) │
└─────────────────────────────────────────┘
┌─────────────────────────────────────────┐
│ 适配器层 │
│ (SharedWorker, PostMessage, WebRTC...) │
└─────────────────────────────────────────┘
┌─────────────────────────────────────────┐
│ 存储层 │
│ (Memory, SessionStorage, LocalStorage) │
└─────────────────────────────────────────┘通信流程
- 消息发送: 应用层 → API 层 → 核心层 → 适配器层
- 消息接收: 适配器层 → 核心层 → API 层 → 应用层
- 智能路由: 根据目标和数据特征选择最优适配器
- 消息队列: 离线页面的消息缓存和延迟投递
- 生命周期: 页面连接状态管理和自动重连
🚀 性能表现
| 通信方式 | 延迟 | 吞吐量 | 适用场景 |
|---|---|---|---|
| SharedWorker | < 1ms | > 1000 msg/s | 同域标签页 |
| PostMessage | < 1ms | > 1000 msg/s | iframe 通信 |
| WebRTC P2P | < 50ms | > 100 msg/s | 跨域高频数据 |
| iframe 桥接 | < 100ms | > 50 msg/s | 跨域中频数据 |
| WebSocket 中继 | < 200ms | > 10 msg/s | 跨域低频重要数据 |
🔧 开发指南
本地开发
bash
# 安装依赖
pnpm install
# 开发模式
pnpm dev
# 构建
pnpm build
# 运行示例
cd examples && python -m http.server 8080🤝 贡献
欢迎提交 Issue 和 Pull Request!
📄 许可证
MIT License