diff --git a/bin/expo-setup.js b/bin/expo-setup.js index 25f3d57..05dad77 100644 --- a/bin/expo-setup.js +++ b/bin/expo-setup.js @@ -1,17 +1,22 @@ -// Enable Expo non-default options for performance: +// Enable Expo non-default options for performance and consistency: // -// 1. app.json - Enable New Architecture for iOS and Android -// - https://docs.expo.dev/guides/new-architecture/ +// 1. Convert app.json to app.config.ts for consistent TS language and dynamic config +// - https://docs.expo.dev/workflow/configuration/#dynamic-configuration +// +// TODO: Remove this if `create-expo-app` generates `app.config.ts` in future +// - https://github.com/expo/expo/issues/34357 // 2. .env.development, .env.production, eas.json - Enable the new Metro resolver available starting in Expo SDK 51 // - https://github.com/EvanBacon/pillar-valley/commit/ede321ef7addc67e4047624aedb3e92af3cb5060 // - https://archive.ph/MG03E // // TODO: Remove when Expo enables New Architecture and new Metro resolver by default -import { readFile, writeFile } from 'node:fs/promises'; +import { exec } from 'node:child_process'; +import { readFile, unlink, writeFile } from 'node:fs/promises'; +import { promisify } from 'node:util'; import isPlainObject from 'is-plain-obj'; -const appFilePath = 'app.json'; -const appJson = JSON.parse(await readFile(appFilePath, 'utf8')); +const appJsonFilePath = 'app.json'; +const appJson = JSON.parse(await readFile(appJsonFilePath, 'utf8')); if (!isPlainObject(appJson) || !isPlainObject(appJson.expo)) { throw new Error( @@ -19,28 +24,33 @@ if (!isPlainObject(appJson) || !isPlainObject(appJson.expo)) { ); } -appJson.expo.experiments ||= {}; -// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access -- Set to empty object in previous line, if falsy -appJson.expo.experiments.typedRoutes = true; +// Install Prettier to format `app.config.ts`, colocated in this script for +// easier removal +// +// TODO: Remove this if `create-expo-app` generates `app.config.ts` in future +// - https://github.com/expo/expo/issues/34357 +await promisify(exec)('pnpm add --save-dev prettier'); +const { format } = await import('prettier'); + +await writeFile( + 'app.config.ts', + await format( + `import { type ExpoConfig } from 'expo/config'; -appJson.expo.plugins = [ - [ - 'expo-build-properties', +const config: ExpoConfig = ${JSON.stringify(appJson.expo, null, 2)}; + +export default config;`, { - ios: { - newArchEnabled: true, - }, - android: { - newArchEnabled: true, - }, + parser: 'typescript', + singleQuote: true, }, - ], -]; - -await writeFile(appFilePath, JSON.stringify(appJson, null, 2), 'utf8'); -console.log( - '✅ Enabled New Architecture and typedRoutes experiment in app.json', + ), + 'utf8', ); +console.log('✅ Created app.config.ts'); + +await unlink(appJsonFilePath); +console.log('✅ Deleted app.json'); await writeFile('.env.development', 'EXPO_USE_FAST_RESOLVER=1', 'utf8'); console.log('✅ Enabled new Metro resolver in .env.development');