0

我已经有这个问题很长时间了。我真的希望有人克服了这个问题。

我们已经有一个正在开发的应用程序,但我们决定构建微前端以将一些功能剥离到单独的模块中。现有的应用程序没有这个问题。

我创建了一个带有纯 react-native 的 react native 模块,其中包含一个示例应用程序来测试它使用 expo。代码大部分是从上面提到的现有应用程序中复制过来的,并在此处和那里进行了一些更改。该模块使用 react-native-paper。

示例应用程序在 ios 和 android 上运行良好,直到我从模块中添加一个使用图标的组件。

例如,在我的模块中,存在以下代码:

 <Modal visible={visible} onDismiss={() => setVisible(false)}>
  <Surface style={styles.containerStyle}>
    <Appbar.Header>
      <Appbar.Action
        icon={{
          uri: 'https://avatars0.githubusercontent.com/u/17571969?v=3&s=400',
        }}
        testID={`${props.textInputProps?.testID}Close`}
        onPress={() => setVisible(false)}
        touchSoundDisabled={false}
      />

我也试过:

<Modal visible={visible} onDismiss={() => setVisible(false)}>
  <Surface style={styles.containerStyle}>
    <Appbar.Header>
      <Appbar.Action
        icon={'close'}
        testID={`${props.textInputProps?.testID}Close`}
        onPress={() => setVisible(false)}
        touchSoundDisabled={false}
      />

和:

 <Modal visible={visible} onDismiss={() => setVisible(false)}>
  <Surface style={styles.containerStyle}>
    <Appbar.Header>
      <Appbar.Action
        icon={() => <MaterialCommunityIcons name="close" />}

(这个给出了一个不同的错误):无法从/../../../../../src/models/FormModel.tsx解析模块@expo/vector-icons/MaterialCommunityIcons:@expo/vector -icons/MaterialCommunityIcons 在项目或以下目录中找不到:../node_modlues 或 ../../../../node_modules

这来自我的示例代码,其中正在调用带有图标的模块代码,并带有指定结果的注释:

 <FormBuilder
          control={formControl.control}
          setFocus={formControl.setFocus}
          formConfigArray={[
            formModel.AddressLine1,
            formModel.AddressLine2,
            formModel.City,
            formModel.Country, //component with icon that gives error
          ]}
        />
        <Button icon="car">Press me</Button> {/* works perfectly */}
        <IconButton icon="check" /> {/* works perfectly */}

从任何组件添加 react-native-paper 中的图标后,我开始收到此错误:

渲染错误 - undefined 不是一个对象(评估 '_$$_REQUIRE(_dependencyMap[6], "react/jsx-runtime").jsx')在 react-native-paper 内的 MaterialCommunitIcons

未捕获的错误 - 需要未知模块“未定义”。如果您确定该模块存在,请尝试重新启动 Metro。您可能还想运行 'yarn' 或 'npm install'

我在 Android 上遇到同样的错误。

我已经尝试在组件中加载字体,但我似乎无法解决这个问题。

请注意,如果我直接从示例文件夹中添加图标,我不会收到任何错误并且图标会呈现

这是我在终端中遇到的错误:

Error: Requiring unknown module "undefined". If you are sure the module exists, try restarting Metro. You may also want to run `yarn` or `npm install`.
Error: Requiring unknown module "undefined". If you are sure the module exists, try restarting Metro. You may also want to run `yarn` or `npm install`.
TypeError: undefined is not an object (evaluating '_$$_REQUIRE(_dependencyMap[6], "react/jsx-runtime").jsx')

