Skip to content

Commit

Permalink
Switch Babel preset on eject (#328)
Browse files Browse the repository at this point in the history
* Switch from `babel-preset-expo` to `babel-preset-react-native-stage-0`
  when ejecting.
* Automatically install the `babel-preset-react-native-stage-0` package.
* Also prune removed packages when ejecting.
  • Loading branch information
fson authored and brentvatne committed Jul 27, 2017
1 parent bfa0576 commit 7b01ef0
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 36 deletions.
1 change: 1 addition & 0 deletions react-native-scripts/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
"path-exists": "^3.0.0",
"progress": "^2.0.0",
"qrcode-terminal": "^0.11.0",
"rimraf": "^2.6.1",
"xdl": "43.0.0",
"@expo/bunyan": "1.8.10"
},
Expand Down
83 changes: 50 additions & 33 deletions react-native-scripts/src/scripts/eject.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import fse from 'fs-extra';
import inquirer from 'inquirer';
import matchRequire from 'match-require';
import path from 'path';
import rimraf from 'rimraf';
import spawn from 'cross-spawn';
import log from '../util/log';

Expand Down Expand Up @@ -77,7 +78,8 @@ Ejecting is permanent! Please be careful with your selection.
const { ejectMethod } = await inquirer.prompt(questions);

if (ejectMethod === 'raw') {
const npmOrYarn = (await fse.exists(path.resolve('yarn.lock'))) ? 'yarnpkg' : 'npm';
const useYarn = await fse.exists(path.resolve('yarn.lock'));
const npmOrYarn = useYarn ? 'yarn' : 'npm';
const appJson = JSON.parse(await fse.readFile(path.resolve('app.json')));
const pkgJson = JSON.parse(await fse.readFile(path.resolve('package.json')));
let {
Expand Down Expand Up @@ -142,36 +144,41 @@ Ejecting is permanent! Please be careful with your selection.
log('Successfully copied template native code.');
}

// if the project .babelrc matches the template one, then we don't need to have it around anymore
// if it doesn't, then print a warning
const newDevDependencies = [];
// Try to replace the Babel preset.
try {
const projectBabelPath = path.resolve(process.cwd(), '.babelrc');
const projectBabelRc = (await fse.readFile(projectBabelPath)).toString();

const templateBabelPath = path.resolve(__dirname, '..', '..', 'template', '.babelrc');
const templateBabelRc = (await fse.readFile(templateBabelPath)).toString();

if (projectBabelRc === templateBabelRc) {
await fse.unlink(projectBabelPath);
log(
chalk.green(
`The template .babelrc is no longer necessary after ejecting.
It has been successfully deleted.`
)
);
} else {
log(
chalk.yellow(
`It looks like you modified your .babelrc file.
Make sure to change your babel preset to \`react-native\`.`
)
);
const projectBabelPath = path.resolve('.babelrc');
// If .babelrc doesn't exist, the app is using the default config and
// editing the config is not necessary.
if (await fse.exists(projectBabelPath)) {
const projectBabelRc = (await fse.readFile(projectBabelPath)).toString();

// We assume the .babelrc is valid JSON. If we can't parse it (e.g. if
// it's JSON5) the error is caught and a message asking to change it
// manually gets printed.
const babelRcJson = JSON.parse(projectBabelRc);
if (babelRcJson.presets && babelRcJson.presets.includes('babel-preset-expo')) {
babelRcJson.presets = babelRcJson.presets.map(
preset =>
preset === 'babel-preset-expo'
? 'babel-preset-react-native-stage-0/decorator-support'
: preset
);
await fse.writeFile(projectBabelPath, JSON.stringify(babelRcJson, null, 2));
newDevDependencies.push('babel-preset-react-native-stage-0');
log(
chalk.green(
`Babel preset changed to \`babel-preset-react-native-stage-0/decorator-support\`.`
)
);
}
}
} catch (e) {
log(
chalk.yellow(
`We had an issue preparing your .babelrc for ejection.
If you have a .babelrc in your project, make sure to change the preset to \`react-native\`.`
If you have a .babelrc in your project, make sure to change the preset
from \`babel-preset-expo\` to \`babel-preset-react-native-stage-0/decorator-support\`.`
)
);
log(chalk.red(e));
Expand Down Expand Up @@ -217,14 +224,24 @@ Note that using \`${npmOrYarn} start\` will now require you to run Xcode and/or
Android Studio to build the native code for your project.`
);

log(
chalk.yellow(
`
It's recommended to delete your node_modules directory and rerun ${npmOrYarn}
to ensure that the changes we made to package.json persist correctly.
`
)
);
log('Removing node_modules...');
rimraf.sync(path.resolve('node_modules'));
if (useYarn) {
log('Installing packages with yarn...');
const args = newDevDependencies.length > 0 ? ['add', '--dev', ...newDevDependencies] : [];
spawn.sync('yarnpkg', args, { stdio: 'inherit' });
} else {
// npm prints the whole package tree to stdout unless we ignore it.
const stdio = [process.stdin, 'ignore', process.stderr];

log('Installing existing packages with npm...');
spawn.sync('npm', ['install'], { stdio });

if (newDevDependencies.length > 0) {
log('Installing new packages with npm...');
spawn.sync('npm', ['install', '--save-dev', ...newDevDependencies], { stdio });
}
}
} else if (ejectMethod === 'expoKit') {
await detach();
} else {
Expand Down
6 changes: 3 additions & 3 deletions react-native-scripts/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3153,9 +3153,9 @@ wrappy@1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"

xdl@42.4.0:
version "42.4.0"
resolved "https://registry.yarnpkg.com/xdl/-/xdl-42.4.0.tgz#eeae75398090d642c55fce8e955edbf44ea416a0"
xdl@43.0.0:
version "43.0.0"
resolved "https://registry.yarnpkg.com/xdl/-/xdl-43.0.0.tgz#d73392fcc654ee22a0d466b6acb782453bfb6a2a"
dependencies:
"@ccheever/crayon" "^5.0.0"
"@expo/bunyan" "^1.8.10"
Expand Down

0 comments on commit 7b01ef0

Please sign in to comment.