/** @type {import('expo/metro-config').MetroConfig} */ const { getDefaultConfig } = require('expo/metro-config'); const path = require('path'); const config = getDefaultConfig(__dirname); // Add wasm asset support config.resolver.assetExts.push('wasm'); // Fix for react-native-webrtc event-target-shim import warning // The package doesn't properly export "./index" in its exports field config.resolver.unstable_enablePackageExports = false; // Support TypeScript path aliases (@/ -> ./src/) config.resolver.alias = { '@': path.resolve(__dirname, 'src'), }; // Ensure platform-specific files are resolved correctly config.resolver.platforms = ['ios', 'android', 'native', 'web']; // Web shims for native-only React Native APIs that don't exist in react-native-web. // Packages like react-native-pager-view import codegenNativeComponent from // react-native/Libraries/Utilities/codegenNativeComponent, which calls // requireNativeComponent internally. On web (react-native-web), these APIs // don't exist, causing "(0 , _reactNativeWebDistIndex.requireNativeComponent) // is not a function". const webShimPaths = [ 'react-native/Libraries/Utilities/codegenNativeComponent', 'react-native/Libraries/Utilities/codegenNativeCommands', 'react-native/Libraries/Types/CodegenTypes', 'react-native/Libraries/ReactNative/requireNativeComponent', ]; // Packages that should be entirely replaced with web shims on web platform. // These packages import requireNativeComponent directly from 'react-native' // (which resolves to react-native-web on web) and don't have web implementations. const webPackageShims = { 'react-native-webrtc': path.resolve(__dirname, 'web-shims/react-native-webrtc/index.js'), }; const originalResolveRequest = config.resolver.resolveRequest; const shimDir = path.resolve(__dirname, 'web-shims'); config.resolver.resolveRequest = (context, moduleName, platform) => { // Redirect entire native-only packages to web shims if (platform === 'web' && webPackageShims[moduleName]) { return { type: 'sourceFile', filePath: webPackageShims[moduleName], }; } // Redirect specific React Native internal modules to web shims if (platform === 'web' && webShimPaths.some((p) => moduleName.endsWith(p))) { // For requireNativeComponent, the path doesn't follow the Libraries/* pattern if (moduleName.endsWith('react-native/Libraries/ReactNative/requireNativeComponent')) { return { type: 'sourceFile', filePath: path.join(shimDir, 'react-native', 'Libraries', 'ReactNative', 'requireNativeComponent.js'), }; } const shimName = moduleName.replace('react-native/Libraries/', ''); return { type: 'sourceFile', filePath: path.join(shimDir, 'react-native', 'Libraries', shimName + '.js'), }; } if (originalResolveRequest) { return originalResolveRequest(context, moduleName, platform); } return context.resolveRequest(context, moduleName, platform); }; // NOTE: enhanceMiddleware is marked as deprecated in Metro's types, // but there's currently no official alternative for custom dev server headers. // For production, configure COEP/COOP headers on your hosting platform. // These headers are required for SharedArrayBuffer (used by expo-sqlite on web). config.server.enhanceMiddleware = (middleware) => { return (req, res, next) => { res.setHeader('Cross-Origin-Embedder-Policy', 'credentialless'); res.setHeader('Cross-Origin-Opener-Policy', 'same-origin'); middleware(req, res, next); }; }; module.exports = config;