Skip to content

Commit d87cd35

Browse files
iansugaearon
authored andcommitted
Replace prompt function from react-dev-utils with Inquirer.js. (facebook#1772)
1 parent 8af1c13 commit d87cd35

File tree

3 files changed

+182
-170
lines changed

3 files changed

+182
-170
lines changed

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
"fs-extra": "0.30.0",
4848
"html-webpack-plugin": "2.28.0",
4949
"http-proxy-middleware": "0.17.3",
50+
"inquirer": "3.0.6",
5051
"jest": "18.1.0",
5152
"object-assign": "4.1.1",
5253
"postcss-loader": "1.3.3",

scripts/eject.js

+168-162
Original file line numberDiff line numberDiff line change
@@ -20,181 +20,187 @@ const fs = require('fs-extra');
2020
const path = require('path');
2121
const spawnSync = require('cross-spawn').sync;
2222
const chalk = require('chalk');
23-
const prompt = require('react-dev-utils/prompt');
23+
const inquirer = require('inquirer');
2424
const paths = require('../config/paths');
2525
const createJestConfig = require('./utils/createJestConfig');
2626

2727
const green = chalk.green;
2828
const cyan = chalk.cyan;
2929

30-
prompt(
31-
'Are you sure you want to eject? This action is permanent.',
32-
false
33-
).then(shouldEject => {
34-
if (!shouldEject) {
35-
console.log(cyan('Close one! Eject aborted.'));
36-
process.exit(1);
37-
}
38-
39-
console.log('Ejecting...');
40-
41-
const ownPath = paths.ownPath;
42-
const appPath = paths.appPath;
43-
44-
function verifyAbsent(file) {
45-
if (fs.existsSync(path.join(appPath, file))) {
46-
console.error(
47-
`\`${file}\` already exists in your app folder. We cannot ` +
48-
'continue as you would lose all the changes in that file or directory. ' +
49-
'Please move or delete it (maybe make a copy for backup) and run this ' +
50-
'command again.'
51-
);
30+
inquirer
31+
.prompt({
32+
type: 'confirm',
33+
name: 'shouldEject',
34+
message: 'Are you sure you want to eject? This action is permanent.',
35+
default: false,
36+
})
37+
.then(answer => {
38+
if (!answer.shouldEject) {
39+
console.log(cyan('Close one! Eject aborted.'));
5240
process.exit(1);
5341
}
54-
}
55-
56-
const folders = ['config', 'config/jest', 'scripts', 'scripts/utils'];
57-
58-
// Make shallow array of files paths
59-
const files = folders.reduce(
60-
(files, folder) => {
61-
return files.concat(
62-
fs
63-
.readdirSync(path.join(ownPath, folder))
64-
// set full path
65-
.map(file => path.join(ownPath, folder, file))
66-
// omit dirs from file list
67-
.filter(file => fs.lstatSync(file).isFile())
68-
);
69-
},
70-
[]
71-
);
72-
73-
// Ensure that the app folder is clean and we won't override any files
74-
folders.forEach(verifyAbsent);
75-
files.forEach(verifyAbsent);
76-
77-
console.log();
78-
console.log(cyan(`Copying files into ${appPath}`));
79-
80-
folders.forEach(folder => {
81-
fs.mkdirSync(path.join(appPath, folder));
82-
});
8342

84-
files.forEach(file => {
85-
let content = fs.readFileSync(file, 'utf8');
43+
console.log('Ejecting...');
44+
45+
const ownPath = paths.ownPath;
46+
const appPath = paths.appPath;
47+
48+
function verifyAbsent(file) {
49+
if (fs.existsSync(path.join(appPath, file))) {
50+
console.error(
51+
`\`${file}\` already exists in your app folder. We cannot ` +
52+
'continue as you would lose all the changes in that file or directory. ' +
53+
'Please move or delete it (maybe make a copy for backup) and run this ' +
54+
'command again.'
55+
);
56+
process.exit(1);
57+
}
58+
}
8659

87-
// Skip flagged files
88-
if (content.match(/\/\/ @remove-file-on-eject/)) {
89-
return;
60+
const folders = ['config', 'config/jest', 'scripts', 'scripts/utils'];
61+
62+
// Make shallow array of files paths
63+
const files = folders.reduce(
64+
(files, folder) => {
65+
return files.concat(
66+
fs
67+
.readdirSync(path.join(ownPath, folder))
68+
// set full path
69+
.map(file => path.join(ownPath, folder, file))
70+
// omit dirs from file list
71+
.filter(file => fs.lstatSync(file).isFile())
72+
);
73+
},
74+
[]
75+
);
76+
77+
// Ensure that the app folder is clean and we won't override any files
78+
folders.forEach(verifyAbsent);
79+
files.forEach(verifyAbsent);
80+
81+
console.log();
82+
console.log(cyan(`Copying files into ${appPath}`));
83+
84+
folders.forEach(folder => {
85+
fs.mkdirSync(path.join(appPath, folder));
86+
});
87+
88+
files.forEach(file => {
89+
let content = fs.readFileSync(file, 'utf8');
90+
91+
// Skip flagged files
92+
if (content.match(/\/\/ @remove-file-on-eject/)) {
93+
return;
94+
}
95+
content = content
96+
// Remove dead code from .js files on eject
97+
.replace(
98+
/\/\/ @remove-on-eject-begin([\s\S]*?)\/\/ @remove-on-eject-end/mg,
99+
''
100+
)
101+
// Remove dead code from .applescript files on eject
102+
.replace(
103+
/-- @remove-on-eject-begin([\s\S]*?)-- @remove-on-eject-end/mg,
104+
''
105+
)
106+
.trim() + '\n';
107+
console.log(` Adding ${cyan(file.replace(ownPath, ''))} to the project`);
108+
fs.writeFileSync(file.replace(ownPath, appPath), content);
109+
});
110+
console.log();
111+
112+
const ownPackage = require(path.join(ownPath, 'package.json'));
113+
const appPackage = require(path.join(appPath, 'package.json'));
114+
115+
console.log(cyan('Updating the dependencies'));
116+
const ownPackageName = ownPackage.name;
117+
if (appPackage.devDependencies[ownPackageName]) {
118+
console.log(` Removing ${cyan(ownPackageName)} from devDependencies`);
119+
delete appPackage.devDependencies[ownPackageName];
90120
}
91-
content = content
92-
// Remove dead code from .js files on eject
93-
.replace(
94-
/\/\/ @remove-on-eject-begin([\s\S]*?)\/\/ @remove-on-eject-end/mg,
95-
''
96-
)
97-
// Remove dead code from .applescript files on eject
98-
.replace(
99-
/-- @remove-on-eject-begin([\s\S]*?)-- @remove-on-eject-end/mg,
100-
''
101-
)
102-
.trim() + '\n';
103-
console.log(` Adding ${cyan(file.replace(ownPath, ''))} to the project`);
104-
fs.writeFileSync(file.replace(ownPath, appPath), content);
105-
});
106-
console.log();
107-
108-
const ownPackage = require(path.join(ownPath, 'package.json'));
109-
const appPackage = require(path.join(appPath, 'package.json'));
110-
111-
console.log(cyan('Updating the dependencies'));
112-
const ownPackageName = ownPackage.name;
113-
if (appPackage.devDependencies[ownPackageName]) {
114-
console.log(` Removing ${cyan(ownPackageName)} from devDependencies`);
115-
delete appPackage.devDependencies[ownPackageName];
116-
}
117-
if (appPackage.dependencies[ownPackageName]) {
118-
console.log(` Removing ${cyan(ownPackageName)} from dependencies`);
119-
delete appPackage.dependencies[ownPackageName];
120-
}
121-
122-
Object.keys(ownPackage.dependencies).forEach(key => {
123-
// For some reason optionalDependencies end up in dependencies after install
124-
if (ownPackage.optionalDependencies[key]) {
125-
return;
121+
if (appPackage.dependencies[ownPackageName]) {
122+
console.log(` Removing ${cyan(ownPackageName)} from dependencies`);
123+
delete appPackage.dependencies[ownPackageName];
126124
}
127-
console.log(` Adding ${cyan(key)} to devDependencies`);
128-
appPackage.devDependencies[key] = ownPackage.dependencies[key];
129-
});
130-
console.log();
131-
console.log(cyan('Updating the scripts'));
132-
delete appPackage.scripts['eject'];
133-
Object.keys(appPackage.scripts).forEach(key => {
134-
Object.keys(ownPackage.bin).forEach(binKey => {
135-
const regex = new RegExp(binKey + ' (\\w+)', 'g');
136-
appPackage.scripts[key] = appPackage.scripts[key].replace(
137-
regex,
138-
'node scripts/$1.js'
139-
);
140-
console.log(
141-
` Replacing ${cyan(`"${binKey} ${key}"`)} with ${cyan(`"node scripts/${key}.js"`)}`
142-
);
143-
});
144-
});
145125

146-
console.log();
147-
console.log(cyan('Configuring package.json'));
148-
// Add Jest config
149-
console.log(` Adding ${cyan('Jest')} configuration`);
150-
appPackage.jest = createJestConfig(
151-
filePath => path.posix.join('<rootDir>', filePath),
152-
null,
153-
true
154-
);
155-
156-
// Add Babel config
157-
console.log(` Adding ${cyan('Babel')} preset`);
158-
appPackage.babel = {
159-
presets: ['react-app'],
160-
};
161-
162-
// Add ESlint config
163-
console.log(` Adding ${cyan('ESLint')} configuration`);
164-
appPackage.eslintConfig = {
165-
extends: 'react-app',
166-
};
167-
168-
fs.writeFileSync(
169-
path.join(appPath, 'package.json'),
170-
JSON.stringify(appPackage, null, 2) + '\n'
171-
);
172-
console.log();
173-
174-
// "Don't destroy what isn't ours"
175-
if (ownPath.indexOf(appPath) === 0) {
176-
try {
177-
// remove react-scripts and react-scripts binaries from app node_modules
126+
Object.keys(ownPackage.dependencies).forEach(key => {
127+
// For some reason optionalDependencies end up in dependencies after install
128+
if (ownPackage.optionalDependencies[key]) {
129+
return;
130+
}
131+
console.log(` Adding ${cyan(key)} to devDependencies`);
132+
appPackage.devDependencies[key] = ownPackage.dependencies[key];
133+
});
134+
console.log();
135+
console.log(cyan('Updating the scripts'));
136+
delete appPackage.scripts['eject'];
137+
Object.keys(appPackage.scripts).forEach(key => {
178138
Object.keys(ownPackage.bin).forEach(binKey => {
179-
fs.removeSync(path.join(appPath, 'node_modules', '.bin', binKey));
139+
const regex = new RegExp(binKey + ' (\\w+)', 'g');
140+
appPackage.scripts[key] = appPackage.scripts[key].replace(
141+
regex,
142+
'node scripts/$1.js'
143+
);
144+
console.log(
145+
` Replacing ${cyan(`"${binKey} ${key}"`)} with ${cyan(`"node scripts/${key}.js"`)}`
146+
);
180147
});
181-
fs.removeSync(ownPath);
182-
} catch (e) {
183-
// It's not essential that this succeeds
148+
});
149+
150+
console.log();
151+
console.log(cyan('Configuring package.json'));
152+
// Add Jest config
153+
console.log(` Adding ${cyan('Jest')} configuration`);
154+
appPackage.jest = createJestConfig(
155+
filePath => path.posix.join('<rootDir>', filePath),
156+
null,
157+
true
158+
);
159+
160+
// Add Babel config
161+
console.log(` Adding ${cyan('Babel')} preset`);
162+
appPackage.babel = {
163+
presets: ['react-app'],
164+
};
165+
166+
// Add ESlint config
167+
console.log(` Adding ${cyan('ESLint')} configuration`);
168+
appPackage.eslintConfig = {
169+
extends: 'react-app',
170+
};
171+
172+
fs.writeFileSync(
173+
path.join(appPath, 'package.json'),
174+
JSON.stringify(appPackage, null, 2) + '\n'
175+
);
176+
console.log();
177+
178+
// "Don't destroy what isn't ours"
179+
if (ownPath.indexOf(appPath) === 0) {
180+
try {
181+
// remove react-scripts and react-scripts binaries from app node_modules
182+
Object.keys(ownPackage.bin).forEach(binKey => {
183+
fs.removeSync(path.join(appPath, 'node_modules', '.bin', binKey));
184+
});
185+
fs.removeSync(ownPath);
186+
} catch (e) {
187+
// It's not essential that this succeeds
188+
}
184189
}
185-
}
186-
187-
if (fs.existsSync(paths.yarnLockFile)) {
188-
console.log(cyan('Running yarn...'));
189-
spawnSync('yarnpkg', [], { stdio: 'inherit' });
190-
} else {
191-
console.log(cyan('Running npm install...'));
192-
spawnSync('npm', ['install'], { stdio: 'inherit' });
193-
}
194-
console.log(green('Ejected successfully!'));
195-
console.log();
196-
197-
console.log(green('Please consider sharing why you ejected in this survey:'));
198-
console.log(green(' http://goo.gl/forms/Bi6CZjk1EqsdelXk1'));
199-
console.log();
200-
});
190+
191+
if (fs.existsSync(paths.yarnLockFile)) {
192+
console.log(cyan('Running yarn...'));
193+
spawnSync('yarnpkg', [], { stdio: 'inherit' });
194+
} else {
195+
console.log(cyan('Running npm install...'));
196+
spawnSync('npm', ['install'], { stdio: 'inherit' });
197+
}
198+
console.log(green('Ejected successfully!'));
199+
console.log();
200+
201+
console.log(
202+
green('Please consider sharing why you ejected in this survey:')
203+
);
204+
console.log(green(' http://goo.gl/forms/Bi6CZjk1EqsdelXk1'));
205+
console.log();
206+
});

scripts/start.js

+13-8
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ const clearConsole = require('react-dev-utils/clearConsole');
3030
const checkRequiredFiles = require('react-dev-utils/checkRequiredFiles');
3131
const getProcessForPort = require('react-dev-utils/getProcessForPort');
3232
const openBrowser = require('react-dev-utils/openBrowser');
33-
const prompt = require('react-dev-utils/prompt');
33+
const inquirer = require('inquirer');
3434
const paths = require('../config/paths');
3535
const config = require('../config/webpack.config.dev');
3636
const devServerConfig = require('../config/webpackDevServer.config');
@@ -114,13 +114,18 @@ detect(DEFAULT_PORT, HOST).then(port => {
114114
if (isInteractive) {
115115
clearConsole();
116116
const existingProcess = getProcessForPort(DEFAULT_PORT);
117-
const question = chalk.yellow(
118-
`Something is already running on port ${DEFAULT_PORT}.` +
119-
`${existingProcess ? ` Probably:\n ${existingProcess}` : ''}`
120-
) + '\n\nWould you like to run the app on another port instead?';
121-
122-
prompt(question, true).then(shouldChangePort => {
123-
if (shouldChangePort) {
117+
const question = {
118+
type: 'confirm',
119+
name: 'shouldChangePort',
120+
message: chalk.yellow(
121+
`Something is already running on port ${DEFAULT_PORT}.` +
122+
`${existingProcess ? ` Probably:\n ${existingProcess}` : ''}`
123+
) + '\n\nWould you like to run the app on another port instead?',
124+
default: true,
125+
};
126+
127+
inquirer.prompt(question).then(answer => {
128+
if (answer.shouldChangePort) {
124129
run(port);
125130
}
126131
});

0 commit comments

Comments
 (0)