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

@hxa-rn/react-native-qrcode-scanner

v1.0.0

Published

A QR code scanner for React Native.

Downloads

242

Readme

本项目基于 react-native-qrcode-scanner 开发。如果在使用过程中有任何问题,可以在 GitCode Issues 提交 Issue,会及时跟进。

项目介绍

react-native-qrcode-scanner 是一个二维码/条码扫描组件,提供取景预览、条码识别与结果派发、 扫码去重与重新武装(reactivate)、震动反馈、读码启停、取景框与顶/底部内容区、闪光灯与相机休眠等能力。

本仓为其 HarmonyOS 适配版本,适配基线 = 上游 1.6.0;npm 包为 @hxa-rn/react-native-qrcode-scanner,当前版本 1.0.0。

架构形态(务必先读):上游自身零原生代码(index.js 348 行 JS 包装组件), 把「取景 + 出码」全权委托给 peer 依赖 react-native-camera。该 peer 已归档停维、无 RNOH 移植、 103 个原生文件的旧架构,照搬即强阻塞。

本适配采用依赖倒置:把相机来源抽象成可注入的 cameraProvider 契约,鸿蒙侧用 HarmonyOS Scan Kit 的 customScan 自建 Fabric 原生组件 QRScanKitCamera(customScan + XComponent + codegen C++ glue + emitComponentEvent('barCodeRead'))。本库自身的控制逻辑(去重 / 震动 / reactivate)与解码流映射无平台障碍。

集成指南

本节用于接入已有 RN 鸿蒙应用;运行本仓库示例请参见「快速验证(运行 Example)」。

1. 安装适配包

npm 包:@hxa-rn/[email protected](正式版,dist-tag latest;预发布版 0.0.1-beta 保留在 dist-tag beta),业务别名为 react-native-qrcode-scanner。在你的 RN 应用根目录执行:

npm install @hxa-rn/[email protected] --legacy-peer-deps

peerDependencies:{"react-native":">=0.72","react":"*"}。还需已有可运行的 RNOH 宿主工程(示例基线为 RN 0.72.5 + RNOH 0.72.143)。

包内含源码 HAR harmony/qrcode_scanner.har(ArkTS 源码 + C++ 源码,由宿主工程一起编译),其 ohpm 模块名为 @oh-rn/react-native-qrcode-scanner(与 npm 包名不同,下文 ohpm 依赖、ArkTS/C++ 导入一律用 ohpm 名)。

2. 配置 Metro 并导入

适配包已声明 harmony.alias。宿主 metro.config.js 合并以下配置,并保留原有的自定义设置:

const {getDefaultConfig, mergeConfig} = require('@react-native/metro-config');
const {createHarmonyMetroConfig} = require('@react-native-oh/react-native-harmony/metro.config');

module.exports = mergeConfig(
  getDefaultConfig(__dirname),
  createHarmonyMetroConfig({
    reactNativeHarmonyPackageName: '@react-native-oh/react-native-harmony',
  }),
);

业务代码(两种写法等价,createHarmonyMetroConfig 会把别名解析到本包):

import QRCodeScanner, {checkCameraPermission, requestCameraPermission} from 'react-native-qrcode-scanner';
// 或
import QRCodeScanner from '@hxa-rn/react-native-qrcode-scanner';

3. 声明 HAR 依赖

在宿主鸿蒙工程根 harmony/oh-package.json5 与 harmony/entry/oh-package.json5 的 dependencies 追加下项(路径相对于各自文件所在目录,按宿主实际 node_modules 位置调整),并在根 overrides 中将 @rnoh/react-native-openharmony 指向宿主正在使用的同一 RNOH HAR(勿混用 debug/release 或不同版本):

// harmony/oh-package.json5
"dependencies": {
  "@oh-rn/react-native-qrcode-scanner": "file:../node_modules/@hxa-rn/react-native-qrcode-scanner/harmony/qrcode_scanner.har"
},
"overrides": {
  "@rnoh/react-native-openharmony": "file:../node_modules/@react-native-oh/react-native-harmony/react_native_openharmony_release.har"
}

