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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@bud-fe/h5-native-bridge

v1.0.4

Published

H5与原生App通信工具库

Downloads

59

Readme

H5-Native-Bridge

H5与原生App通信工具库,使用TypeScript开发,Vite构建。

功能特性

  • 提供H5页面与原生App的双向通信能力
  • 支持位置信息获取、设备信息、媒体保存、页面导航等原生能力调用
  • 类型安全,完全使用TypeScript开发
  • 支持开发环境下模拟数据
  • 支持多种打包格式(ESM, UMD)
  • 单元测试覆盖核心功能

安装

npm install h5-native-bridge

打包

npm run build

使用方法

基本使用

import nativeBridge from 'h5-native-bridge';

// 获取位置信息
nativeBridge
  .getLocation({
    enableHighAccuracy: true,
  })
  .then((location) => {
    console.log('✅ 位置信息:', location);
  })
  .catch((error) => {
    console.error('获取位置失败:', error);
  });

开启调试模式

import nativeBridge from 'h5-native-bridge';

// 开启调试模式可以在控制台查看详细日志
nativeBridge.setDebug(true);

完整示例

import nativeBridge from 'h5-native-bridge';

// 获取位置信息
nativeBridge
  .getLocation({
    enableHighAccuracy: true,
  })
  .then((location) => {
    console.log('✅ 位置信息:', location);
  })
  .catch((error) => {
    console.error('获取位置失败:', error);
  });

// 获取WiFi列表
nativeBridge
  .getWifiList()
  .then((deviceInfo) => {
    console.log('设备信息:', deviceInfo);
  })
  .catch((error) => {
    console.error('获取WiFi失败:', error);
  });

// 保存图片
nativeBridge
  .saveImage({
    url: 'https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/ecbfab94b77e4c73a9635f4639bf41fd~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5Y-q5oOz6Lq65bmz5LiN5oOz5Yqq5Yqb:q75.awebp?rk3s=f64ab15b&x-expires=1747911373&x-signature=bqy63dhMBpzZuILHRSVE37RuRLM%3D',
  })
  .then((deviceInfo) => {
    console.log('图片信息:', deviceInfo);
  })
  .catch((error) => {
    console.error('图片保存失败:', error);
  });

原生App对接说明

Android端

// MainActivity.java
public class MainActivity extends AppCompatActivity {
    private WebView webView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        webView = findViewById(R.id.webview);

        // 初始化WebView
        WebSettings settings = webView.getSettings();
        settings.setJavaScriptEnabled(true);

        // 注册JavaScript接口
        webView.addJavascriptInterface(new NativeBridgeInterface(), "AndroidBridge");

        // 加载H5页面
        webView.loadUrl("https://your-app-url.com");
    }

    // JavaScript接口
    private class NativeBridgeInterface {
        @JavascriptInterface
        public void postMessage(String message) {
            try {
                JSONObject jsonMessage = new JSONObject(message);
                String action = jsonMessage.getString("action");
                JSONObject params = jsonMessage.getJSONObject("params");
                String callbackId = jsonMessage.getString("callbackId");

                // 根据action处理不同的请求
                if ("getLocation".equals(action)) {
                    handleGetLocation(callbackId, params);
                }
                // 其他action处理...

            } catch (JSONException e) {
                e.printStackTrace();
            }
        }

        private void handleGetLocation(final String callbackId, JSONObject params) {
            // 获取定位权限并执行定位
            // 获取到位置后,调用JavaScript回调
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    try {
                        // 假设已获取到位置信息
                        JSONObject location = new JSONObject();
                        location.put("latitude", 31.2304);
                        location.put("longitude", 121.4737);
                        location.put("accuracy", 10);
                        location.put("timestamp", System.currentTimeMillis());
                        location.put("address", "上海市某某路123号");

                        // 调用JavaScript回调
                        String script = "window.nativeBridgeCallback('" + callbackId + "', 'success', " + location.toString() + ")";
                        webView.evaluateJavascript(script, null);
                    } catch (Exception e) {
                        // 处理错误
                        String script = "window.nativeBridgeCallback('" + callbackId + "', 'fail', {message: '" + e.getMessage() + "'})";
                        webView.evaluateJavascript(script, null);
                    }
                }
            });
        }
    }
}

iOS端

// ViewController.swift
import UIKit
import WebKit

class ViewController: UIViewController, WKScriptMessageHandler, WKNavigationDelegate {

    var webView: WKWebView!

    override func viewDidLoad() {
        super.viewDidLoad()

        // 配置WKWebView
        let configuration = WKWebViewConfiguration()
        let userContentController = WKUserContentController()

        // 注册JS消息处理,名称为 "nativeBridge"
        userContentController.add(self, name: "nativeBridge")
        configuration.userContentController = userContentController

        // 创建WKWebView
        webView = WKWebView(frame: view.bounds, configuration: configuration)
        webView.navigationDelegate = self
        view.addSubview(webView)

        // 加载H5页面
        if let url = URL(string: "https://your-app-url.com") {
            webView.load(URLRequest(url: url))
        }
    }

