npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

aix-jsbridge

v0.0.1

Published

轻量的 JSBridge,用于 Web 与原生 App 之间的通信,支持 iOS 和 Android

Readme

JSBridge

轻量的 JSBridge,用于 Web 与原生 App 之间的通信,支持 iOS 和 Android。

安装

npm install aix-jsbridge --save

或者使用 CDN 直接引入:

<script src="https://unpkg.com/jsbridge/dist/jsbridge.min.js"></script>

基本用法

初始化

import JSBridge from 'aix-jsbridge';

// 初始化 JSBridge
JSBridge.init({
  debug: true,             // 是否开启调试模式
  timeout: 15000,          // 请求超时时间(毫秒)
  enableCache: true        // 是否启用缓存
});

调用原生方法

// 方式 1:回调方式
JSBridge.call('getDeviceInfo', function(result) {
  console.log('设备信息:', result);
});

// 方式 2:带参数
JSBridge.call('getLocation', { type: 'gcj02' }, function(result) {
  console.log('位置信息:', result);
});

// 方式 3:Promise 方式
JSBridge.callAsync('getNetworkStatus')
  .then(result => {
    console.log('网络状态:', result);
  })
  .catch(error => {
    console.error('获取网络状态失败:', error);
  });

注册 H5 方法供原生调用

// 注册方法
JSBridge.register('updateUI', function(data) {
  console.log('收到原生传来的数据:', data);
  // 更新界面逻辑
  return {
    success: true,
    message: '界面已更新'
  };
});

// 注销方法
JSBridge.unregister('updateUI');

事件监听

// 监听事件
function networkChangeHandler(data) {
  console.log('网络状态变化:', data);
}
JSBridge.on('networkChange', networkChangeHandler);

// 取消监听
JSBridge.off('networkChange', networkChangeHandler);

在 Vue 中使用

创建插件

// src/plugins/jsbridge.js
import JSBridge from 'aix-jsbridge';

export default {
  install(app, options = {}) {
    // 初始化 JSBridge
    JSBridge.init({
      debug: options.debug || false,
      enableCache: options.enableCache !== false,
      timeout: options.timeout || 15000
    });

    // 添加全局属性 $jsbridge
    app.config.globalProperties.$jsbridge = JSBridge;

    // 提供 JSBridge
    app.provide('jsbridge', JSBridge);
  }
};

// 导出 JSBridge 单例,方便直接使用
export { JSBridge };

在 main.js 中注册插件

import { createApp } from 'vue';
import App from './App.vue';
import JSBridgePlugin from './plugins/jsbridge';

const app = createApp(App);
app.use(JSBridgePlugin, { debug: true });
app.mount('#app');

在组件中使用

// 选项式 API
export default {
  methods: {
    getDeviceInfo() {
      this.$jsbridge.call('getDeviceInfo', result => {
        this.deviceInfo = result;
      });
    }
  }
};

// 组合式 API
import { inject } from 'vue';

export default {
  setup() {
    const jsbridge = inject('jsbridge');

    const getDeviceInfo = async () => {
      try {
        const result = await jsbridge.callAsync('getDeviceInfo');
        // 处理结果
      } catch (err) {
        // 处理错误
      }
    };

    return { getDeviceInfo };
  }
};

原生端实现

本 SDK 提供 JavaScript 端的实现,原生端需要实现相应的接口才能完成通信。

iOS 实现(WKWebView)

// 简化示例
extension ViewController: WKScriptMessageHandler {
    func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
        guard let body = message.body as? [String: Any],
              let methodName = body["method"] as? String,
              let params = body["params"] as? [String: Any],
              let callbackId = body["callbackId"] as? String else {
            return
        }

        // 处理方法调用
        handleJSBridgeCall(methodName: methodName, params: params, callbackId: callbackId)
    }

    func handleJSBridgeCall(methodName: String, params: [String: Any], callbackId: String) {
        // 根据方法名执行相应的原生操作
        var result: [String: Any] = [:]

        switch methodName {
        case "getDeviceInfo":
            // 获取设备信息
            result = ["platform": "iOS", "version": UIDevice.current.systemVersion]
        // 其他方法...
        default:
            result = ["error": "方法不存在"]
        }

        // 返回结果给 JS
        let script = "window.JSBridgeCallback('\(callbackId)', \(toJSONString(result)))"
        webView.evaluateJavaScript(script, completionHandler: nil)
    }

    // 调用 JS 方法
    func callJSMethod(name: String, data: [String: Any], completion: ((Any?) -> Void)? = nil) {
        let script = "window.JSBridgeInvoke('\(name)', \(toJSONString(data)))"
        webView.evaluateJavaScript(script) { (result, error) in
            completion?(result)
        }
    }

    // 触发事件
    func triggerJSEvent(eventName: String, data: [String: Any]) {
        let script = "window.JSBridgeEvent('\(eventName)', \(toJSONString(data)))"
        webView.evaluateJavaScript(script, completionHandler: nil)
    }
}

Android 实现(JavaScriptInterface)

// 简化示例
public class JSBridgeInterface {
    private WebView webView;
    private Context context;

    public JSBridgeInterface(WebView webView, Context context) {
        this.webView = webView;
        this.context = context;
    }

    @JavascriptInterface
    public void call(String message) {
        try {
            JSONObject jsonObject = new JSONObject(message);
            String method = jsonObject.getString("method");
            JSONObject params = jsonObject.optJSONObject("params");
            String callbackId = jsonObject.getString("callbackId");

            // 根据方法名执行相应操作
            JSONObject result = handleMethod(method, params);

            // 返回结果给 JS
            callJSCallback(callbackId, result);
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    private JSONObject handleMethod(String method, JSONObject params) throws JSONException {
        JSONObject result = new JSONObject();

        switch (method) {
            case "getDeviceInfo":
                // 获取设备信息
                result.put("platform", "Android");
                result.put("version", Build.VERSION.RELEASE);
                break;
            // 其他方法...
            default:
                result.put("error", "方法不存在");
        }

        return result;
    }

    // 在主线程中调用 JS 回调
    private void callJSCallback(final String callbackId, final JSONObject result) {
        webView.post(() -> {
            webView.evaluateJavascript(
                "window.JSBridgeCallback('" + callbackId + "', " + result.toString() + ")",
                null
            );
        });
    }

    // 在主线程中调用 JS 方法
    public void callJSMethod(String name, JSONObject data, ValueCallback<String> callback) {
        webView.post(() -> {
            webView.evaluateJavascript(
                "window.JSBridgeInvoke('" + name + "', " + data.toString() + ")",
                callback
            );
        });
    }

    // 在主线程中触发 JS 事件
    public void triggerJSEvent(String eventName, JSONObject data) {
        webView.post(() -> {
            webView.evaluateJavascript(
                "window.JSBridgeEvent('" + eventName + "', " + data.toString() + ")",
                null
            );
        });
    }

    @JavascriptInterface
    public void onJSBridgeReady() {
        // Bridge 已就绪
        Log.d("JSBridge", "Bridge is ready");
    }
}

示例

查看 examples 目录中的完整示例:

  • examples/basic.html - 基本用法示例
  • examples/vue-demo/ - Vue 集成示例

API 文档

JSBridge

方法

  • init(options?: JSBridgeOptions): JSBridgeInterface - 初始化 JSBridge
  • call(method: string, params?: any, callback?: CallbackFunction): JSBridgeInterface - 调用原生方法
  • callAsync(method: string, params?: any): Promise<any> - Promise 风格的原生方法调用
  • register(name: string, handler: MethodHandler): JSBridgeInterface - 注册 H5 方法供原生调用
  • unregister(name: string): JSBridgeInterface - 注销 H5 方法
  • on(eventName: string, handler: EventHandler): JSBridgeInterface - 监听原生事件
  • off(eventName: string, handler?: EventHandler): JSBridgeInterface - 取消监听原生事件
  • setDebug(enabled: boolean, options?: Partial<DebugOptions>): JSBridgeInterface - 设置调试模式
  • clearCache(): JSBridgeInterface - 清除所有缓存

类型定义

interface JSBridgeOptions {
  debug?: boolean;
  timeout?: number;
  enableCache?: boolean;
}

type CallbackFunction = (data: any) => void;
type MethodHandler = (data: any) => any | Promise<any>;
type EventHandler = (data: any) => void;

interface DebugOptions {
  enabled: boolean;
  logLevel?: string;
  useConsole?: boolean;
}

构建与开发

# 安装依赖
npm install

# 开发模式
npm run dev

# 构建
npm run build

# 运行示例
npm run example:basic