Skip to content

Commit bc18c18

Browse files
eanplattervjeux
authored andcommitted
wrap eject around prompt (#12)
1 parent 5afb14a commit bc18c18

File tree

7 files changed

+113
-94
lines changed

7 files changed

+113
-94
lines changed

README.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ Create React apps with no build configuration.
77

88
* **Zero Configuration:** There are no configuration files or command line options. Configuring both development and production builds is handled for you so you can focus on writing code.
99

10-
* **No Lock-In:** You can “graduate” to a custom setup at any time. Run a single command, and all the configuration and build dependencies will be moved directly into your project, so you can pick up where we left off.
10+
* **No Lock-In:** You can “eject” to a custom setup at any time. Run a single command, and all the configuration and build dependencies will be moved directly into your project, so you can pick up where we left off.
1111

1212
## Installation
1313

@@ -47,15 +47,15 @@ It correctly bundles React in production mode and optimizes the build for the be
4747
The build is minified and the filenames include the hashes.
4848
Your app is ready to be deployed!
4949

50-
### `npm run graduate`
50+
### `npm run eject`
5151

52-
**Note: this is a one-way operation. Once you “graduate”, you can’t go back!**
52+
**Note: this is a one-way operation. Once you “eject”, you can’t go back!**
5353

54-
If you aren’t satisfied with the build tool and configuration choices, you can “graduate” at any time. This command will remove the single build dependency from your project.
54+
If you aren’t satisfied with the build tool and configuration choices, you can “eject” at any time. This command will remove the single build dependency from your project.
5555

56-
Instead, it will copy all the configuration files and the transient dependencies (Webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `graduate` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own.
56+
Instead, it will copy all the configuration files and the transient dependencies (Webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own.
5757

58-
You don’t have to ever graduate. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obliged to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it.
58+
You don’t have to ever eject. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obliged to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it.
5959

6060
## What’s Inside?
6161

@@ -80,7 +80,7 @@ Our goal is to provide a tool that bootstraps a minimal production-ready React p
8080

8181
This is why many features such as server rendering, experimental Babel plugins, or custom ESLint configuration, are not supported. It is hard to add features that would work for everyone without adding configuration. Having no configuration is an explicit design decision of this project. Currently, even running tests is not supported, although this limitation is temporary.
8282

83-
If you want an advanced feature, you can still use this tool, and later run `npm run graduate` (but then there’s no going back!)
83+
If you want an advanced feature, you can still use this tool, and later run `npm run eject` (but then there’s no going back!)
8484

8585
## You Don’t Have to Use This
8686

bin/eject-react-app.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
#!/usr/bin/env node
2+
require('../scripts/eject');

bin/graduate-react-app.js

Lines changed: 0 additions & 2 deletions
This file was deleted.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
"bin": {
2121
"start-react-app": "./bin/start-react-app.js",
2222
"build-react-app": "./bin/build-react-app.js",
23-
"graduate-react-app": "./bin/graduate-react-app.js"
23+
"eject-react-app": "./bin/eject-react-app.js"
2424
},
2525
"dependencies": {
2626
"autoprefixer": "^6.3.7",

scripts/eject.js

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
/**
2+
* Copyright (c) 2015-present, Facebook, Inc.
3+
* All rights reserved.
4+
*
5+
* This source code is licensed under the BSD-style license found in the
6+
* LICENSE file in the root directory of this source tree. An additional grant
7+
* of patent rights can be found in the PATENTS file in the same directory.
8+
*/
9+
10+
var fs = require('fs');
11+
var path = require('path');
12+
var rl = require('readline');
13+
var rimrafSync = require('rimraf').sync;
14+
var spawnSync = require('child_process').spawnSync;
15+
16+
var prompt = function(question, cb) {
17+
var rlInterface = rl.createInterface({
18+
input: process.stdin,
19+
output: process.stdout,
20+
});
21+
rlInterface.question(question + '\n', function(answer) {
22+
rlInterface.close();
23+
cb(answer);
24+
})
25+
}
26+
27+
prompt('Are you sure you want to eject? This action is permanent. [Y/n]', function(answer) {
28+
if (answer && answer !== 'Y' && answer !== 'yes') {
29+
console.log('Close one! Eject aported.');
30+
process.exit(1);
31+
}
32+
33+
console.log('Ejecting...');
34+
console.log();
35+
var selfPath = path.join(__dirname, '..');
36+
var hostPath = path.join(selfPath, '..', '..');
37+
38+
var files = [
39+
'scripts',
40+
'webpack.config.dev.js',
41+
'webpack.config.prod.js',
42+
'.eslintrc'
43+
];
44+
45+
// Ensure that the host folder is clean and we won't override any files
46+
files.forEach(function(file) {
47+
if (fs.existsSync(path.join(hostPath, file))) {
48+
console.error(
49+
'`' + file + '` already exists in your app folder. We cannot ' +
50+
'continue as you would lose all the changes in that file or directory. ' +
51+
'Please delete it (maybe make a copy for backup) and run this ' +
52+
'command again.'
53+
);
54+
process.exit(1);
55+
}
56+
});
57+
58+
// Move the files over
59+
files.forEach(function(file) {
60+
console.log('Moving ' + file + ' to ' + hostPath);
61+
fs.renameSync(path.join(selfPath, file), path.join(hostPath, file));
62+
});
63+
64+
// These are unnecessary after graduation
65+
fs.unlinkSync(path.join(hostPath, 'scripts', 'init.js'));
66+
fs.unlinkSync(path.join(hostPath, 'scripts', 'eject.js'));
67+
68+
console.log();
69+
70+
var selfPackage = require(path.join(selfPath, 'package.json'));
71+
var hostPackage = require(path.join(hostPath, 'package.json'));
72+
73+
console.log('Removing dependency: create-react-app-scripts');
74+
delete hostPackage.devDependencies['create-react-app-scripts'];
75+
76+
Object.keys(selfPackage.dependencies).forEach(function (key) {
77+
console.log('Adding dependency: ' + key);
78+
hostPackage.devDependencies[key] = selfPackage.dependencies[key];
79+
});
80+
81+
console.log('Updating scripts');
82+
Object.keys(hostPackage.scripts).forEach(function (key) {
83+
hostPackage.scripts[key] = 'node ./scripts/' + key + '.js'
84+
});
85+
delete hostPackage.scripts['eject'];
86+
87+
console.log('Writing package.json');
88+
fs.writeFileSync(
89+
path.join(hostPath, 'package.json'),
90+
JSON.stringify(hostPackage, null, 2)
91+
);
92+
console.log();
93+
94+
console.log('Running npm install...');
95+
rimrafSync(selfPath);
96+
spawnSync('npm', ['install'], {stdio: 'inherit'});
97+
console.log();
98+
99+
console.log('Done!');
100+
101+
});

scripts/graduate.js

Lines changed: 0 additions & 82 deletions
This file was deleted.

scripts/init.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ module.exports = function(hostPath, appName, verbose) {
2525

2626
// Setup the script rules
2727
hostPackage.scripts = {};
28-
['start', 'build', 'graduate'].forEach(function(command) {
28+
['start', 'build', 'eject'].forEach(function(command) {
2929
hostPackage.scripts[command] =
3030
command + '-react-app';
3131
});
@@ -58,7 +58,7 @@ module.exports = function(hostPath, appName, verbose) {
5858
console.log('Inside that directory, you can run several commands:');
5959
console.log(' * npm start: Starts the development server.');
6060
console.log(' * npm run build: Builds the app for production.');
61-
console.log(' * npm run graduate: Removes this tool. If you do this, you can’t go back!');
61+
console.log(' * npm run eject: Removes this tool. If you do this, you can’t go back!');
6262
console.log();
6363
console.log('We suggest that you begin by typing:');
6464
console.log(' cd', appName);

0 commit comments

Comments
 (0)