@ybais/bridge
v1.0.1
Published
YBAIS WebView JSBridge (MessageHandle)
Readme
@ybais/bridge — JSBridge
H5 与 App Native 通信:调用原生方法、订阅原生命名回调。核心 API 无 React 依赖,可在拦截器、普通模块中使用;函数组件请从 @ybais/bridge/react 引入 Hooks。
协议清单(monorepo 源码):原生与web交互MessageHandle.md。
Install
pnpm add @ybais/bridge
# 使用 React Hooks(@ybais/bridge/react)时:
pnpm add react
# npm i @ybais/bridge
# yarn add @ybais/bridgeRequirements
| 依赖 | 类型 | 说明 |
|------|------|------|
| react | optional peer | 仅使用 @ybais/bridge/react 时需要 |
无其它 @ybais/* 硬依赖。与 @ybais/error-guard 联用时,建议把「非 WebView / 方法未注入」接到 reportDebug(见下方 Get started)。
Get started
import {
callNative,
goLogin,
isBridgeUnavailableError,
configureBridge,
} from "@ybais/bridge";
// 可选:统一处理 Bridge 不可用(浏览器预览属预期)
configureBridge({
onUnavailable: (error, context) => {
console.warn(`[bridge] ${context.method}`, context.reason, error);
},
});
// 推荐:类型化 MessageHandle 封装
await goLogin().catch((err) => {
if (isBridgeUnavailableError(err)) {
// H5 回退:跳转自有登录页等
}
});
// 通用调用
await callNative("goLogin");
await callNative<{ token: string }>("getToken", { force: true }, 8000);React:
import { useNativeCall, useNativeCallback } from "@ybais/bridge/react";
import { startRpCheck } from "@ybais/bridge";
function FaceAuthPage() {
useNativeCallback("faceAuthSuccess", () => {
console.log("人脸认证成功");
});
return (
<button type="button" onClick={() => void startRpCheck()}>
开始人脸
</button>
);
}与 error-guard 联用(脚手架推荐):
import { configureBridge } from "@ybais/bridge";
import { reportDebug } from "@ybais/error-guard";
configureBridge({
onUnavailable: (error, context) => {
reportDebug(`原生能力不可用:${context.method}`, {
source: "bridge",
error,
detail: { method: context.method, reason: context.reason },
});
},
});MessageHandle 封装(推荐)
相对字符串 callNative("…"),优先用类型化方法(参数已对齐原生约定;无参方法自动传 { title: "" }):
import {
jumpGeneralWebPage,
jumpNativePage,
exitWebPage,
goBack,
openFdInteractivePop,
closeFdInteractivePop,
saveImage,
endEditing,
reloadWebView,
openSystemWebView,
pay,
toAuthenticate,
goLogin,
startRpCheck,
onNative,
} from "@ybais/bridge";
await goLogin();
await jumpNativePage("accountCenter");
await pay({ channel_code: "wechat", appPayRequest: { /* … */ } });
onNative("authSuccess", () => { /* 实名成功 */ });
await toAuthenticate();
onNative("faceAuthSuccess", () => { /* 人脸成功 */ });
await startRpCheck();| TS 方法 | Native method | 说明 |
|---------|---------------|------|
| jumpGeneralWebPage(url) | jumpGeneralWebPage | 打开通用 Web 页 |
| jumpNativePage(pageName) | jumpNativePage | login / accountCenter / userPorfile |
| exitWebPage() | exitWebPage | 关闭 WebView |
| goBack() | goBack | 可回退则回退,否则关页 |
| openFdInteractivePop() | open_fd_interactivePopDisabled | iOS 开侧滑返回 |
| closeFdInteractivePop() | close_fd_interactivePopDisabled | iOS 关侧滑返回 |
| saveImage(base64) | saveImage | 存相册 |
| endEditing() | endEditing | 收起键盘 |
| reloadWebView() | reload | 刷新 WebView |
| openSystemWebView(url) | openSystemWebView | 系统浏览器 |
| pay(params) | pay | 支付宝 / 微信 |
| toAuthenticate() | toAuthenticate | 实名;回调 authSuccess |
| goLogin() | goLogin | 登录 |
| startRpCheck() | startRpCheck | 人脸;回调 faceAuthSuccess |
H5 → Native:callNative
await callNative("goLogin");
await callNative<{ token: string }>("getToken", { force: true }, 8000);| 参数 | 说明 |
|------|------|
| method | Native 方法名(iOS messageHandlers / Android AndroidBridge) |
| params | 传给 Native 的对象;省略时默认 { title: "" } |
| timeout | 超时毫秒,默认 5000 |
- 成功:Promise resolve 为
BridgeResponse.data(code === 0) - 失败:Promise reject
- 非 WebView / 未注入 Bridge / 方法未配置 →
BridgeUnavailableError(非流程阻断) - 超时、业务
code !== 0、解析错误 → 普通Error
- 非 WebView / 未注入 Bridge / 方法未配置 →
- 判断环境:
isNativeBridgeAvailable();判断错误:isBridgeUnavailableError(err)
import { goBack, isBridgeUnavailableError } from "@ybais/bridge";
goBack().catch((err) => {
if (isBridgeUnavailableError(err)) {
history.back();
}
});Native → H5:onNative / offNative
const stop = onNative("AuthCallback", (result) => {
if (result === "success") {
// …
}
});
onNative("authSuccess", () => { /* … */ });
onNative("faceAuthSuccess", () => { /* … */ });
stop();
offNative("AuthCallback", handler);
offNative("AuthCallback");未在类型 Map 中的名称仍可用 string 订阅(payload 为 unknown)。
React Hooks
useNativeCall():返回稳定的callNativeuseNativeCallback(name, handler):挂载时订阅,卸载时自动取消;handler 始终读最新闭包
注意
- 不要手写覆盖
window.AuthCallback/authSuccess/faceAuthSuccess,以免破坏多订阅代理 - 临时请求回调由
callNative内部挂__bridge_cb_*,业务无需关心 - 无参协议方法务必传
{ title: "" }(封装与callNative默认参数已处理)
