@@ -3,7 +3,7 @@ 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 type { TemplateConfiguration } from '../template ' ;
77
88const FILES_TO_DELETE = [
99 '__tests__' ,
@@ -35,40 +35,34 @@ const PACKAGES_TO_REMOVE = [
3535 'typescript' ,
3636] ;
3737
38- const PACKAGES_TO_ADD_WEB = {
38+ const PACKAGES_TO_ADD_EXPO_WEB = {
3939 '@expo/metro-runtime' : '~3.2.1' ,
4040 'react-dom' : '18.2.0' ,
4141 'react-native-web' : '~0.18.10' ,
4242} ;
4343
44+ const PACKAGES_TO_ADD_DEV_EXPO_NATIVE = {
45+ 'expo-dev-client' : '~5.0.3' ,
46+ } ;
47+
4448export default async function generateExampleApp ( {
45- type,
46- dest,
47- arch,
48- project,
49- bobVersion,
49+ config,
50+ destination,
5051 reactNativeVersion = 'latest' ,
5152} : {
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 ;
53+ config : TemplateConfiguration ;
54+ destination : string ;
55+ reactNativeVersion : string | undefined ;
6256} ) {
63- const directory = path . join ( dest , 'example' ) ;
57+ const directory = path . join ( destination , 'example' ) ;
6458
6559 // `npx --package react-native-test-app@latest init --name ${projectName}Example --destination example --version ${reactNativeVersion}`
6660 const testAppArgs = [
6761 '--package' ,
6862 `react-native-test-app@latest` ,
6963 'init' ,
7064 '--name' ,
71- `${ project . name } Example` ,
65+ `${ config . project . name } Example` ,
7266 `--destination` ,
7367 directory ,
7468 ...( reactNativeVersion !== 'latest'
@@ -84,9 +78,9 @@ export default async function generateExampleApp({
8478 const vanillaArgs = [
8579 `@react-native-community/cli` ,
8680 'init' ,
87- `${ project . name } Example` ,
81+ `${ config . project . name } Example` ,
8882 '--package-name' ,
89- `${ project . package } .example` ,
83+ `${ config . project . package } .example` ,
9084 '--directory' ,
9185 directory ,
9286 '--version' ,
@@ -107,7 +101,7 @@ export default async function generateExampleApp({
107101
108102 let args : string [ ] = [ ] ;
109103
110- switch ( type ) {
104+ switch ( config . example ) {
111105 case 'vanilla' :
112106 args = vanillaArgs ;
113107 break ;
@@ -131,7 +125,7 @@ export default async function generateExampleApp({
131125 // Patch the example app's package.json
132126 const pkg = await fs . readJSON ( path . join ( directory , 'package.json' ) ) ;
133127
134- pkg . name = `${ project . slug } -example` ;
128+ pkg . name = `${ config . project . slug } -example` ;
135129
136130 // Remove Jest config for now
137131 delete pkg . jest ;
@@ -144,12 +138,12 @@ export default async function generateExampleApp({
144138 const SCRIPTS_TO_ADD = {
145139 'build:android' :
146140 '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"` ,
141+ '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"` ,
148142 } ;
149143
150- if ( type === 'vanilla' ) {
144+ if ( config . example === 'vanilla' ) {
151145 Object . assign ( scripts , SCRIPTS_TO_ADD ) ;
152- } else if ( type === 'test-app' ) {
146+ } else if ( config . example === 'test-app' ) {
153147 // `react-native-test-app` doesn't bundle application by default in 'Release' mode and also `bundle` command doesn't create a directory.
154148 // `mkdist` script should be removed after stable React Native major contains this fix: https://github.com/facebook/react-native/pull/45182.
155149
@@ -173,9 +167,9 @@ export default async function generateExampleApp({
173167 const app = await fs . readJSON ( path . join ( directory , 'app.json' ) ) ;
174168
175169 app . android = app . android || { } ;
176- app . android . package = `${ project . package } .example` ;
170+ app . android . package = `${ config . project . package } .example` ;
177171 app . ios = app . ios || { } ;
178- app . ios . bundleIdentifier = `${ project . package } .example` ;
172+ app . ios . bundleIdentifier = `${ config . project . package } .example` ;
179173
180174 await fs . writeJSON ( path . join ( directory , 'app.json' ) , app , {
181175 spaces : 2 ,
@@ -188,12 +182,12 @@ export default async function generateExampleApp({
188182 } ) ;
189183
190184 const PACKAGES_TO_ADD_DEV = {
191- 'react-native-builder-bob' : `^${ bobVersion } ` ,
185+ 'react-native-builder-bob' : `^${ config . bob . version } ` ,
192186 } ;
193187
194188 Object . assign ( devDependencies , PACKAGES_TO_ADD_DEV ) ;
195189
196- if ( type === 'expo' ) {
190+ if ( config . example === 'expo' ) {
197191 const sdkVersion = dependencies . expo . split ( '.' ) [ 0 ] . replace ( / [ ^ \d ] / , '' ) ;
198192
199193 let bundledNativeModules : Record < string , string > ;
@@ -222,18 +216,34 @@ export default async function generateExampleApp({
222216 bundledNativeModules = { } ;
223217 }
224218
225- Object . entries ( PACKAGES_TO_ADD_WEB ) . forEach ( ( [ name , version ] ) => {
226- dependencies [ name ] = bundledNativeModules [ name ] || version ;
227- } ) ;
219+ if ( config . project . native ) {
220+ Object . entries ( PACKAGES_TO_ADD_DEV_EXPO_NATIVE ) . forEach (
221+ ( [ name , version ] ) => {
222+ devDependencies [ name ] = bundledNativeModules [ name ] || version ;
223+ }
224+ ) ;
228225
229- scripts . web = 'expo start --web' ;
226+ scripts . start = 'expo start --dev-client' ;
227+ scripts . android = 'expo run:android' ;
228+ scripts . ios = 'expo run:ios' ;
229+
230+ delete scripts . web ;
231+ } else {
232+ Object . entries ( PACKAGES_TO_ADD_EXPO_WEB ) . forEach ( ( [ name , version ] ) => {
233+ dependencies [ name ] = bundledNativeModules [ name ] || version ;
234+ } ) ;
235+
236+ scripts . web = 'expo start --web' ;
237+ }
230238
231239 const app = await fs . readJSON ( path . join ( directory , 'app.json' ) ) ;
232240
241+ app . expo . name = `${ config . project . name } Example` ;
242+ app . expo . slug = `${ config . project . slug } -example` ;
233243 app . expo . android = app . expo . android || { } ;
234- app . expo . android . package = `${ project . package } .example` ;
244+ app . expo . android . package = `${ config . project . package } .example` ;
235245 app . expo . ios = app . expo . ios || { } ;
236- app . expo . ios . bundleIdentifier = `${ project . package } .example` ;
246+ app . expo . ios . bundleIdentifier = `${ config . project . package } .example` ;
237247
238248 await fs . writeJSON ( path . join ( directory , 'app.json' ) , app , {
239249 spaces : 2 ,
@@ -250,7 +260,7 @@ export default async function generateExampleApp({
250260 spaces : 2 ,
251261 } ) ;
252262
253- if ( type !== 'expo' ) {
263+ if ( config . example !== 'expo' ) {
254264 let gradleProperties = await fs . readFile (
255265 path . join ( directory , 'android' , 'gradle.properties' ) ,
256266 'utf8'
@@ -264,7 +274,7 @@ export default async function generateExampleApp({
264274 ) ;
265275
266276 // If the library is on new architecture, enable new arch for iOS and Android
267- if ( arch === 'new' ) {
277+ if ( config . project . arch === 'new' ) {
268278 // iOS
269279 // Add ENV['RCT_NEW_ARCH_ENABLED'] = 1 on top of example/ios/Podfile
270280 const podfile = await fs . readFile (
0 commit comments