PnP React Native - v5 to v6
Overview
This guide provides a detailed step-by-step process to help you migrate your PnP React Native
project from version 5 to version 6 of the SDK. This includes necessary changes to your
metro.config.js
and globals.ts
files and updates for both bare React Native and Expo workflows.
Metro Configurations
Expo Workflow
Before:
const { getDefaultConfig } = require("expo/metro-config");
/** @type {import('expo/metro-config').MetroConfig} */
const config = getDefaultConfig(__dirname);
config.resolver.extraNodeModules = {
assert: require.resolve("empty-module"), // assert can be polyfilled here if needed
http: require.resolve("empty-module"), // stream-http can be polyfilled here if needed
https: require.resolve("empty-module"), // https-browserify can be polyfilled here if needed
os: require.resolve("empty-module"), // os-browserify can be polyfilled here if needed
url: require.resolve("empty-module"), // url can be polyfilled here if needed
zlib: require.resolve("empty-module"), // browserify-zlib can be polyfilled here if needed
path: require.resolve("empty-module"),
crypto: require.resolve("crypto-browserify"),
stream: require.resolve("readable-stream"),
buffer: require.resolve("buffer"),
};
config.transformer.getTransformOptions = () => ({
transform: {
experimentalImportSupport: false,
inlineRequires: true,
},
});
module.exports = config;
After:
const { getDefaultConfig } = require("expo/metro-config");
/** @type {import('expo/metro-config').MetroConfig} */
const config = getDefaultConfig(__dirname);
config.resolver.extraNodeModules = {
assert: require.resolve("empty-module"), // assert can be polyfilled here if needed
http: require.resolve("empty-module"), // stream-http can be polyfilled here if needed
https: require.resolve("empty-module"), // https-browserify can be polyfilled here if needed
os: require.resolve("empty-module"), // os-browserify can be polyfilled here if needed
url: require.resolve("empty-module"), // url can be polyfilled here if needed
zlib: require.resolve("empty-module"), // browserify-zlib can be polyfilled here if needed
path: require.resolve("empty-module"),
stream: require.resolve("readable-stream"),
buffer: require.resolve("buffer"),
};
config.resolver.resolveRequest = (context, moduleName, platform) => {
if (moduleName === "crypto") {
// when importing crypto, resolve to react-native-quick-crypto
return context.resolveRequest(context, "react-native-quick-crypto", platform);
}
// otherwise chain to the standard Metro resolver.
return context.resolveRequest(context, moduleName, platform);
};
config.transformer.getTransformOptions = () => ({
transform: {
experimentalImportSupport: false,
inlineRequires: true,
},
});
module.exports = config;
Updating globals.ts
Bare React Native Workflow
import { install } from "react-native-quick-crypto";
install();
// Needed so that 'stream-http' chooses the right default protocol.
// @ts-ignore
global.location = {
protocol: "file:",
};
// @ts-ignore
global.process.version = "v16.0.0";
if (!global.process.version) {
global.process = require("process");
console.log({ process: global.process });
}
// @ts-ignore
process.browser = true;
Expo Workflow
import "./globals";
import "@ethersproject/shims";
import "@expo/metro-runtime";
import { App } from "expo-router/build/qualified-entry";
import { renderRootComponent } from "expo-router/build/renderRootComponent";
// This file should only import and register the root. No components or exports
// should be added here.
renderRootComponent(App);
note
Make sure to install the react-native-quick-crypto
module:
npm install react-native-quick-crypto
Updating index.ts
Bare React Native Workflow
import { AppRegistry } from "react-native";
import "./globals";
import App from "./App";
import { name as appName } from "./app.json";
AppRegistry.registerComponent(appName, () => App);
Expo Workflow
import "./globals";
import "@ethersproject/shims";
import "@expo/metro-runtime";
import { App } from "expo-router/build/qualified-entry";
import { renderRootComponent } from "expo-router/build/renderRootComponent";
// This file should only import and register the root. No components or exports
// should be added here.
renderRootComponent(App);