我正在建立一个Yarn 3 Monorepo使用该应用程序的 react native .我有一个应用程序和一个用户界面包.在UI包中,我使用AsyncStorage设置如下所示的值

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

export const ThemeProvider: React.FC<IProvider> = () => {
    useEffect(() => {
    const storeValue = async () => {
      try {
        await AsyncStorage.setItem("value", JSON.stringify("test"));
      } catch (error) {
        console.log(error);
      }
    };

    storeValue();
  }, []);

...
}

现在,当我通过我的lib工作区导入和使用这段代码时.我收到以下错误[TypeError: Cannot read property 'setItem' of undefined]

是的,我在应用程序和用户界面工作区上都安装了@REACT-Native-Async-Storage/Async-Storage

如果我在应用程序中直接使用await AsyncStorage.setItem("value", JSON.stringify("test"));,它工作得很好.只是如果代码来自依赖项(我的UI工作区)

UPDATE

下面是我的Metro在Reaction原生工作区中的样子

const { makeMetroConfig } = require('@rnx-kit/metro-config')
const MetroSymlinksResolver = require('@rnx-kit/metro-resolver-symlinks')
const { getDefaultConfig } = require('metro-config')
const exclusionList = require('metro-config/src/defaults/exclusionList')
const path = require('path')

module.exports = async () => {
  const {
    resolver: { sourceExts, assetExts },
  } = await getDefaultConfig()

  return makeMetroConfig({
    resolver: {
      resolveRequest: MetroSymlinksResolver(),
      symlinks: false,
      blockList: exclusionList([
        /^((?!rnapp).)+[\/\\]node_modules[/\\]react-native[/\\].*/,
        /ui[\/\\]node_modules[/\\]react-native-svg[/\\].*/,
        /ui[\/\\]node_modules[/\\]react-native-safe-area-context[/\\].*/,
      ]),
      extraNodeModules: {
        // Resolve all react-native module imports to the locally-installed version
        'react-native': path.resolve(__dirname, 'node_modules', 'react-native'),

        // Resolve additional nohoist modules depended on by other packages
        'react-native-svg': path.resolve(__dirname, 'node_modules', 'react-native-svg'),
        'react-native-safe-area-context': path.resolve(__dirname, 'node_modules', 'react-native-safe-area-context'),
        '@react-native-async-storage/async-storage': path.resolve(
          __dirname,
          'node_modules',
          '@react-native-async-storage/async-storage'
        ),

        // Resolve core-js imports to the locally installed version
        'core-js': path.resolve(__dirname, 'node_modules', 'core-js'),
      },

      assetExts: assetExts.filter(ext => ext !== 'svg'),
      sourceExts: [...sourceExts, 'svg'],
    },
    transformer: {
      babelTransformerPath: require.resolve('react-native-svg-transformer'),
      getTransformOptions: async () => ({
        transform: {
          experimentalImportSupport: false,
          inlineRequires: true,
        },
      }),
    },
  })
}

文件 struct

├── apps
│   └── rnapp
│       ├── src
│       └── package.json
├── packages
│   └── ui
│       ├── src
│       ├── dist (generated by rollup, also ignored by git)
│       └── package.json
├── README.md
└── package.json

Rnapp Package.json

