Skip to content

Commit cb6ff39

Browse files
committed
Add file.
0 parents  commit cb6ff39

10 files changed

+966
-0
lines changed

Diff for: .gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
node_modules

Diff for: WatchMissingNodeModulesPlugin.js

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
2+
class WatchMissingNodeModulesPlugin {
3+
constructor(nodeModulesPath) {
4+
this.nodeModulesPath = nodeModulesPath;
5+
}
6+
7+
apply(compiler) {
8+
compiler.plugin('emit', (compilation, callback) => {
9+
var missingDeps = compilation.missingDependencies;
10+
var nodeModulesPath = this.nodeModulesPath;
11+
12+
if (this.nodeModulesPath && !Array.isArray(this.nodeModulesPath)){
13+
nodeModulesPath = [this.nodeModulesPath];
14+
}
15+
nodeModulesPath.forEach((nodeModulesPathItem) => {
16+
// If any missing files are expected to appear in node_modules...
17+
if (missingDeps.some(file => file.indexOf(nodeModulesPathItem) !== -1)) {
18+
// ...tell webpack to watch node_modules recursively until they appear.
19+
compilation.contextDependencies.push(nodeModulesPathItem);
20+
}
21+
})
22+
callback();
23+
});
24+
}
25+
}
26+
27+
module.exports = WatchMissingNodeModulesPlugin;

Diff for: choosePort.js

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
const isRoot = require('is-root');
2+
const color = require('colors-cli');
3+
const inquirer = require('inquirer');
4+
const detect = require('detect-port-alt');
5+
const clearConsole = require('./clearConsole');
6+
const getProcessForPort = require('./getProcessForPort');
7+
const isInteractive = process.stdout.isTTY;
8+
9+
module.exports = function choosePort(host, defaultPort) {
10+
return detect(defaultPort, host).then(
11+
port =>
12+
new Promise(resolve => {
13+
if (port === defaultPort) {
14+
return resolve(port);
15+
}
16+
const message =
17+
process.platform !== 'win32' && defaultPort < 1024 && !isRoot()
18+
? `Admin permissions are required to run a server on a port below 1024.`
19+
: `Something is already running on port ${defaultPort}.`;
20+
if (isInteractive) {
21+
clearConsole();
22+
const existingProcess = getProcessForPort(defaultPort);
23+
const question = {
24+
type: 'confirm',
25+
name: 'shouldChangePort',
26+
message:
27+
color.yellow(
28+
message +
29+
`${existingProcess ? ` Probably:\n ${existingProcess}` : ''}`
30+
) + '\n\nWould you like to run the app on another port instead?',
31+
default: true,
32+
};
33+
inquirer.prompt(question).then(answer => {
34+
if (answer.shouldChangePort) {
35+
resolve(port);
36+
} else {
37+
resolve(null);
38+
}
39+
});
40+
} else {
41+
console.log(color.red(message));
42+
resolve(null);
43+
}
44+
}),
45+
err => {
46+
throw new Error(
47+
color.red(`Could not find an open port at ${color.bold(host)}.`) +
48+
'\n' +
49+
('Network error message: ' + err.message || err) +
50+
'\n'
51+
);
52+
}
53+
);
54+
}

Diff for: clearConsole.js

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
2+
module.exports = function clearConsole() {
3+
process.stdout.write(
4+
process.platform === 'win32' ? '\x1Bc' : '\x1B[2J\x1B[3J\x1B[H'
5+
);
6+
}

Diff for: createCompiler.js

