expo / config-plugins

Out-of-tree Expo config plugins for packages that haven't adopted the config plugin system yet.
465 stars 99 forks source link

fix: event-target-shim/package.json Package subpath './index' is not defined in `react-native-webrtc` config plugin #235

Open mrakesh0608 opened 5 months ago

mrakesh0608 commented 5 months ago

Why

Fixes #1569

How

react-native-webrtc already forcing to use the correct event-target-shim module #1515.

Test

When event-target-shim is requested by react-native-webrtc, Metro by default resolves event-target-shim relative to react-native-webrtc.

When both variables isEventTargetShimPkg and isWebrtc are true, event-target-shim is resolved relative to react-native-webrtc, as shown in the video.

So, there is no need to explicitly resolve event-target-shim for react-native-webrtc.

https://github.com/expo/config-plugins/assets/101246871/6ad38742-4145-4b07-9047-b3fb8b7652c1

Screenshot 2024-05-16 at 7 33 41 PM

mrakesh0608 commented 5 months ago

Hi @EvanBacon, I have tested Expo SDK 50 with react-native-webrtc@118.0.4 and @config-plugins/react-native-webrtc@7.0.0, and it is working fine. I think it would be better if we update the compatibility table.

Chirag-kalsariya commented 3 months ago

This issue still in my new project.

I am using Turborepo.

`Android Bundling failed 16847ms index.js (1 module) Unable to resolve "event-target-shim/index" from "../../node_modules/@stream-io/react-native-webrtc/src/MediaDevices.ts" ERROR [Error: undefined Unable to resolve module event-target-shim/index from /Users/chirag/Heatrabbit/client-tamagui/node_modules/@stream-io/react-native-webrtc/src/MediaDevices.ts: event-target-shim/index could not be found within the project or in these directories: node_modules ../../node_modules

1 | import { EventTarget, Event, defineEventAttribute } from 'event-target-shim/index'; | ^ 2 | import { NativeModules } from 'react-native'; 3 | 4 | import getDisplayMedia from './getDisplayMedia';] `

My packages: "expo": "^51.0.0", "react-native": "0.74.2", "@stream-io/react-native-webrtc": "^118.1.0", "@config-plugins/react-native-webrtc": "^9.0.0"

mrakesh0608 commented 3 months ago

@Chirag-kalsariya Could you please share your metro.config.js ?

Chirag-kalsariya commented 3 months ago

Here it is my metro-config.js

const { getDefaultConfig } = require('@expo/metro-config')
const path = require('path')

const projectRoot = __dirname
const workspaceRoot = path.resolve(projectRoot, '../..')

const config = getDefaultConfig(projectRoot)

// 1. Watch all files within the monorepo
config.watchFolders = [workspaceRoot]
// 2. Let Metro know where to resolve packages and in what order
config.resolver.nodeModulesPaths = [
  path.resolve(projectRoot, 'node_modules'),
  path.resolve(workspaceRoot, 'node_modules'),
]
// 3. Force Metro to resolve (sub)dependencies only from the `nodeModulesPaths`
config.resolver.disableHierarchicalLookup = true

config.transformer = { ...config.transformer, unstable_allowRequireContext: true }
config.transformer.minifierPath = require.resolve('metro-minify-terser')

module.exports = config

If i use this I get above error. error

Now I change it my metro-config.js like this

const { getDefaultConfig } = require('@expo/metro-config')
const path = require('path')
const resolveFrom = require('resolve-from')

const projectRoot = __dirname
const workspaceRoot = path.resolve(projectRoot, '../..')

const config = getDefaultConfig(projectRoot)

// 1. Watch all files within the monorepo
config.watchFolders = [workspaceRoot]
// 2. Let Metro know where to resolve packages and in what order
config.resolver.nodeModulesPaths = [
  path.resolve(projectRoot, 'node_modules'),
  path.resolve(workspaceRoot, 'node_modules'),
]
// 3. Force Metro to resolve (sub)dependencies only from the `nodeModulesPaths`
config.resolver.disableHierarchicalLookup = true

config.transformer = { ...config.transformer, unstable_allowRequireContext: true }
config.transformer.minifierPath = require.resolve('metro-minify-terser')