This error is located at:
    in Icon
    in ThemedComponent (created by withTheme(Icon))
    in withTheme(Icon) (created by IconButton)
    in RCTView (created by View)
    in View (created by IconButton)
    in RCTView (created by View)
    in View (created by TouchableHighlight)
    in TouchableHighlight
    in Unknown (created by TouchableRipple)
    in TouchableRipple
    in ThemedComponent (created by withTheme(TouchableRipple))
    in withTheme(TouchableRipple) (created by IconButton)
    in IconButton
    in ThemedComponent (created by withTheme(IconButton))
    in withTheme(IconButton) (created by TextInput.Icon)
    in RCTView (created by View)
    in View (created by TextInput.Icon)
    in TextInput.Icon (created by Logic)
    in IconAdornment (created by TextInputAdornment)
    in TextInputAdornment (created by TextInputOutlined)
    in RCTView (created by View)
    in View (created by TextInputOutlined)
    in RCTView (created by View)
    in View (created by TextInputOutlined)
    in TextInputOutlined (created by TextInput)
    in TextInput
    in ThemedComponent (created by withTheme(TextInput))
    in withTheme(TextInput) (created by InputAutocomplete)
    in RCTView (created by View)
    in View (created by InputAutocomplete)
    in RCTView (created by View)
    in View (created by TouchableHighlight)
    in TouchableHighlight
    in Unknown (created by TouchableRipple)
    in TouchableRipple
    in ThemedComponent (created by withTheme(TouchableRipple))
    in withTheme(TouchableRipple) (created by InputAutocomplete)
    in InputAutocomplete (created by Logic)
    in Logic (created by FormBuilder)
    in FormBuilder (created by App)
    in RCTScrollContentView (created by ScrollView)
    in RCTScrollView (created by ScrollView)
    in ScrollView (created by ScrollView)
    in ScrollView (created by App)
    in RCTView (created by View)
    in View (created by App)
    in App (created by ExpoRoot)
    in ExpoRoot
    in RCTView (created by View)
    in View (created by AppContainer)
    in RCTView (created by View)
    in View (created by AppContainer)
    in AppContainer
TypeError: undefined is not an object (evaluating '_$$_REQUIRE(_dependencyMap[6], "react/jsx-runtime").jsx')

This error is located at:
    in Icon
    in ThemedComponent (created by withTheme(Icon))
    in withTheme(Icon) (created by IconButton)
    in RCTView (created by View)
    in View (created by IconButton)
    in RCTView (created by View)
    in View (created by TouchableHighlight)
    in TouchableHighlight
    in Unknown (created by TouchableRipple)
    in TouchableRipple
    in ThemedComponent (created by withTheme(TouchableRipple))
    in withTheme(TouchableRipple) (created by IconButton)
    in IconButton
    in ThemedComponent (created by withTheme(IconButton))
    in withTheme(IconButton) (created by TextInput.Icon)
    in RCTView (created by View)
    in View (created by TextInput.Icon)
    in TextInput.Icon (created by Logic)
    in IconAdornment (created by TextInputAdornment)
    in TextInputAdornment (created by TextInputOutlined)
    in RCTView (created by View)
    in View (created by TextInputOutlined)
    in RCTView (created by View)
    in View (created by TextInputOutlined)
    in TextInputOutlined (created by TextInput)
    in TextInput
    in ThemedComponent (created by withTheme(TextInput))
    in withTheme(TextInput) (created by InputAutocomplete)
    in RCTView (created by View)
    in View (created by InputAutocomplete)
    in RCTView (created by View)
    in View (created by TouchableHighlight)
    in TouchableHighlight
    in Unknown (created by TouchableRipple)
    in TouchableRipple
    in ThemedComponent (created by withTheme(TouchableRipple))
    in withTheme(TouchableRipple) (created by InputAutocomplete)
    in InputAutocomplete (created by Logic)
    in Logic (created by FormBuilder)
    in FormBuilder (created by App)
    in RCTScrollContentView (created by ScrollView)
    in RCTScrollView (created by ScrollView)
    in ScrollView (created by ScrollView)
    in ScrollView (created by App)
    in RCTView (created by View)
    in View (created by App)
    in App (created by ExpoRoot)
    in ExpoRoot
    in RCTView (created by View)
    in View (created by AppContainer)
    in RCTView (created by View)
    in View (created by AppContainer)
    in AppContainer

这是我的 package.json:

