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