// harmony/entry/oh-package.json5
"dependencies": {
  "@oh-rn/react-native-qrcode-scanner": "file:../../node_modules/@hxa-rn/react-native-qrcode-scanner/harmony/qrcode_scanner.har"
}

然后在 harmony 目录执行 ohpm install --all 并同步工程。不要把 file: 指向解包后的源码目录 harmony/qrcode_scanner/(ohpm 会建越界 junction,ArkTS 编译报 EINVAL),只依赖 .har。

4. 注册原生 Package(Autolink 与 Manual 二选一)

路线 A:Autolink(推荐,与本仓示例一致)

本包声明了 Autolinking 元数据:CMake 目标 qrcode_scanner,ohpm 包 @oh-rn/react-native-qrcode-scanner,C++ / ETS 类 QrcodeScannerPackage。宿主 harmony/hvigorfile.ts 的 createRNOHModulePlugin 启用 autolinking: {} 即可;构建时 hvigor 会生成 entry/src/main/ets/RNOHPackagesFactory.ets、entry/src/main/cpp/RNOHPackagesFactory.h 与 autolinking.cmake。宿主 CMakeLists.txt 需 include("${CMAKE_CURRENT_SOURCE_DIR}/autolinking.cmake") 并 autolink_libraries(rnoh_app),PackageProvider.cpp 与 RNPackagesFactory.ets 需合并 createRNOHPackages(ctx) 的返回值(RNOH 模板已含)。此时不要再做下面的手工注册,否则会重复注册(CMake 报 binary directory … is already used)。

路线 B:Manual Link

宿主已启用 Autolinking 时,先把本包排除,避免与手工注册冲突(排除项写 npm 包名):

autolinking: {
  excludeNpmPackages: ['@hxa-rn/react-native-qrcode-scanner'],
},

然后补齐以下三处:

  1. harmony/entry/src/main/cpp/CMakeLists.txt:添加子目录,并在已有 add_library(rnoh_app ...) 之后链接:
set(OH_MODULE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../oh_modules")
add_subdirectory("${OH_MODULE_DIR}/@oh-rn/react-native-qrcode-scanner/src/main/cpp" ./qrcode_scanner)
# 放在 rnoh_app 目标创建之后:
target_link_libraries(rnoh_app PUBLIC qrcode_scanner)
  1. harmony/entry/src/main/cpp/PackageProvider.cpp:添加头文件,并把实例加入 getPackages 返回集合(RNOH 模板可加入 ManualLinkingPackage 列表):
#include "QrcodeScannerPackage.h"

// 加入已有 Package 集合:
std::make_shared<rnoh::QrcodeScannerPackage>(ctx)
  1. harmony/entry/src/main/ets/RNPackagesFactory.ets:添加默认导入,并把实例加入 createRNPackages 返回数组:
import QrcodeScannerPackage from '@oh-rn/react-native-qrcode-scanner';

// 加入 createRNPackages(ctx) 返回数组:
new QrcodeScannerPackage(ctx)

5. 注册 ArkTS 取景组件(两条路线都必须)

取景组件 QRScanKitCamera 由 ArkTS 实现。包内 QrcodeScannerPackage 已登记组件描述符与构建器,但宿主 RNApp 必须声明 arkTsComponentNames,Autolink 不会替你改宿主页面。在宿主承载 RNApp 的页面(示例为 harmony/entry/src/main/ets/pages/Index.ets)按本仓示例写法补齐三处(示例同时在宿主提供构建器,已随示例编译验证):

import { ComponentBuilderContext, RNApp } from '@rnoh/react-native-openharmony';
import { QRScanKitCamera, QR_SCAN_KIT_CAMERA_TYPE } from '@oh-rn/react-native-qrcode-scanner';

// 1) 声明由 ArkTS 实现的组件名(与 JS 侧 codegenNativeComponent('QRScanKitCamera') 逐字一致)
const ARK_TS_COMPONENT_NAMES: string[] = [QR_SCAN_KIT_CAMERA_TYPE];

// 2) 组件构建器:C-API 混合方案要求外层 Stack 且 position 为 (0,0)
@Builder
export function buildCustomRNComponent(ctx: ComponentBuilderContext) {
  Stack() {
    if (ctx.componentName === QR_SCAN_KIT_CAMERA_TYPE) {
      QRScanKitCamera({ ctx: ctx.rnComponentContext, tag: ctx.tag })
    }
  }
  .position({ x: 0, y: 0 })
}
const wrappedCustomRNComponentBuilder = wrapBuilder(buildCustomRNComponent)

// 3) 传给 RNApp(其余参数保持宿主原样)
RNApp({
  rnInstanceConfig: {
    createRNPackages,
    enableCAPIArchitecture: true,
    arkTsComponentNames: ARK_TS_COMPONENT_NAMES,
    // ...
  },
  wrappedCustomRNComponentBuilder: wrappedCustomRNComponentBuilder,
  // ...
})

漏掉 arkTsComponentNames 时,RNOH 会去找不存在的 C++ ComponentInstance,取景区不渲染。宿主已有其他 ArkTS 组件时,把名字并入同一数组、在同一构建器里追加分支。

6. 权限

在宿主 harmony/entry/src/main/module.json5 的 requestPermissions 声明(本 HAR 未声明任何权限,须由宿主声明):

"requestPermissions": [
  {
    "name": "ohos.permission.CAMERA",
    "reason": "$string:camera_permission_reason",
    "usedScene": { "abilities": ["EntryAbility"], "when": "inuse" }
  },
  { "name": "ohos.permission.VIBRATE" }
]

camera_permission_reason 需在宿主 resources/base/element/string.json 中定义。CAMERA 为 user_grant,运行时通过 checkCameraPermission() / requestCameraPermission() 检查与申请(组件挂载时也会自动发起);VIBRATE 供 vibrate(默认 true)使用。设备需支持 HarmonyOS Scan Kit。

完成以上步骤后重新生成宿主 Bundle、构建并安装 HAP;只刷新 JS 不会加载新增的原生模块。

使用说明

import React from 'react';
import {Text} from 'react-native';
import QRCodeScanner, {QRScanKitCamera as QRScanKitCameraProvider} from 'react-native-qrcode-scanner';


export default function App() {
  return (
    <QRCodeScanner
      cameraProvider={QRScanKitCameraProvider}
      onRead={(e) => console.log(e.data, e.type, e.bounds)}
      vibrate
      reactivate
      reactivateTimeout={2000}
      showMarker
      topContent={<Text>将二维码放入框内</Text>}
      bottomContent={<Text>扫描中…</Text>}
    />
  );
}

派发链路(禁止绕过):

Scan Kit customScan 回调 → QRScanKitCamera.ets → eventEmitter.emit('barCodeRead')(codegen 封装的 emitComponentEvent)
  → JS 包装 → cameraProvider 的 onBarCodeRead
  → QRCodeScanner._handleBarCodeRead(去重锁 / 震动 / reactivate 定时器 / disable 门控)
  → props.onRead

若图省事直接调 onRead,「去重与重新武装」「震动与启停」两组行为会全部假通过——它们判的正是被绕过的那一段。

接口文档

公开接口 = 默认导出组件的 props(25 个) + 公开实例方法(3 个),另有适配层新增的 cameraProvider。主要项:

| API | 类型 | 默认值 | 说明 | |---|---|---|---| | onRead | (e: BarCodeReadEvent) => void | 打印日志 | 必填。识别到条码时派发一次 | | cameraProvider | Component | 内置 Scan Kit 相机组件 | 可选的自定义相机来源注入点(适配层新增) | | vibrate | boolean | true | 识别成功是否震动 | | reactivate | boolean | false | 一次识别后是否自动重新武装 | | reactivateTimeout | number | 0 | 重新武装延时(ms) | | cameraTimeout | number | 0 | 相机空闲休眠时长(ms);0 = 不休眠 | | showMarker | boolean | false | 取景框总开关 | | customMarker | Element | 未定义 | 自定义取景框(受 showMarker 门控) | | topContent / bottomContent | Element | string | 未定义 | 顶/底部内容区 | | containerStyle / cameraStyle / markerStyle / topViewStyle / bottomViewStyle | Style | — | 各层样式 | | fadeIn | boolean | true | 取景区淡入动画 | | flashMode | 'off'\|'on'\|'auto'\|'torch' | 'auto' | 闪光灯档位(鸿蒙侧 auto 按环境亮度自动开关补光,见「约束与限制」) | | cameraType | 'front'\|'back' | 'back' | 鸿蒙侧仅后置 | | notAuthorizedView / pendingAuthorizationView | Element | 内置视图 | 未授权 / 待授权视图,鸿蒙侧由 QRScannerPermission TurboModule 提供授权状态 | | cameraTimeoutView | Element | 内置「Tap to activate camera」 | 相机休眠时呈现 | | permissionDialogTitle / permissionDialogMessage / buttonPositive / checkAndroid6Permissions | — | 'Info' / 'Need camera permission' / 'OK' / false | 源平台授权对话框参数,鸿蒙侧无对应表现 | | cameraProps | object | {} | 透传给底层相机组件的任意 props | | disable() | 方法 | — | 停止读码(门控整个读码处理) | | enable() | 方法 | — | 恢复读码 | | reactivate() | 方法 | — | 手动重新武装(解锁去重) |

onRead 事件对象:

| 字段 | 类型 | 说明 | |------|------|------| | data | string | 条码原始内容(Scan Kit ScanResult.originalValue) | | type | string | 码制字符串(scanType 经映射;无对等者为 unknown) | | bounds | { width, height, origin } | 码区域与四角点(Scan Kit scanCodeRect 折算,Android 形态) |

Fabric 原生组件契约(QRScanKitCamera,供接入方了解,不直接对外): props flashMode(string,默认 'auto',上游 flashMode 原值直传,由 ArkTS 侧折算)、scanTypesCsv(string,默认 '',Scan Kit ScanType 数值 CSV,空 = 全部); 事件 onBarCodeRead(DirectEventHandler,bounds.origin 以 originJson JSON 字符串承载)、onCameraError(DirectEventHandler,{ code, message },经 cameraProps 透传可见)。

快速验证(运行 Example)

前置条件

  • Node.js >= 20(以示例 engines 为准)与 npm,DevEco Studio 及配套 ohpm / SDK。示例的 ohpm preInstall 钩子会用 PATH 中的 Node.js >= 20 补齐依赖,请确保启动 DevEco Studio 时 PATH 能找到它(或设置环境变量 DEVECO_PRELOAD_NODE 指向 node.exe)。
  • 示例版本:React Native 0.72.5、RNOH 0.72.143;本包从 npmjs 安装 @hxa-rn/[email protected]。
  • 鸿蒙工程配置:compatibleSdkVersion=5.1.0(18);targetSdkVersion 未在产品配置显式指定,以本机 SDK 同步结果为准。设备需支持 HarmonyOS Scan Kit。
  • 在 DevEco Studio 中配置与当前应用包名匹配的签名,不能直接使用其他电脑上的证书路径。

运行步骤

1. 克隆仓库(默认分支不是适配分支,必须带 -b br_rnoh0.72)

git clone -b br_rnoh0.72 https://gitcode.com/hxa-rn/react-native-qrcode-scanner.git
cd react-native-qrcode-scanner

以下步骤使用 example 展示工程;example_auto(自动化用例工程)步骤相同,两者的依赖与构建输出独立,不要混用。Windows 建议使用较短目录,避免 RNOH 原生构建中间路径过长。

2. 安装示例依赖(本包从 npm 安装,无需在仓库根目录打包)

cd example
npm install --legacy-peer-deps

3. 生成 JS Bundle

npm run dev

确认生成 example/harmony/entry/src/main/resources/rawfile/bundle.harmony.js。先解决命令报错,再进入原生构建。

4. 同步与运行鸿蒙工程

用 DevEco Studio 打开 example/harmony,完成依赖同步(ohpm install 的 preInstall 钩子会检查并补齐 npm 依赖与 Bundle)。也可在该目录执行 ohpm install --all 后再同步。保留示例已有的 RNOH HAR 路径和版本。

示例已按「集成指南」第 3~6 步完成 HAR 依赖、Autolink、ArkTS 组件注册与权限声明,无需重复添加。选择设备、配置签名并点击运行,生成并安装 HAP。修改 JS 后重新生成 Bundle;修改原生依赖后重新构建安装 HAP。

常见问题

  • 找不到 JS 模块:检查适配包安装、Metro 别名及对应入口,修改 Metro 后重启打包进程。
  • 找不到 HAR:核对 node_modules/@hxa-rn/react-native-qrcode-scanner/harmony/qrcode_scanner.har 是否存在;不要将 example_auto 的 node_modules 当成 example 的依赖。
  • 取景区空白:检查「集成指南」第 5 步的 arkTsComponentNames 与组件构建器,以及相机权限是否已授予。
  • 原生模块未注册或重复注册:检查 HAR、CMake、C++ 和 ETS 注册,Autolink 与 Manual 只能二选一,然后重建 HAP。
  • DevEco 同步时报 Node.js 20 or newer with npm is required:安装 Node.js 20+ 并重启 DevEco Studio,或设置 DEVECO_PRELOAD_NODE。
  • SDK / 签名报错:按当前工程配置安装对应 SDK,并重新配置本机签名。
  • Ninja .rsp 创建失败:查看完整日志;确认是路径长度问题后,缩短工程目录、清理旧路径构建缓存再构建。

约束与限制

兼容性:RNOH 0.72.143 / RN 0.72.5;HarmonyOS Scan Kit customScan(since API 4.1.0(11))。

本版本(1.0.0)验证范围:发布前以本包安装文件为依赖,本仓 example、example_auto(Autolink)及按「集成指南」路线 B 改接的宿主副本(Manual Link),在 DevEco Studio 6.1.1 下 assembleHap 编译通过。

权限:ohos.permission.CAMERA(取景与识码依赖)、ohos.permission.VIBRATE(震动反馈),宿主 module.json5 需声明。

  • 相机来源:当前适配包默认使用内置 Scan Kit 相机组件;cameraProvider 用于自定义来源,不依赖 react-native-camera。
  • 未授权 / 待授权两态视图:鸿蒙侧新增 QRScannerPermission TurboModule,授权由 JS 侧发起 (与上游 iOS 分支同构),checkCameraPermission() / requestCameraPermission() 返回真实相机授权状态, notAuthorizedView / pendingAuthorizationView 两态视图分支可按授权状态呈现。
  • flashMode='auto' 自动补光:使用 customScan.on('lightingFlash') (5.0.0(12) 起)订阅环境亮度,暗则 openFlashLight()、亮则 closeFlashLight(),切出 auto 或组件销毁时退订。
  • 仅支持后置相机:cameraType='front' 无效,customScan API 无前置相机参数。
  • 部分码制无对等映射:QR / AZTEC / CODE39 / 93 / 128 / DATAMATRIX / EAN8 / 13 / ITF14 / PDF417 / UPC_E 一一对应;CODABAR / UPC_A / 聚合枚举归 unknown(诚实归类,不伪造映射); code39mod43 / interleaved2of5 无 Scan Kit 对等,已剔除。
  • disable() 的语义:它门控的是整个读码处理(既不派发也不震动), 尽管上游内部字段名为 disableVibrationByUser——该命名有误导性,只按「关震动」理解会用错。
  • 自定义取景框受总开关门控:showMarker 关闭时,即便传了 customMarker 也不呈现。
  • static defaultProps 禁止引用文件底部的 styles:类属性初始化器在类定义时即求值, 那一刻 const styles = StyleSheet.create({...}) 尚未初始化 → 取到 undefined → 模块加载即抛 → 首装纯白屏。三个默认视图必须写成内联样式对象。
  • 依赖精简:上游声明的 @react-native-community/async-storage、prop-types、react-native-permissions 与 peer react-native-camera 在鸿蒙实现中均未使用,本包不声明这些依赖(授权改由内置 QRScannerPermission TurboModule 提供)。

开源 License

本项目基于 MIT License,与上游react-native-qrcode-scanner 保持一致,请自由地享受和参与开源。

问题反馈渠道

使用过程中发现任何问题,欢迎在GitCode 提交 Issue,也欢迎提交 PR 参与共建。