| title | Bundler polyfill issues - React Native Metro |
|---|---|
| image | img/metamaskog.jpg |
| sidebar_label | React Native Metro polyfill issues |
| description | Bundler Polyfill Issues - React Native Metro | Embedded Wallets |
import TabItem from '@theme/TabItem' import Tabs from '@theme/Tabs'
This page documents how to configure Metro to handle Node.js polyfills required by the Embedded Wallets React Native SDK.
SDK v9 ships a single helper that configures Metro and polyfills automatically. No manual extraNodeModules is needed.
npm install @web3auth/react-native-sdk
npm install --save-dev @babel/plugin-transform-export-namespace-fromAdd import "@web3auth/react-native-sdk/setup" as the first line of your app's entry file:
<Tabs defaultValue="bare" values={[ { label: 'Bare React Native', value: 'bare' }, { label: 'Expo', value: 'expo' }, ]}
import '@web3auth/react-native-sdk/setup' // must be first
import { AppRegistry } from 'react-native'
import App from './App'
import { name as appName } from './app.json'
AppRegistry.registerComponent(appName, () => App)Create index.ts and set "main": "index.ts" in package.json:
import '@web3auth/react-native-sdk/setup' // must be first
import { registerRootComponent } from 'expo'
import App from './App'
registerRootComponent(App)<Tabs defaultValue="bare" values={[ { label: 'Bare React Native', value: 'bare' }, { label: 'Expo', value: 'expo' }, ]}
const { getDefaultConfig } = require('@react-native/metro-config')
const { withWeb3Auth } = require('@web3auth/react-native-sdk/metro-config')
const config = getDefaultConfig(__dirname)
module.exports = withWeb3Auth(config)const { getDefaultConfig } = require('expo/metro-config')
const { withWeb3Auth } = require('@web3auth/react-native-sdk/metro-config')
const config = getDefaultConfig(__dirname)
module.exports = withWeb3Auth(config):::info
Polyfills are not supported with the Expo Go app. Use a custom dev client or an EAS build and run npx expo prebuild to generate native code.
:::
withWeb3Auth applies all required polyfill aliases (crypto, stream, buffer, and so on) internally. You can still add custom sourceExts or other resolver options after calling it.
Add @babel/plugin-transform-export-namespace-from. Without it, Metro fails to parse some SDK internal re-exports.
<Tabs defaultValue="bare" values={[ { label: 'Bare React Native', value: 'bare' }, { label: 'Expo', value: 'expo' }, ]}
module.exports = {
presets: ['module:@react-native/babel-preset'],
plugins: ['@babel/plugin-transform-export-namespace-from'],
}module.exports = function (api) {
api.cache(true)
return {
presets: ['babel-preset-expo'],
plugins: ['@babel/plugin-transform-export-namespace-from'],
}
}If you are still using @web3auth/react-native-sdk@^8.x, follow the manual polyfill steps below. We recommend upgrading to v9.
npm install --save empty-module readable-stream crypto-browserify react-native-get-random-values buffer process<Tabs defaultValue="bare" values={[ { label: 'Bare React Native', value: 'bare' }, { label: 'Expo', value: 'expo' }, ]}
const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config')
const defaultConfig = getDefaultConfig(__dirname)
const config = {
resolver: {
extraNodeModules: {
assert: require.resolve('empty-module'),
http: require.resolve('empty-module'),
https: require.resolve('empty-module'),
os: require.resolve('empty-module'),
url: require.resolve('empty-module'),
zlib: require.resolve('empty-module'),
path: require.resolve('empty-module'),
crypto: require.resolve('crypto-browserify'),
stream: require.resolve('readable-stream'),
},
sourceExts: [...defaultConfig.resolver.sourceExts, 'svg'],
},
}
module.exports = mergeConfig(defaultConfig, config)const { getDefaultConfig } = require('expo/metro-config')
const config = getDefaultConfig(__dirname)
config.resolver.extraNodeModules = {
assert: require.resolve('empty-module'),
http: require.resolve('empty-module'),
https: require.resolve('empty-module'),
os: require.resolve('empty-module'),
url: require.resolve('empty-module'),
zlib: require.resolve('empty-module'),
path: require.resolve('empty-module'),
crypto: require.resolve('crypto-browserify'),
stream: require.resolve('readable-stream'),
buffer: require.resolve('buffer'),
}
module.exports = configCreate globals.js at your project root:
global.Buffer = require('buffer').Buffer
global.location = { protocol: 'file:' }
global.process.version = 'v16.0.0'
if (!global.process.version) {
global.process = require('process')
}
process.browser = trueThen import it in your entry point:
import { AppRegistry } from 'react-native'
import './globals'
import 'react-native-get-random-values'
import App from './App'
import { name as appName } from './app.json'
AppRegistry.registerComponent(appName, () => App)