{
  "name": "@app/rnapp",
  "packageManager": "yarn@3.5.1",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "android": "react-native run-android",
    "ios": "react-native run-ios",
    "lint": "eslint .",
    "start": "react-native start --reset-cache",
    "test": "jest"
  },
  "dependencies": {
    "@app/ui": "1.0.0",
    "@react-native-async-storage/async-storage": "^1.18.1",
    "@react-native-community/cli-platform-ios": "^11.3.0",
    "@react-navigation/bottom-tabs": "^6.5.7",
    "@react-navigation/native": "^6.1.6",
    "@react-navigation/native-stack": "^6.9.12",
    "@reduxjs/toolkit": "^1.9.5",
    "date-fns": "^2.30.0",
    "humps": "^2.0.1",
    "lottie-ios": "3.4.0",
    "lottie-react-native": "^5.1.6",
    "qs": "^6.11.1",
    "react": "18.2.0",
    "react-native": "0.71.8",
    "react-native-flipper": "^0.190.0",
    "react-native-gesture-handler": "^2.10.1",
    "react-native-keyboard-aware-scroll-view": "^0.9.5",
    "react-native-safe-area-context": "4.5.3",
    "react-native-screens": "^3.20.0",
    "react-native-sensitive-info": "^5.5.8",
    "react-native-svg": "^13.9.0",
    "react-redux": "^8.0.5",
    "redux": "^4.2.1",
    "redux-deep-persist": "^1.0.7",
    "redux-flipper": "^2.0.2",
    "redux-persist": "^6.0.0",
    "redux-persist-sensitive-storage": "^1.0.0"
  },
  "devDependencies": {
    "@babel/core": "^7.20.0",
    "@babel/plugin-syntax-flow": "^7.21.4",
    "@babel/plugin-transform-react-jsx": "^7.21.5",
    "@babel/preset-env": "^7.20.0",
    "@babel/runtime": "^7.20.0",
    "@react-native-community/eslint-config": "^3.2.0",
    "@rnx-kit/metro-config": "^1.3.6",
    "@rnx-kit/metro-resolver-symlinks": "^0.1.28",
    "@tsconfig/react-native": "^2.0.2",
    "@types/humps": "^2.0.2",
    "@types/jest": "29.2.1",
    "@types/qs": "^6.9.7",
    "@types/react": "18.0.24",
    "@types/react-test-renderer": "18.0.0",
    "babel-jest": "^29.2.1",
    "babel-plugin-module-resolver": "5.0.0",
    "eslint": "^8.19.0",
    "eslint-config-prettier": "8.8.0",
    "eslint-import-resolver-typescript": "3.5.5",
    "eslint-plugin-flowtype": "8.0.3",
    "eslint-plugin-import": "2.27.5",
    "eslint-plugin-module-resolver": "1.5.0",
    "eslint-plugin-prettier": "4.2.1",
    "eslint-plugin-react": "7.32.2",
    "eslint-plugin-react-hooks": "4.6.0",
    "get-yarn-workspaces": "^1.0.2",
    "jest": "^29.2.1",
    "metro-config": "^0.76.4",
    "metro-react-native-babel-preset": "0.73.9",
    "prettier": "^2.4.1",
    "react-native-dotenv": "3.4.8",
    "react-native-svg-transformer": "^1.0.0",
    "react-test-renderer": "18.2.0",
    "typescript": "4.8.4"
  },
  "jest": {
    "preset": "react-native"
  }
}

我打包了.json