{
  "main": "index.js",
  "scripts": {
    "start": "expo start --dev-client",
    "android": "expo start --android",
    "ios": "expo run:ios",
    "web": "expo start --web",
    "test": "jest",
    "e2e:test": "detox test -c android.emu.release  --debug-synchronization 3000 --take-screenshots failing",
    "e2e:build": "RN_SRC_EXT=e2e.ts detox build -c android.emu.release",
    "e2e:ci": "npm run e2e:build && npm run e2e:test",
    "e2e:test-ios": "detox test -c ios.emu.release --debug-synchronization 3000 --take-screenshots failing",
    "e2e:test-ios-showHierarchy": "detox test -c ios.emu.release --debug-synchronization 3000 --take-screenshots failing --capture-view-hierarchy enabled",
    "e2e:build-ios": "RN_SRC_EXT=e2e.ts detox build -c ios.emu.release",
    "e2e:ci-ios": "npm run e2e:build-ios && npm run e2e:test-ios"
  },
  "dependencies": {
    "expo": "~44.0.2",
    "expo-app-loading": "~1.3.0",
    "expo-splash-screen": "~0.14.1",
    "expo-status-bar": "~1.2.0",
    "react": "17.0.1",
    "react-dom": "17.0.1",
    "react-native": "0.64.3",
    "react-native-web": "0.17.1"
  },
  "devDependencies": {
    "@babel/core": "^7.16.5",
    "@babel/preset-env": "^7.16.5",
    "@babel/preset-typescript": "^7.16.5",
    "@expo/vector-icons": "^12.0.5",
    "@types/jest": "^27.0.3",
    "@types/react": "^17.0.38",
    "@types/react-native": "^0.66.10",
    "@types/react-test-renderer": "^17.0.1",
    "babel-jest": "^27.4.5",
    "babel-plugin-module-resolver": "^4.1.0",
    "detox": "^19.3.1",
    "jest": "^27.4.5",
    "react-native-vector-icons": "^9.0.0",
    "typescript": "^4.5.4"
  },
  "private": true
}

我的 app.json:

{
  "expo": {
    "name": "example",
    "slug": "example",
    "version": "1.0.0",
    "icon": "./appIcon.png",
    "assetBundlePatterns": [
      "**/*"
    ]
  },
  "name": "example"
}

我的 babel.config.ts:

const path = require("path");
const pak = require("../package.json");

module.exports = function (api) {
  api.cache(true);
  return {
    presets: [
      "babel-preset-expo",
      ["@babel/preset-env", { targets: { node: "current" } }],
      "@babel/preset-typescript",
    ],
    plugins: [
    [
      "module-resolver",
      {
        extensions: [".tsx", ".ts", ".js", ".json"],
        alias: {
          [pak.name]: path.join(__dirname, "..", pak.source),
        }
      }
    ]
  ]
  };
};

我的 Metro.config.js:

const path = require("path");
const blacklist = require("metro-config/src/defaults/exclusionList");
const escape = require("escape-string-regexp");
const pak = require("../package.json");

const root = path.resolve(__dirname, "..");

const modules = Object.keys({
  ...pak.peerDependencies,
});

module.exports = {
  projectRoot: __dirname,
  watchFolders: [root],

  // We need to make sure that only one version is loaded for peerDependencies
  // So we blacklist them at the root, and alias them to the versions in example's node_modules
  resolver: {
    blacklistRE: blacklist(
      modules.map(
        (m) =>
          new RegExp(`^${escape(path.join(root, "node_modules", m))}\\/.*$`)
      )
    ),

    extraNodeModules: modules.reduce((acc, name) => {
      acc[name] = path.join(__dirname, "node_modules", name);
      return acc;
    }, {}),
  },

  transformer: {
    getTransformOptions: async () => ({
      transform: {
        experimentalImportSupport: false,
        inlineRequires: true,
      },
    }),
  },
};

请帮忙!!

4

1 回答 1

0

我的同事设法解决了这个问题,所以我想在这里分享一下,以防其他人遇到这个问题。

正在发生的事情是示例应用程序对它应该使用哪些矢量图标感到困惑,因为示例应用程序中的 expo 是矢量图标,而示例应用程序外部的模块具有反应本机矢量图标。关键是在你的模块中指定这些依赖项应该来自调用应用程序而不是模块。

为此,您在模块的“peerDependencies”中指定这些模块,以便使用示例中的 npm 包,而不是模块中的 npm 包:

  "peerDependencies": {
     "@expo/vector-icons": "*",
     "expo-font": "*",
     "lodash": "*",
     "lodash.isstring": "*",
     "react": "*",
     "react-native": "*",
     "react-native-vector-icons": "*",
     "react-native-paper": "*"
   },

希望这可以帮助世界上的其他人,因为它有我。

PS,我现在欠我同事一个月的咖啡!

于 2022-01-24T13:19:54.573 回答