Solving React Native Maps Compatibility Issue for Web Builds in Expo
Introduction
Developing with React Native and Expo offers a smooth experience for mobile app development. However, when it comes to extending this development to web platforms, certain libraries like react-native-maps
can cause compatibility issues. This blog post details a specific problem encountered when building for the web and the effective solution that addresses it.
The Problem
Recently I created a mobile app using react native and ported the same for the web using react-native-web. When using react-native-maps
with Expo, everything functions correctly in native builds. However, an issue arises when attempting to build for the web. The problem stems from the Metro Bundler trying to resolve react-native-maps
during the web build process, leading to errors such as:
Unable to resolve "../Utilities/Platform" from "node_modules/react-native/Libraries/ReactPrivate/ReactNativePrivateInterface.js"
This occurs despite the conditional code that should prevent react-native-maps
from being executed in web environments:
if (Platform != 'web') {
const MapView = require(`react-native-maps`).default;
// ...
}
The Solution
The solution involves creating a script that ensures web compatibility by using an empty module for web builds. Here’s a step-by-step guide to implementing this solution:
Step 1: Create the Fix Script
Create a file named react-native-map-web-fix.js
and insert the following code:
const chalk = require('chalk');
const { readFile, writeFile, copyFile } = require('fs').promises;
console.log(chalk.green('here'));
function log(...args) {
console.log(chalk.yellow('[react-native-maps]'), ...args);
}
async function reactNativeMaps() {
log('📦 Creating web compatibility of react-native-maps using an empty module loaded on web builds');
const modulePath = 'node_modules/react-native-maps';
await writeFile(`${modulePath}/lib/index.web.js`, 'module.exports = {}', 'utf-8');
await copyFile(`${modulePath}/lib/index.d.ts`, `${modulePath}/lib/index.web.d.ts`);
const pkg = JSON.parse(await readFile(`${modulePath}/package.json`));
pkg['react-native'] = 'lib/index.js';
pkg['main'] = 'lib/index.web.js';
await writeFile(`${modulePath}/package.json`, JSON.stringify(pkg, null, 2), 'utf-8');
log('✅ script ran successfully');
}
reactNativeMaps();
Step 2: Modify package.json
Open package.json
and modify the postinstall
script inside the scripts
section. If there's already an existing postinstall
action, append the new script to it:
"scripts": {
...
"postinstall": "node ./bin/postInstall && node react-native-map-web-fix.js",
...
}
Step 3: Run Yarn
Run yarn
or npm install
to execute the postinstall
script. This script will run and fix the issue automatically.
Conclusion
This approach effectively resolves the compatibility issues of react-native-maps
on web builds when using Expo. It demonstrates a practical way to tailor third-party libraries for specific platforms, ensuring a seamless development experience across different environments. By automating this fix in the postinstall
script, developers can ensure that this compatibility adjustment is consistently applied, maintaining the integrity of the web build process.