@@ -3,7 +3,8 @@ import path from 'path';
33import https from 'https' ;
44import { spawn } from '../utils/spawn' ;
55import sortObjectKeys from '../utils/sortObjectKeys' ;
6- import type { ExampleApp } from '../input' ;
6+ import dedent from 'dedent' ;
7+ import type { TemplateConfiguration } from '../template' ;
78
89const FILES_TO_DELETE = [
910 '__tests__' ,
@@ -35,40 +36,34 @@ const PACKAGES_TO_REMOVE = [
3536 'typescript' ,
3637] ;
3738
38- const PACKAGES_TO_ADD_WEB = {
39+ const PACKAGES_TO_ADD_EXPO_WEB = {
3940 '@expo/metro-runtime' : '~3.2.1' ,
4041 'react-dom' : '18.2.0' ,
4142 'react-native-web' : '~0.18.10' ,
4243} ;
4344
45+ const PACKAGES_TO_ADD_DEV_EXPO_NATIVE = {
46+ 'expo-dev-client' : '~5.0.3' ,
47+ } ;
48+
4449export default async function generateExampleApp ( {
45- type,
46- dest,
47- arch,
48- project,
49- bobVersion,
50+ config,
51+ destination,
5052 reactNativeVersion = 'latest' ,
5153} : {
52- type : ExampleApp ;
53- dest : string ;
54- arch : 'new' | 'legacy' ;
55- project : {
56- slug : string ;
57- name : string ;
58- package : string ;
59- } ;
60- bobVersion : string ;
61- reactNativeVersion ?: string ;
54+ config : TemplateConfiguration ;
55+ destination : string ;
56+ reactNativeVersion : string | undefined ;
6257} ) {
63- const directory = path . join ( dest , 'example' ) ;
58+ const directory = path . join ( destination , 'example' ) ;
6459
6560 // `npx --package react-native-test-app@latest init --name ${projectName}Example --destination example --version ${reactNativeVersion}`
6661 const testAppArgs = [
6762 '--package' ,
6863 `react-native-test-app@latest` ,
6964 'init' ,
7065 '--name' ,
71- `${ project . name } Example` ,
66+ `${ config . project . name } Example` ,
7267 `--destination` ,
7368 directory ,
7469 ...( reactNativeVersion !== 'latest'
@@ -84,9 +79,9 @@ export default async function generateExampleApp({
8479 const vanillaArgs = [
8580 `@react-native-community/cli` ,
8681 'init' ,
87- `${ project . name } Example` ,
82+ `${ config . project . name } Example` ,
8883 '--package-name' ,
89- `${ project . package } .example` ,
84+ `${ config . project . package } .example` ,
9085 '--directory' ,
9186 directory ,
9287 '--version' ,
@@ -107,7 +102,7 @@ export default async function generateExampleApp({
107102
108103 let args : string [ ] = [ ] ;
109104
110- switch ( type ) {
105+ switch ( config . example ) {
111106 case 'vanilla' :
112107 args = vanillaArgs ;
113108 break ;
@@ -131,7 +126,7 @@ export default async function generateExampleApp({
131126 // Patch the example app's package.json
132127 const pkg = await fs . readJSON ( path . join ( directory , 'package.json' ) ) ;
133128
134- pkg . name = `${ project . slug } -example` ;
129+ pkg . name = `${ config . project . slug } -example` ;
135130
136131 // Remove Jest config for now
137132 delete pkg . jest ;
@@ -144,12 +139,12 @@ export default async function generateExampleApp({
144139 const SCRIPTS_TO_ADD = {
145140 'build:android' :
146141 'react-native build-android --extra-params "--no-daemon --console=plain -PreactNativeArchitectures=arm64-v8a"' ,
147- 'build:ios' : `react-native build-ios --scheme ${ project . name } Example --mode Debug --extra-params "-sdk iphonesimulator CC=clang CPLUSPLUS=clang++ LD=clang LDPLUSPLUS=clang++ GCC_OPTIMIZATION_LEVEL=0 GCC_PRECOMPILE_PREFIX_HEADER=YES ASSETCATALOG_COMPILER_OPTIMIZATION=time DEBUG_INFORMATION_FORMAT=dwarf COMPILER_INDEX_STORE_ENABLE=NO"` ,
142+ 'build:ios' : `react-native build-ios --scheme ${ config . project . name } Example --mode Debug --extra-params "-sdk iphonesimulator CC=clang CPLUSPLUS=clang++ LD=clang LDPLUSPLUS=clang++ GCC_OPTIMIZATION_LEVEL=0 GCC_PRECOMPILE_PREFIX_HEADER=YES ASSETCATALOG_COMPILER_OPTIMIZATION=time DEBUG_INFORMATION_FORMAT=dwarf COMPILER_INDEX_STORE_ENABLE=NO"` ,
148143 } ;
149144
150- if ( type === 'vanilla' ) {
145+ if ( config . example === 'vanilla' ) {
151146 Object . assign ( scripts , SCRIPTS_TO_ADD ) ;
152- } else if ( type === 'test-app' ) {
147+ } else if ( config . example === 'test-app' ) {
153148 // `react-native-test-app` doesn't bundle application by default in 'Release' mode and also `bundle` command doesn't create a directory.
154149 // `mkdist` script should be removed after stable React Native major contains this fix: https://github.com/facebook/react-native/pull/45182.
155150
@@ -173,9 +168,9 @@ export default async function generateExampleApp({
173168 const app = await fs . readJSON ( path . join ( directory , 'app.json' ) ) ;
174169
175170 app . android = app . android || { } ;
176- app . android . package = `${ project . package } .example` ;
171+ app . android . package = `${ config . project . package } .example` ;
177172 app . ios = app . ios || { } ;
178- app . ios . bundleIdentifier = `${ project . package } .example` ;
173+ app . ios . bundleIdentifier = `${ config . project . package } .example` ;
179174
180175 await fs . writeJSON ( path . join ( directory , 'app.json' ) , app , {
181176 spaces : 2 ,
@@ -188,12 +183,12 @@ export default async function generateExampleApp({
188183 } ) ;
189184
190185 const PACKAGES_TO_ADD_DEV = {
191- 'react-native-builder-bob' : `^${ bobVersion } ` ,
186+ 'react-native-builder-bob' : `^${ config . bob . version } ` ,
192187 } ;
193188
194189 Object . assign ( devDependencies , PACKAGES_TO_ADD_DEV ) ;
195190
196- if ( type === 'expo' ) {
191+ if ( config . example === 'expo' ) {
197192 const sdkVersion = dependencies . expo . split ( '.' ) [ 0 ] . replace ( / [ ^ \d ] / , '' ) ;
198193
199194 let bundledNativeModules : Record < string , string > ;
@@ -222,18 +217,43 @@ export default async function generateExampleApp({
222217 bundledNativeModules = { } ;
223218 }
224219
225- Object . entries ( PACKAGES_TO_ADD_WEB ) . forEach ( ( [ name , version ] ) => {
226- dependencies [ name ] = bundledNativeModules [ name ] || version ;
227- } ) ;
220+ if ( config . project . native ) {
221+ Object . entries ( PACKAGES_TO_ADD_DEV_EXPO_NATIVE ) . forEach (
222+ ( [ name , version ] ) => {
223+ devDependencies [ name ] = bundledNativeModules [ name ] || version ;
224+ }
225+ ) ;
226+
227+ scripts . start = 'expo start --dev-client' ;
228+ scripts . android = 'expo run:android' ;
229+ scripts . ios = 'expo run:ios' ;
228230
229- scripts . web = 'expo start --web' ;
231+ delete scripts . web ;
232+
233+ await fs . writeFile (
234+ path . join ( directory , '.gitignore' ) ,
235+ dedent `
236+ # These folders are generated with prebuild (CNG)
237+ android/
238+ ios/
239+ `
240+ ) ;
241+ } else {
242+ Object . entries ( PACKAGES_TO_ADD_EXPO_WEB ) . forEach ( ( [ name , version ] ) => {
243+ dependencies [ name ] = bundledNativeModules [ name ] || version ;
244+ } ) ;
245+
246+ scripts . web = 'expo start --web' ;
247+ }
230248
231249 const app = await fs . readJSON ( path . join ( directory , 'app.json' ) ) ;
232250
251+ app . expo . name = `${ config . project . name } Example` ;
252+ app . expo . slug = `${ config . project . slug } -example` ;
233253 app . expo . android = app . expo . android || { } ;
234- app . expo . android . package = `${ project . package } .example` ;
254+ app . expo . android . package = `${ config . project . package } .example` ;
235255 app . expo . ios = app . expo . ios || { } ;
236- app . expo . ios . bundleIdentifier = `${ project . package } .example` ;
256+ app . expo . ios . bundleIdentifier = `${ config . project . package } .example` ;
237257
238258 await fs . writeJSON ( path . join ( directory , 'app.json' ) , app , {
239259 spaces : 2 ,
@@ -250,7 +270,7 @@ export default async function generateExampleApp({
250270 spaces : 2 ,
251271 } ) ;
252272
253- if ( type !== 'expo' ) {
273+ if ( config . example !== 'expo' ) {
254274 let gradleProperties = await fs . readFile (
255275 path . join ( directory , 'android' , 'gradle.properties' ) ,
256276 'utf8'
@@ -264,7 +284,7 @@ export default async function generateExampleApp({
264284 ) ;
265285
266286 // If the library is on new architecture, enable new arch for iOS and Android
267- if ( arch === 'new' ) {
287+ if ( config . project . arch === 'new' ) {
268288 // iOS
269289 // Add ENV['RCT_NEW_ARCH_ENABLED'] = 1 on top of example/ios/Podfile
270290 const podfile = await fs . readFile (
0 commit comments