Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bundled Expo DOM with Metro #1427

Open
julienqueffelec opened this issue Jan 16, 2025 · 1 comment
Open

Bundled Expo DOM with Metro #1427

julienqueffelec opened this issue Jan 16, 2025 · 1 comment

Comments

@julienqueffelec
Copy link

I'm trying to get Expo DOM to work on a monorepo using Rush (from Microsoft)

I'm having trouble because Metro doesn't seem to compile linked to React Native

The error I have in output:
Image

My metro config:

  • I deliberately put a hard path to see that it works, I should do this better
const path = require('path');
const { getDefaultConfig } = require('expo/metro-config');
const MetroSymlinksResolver = require('@rnx-kit/metro-resolver-symlinks');
const { getSentryExpoConfig } = require('@sentry/react-native/metro');

// Define absolute paths
const projectRoot = path.resolve(__dirname);
const workspaceRoot = path.resolve(projectRoot, '../..'); // Path to the abby root

const defaultConfig = getDefaultConfig(projectRoot);
const sentryConfig = getSentryExpoConfig(projectRoot, {
  annotateReactComponents: true,
  enableSourceContextInDevelopment: true
});

const config = {
  ...defaultConfig,
  ...sentryConfig
};

// SVG configuration
config.transformer = {
  ...config.transformer,
  babelTransformerPath: require.resolve('react-native-svg-transformer'),
  getTransformOptions: async () => ({
    transform: {
      experimentalImportSupport: false,
      inlineRequires: true
    }
  })
};

// Resolver configuration
config.resolver = {
  ...config.resolver,
  assetExts: [
    ...config.resolver.assetExts.filter(ext => ext !== 'svg'),
    'lottie'
  ],
  sourceExts: [...config.resolver.sourceExts, 'svg', 'd.ts'],
  unstable_enablePackageExports: true,
  useWatchman: true,
  unstable_conditionNames: ['browser', 'require', 'react-native'],
  extraNodeModules: {
    stream: require.resolve('readable-stream')
  },
  // Configure module paths
  nodeModulesPaths: [
    path.resolve(projectRoot, 'node_modules'),
    path.resolve(workspaceRoot, 'common/temp/mobile/node_modules'),
    path.resolve(
      workspaceRoot,
      'common/temp/mobile/node_modules/.pnpm/node_modules'
    )
  ],
  disableHierarchicalLookup: true
};

// Configure symlink resolver
const symlinkResolver = MetroSymlinksResolver({
  experimental_retryResolvingFromDisk: 'force'
});

// Custom resolver
config.resolver.resolveRequest = (context, moduleName, platform) => {
  // Handle aliases
  if (moduleName.startsWith('@/') || moduleName.startsWith('@assets/')) {
    return context.resolveRequest(context, moduleName, platform);
  }

  // Handle storybook
  if (
    process.env.STORYBOOK_ENABLED !== 'true' &&
    moduleName.includes('.storybook')
  ) {
    return { type: 'empty' };
  }

  // Handle special web platform cases

  if (platform === 'web' && moduleName.includes('expo/dom/internal')) {
    const webModulesPath = workspaceRoot;
    console.log('yo', path.resolve(webModulesPath, moduleName));

    return symlinkResolver(
      context,
      '/Users/..../node_modules/.pnpm/[email protected]_@[email protected]_@[email protected]_@[email protected]__@expo+dom-webvie_vxjsci2yupb2qjiqh47icvsgve/node_modules/expo/dom/internal.js',
      platform
    );
  }

  if (platform === 'web' && moduleName.includes('expo/dom')) {
    const webModulesPath = workspaceRoot;
    console.log(path.resolve(webModulesPath, moduleName));
    console.log(
      'path.resolve(webModulesPath, moduleName)',
      JSON.stringify(path.resolve(webModulesPath, moduleName), null, 2)
    );
    return symlinkResolver(
      context,
      path.resolve(webModulesPath, moduleName),
      platform
    );
  }

  return symlinkResolver(context, moduleName, platform);
};

// Watch configuration - only watch necessary folders
config.watchFolders = [
  projectRoot,
  path.resolve(workspaceRoot, 'common/temp/mobile')
];

module.exports = config;

Dependences used:

  • "expo": "~52.0.25",
  • "metro-config": "~0.81.0",
@julienqueffelec
Copy link
Author

I made a simple repo to reproduce the problem https://github.com/julienqueffelec/rush-expo-dom-demo

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant