Skip to content

Commit be2378b

Browse files
authored
Move more logic from react-scripts to react-dev-utils (facebook#2209)
* Show warnings for builds * Move WebpackDevServer helpers into react-dev-utils
1 parent bacbf59 commit be2378b

File tree

5 files changed

+71
-268
lines changed

5 files changed

+71
-268
lines changed

package.json

-2
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,6 @@
2121
"react-scripts": "./bin/react-scripts.js"
2222
},
2323
"dependencies": {
24-
"@timer/detect-port": "1.1.3",
25-
"address": "1.0.1",
2624
"autoprefixer": "7.1.0",
2725
"babel-core": "6.24.1",
2826
"babel-eslint": "7.2.3",

scripts/build.js

+27-14
Original file line numberDiff line numberDiff line change
@@ -56,12 +56,25 @@ measureFileSizesBeforeBuild(paths.appBuild)
5656
return build(previousFileSizes);
5757
})
5858
.then(
59-
({ stats, previousFileSizes }) => {
60-
console.log(chalk.green('Compiled successfully.'));
61-
console.log();
59+
({ stats, previousFileSizes, warnings }) => {
60+
if (warnings.length) {
61+
console.log(chalk.yellow('Compiled with warnings.\n'));
62+
console.log(warnings.join('\n\n'));
63+
console.log(
64+
'\nSearch for the ' +
65+
chalk.underline(chalk.yellow('rule keywords')) +
66+
' to learn more about each warning.'
67+
);
68+
console.log(
69+
'To ignore, add ' +
70+
chalk.cyan('// eslint-disable-next-line') +
71+
' to the line before.\n'
72+
);
73+
} else {
74+
console.log(chalk.green('Compiled successfully.\n'));
75+
}
6276

63-
console.log('File sizes after gzip:');
64-
console.log();
77+
console.log('File sizes after gzip:\n');
6578
printFileSizesAfterBuild(stats, previousFileSizes);
6679
console.log();
6780

@@ -78,10 +91,8 @@ measureFileSizesBeforeBuild(paths.appBuild)
7891
);
7992
},
8093
err => {
81-
console.log(chalk.red('Failed to compile.'));
82-
console.log();
83-
console.log(err.message || err);
84-
console.log();
94+
console.log(chalk.red('Failed to compile.\n'));
95+
console.log((err.message || err) + '\n');
8596
process.exit(1);
8697
}
8798
);
@@ -101,17 +112,19 @@ function build(previousFileSizes) {
101112
return reject(new Error(messages.errors.join('\n\n')));
102113
}
103114
if (process.env.CI && messages.warnings.length) {
104-
console.log();
105115
console.log(
106116
chalk.yellow(
107-
'Treating warnings as errors because process.env.CI = true.\n' +
108-
'Most CI servers set it automatically.'
117+
'\nTreating warnings as errors because process.env.CI = true.\n' +
118+
'Most CI servers set it automatically.\n'
109119
)
110120
);
111-
console.log();
112121
return reject(new Error(messages.warnings.join('\n\n')));
113122
}
114-
return resolve({ stats, previousFileSizes });
123+
return resolve({
124+
stats,
125+
previousFileSizes,
126+
warnings: messages.warnings,
127+
});
115128
});
116129
});
117130
}

scripts/eject.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ inquirer
5757
}
5858
}
5959

60-
const folders = ['config', 'config/jest', 'scripts', 'scripts/utils'];
60+
const folders = ['config', 'config/jest', 'scripts'];
6161

6262
// Make shallow array of files paths
6363
const files = folders.reduce(

scripts/start.js

+43-131
Original file line numberDiff line numberDiff line change
@@ -22,25 +22,24 @@ process.env.NODE_ENV = 'development';
2222
// Ensure environment variables are read.
2323
require('../config/env');
2424

25-
const address = require('address');
2625
const fs = require('fs');
2726
const chalk = require('chalk');
28-
const detect = require('@timer/detect-port');
27+
const webpack = require('webpack');
2928
const WebpackDevServer = require('webpack-dev-server');
3029
const clearConsole = require('react-dev-utils/clearConsole');
3130
const checkRequiredFiles = require('react-dev-utils/checkRequiredFiles');
32-
const getProcessForPort = require('react-dev-utils/getProcessForPort');
31+
const {
32+
choosePort,
33+
createCompiler,
34+
prepareProxy,
35+
prepareUrls,
36+
} = require('react-dev-utils/WebpackDevServerUtils');
3337
const openBrowser = require('react-dev-utils/openBrowser');
34-
const inquirer = require('inquirer');
3538
const paths = require('../config/paths');
3639
const config = require('../config/webpack.config.dev');
37-
const devServerConfig = require('../config/webpackDevServer.config');
38-
const createWebpackCompiler = require('./utils/createWebpackCompiler');
39-
const prepareProxy = require('react-dev-utils/prepareProxy');
40-
const url = require('url');
40+
const createDevServerConfig = require('../config/webpackDevServer.config');
4141

4242
const useYarn = fs.existsSync(paths.yarnLockFile);
43-
const cli = useYarn ? 'yarn' : 'npm';
4443
const isInteractive = process.stdout.isTTY;
4544

4645
// Warn and crash if required files are missing
@@ -52,130 +51,43 @@ if (!checkRequiredFiles([paths.appHtml, paths.appIndexJs])) {
5251
const DEFAULT_PORT = parseInt(process.env.PORT, 10) || 3000;
5352
const HOST = process.env.HOST || '0.0.0.0';
5453

55-
function run(port) {
56-
const protocol = process.env.HTTPS === 'true' ? 'https' : 'http';
57-
58-
const formatUrl = hostname => url.format({
59-
protocol,
60-
hostname,
61-
port,
62-
pathname: '/',
63-
});
64-
const prettyPrintUrl = hostname => url.format({
65-
protocol,
66-
hostname,
67-
port: chalk.bold(port),
68-
pathname: '/',
69-
});
70-
71-
const isUnspecifiedAddress = HOST === '0.0.0.0' || HOST === '::';
72-
let prettyHost, lanAddress, prettyLanUrl;
73-
if (isUnspecifiedAddress) {
74-
prettyHost = 'localhost';
75-
try {
76-
lanAddress = address.ip();
77-
if (lanAddress) {
78-
prettyLanUrl = prettyPrintUrl(lanAddress);
79-
}
80-
} catch (_e) {
81-
// ignored
82-
}
83-
} else {
84-
prettyHost = HOST;
85-
}
86-
const prettyLocalUrl = prettyPrintUrl(prettyHost);
87-
88-
// Create a webpack compiler that is configured with custom messages.
89-
const compiler = createWebpackCompiler(
90-
config,
91-
function onReady(showInstructions) {
92-
if (!showInstructions) {
93-
return;
94-
}
95-
console.log();
96-
console.log(
97-
`You can now view ${chalk.bold(require(paths.appPackageJson).name)} in the browser.`
98-
);
99-
console.log();
100-
101-
if (prettyLanUrl) {
102-
console.log(` ${chalk.bold('Local:')} ${prettyLocalUrl}`);
103-
console.log(` ${chalk.bold('On Your Network:')} ${prettyLanUrl}`);
104-
} else {
105-
console.log(` ${prettyLocalUrl}`);
106-
}
107-
108-
console.log();
109-
console.log('Note that the development build is not optimized.');
110-
console.log(
111-
`To create a production build, use ${chalk.cyan(`${cli} run build`)}.`
112-
);
113-
console.log();
114-
}
115-
);
116-
117-
// Load proxy config
118-
const proxy = require(paths.appPackageJson).proxy;
119-
// Serve webpack assets generated by the compiler over a web sever.
120-
const devServer = new WebpackDevServer(
121-
compiler,
122-
devServerConfig(prepareProxy(proxy), lanAddress)
123-
);
124-
125-
// Launch WebpackDevServer.
126-
devServer.listen(port, HOST, err => {
127-
if (err) {
128-
return console.log(err);
129-
}
130-
131-
if (isInteractive) {
132-
clearConsole();
133-
}
134-
console.log(chalk.cyan('Starting the development server...'));
135-
console.log();
136-
137-
openBrowser(formatUrl(prettyHost));
138-
});
139-
}
140-
14154
// We attempt to use the default port but if it is busy, we offer the user to
14255
// run on a different port. `detect()` Promise resolves to the next free port.
143-
detect(DEFAULT_PORT, HOST).then(
144-
port => {
145-
if (port === DEFAULT_PORT) {
146-
run(port);
56+
choosePort(HOST, DEFAULT_PORT)
57+
.then(port => {
58+
if (port == null) {
59+
// We have not found a port.
14760
return;
14861
}
149-
150-
if (isInteractive) {
151-
clearConsole();
152-
const existingProcess = getProcessForPort(DEFAULT_PORT);
153-
const question = {
154-
type: 'confirm',
155-
name: 'shouldChangePort',
156-
message: chalk.yellow(
157-
`Something is already running on port ${DEFAULT_PORT}.` +
158-
`${existingProcess ? ` Probably:\n ${existingProcess}` : ''}`
159-
) + '\n\nWould you like to run the app on another port instead?',
160-
default: true,
161-
};
162-
163-
inquirer.prompt(question).then(answer => {
164-
if (answer.shouldChangePort) {
165-
run(port);
166-
}
167-
});
168-
} else {
169-
console.log(
170-
chalk.red(`Something is already running on port ${DEFAULT_PORT}.`)
171-
);
172-
}
173-
},
174-
err => {
175-
console.log(
176-
chalk.red(`Could not find an open port at ${chalk.bold(HOST)}.`)
62+
const protocol = process.env.HTTPS === 'true' ? 'https' : 'http';
63+
const appName = require(paths.appPackageJson).name;
64+
const urls = prepareUrls(protocol, HOST, port);
65+
// Create a webpack compiler that is configured with custom messages.
66+
const compiler = createCompiler(webpack, config, appName, urls, useYarn);
67+
// Load proxy config
68+
const proxySetting = require(paths.appPackageJson).proxy;
69+
const proxyConfig = prepareProxy(proxySetting);
70+
// Serve webpack assets generated by the compiler over a web sever.
71+
const serverConfig = createDevServerConfig(
72+
proxyConfig,
73+
urls.lanUrlForConfig
17774
);
178-
console.log('Network error message: ' + err.message || err);
179-
console.log();
180-
}
181-
);
75+
const devServer = new WebpackDevServer(compiler, serverConfig);
76+
// Launch WebpackDevServer.
77+
devServer.listen(port, HOST, err => {
78+
if (err) {
79+
return console.log(err);
80+
}
81+
if (isInteractive) {
82+
clearConsole();
83+
}
84+
console.log(chalk.cyan('Starting the development server...\n'));
85+
openBrowser(urls.localUrlForBrowser);
86+
});
87+
})
88+
.catch(err => {
89+
if (err && err.message) {
90+
console.log(err.message);
91+
}
92+
process.exit(1);
93+
});

0 commit comments

Comments
 (0)