Marc Lu
Marc Lu

Reputation: 11

Unable to use react-native-web-maps in expo

I'm trying to add a map to my project, so I used react-native-maps in native, and @teovilla/react-native-web-maps in web.

Here is the dependencies in package.json

 "dependencies": {
    .....
    "@react-navigation/native": "^6.0.2",
    "@teovilla/react-native-web-maps": "^0.9.3",
    "expo": "~49.0.11",
    "expo-router": "^2.0.9",
    "react-native": "0.72.6",
    "react-native-maps": "1.7.1",
    "react-native-web": "~0.19.6",
    .....
  },

I tried several ways to set up config for @teovilla/react-native-web-maps but it's still not working.

1. @teovilla/react-native-web-maps config with Webpack, but I use Metro (with expo router v2). So I tried the way in Map for React Native Web With Expo and Metro
// /components/mymap.web.js
import MapView from "@teovilla/react-native-web-maps";
export default MapView;
// /components/mymap.js
import MapView from 'react-native-maps';
export default MapView;

// in my component
import MapView from '../components/mymap';

compile success, but the map did not show in web.

2. set the webpack.config.js as the docs
// webpack.config.js

module.exports = async function (env, argv) {
  const config = await createExpoWebpackConfigAsync(env, argv);

  config.resolve.alias['react-native-maps'] = '@teovilla/react-native-web-maps';

  return config;
};

compile failed

3. add the config in metro.config.js (?)
const { getDefaultConfig } = require("expo/metro-config");

/** @type {import('expo/metro-config').MetroConfig} */
const config = getDefaultConfig(__dirname, {
  // [Web-only]: Enables CSS support in Metro.
  isCSSEnabled: true,
});
config.resolver.sourceExts.push("mjs");

config.resolver.extraNodeModules = {
  ...config.resolver.extraNodeModules,
  "react-native-maps": require.resolve(
    process.env.EXPO_WEBPACK_PLATFORM === "web"
      ? "@teovilla/react-native-web-maps"
      : "react-native-maps",
  ),
};

module.exports = config;

still compile failed

Upvotes: 1

Views: 655

Answers (2)

Bingus
Bingus

Reputation: 21

Instead of using Teo's exact instructions, I used the Expo documentation AND his for the aliasing implementation.

//metro.config.js
const { getDefaultConfig } = require('expo/metro-config');
    
    /** @type {import('expo/metro-config').MetroConfig} */
    const config = getDefaultConfig(__dirname);
    const ALIASES = {
        'react-native-maps': '@teovilla/react-native-web-maps',
    }
    
    config.resolver.resolveRequest = (context, moduleName, platform) => {
        if (platform === 'web') {
          // The alias will only be used when bundling for the web.
          return context.resolveRequest(context, ALIASES[moduleName] ?? moduleName, platform);
        }
        // Ensure you call the default resolver.
        return context.resolveRequest(context, moduleName, platform);
      };
      
    module.exports = config;

Upvotes: 0

Behnam Kamrani
Behnam Kamrani

Reputation: 885

Your first way seems to be correct and is working for me. The only difference is that I used Mapbox from @rnmapbox/maps module for web. It is explained in the Expo documentation under Platform Specific modules.

Here is how the native file map.native.tsx looks like:

import MapView, { Marker, PROVIDER_DEFAULT, Region } from 'react-native-maps';

export { MapView, Marker, PROVIDER_DEFAULT };
export type { Region };

For the Web, I ended up importing it separately wherever needed and rendered it conditionally.

import MapboxGL, { MapState } from '@rnmapbox/maps';

And then:

{Platform.OS === 'web' ? (...'use MapboxGL here' ) : ('use mapview here')

Upvotes: 0

Related Questions