You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Yarn 3 Monorepo中UI包调用AsyncStorage.setItem报undefined错误

React Native Yarn 3 Monorepo UI包调用AsyncStorage报错解决指南

问题说明

用Yarn 3搭建的React Native monorepo项目,包含主App工程rnapp和一个独立UI包。UI包内的ThemeProvider组件调用@react-native-async-storage/async-storage的setItem方法时,主App引入该UI包会触发以下错误:

[TypeError: Cannot read property 'setItem' of undefined]

已确认主App和UI包均安装该依赖,主App直接调用setItem正常,仅通过UI包调用时出错。

问题根源

  1. 原生模块解析缺失:AsyncStorage属于原生模块,Metro默认未对monorepo子包做完整的原生依赖解析,导致UI包无法获取正确的模块实例
  2. 依赖隔离/重复实例:Yarn 3的依赖隔离机制可能让UI包与主App的AsyncStorage实例不共享,或版本不一致引发冲突

解决步骤

1. 统一依赖配置,避免重复安装

  • 在根目录package.json中,将@react-native-async-storage/async-storage声明为工作区共享依赖:
{
  "workspaces": {
    "packages": ["rnapp", "packages/ui"],
    "dependencies": {
      "@react-native-async-storage/async-storage": "^1.19.0"
    }
  }
}
  • 在UI包的package.json中,将该依赖移至peerDependencies,复用主App的依赖实例:
{
  "peerDependencies": {
    "@react-native-async-storage/async-storage": "^1.19.0"
  }
}
  • 执行yarn install更新依赖

2. 修改Metro配置,支持子包解析

编辑主App的metro.config.js,让Metro识别工作区中的UI包:

const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config');
const path = require('path');

module.exports = mergeConfig(getDefaultConfig(__dirname), {
  resolver: {
    extraNodeModules: {
      // 替换为你的UI包实际名称
      "your-ui-package-name": path.resolve(__dirname, "../packages/ui")
    }
  },
  watchFolders: [
    path.resolve(__dirname, "../packages/ui")
  ]
});

3. 规范UI包的导入方式

UI包必须使用标准导入语法,禁止使用相对路径或非官方导入:

import AsyncStorage from '@react-native-async-storage/async-storage';

// ThemeProvider中的使用示例
const saveTheme = async (themeValue) => {
  try {
    await AsyncStorage.setItem('app-theme', themeValue);
  } catch (err) {
    console.error('存储主题失败:', err);
  }
};

4. 清除缓存并重建项目

执行以下命令彻底清除缓存,避免旧缓存干扰:

# 清除Metro缓存
npx metro-cache clean

# 进入主App目录清除React Native缓存
cd rnapp && npx react-native clean

# 重新构建项目(根据平台选择)
cd rnapp && npx react-native run-android # iOS环境用run-ios

验证方法

  1. 在UI包的ThemeProvider中添加测试代码,调用AsyncStorage.getItem验证模块实例是否正常
  2. 主App引入UI包后运行项目,检查是否仍出现报错
  3. 执行yarn why @react-native-async-storage/async-storage查看依赖树,确认该依赖仅存在一个实例

内容的提问来源于stack exchange,提问作者themaster

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 04:47:01