config.resolver.resolveRequest = (context, moduleName, platform) => {
  if (
    // If the bundle is resolving "event-target-shim" from a module that is part of "react-native-webrtc".
    moduleName.startsWith('event-target-shim') &&
    context.originModulePath.includes('react-native-webrtc')
  ) {
    console.log('event-target-shim', moduleName.startsWith('event-target-shim'))
    console.log('react-native-webrtc', context.originModulePath.includes('react-native-webrtc'))
    // Resolve event-target-shim relative to the react-native-webrtc package to use v6.
    // React Native requires v5 which is not compatible with react-native-webrtc.
    const eventTargetShimPath = resolveFrom(context.originModulePath, moduleName)

    console.log('eventTargetShimPath', eventTargetShimPath)

    return {
      filePath: eventTargetShimPath,
      type: 'sourceFile',
    }
  }

  // Ensure you call the default resolver.
  return context.resolveRequest(context, moduleName, platform)
}

module.exports = config

Now I am getting this error

event-target-shim true
react-native-webrtc true
event-target-shim true
react-native-webrtc true
event-target-shim true
react-native-webrtc true
event-target-shim true
react-native-webrtc true
event-target-shim true
react-native-webrtc true
event-target-shim true
react-native-webrtc true
Android Bundling failed 9100ms index.js (4737 modules)
error: Error: Package subpath './index' is not defined by "exports" in /Users/chirag/Heatrabbit/client-tamagui/node_modules/@stream-io/react-native-webrtc/node_modules/event-target-shim/package.json
    at exportsNotFound (node:internal/modules/esm/resolve:304:10)
    at packageExportsResolve (node:internal/modules/esm/resolve:651:9)
    at resolveExports (node:internal/modules/cjs/loader:590:36)
    at Function.Module._findPath (node:internal/modules/cjs/loader:667:31)
    at Function.Module._resolveFilename (node:internal/modules/cjs/loader:1129:27)
    at resolveFileName (/Users/chirag/Heatrabbit/client-tamagui/node_modules/resolve-from/index.js:29:39)
    at resolveFrom (/Users/chirag/Heatrabbit/client-tamagui/node_modules/resolve-from/index.js:43:9)
    at module.exports (/Users/chirag/Heatrabbit/client-tamagui/node_modules/resolve-from/index.js:46:47)
    at firstResolver (/Users/chirag/Heatrabbit/client-tamagui/apps/expo/metro.config.js:38:33)
    at resolveRequest (/Users/chirag/Heatrabbit/client-tamagui/node_modules/@expo/cli/src/start/server/metro/withMetroResolvers.ts:108:16)

One more thing I am using @stream-io/react-native-webrtc, And I think it is same as react-native-webrtc.

Chirag-kalsariya commented 3 months ago

Let me verify this issue again using react-native-webrtc in Turborepo with expo 51.

mrakesh0608 commented 3 months ago

Just remove this lines from your metro.config.js.

// 3. Force Metro to resolve (sub)dependencies only from the nodeModulesPaths config.resolver.disableHierarchicalLookup = true

Try this metro.config.js.

const { getDefaultConfig } = require("@expo/metro-config");
const path = require("path");

const projectRoot = __dirname;
const workspaceRoot = path.resolve(projectRoot, "../..");

const config = getDefaultConfig(projectRoot);

// 1. Watch all files within the monorepo
config.watchFolders = [workspaceRoot];
// 2. Let Metro know where to resolve packages and in what order
config.resolver.nodeModulesPaths = [path.resolve(projectRoot, "node_modules"), path.resolve(workspaceRoot, "node_modules")];

config.transformer = { ...config.transformer, unstable_allowRequireContext: true };
config.transformer.minifierPath = require.resolve("metro-minify-terser");

module.exports = config;
Chirag-kalsariya commented 3 months ago

Yes, Above metro config is working, No errors.

And, I also test new expo project not with monorepo, react-native-webrtc is working fine without change on metro-config.js. Now no need to add resolveRequest for event-target-shim in metro-config.js.

bohdan145 commented 3 months ago

