我正在建立一个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