@@ -5,6 +5,7 @@ import fse from 'fs-extra';
55import inquirer from 'inquirer' ;
66import matchRequire from 'match-require' ;
77import path from 'path' ;
8+ import rimraf from 'rimraf' ;
89import spawn from 'cross-spawn' ;
910import log from '../util/log' ;
1011
@@ -77,7 +78,8 @@ Ejecting is permanent! Please be careful with your selection.
7778 const { ejectMethod } = await inquirer . prompt ( questions ) ;
7879
7980 if ( ejectMethod === 'raw' ) {
80- const npmOrYarn = ( await fse . exists ( path . resolve ( 'yarn.lock' ) ) ) ? 'yarnpkg' : 'npm' ;
81+ const useYarn = await fse . exists ( path . resolve ( 'yarn.lock' ) ) ;
82+ const npmOrYarn = useYarn ? 'yarn' : 'npm' ;
8183 const appJson = JSON . parse ( await fse . readFile ( path . resolve ( 'app.json' ) ) ) ;
8284 const pkgJson = JSON . parse ( await fse . readFile ( path . resolve ( 'package.json' ) ) ) ;
8385 let {
@@ -142,36 +144,41 @@ Ejecting is permanent! Please be careful with your selection.
142144 log ( 'Successfully copied template native code.' ) ;
143145 }
144146
145- // if the project .babelrc matches the template one, then we don't need to have it around anymore
146- // if it doesn't, then print a warning
147+ const newDevDependencies = [ ] ;
148+ // Try to replace the Babel preset.
147149 try {
148- const projectBabelPath = path . resolve ( process . cwd ( ) , '.babelrc' ) ;
149- const projectBabelRc = ( await fse . readFile ( projectBabelPath ) ) . toString ( ) ;
150-
151- const templateBabelPath = path . resolve ( __dirname , '..' , '..' , 'template' , '.babelrc' ) ;
152- const templateBabelRc = ( await fse . readFile ( templateBabelPath ) ) . toString ( ) ;
153-
154- if ( projectBabelRc === templateBabelRc ) {
155- await fse . unlink ( projectBabelPath ) ;
156- log (
157- chalk . green (
158- `The template .babelrc is no longer necessary after ejecting.
159- It has been successfully deleted.`
160- )
161- ) ;
162- } else {
163- log (
164- chalk . yellow (
165- `It looks like you modified your .babelrc file.
166- Make sure to change your babel preset to \`react-native\`.`
167- )
168- ) ;
150+ const projectBabelPath = path . resolve ( '.babelrc' ) ;
151+ // If .babelrc doesn't exist, the app is using the default config and
152+ // editing the config is not necessary.
153+ if ( await fse . exists ( projectBabelPath ) ) {
154+ const projectBabelRc = ( await fse . readFile ( projectBabelPath ) ) . toString ( ) ;
155+
156+ // We assume the .babelrc is valid JSON. If we can't parse it (e.g. if
157+ // it's JSON5) the error is caught and a message asking to change it
158+ // manually gets printed.
159+ const babelRcJson = JSON . parse ( projectBabelRc ) ;
160+ if ( babelRcJson . presets && babelRcJson . presets . includes ( 'babel-preset-expo' ) ) {
161+ babelRcJson . presets = babelRcJson . presets . map (
162+ preset =>
163+ preset === 'babel-preset-expo'
164+ ? 'babel-preset-react-native-stage-0/decorator-support'
165+ : preset
166+ ) ;
167+ await fse . writeFile ( projectBabelPath , JSON . stringify ( babelRcJson , null , 2 ) ) ;
168+ newDevDependencies . push ( 'babel-preset-react-native-stage-0' ) ;
169+ log (
170+ chalk . green (
171+ `Babel preset changed to \`babel-preset-react-native-stage-0/decorator-support\`.`
172+ )
173+ ) ;
174+ }
169175 }
170176 } catch ( e ) {
171177 log (
172178 chalk . yellow (
173179 `We had an issue preparing your .babelrc for ejection.
174- If you have a .babelrc in your project, make sure to change the preset to \`react-native\`.`
180+ If you have a .babelrc in your project, make sure to change the preset
181+ from \`babel-preset-expo\` to \`babel-preset-react-native-stage-0/decorator-support\`.`
175182 )
176183 ) ;
177184 log ( chalk . red ( e ) ) ;
@@ -217,14 +224,24 @@ Note that using \`${npmOrYarn} start\` will now require you to run Xcode and/or
217224Android Studio to build the native code for your project.`
218225 ) ;
219226
220- log (
221- chalk . yellow (
222- `
223- It's recommended to delete your node_modules directory and rerun ${ npmOrYarn }
224- to ensure that the changes we made to package.json persist correctly.
225- `
226- )
227- ) ;
227+ log ( 'Removing node_modules...' ) ;
228+ rimraf . sync ( path . resolve ( 'node_modules' ) ) ;
229+ if ( useYarn ) {
230+ log ( 'Installing packages with yarn...' ) ;
231+ const args = newDevDependencies . length > 0 ? [ 'add' , '--dev' , ...newDevDependencies ] : [ ] ;
232+ spawn . sync ( 'yarnpkg' , args , { stdio : 'inherit' } ) ;
233+ } else {
234+ // npm prints the whole package tree to stdout unless we ignore it.
235+ const stdio = [ process . stdin , 'ignore' , process . stderr ] ;
236+
237+ log ( 'Installing existing packages with npm...' ) ;
238+ spawn . sync ( 'npm' , [ 'install' ] , { stdio } ) ;
239+
240+ if ( newDevDependencies . length > 0 ) {
241+ log ( 'Installing new packages with npm...' ) ;
242+ spawn . sync ( 'npm' , [ 'install' , '--save-dev' , ...newDevDependencies ] , { stdio } ) ;
243+ }
244+ }
228245 } else if ( ejectMethod === 'expoKit' ) {
229246 await detach ( ) ;
230247 } else {
0 commit comments