1import { createRunOncePlugin, Mod, withDangerousMod } from '@expo/config-plugins'; 2import { ExpoConfig } from '@expo/config-types'; 3// @ts-expect-error missing types 4import withDevLauncher from 'expo-dev-launcher/app.plugin'; 5// @ts-expect-error missing types 6import withDevMenu from 'expo-dev-menu/app.plugin'; 7import fs from 'fs'; 8import path from 'path'; 9 10const pkg = require('expo-dev-client/package.json'); 11 12const REACT_NATIVE_CONFIG_JS = `// File created by expo-dev-client/app.plugin.js 13 14module.exports = { 15 dependencies: { 16 ...require('expo-dev-client/dependencies'), 17 }, 18}; 19`; 20 21function withReactNativeConfigJs(config: ExpoConfig): ExpoConfig { 22 config = withDangerousMod(config, ['android', addReactNativeConfigAsync]); 23 config = withDangerousMod(config, ['ios', addReactNativeConfigAsync]); 24 return config; 25} 26 27const addReactNativeConfigAsync: Mod = async config => { 28 const filename = path.join(config.modRequest.projectRoot, 'react-native.config.js'); 29 try { 30 const config = fs.readFileSync(filename, 'utf8'); 31 if (!config.includes('expo-dev-client/dependencies')) { 32 throw new Error( 33 `Could not add expo-dev-client dependencies to existing file ${filename}. See expo-dev-client installation instructions to add them manually.` 34 ); 35 } 36 } catch (error) { 37 if (error.code === 'ENOENT') { 38 // The file doesn't exist, so we create it. 39 fs.writeFileSync(filename, REACT_NATIVE_CONFIG_JS); 40 } else { 41 throw error; 42 } 43 } 44 return config; 45}; 46 47function withDevClient(config: ExpoConfig) { 48 config = withDevMenu(config); 49 config = withDevLauncher(config); 50 config = withReactNativeConfigJs(config); 51 return config; 52} 53 54export default createRunOncePlugin(withDevClient, pkg.name, pkg.version); 55