    // 处理来自JS的消息
    func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
        if message.name == "nativeBridge", let messageBody = message.body as? String {
            do {
                // 解析JS发送的JSON消息
                if let messageData = messageBody.data(using: .utf8),
                   let jsonMessage = try JSONSerialization.jsonObject(with: messageData) as? [String: Any],
                   let action = jsonMessage["action"] as? String,
                   let params = jsonMessage["params"] as? [String: Any],
                   let callbackId = jsonMessage["callbackId"] as? String {

                    // 根据action处理不同的请求
                    switch action {
                    case "getLocation":
                        handleGetLocation(callbackId: callbackId, params: params)
                    case "navigate":
                        handleNavigate(callbackId: callbackId, params: params)
                    case "saveImage":
                        handleSaveImage(callbackId: callbackId, params: params)
                    case "getDeviceInfo":
                        handleGetDeviceInfo(callbackId: callbackId, params: params)
                    case "getWifiList":
                        handleGetWifiList(callbackId: callbackId, params: params)
                    default:
                        let error = ["message": "未知的action: \(action)"]
                        let script = "window.nativeBridgeCallback('\(callbackId)', 'fail', \(toJSONString(error)))"
                        webView.evaluateJavaScript(script, completionHandler: nil)
                    }
                } else {
                    throw NSError(domain: "", code: -1, userInfo: [NSLocalizedDescriptionKey: "无效的JSON消息"])
                }
            } catch {
                // 处理解析错误
                let error = ["message": "消息解析失败: \(error.localizedDescription)"]
                if let callbackId = (message.body as? [String: Any])?["callbackId"] as? String {
                    let script = "window.nativeBridgeCallback('\(callbackId)', 'fail', \(toJSONString(error)))"
                    webView.evaluateJavaScript(script, completionHandler: nil)
                }
            }
        }
    }

    // 处理获取位置请求
    private func handleGetLocation(callbackId: String, params: [String: Any]) {
        // 获取定位权限并执行定位
        // 假设已获取到位置信息
        let location: [String: Any] = [
            "latitude": 31.2304,
            "longitude": 121.4737,
            "accuracy": 10,
            "timestamp": Date().timeIntervalSince1970 * 1000,
            "address": "上海市某某路123号"
        ]

        // 调用JavaScript回调
        let script = "window.nativeBridgeCallback('\(callbackId)', 'success', \(toJSONString(location)))"
        webView.evaluateJavaScript(script) { _, error in
            if let error = error {
                print("JavaScript执行错误: \(error)")
            }
        }
    }

    // 处理导航请求
    private func handleNavigate(callbackId: String, params: [String: Any]) {
        // 实现导航逻辑,例如跳转到指定页面
        let response: [String: Any] = ["status": "success"]
        let script = "window.nativeBridgeCallback('\(callbackId)', 'success', \(toJSONString(response)))"
        webView.evaluateJavaScript(script, completionHandler: nil)
    }

    // 处理保存图片请求
    private func handleSaveImage(callbackId: String, params: [String: Any]) {
        // 实现图片保存逻辑
        let response: [String: Any] = ["status": "success"]
        let script = "window.nativeBridgeCallback('\(callbackId)', 'success', \(toJSONString(response)))"
        webView.evaluateJavaScript(script, completionHandler: nil)
    }

    // 处理获取设备信息请求
    private func handleGetDeviceInfo(callbackId: String, params: [String: Any]) {
        // 实现设备信息获取逻辑
        let deviceInfo: [String: Any] = [
            "platform": "ios",
            "osVersion": UIDevice.current.systemVersion,
            "deviceModel": UIDevice.current.model,
            "appVersion": Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? "",
            "uuid": UIDevice.current.identifierForVendor?.uuidString ?? "",
            "screenWidth": UIScreen.main.bounds.width,
            "screenHeight": UIScreen.main.bounds.height,
            "pixelRatio": UIScreen.main.scale,
            "networkType": "wifi",
            "language": Locale.current.languageCode ?? "en"
        ]
        let script = "window.nativeBridgeCallback('\(callbackId)', 'success', \(toJSONString(deviceInfo)))"
        webView.evaluateJavaScript(script, completionHandler: nil)
    }

    // 处理获取WiFi列表请求
    private func handleGetWifiList(callbackId: String, params: [String: Any]) {
        // 实现WiFi列表获取逻辑
        let wifiList: [[String: Any]] = [
            ["ssid": "WiFi-1", "signalStrength": -50],
            ["ssid": "WiFi-2", "signalStrength": -70]
        ]
        let response: [String: Any] = [
            "resultCode": 0,
            "resultMessage": "成功",
            "wifiList": wifiList
        ]
        let script = "window.nativeBridgeCallback('\(callbackId)', 'success', \(toJSONString(response)))"
        webView.evaluateJavaScript(script, completionHandler: nil)
    }

    // 辅助函数:将字典转为JSON字符串
    private func toJSONString(_ dict: [String: Any]) -> String {
        if let data = try? JSONSerialization.data(withJSONObject: dict),
           let str = String(data: data, encoding: .utf8) {
            return str
        }
        return "{}"
    }
}

## 本地开发

```bash
# 安装依赖
npm install

# 启动开发服务器
npm run dev

# 构建生产版本
npm run build

# 运行测试
npm run test

许可证

MIT

贡献指南

欢迎提交issue和PR。