+143
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
const color = require('colors-cli');
2+
const loading = require('loading-cli');
3+
const clearConsole = require('./clearConsole');
4+
const formatWebpackMessages = require('webpack-hot-dev-clients/formatWebpackMessages');
5+
6+
const isInteractive = process.stdout.isTTY;
7+
let handleCompile;
8+
// You can safely remove this after ejecting.
9+
// We only use this block for testing of Create React App itself:
10+
const isSmokeTest = process.argv.some(arg => arg.indexOf('--smoke-test') > -1);
11+
if (isSmokeTest) {
12+
handleCompile = (err, stats) => {
13+
if (err || stats.hasErrors() || stats.hasWarnings()) {
14+
process.exit(1);
15+
} else {
16+
process.exit(0);
17+
}
18+
};
19+
}
20+
21+
22+
function printInstructions(appName, urls, useYarn) {
23+
console.log();
24+
console.log(`You can now view ${color.bold(appName)} in the browser.`);
25+
console.log();
26+
27+
if (urls.lanUrlForTerminal) {
28+
console.log(
29+
` ${color.bold('Local:')} ${urls.localUrlForTerminal}`
30+
);
31+
console.log(
32+
` ${color.bold('On Your Network:')} ${urls.lanUrlForTerminal}`
33+
);
34+
} else {
35+
console.log(` ${urls.localUrlForTerminal}`);
36+
}
37+
38+
console.log();
39+
console.log('Note that the development build is not optimized.');
40+
console.log(
41+
`To create a production build, use ` +
42+
`${color.cyan(`${useYarn ? 'yarn' : 'npm run'} build`)}.`
43+
);
44+
console.log();
45+
}
46+
47+
function printDoneMessage(stats, isInteractive, isFirstCompile, appName, urls, useYarn) {
48+
// We have switched off the default Webpack output in WebpackDevServer
49+
// options so we are going to "massage" the warnings and errors and present
50+
// them in a readable focused way.
51+
const messages = formatWebpackMessages(stats.toJson({}, true));
52+
const isSuccessful = !messages.errors.length && !messages.warnings.length;
53+
if (isSuccessful) {
54+
console.log(color.green('Compiled successfully!'));
55+
}
56+
if (isSuccessful && (isInteractive || isFirstCompile)) {
57+
printInstructions(appName, urls, useYarn);
58+
}
59+
isFirstCompile = false;
60+
61+
// If errors exist, only show errors.
62+
if (messages.errors.length) {
63+
// Only keep the first error. Others are often indicative
64+
// of the same problem, but confuse the reader with noise.
65+
if (messages.errors.length > 1) {
66+
messages.errors.length = 1;
67+
}
68+
console.log(color.red('Failed to compile.\n'));
69+
console.log(messages.errors.join('\n\n'));
70+
return;
71+
}
72+
73+
// Show warnings if no errors were found.
74+
if (messages.warnings.length) {
75+
console.log(color.yellow('Compiled with warnings.\n'));
76+
console.log(messages.warnings.join('\n\n'));
77+
78+
// Teach some ESLint tricks.
79+
console.log(
80+
'\nSearch for the ' +
81+
color.underline(color.yellow('keywords')) +
82+
' to learn more about each warning.'
83+
);
84+
console.log(
85+
'To ignore, add ' +
86+
color.cyan('// eslint-disable-next-line') +
87+
' to the line before.\n'
88+
);
89+
}
90+
}
91+
92+
93+
let isloading = true;
94+
95+
function createCompiler(webpack, config, appName, urls, useYarn) {
96+
// "Compiler" is a low-level interface to Webpack.
97+
// It lets us listen to some events and provide our own custom messages.
98+
let compiler;
99+
try {
100+
compiler = webpack(config, handleCompile);
101+
} catch (err) {
102+
console.log(color.red('Failed to compile.'));
103+
console.log();
104+
console.log(err.message || err);
105+
console.log();
106+
process.exit(1);
107+
}
108+
const load = loading('Starting the development server...\n')
109+
if (isloading) {
110+
isloading = false;
111+
}
112+
113+
// "invalid" event fires when you have changed a file, and Webpack is
114+
// recompiling a bundle. WebpackDevServer takes care to pause serving the
115+
// bundle, so if you refresh, it'll wait instead of serving the old one.
116+
// "invalid" is short for "bundle invalidated", it doesn't imply any errors.
117+
compiler.plugin('invalid', () => {
118+
if (isInteractive) {
119+
clearConsole();
120+
}
121+
load.start()
122+
load.text = ' Compiling...';
123+
});
124+
125+
let isFirstCompile = true;
126+
// "done" event fires when Webpack has finished recompiling the bundle.
127+
// Whether or not you have warnings or errors, you will get this event.
128+
compiler.plugin('done', stats => {
129+
// if (isInteractive) {
130+
// // clearConsole();
131+
// }
132+
clearTimeout(this.timer);
133+
this.timer = setTimeout(() => {
134+
clearConsole();
135+
load.stop()
136+
printDoneMessage(stats, isInteractive, isFirstCompile, appName, urls, useYarn)
137+
},1000)
138+
139+
});
140+
return compiler;
141+
}
142+
143+
module.exports = createCompiler;

Diff for: getProcessForPort.js

+76
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
2+
'use strict';
3+
4+
var color = require('colors-cli');
5+
var execSync = require('child_process').execSync;
6+
var path = require('path');
7+
8+
var execOptions = {
9+
encoding: 'utf8',
10+
stdio: [
11+
'pipe', // stdin (default)
12+
'pipe', // stdout (default)
13+
'ignore', //stderr
14+
],
15+
};
16+
17+
function isProcessAReactApp(processCommand) {
18+
return /^node .*react-scripts\/scripts\/start\.js\s?$/.test(processCommand);
19+
}
20+
21+
function getProcessIdOnPort(port) {
22+
return execSync('lsof -i:' + port + ' -P -t -sTCP:LISTEN', execOptions)
23+
.split('\n')[0]
24+
.trim();
25+
}
26+
27+
function getPackageNameInDirectory(directory) {
28+
var packagePath = path.join(directory.trim(), 'package.json');
29+
30+
try {
31+
return require(packagePath).name;
32+
} catch (e) {
33+
return null;
34+
}
35+
}
36+
37+
function getProcessCommand(processId, processDirectory) {
38+
var command = execSync(
39+
'ps -o command -p ' + processId + ' | sed -n 2p',
40+
execOptions
41+
);
42+
43+
command = command.replace(/\n$/, '');
44+
45+
if (isProcessAReactApp(command)) {
46+
const packageName = getPackageNameInDirectory(processDirectory);
47+
return packageName ? packageName : command;
48+
} else {
49+
return command;
50+
}
51+
}
52+
53+
function getDirectoryOfProcessById(processId) {
54+
return execSync(
55+
'lsof -p ' + processId + ' | awk \'$4=="cwd" {print $9}\'',
56+
execOptions
57+
).trim();
58+
}
59+
60+
function getProcessForPort(port) {
61+
try {
62+
var processId = getProcessIdOnPort(port);
63+
var directory = getDirectoryOfProcessById(processId);
64+
var command = getProcessCommand(processId, directory);
65+
return (
66+
color.cyan(command) +
67+
color.grey(' (pid ' + processId + ')\n') +
68+
color.blue(' in ') +
69+
color.cyan(directory)
70+
);
71+
} catch (e) {
72+
return null;
73+
}
74+
}
75+
76+
module.exports = getProcessForPort;

0 commit comments

Comments
 (0)