I am having a bit of a different problem When I remove config.resolver.disableHierarchicalLookup = true from metro.config.js I receive this warning in the console when the build is just starting.

Attempted to import the module "/Projects/towme-turborepo/packages/mobile-ui/node_modules/@stream-io/react-native-webrtc/node_modules/event-target-shim/index" which is not listed in the "exports" of "Projects/towme-turborepo/packages/mobile-ui/node_modules/@stream-io/react-native-webrtc/node_modules/event-target-shim". Falling back to file-based resolution. Consider updating the call site or ask the package maintainer(s) to expose this API?

And after the build is completed getting these repeating errors ERROR Invariant Violation: No callback found with cbID 0 and callID 0 for module <unknown>. Args: '[{"app_state":"active"}]', js engine: hermes ERROR Invariant Violation: No callback found with cbID 14 and callID 7 for module <unknown>. Args: '[{"app_state":"active"}]', js engine: hermes ERROR Invariant Violation: No callback found with cbID 54 and callID 27 for module <unknown>. Args: '["{\"codeFrame\":{\"content\":\"\\u001b[0m \\u001b[90m 26 |\\u001b[39m __classPrivateFieldSet\\u001b[33m,\\u...(truncated)..."]', js engine: hermes ERROR Invariant Violation: No callback found with cbID 84 and callID 42 for module <unknown>. Args: '["{\"codeFrame\":{\"content\":\"\\u001b[0m \\u001b[90m 207 |\\u001b[39m )\\u001b[33m;\\u001b[39m\\n \\u001b[...(truncated)..."]', js engine: hermes ERROR Invariant Violation: No callback found with cbID 86 and callID 43 for module <unknown>. Args: '["{\"codeFrame\":null,\"stack\":[{\"methodName\":\"invariant\",\"file\":\"/Users/bohdandidchenko/Projects/towme-t...(truncated)..."]', js engine: hermes

My metro.config.js looks like this

const { getDefaultConfig } = require("expo/metro-config");
const { FileStore } = require("metro-cache");
const path = require("path");

// Find the workspace root, this can be replaced with `find-yarn-workspace-root`
const workspaceRoot = path.resolve(__dirname, "../..");
const projectRoot = __dirname;

const config = getDefaultConfig(projectRoot);

const monorepoPackages = {
  "@repo/mobile-assets": path.resolve(workspaceRoot, "packages/mobile-assets"),
  "@repo/mobile-ui": path.resolve(workspaceRoot, "packages/mobile-ui"),
  "@repo/services": path.resolve(workspaceRoot, "packages/services"),
  "@repo/types": path.resolve(workspaceRoot, "packages/types"),
  "@repo/locales": path.resolve(workspaceRoot, "packages/locales"),
};

// 1. Watch the local app folder, and only the shared packages (limiting the scope and speeding it up)
config.watchFolders = [projectRoot, ...Object.values(monorepoPackages)];

// Add the monorepo workspaces as `extraNodeModules` to Metro.
// If your monorepo tooling creates workspace symlinks in the `node_modules` folder,
// you can either add symlink support to Metro or set the `extraNodeModules` to avoid the symlinks.
// See: https://facebook.github.io/metro/docs/configuration/#extranodemodules
config.resolver.extraNodeModules = monorepoPackages;

// 2. Let Metro know where to resolve packages, and in what order
config.resolver.nodeModulesPaths = [
  path.resolve(projectRoot, "node_modules"),
  path.resolve(workspaceRoot, "node_modules"),
];

// Use turborepo to restore the cache when possible
config.cacheStores = [
  new FileStore({ root: path.join(projectRoot, "node_modules", ".cache", "metro") }),
];

// 3. Force Metro to resolve (sub)dependencies only from the `nodeModulesPaths`
// config.resolver.disableHierarchicalLookup = true;
config.resolver.unstable_enablePackageExports = true;
config.resolver.unstable_conditionNames = ["browser", "require", "import", "react-native"];

module.exports = config;

But when config.resolver.disableHierarchicalLookup = true is present getting this error after app is launched Unable to resolve "event-target-shim/index" from "../../node_modules/@stream-io/react-native-webrtc/src/MediaDevices.ts"