Skip to content

Latest commit

 

History

History
245 lines (180 loc) · 5.89 KB

File metadata and controls

245 lines (180 loc) · 5.89 KB
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.

v9 (recommended)

SDK v9 ships a single helper that configures Metro and polyfills automatically. No manual extraNodeModules is needed.

1. Install the SDK

npm install @web3auth/react-native-sdk
npm install --save-dev @babel/plugin-transform-export-namespace-from

2. Entry point, add setup import

Add 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)

3. Update metro.config.js

<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.

4. Update babel.config.js

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'],
  }
}

v8 (legacy manual setup)

If you are still using @web3auth/react-native-sdk@^8.x, follow the manual polyfill steps below. We recommend upgrading to v9.

1. Install polyfill packages

npm install --save empty-module readable-stream crypto-browserify react-native-get-random-values buffer process

2. metro.config.js (v8)

<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 = config

3. globals.js and entry point (v8)

Create 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 = true

Then 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)