{
  "name": "@app/ui",
  "packageManager": "yarn@3.5.1",
  "version": "1.0.0",
  "main": "dist/index.js",
  "types": "dist/index.d.ts",
  "module": "dist/index.js",
  "private": true,
  "scripts": {
    "build": "rm -rf ./dist && rollup -c",
    "storybook": "storybook dev",
    "storybook:build": "storybook build"
  },
  "dependencies": {
    "@react-native-async-storage/async-storage": "^1.18.1",
    "@react-native-community/hooks": "^3.0.0",
    "@rollup/plugin-typescript": "^11.1.1",
    "lottie-ios": "3.4.0",
    "lottie-react-native": "^5.1.6",
    "react": "^18.2.0",
    "react-native": "0.71.8",
    "react-native-pixel-perfect": "^1.0.2",
    "react-native-safe-area-context": "4.5.3",
    "react-native-svg": "^13.9.0"
  },
  "devDependencies": {
    "@babel/core": "^7.21.4",
    "@babel/plugin-transform-modules-commonjs": "^7.21.2",
    "@babel/preset-env": "^7.21.5",
    "@babel/preset-react": "^7.18.6",
    "@babel/preset-typescript": "^7.21.5",
    "@babel/runtime": "^7.20.0",
    "@react-native-community/datetimepicker": "^7.0.1",
    "@react-native-community/eslint-config": "^3.2.0",
    "@react-native-community/slider": "^4.4.2",
    "@rollup/plugin-babel": "^6.0.3",
    "@rollup/plugin-commonjs": "^25.0.0",
    "@rollup/plugin-json": "^6.0.0",
    "@rollup/plugin-node-resolve": "^15.0.2",
    "@storybook/addon-actions": "^7.0.12",
    "@storybook/addon-controls": "^7.0.12",
    "@storybook/addon-docs": "^7.0.12",
    "@storybook/addon-essentials": "^7.0.12",
    "@storybook/addon-interactions": "^7.0.12",
    "@storybook/addon-jest": "^7.0.12",
    "@storybook/addon-links": "^7.0.12",
    "@storybook/addon-mdx-gfm": "^7.0.12",
    "@storybook/addon-react-native-web": "^0.0.20",
    "@storybook/api": "^7.0.12",
    "@storybook/cli": "^7.0.12",
    "@storybook/react": "^7.0.12",
    "@storybook/react-native": "^6.5.3",
    "@storybook/react-webpack5": "^7.0.12",
    "@testing-library/jest-native": "^5.4.2",
    "@testing-library/react": "^14.0.0",
    "@testing-library/react-native": "^12.0.1",
    "@types/jest": "^29.2.1",
    "@types/react": "^18.0.24",
    "@types/react-test-renderer": "^18.0.0",
    "babel-jest": "^29.5.0",
    "babel-loader": "^8.3.0",
    "babel-plugin-react-native-web": "^0.19.2",
    "eslint": "^8.19.0",
    "eslint-config-prettier": "^8.8.0",
    "eslint-import-resolver-typescript": "^3.5.5",
    "eslint-plugin-flowtype": "^8.0.3",
    "eslint-plugin-import": "^2.27.5",
    "eslint-plugin-module-resolver": "^1.5.0",
    "eslint-plugin-prettier": "^4.2.1",
    "eslint-plugin-react": "^7.32.2",
    "eslint-plugin-react-hooks": "^4.6.0",
    "jest": "^29.2.1",
    "jest-environment-jsdom": "^29.5.0",
    "react-dom": "^18.2.0",
    "react-native-web": "~0.18.10",
    "react-test-renderer": "18.2.0",
    "rollup": "^3.22.0",
    "rollup-plugin-terser": "^7.0.2",
    "storybook": "^7.0.12",
    "storybook-dark-mode": "^3.0.0",
    "typescript": "^5.0.4"
  },
  "eslintIgnore": [
    "node_modules/",
    "dist/"
  ],
  "prettierIgnore": [
    "node_modules/",
    "dist/"
  ]
}

Root Package.json

{
  "name": "@app/monorepo",
  "packageManager": "yarn@3.5.1",
  "private": true,
  "scripts": {
    "clean": "find . -name 'node_modules' -type d -prune -exec rm -rf '{}' + && rm -rf apps/rnapp/ios/Pods",
    "app:start": "yarn workspace @app/rnapp run start",
    "app:pod": "cd apps/rnapp/ios && pod install",
    "ui:build": "yarn workspace @app/ui run build",
    "ui:storybook": "yarn workspace @app/ui run storybook"
  },
  "workspaces": [
    "apps/rnapp",
    "packages/ui"
  ]
}

.yarnrc

yarnPath: .yarn/releases/yarn-3.5.1.cjs
nodeLinker: node-modules
nmHoistingLimits: workspaces

推荐答案

因此,我找到了一个与我的用例类似的Monorepo示例,它帮助我找到了我的问题.

原来我需要我的共享包(UI包)来使用peerDependency而不是Package.json中的依赖项.

https://github.com/crutchcorn/react-native-monorepo-example/tree/main

React-native相关问答推荐

PubNubReact无法工作,因为它已被废弃

如何在EXPO路由中重置导航

1.5.1 nxworkspace+react-native 版本的Axios url未定义问题

如何在react native 中从 axios 重定向并将数据传递给路由

PanResponder 在第二次拖动时将 Animated.View 捕捉回原始位置

React 从 babel 6 到 babel 7 的原生升级

为什么会出现此错误:Invariant Violation: Cannot update during an existing state transition

React-native 组件的 elevation样式导致的阴影

iPhone 6s plus 上的字体大小

使用带有 react-native 的 WebView 设置用户代理

React-Native + crypto:如何在 React-Native 中生成 HMAC?

null 不是对象(判断 this.state.count)

我可以将标题传递给图像源吗?

通过 ToolbarAndroid => onIconClicked 显示 DrawerLayoutAndroid

XCode AppIcon 基于方案

React Native 中使用了哪些维度单位?

React Native:使用选项卡动画收缩标题

在 React-native 上加载图像时出错:Unexpected character

如何从react-native应用程序打开外部应用程序?

react-navigation 标题有一条微弱的线