mirror of
https://github.com/zhigang1992/create-react-app.git
synced 2026-04-24 05:05:53 +08:00
This reverts commit b2cf28b7f1 and reapplies #6406.
This commit is contained in:
116
packages/react-dev-utils/WebpackDevServerUtils.js
vendored
116
packages/react-dev-utils/WebpackDevServerUtils.js
vendored
@@ -17,22 +17,10 @@ const inquirer = require('inquirer');
|
||||
const clearConsole = require('./clearConsole');
|
||||
const formatWebpackMessages = require('./formatWebpackMessages');
|
||||
const getProcessForPort = require('./getProcessForPort');
|
||||
const typescriptFormatter = require('./typescriptFormatter');
|
||||
const forkTsCheckerWebpackPlugin = require('./ForkTsCheckerWebpackPlugin');
|
||||
|
||||
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 prepareUrls(protocol, host, port) {
|
||||
const formatUrl = hostname =>
|
||||
@@ -113,12 +101,20 @@ function printInstructions(appName, urls, useYarn) {
|
||||
console.log();
|
||||
}
|
||||
|
||||
function createCompiler(webpack, config, appName, urls, useYarn) {
|
||||
function createCompiler({
|
||||
appName,
|
||||
config,
|
||||
devSocket,
|
||||
urls,
|
||||
useYarn,
|
||||
useTypeScript,
|
||||
webpack,
|
||||
}) {
|
||||
// "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);
|
||||
compiler = webpack(config);
|
||||
} catch (err) {
|
||||
console.log(chalk.red('Failed to compile.'));
|
||||
console.log();
|
||||
@@ -139,10 +135,35 @@ function createCompiler(webpack, config, appName, urls, useYarn) {
|
||||
});
|
||||
|
||||
let isFirstCompile = true;
|
||||
let tsMessagesPromise;
|
||||
let tsMessagesResolver;
|
||||
|
||||
if (useTypeScript) {
|
||||
compiler.hooks.beforeCompile.tap('beforeCompile', () => {
|
||||
tsMessagesPromise = new Promise(resolve => {
|
||||
tsMessagesResolver = msgs => resolve(msgs);
|
||||
});
|
||||
});
|
||||
|
||||
forkTsCheckerWebpackPlugin
|
||||
.getCompilerHooks(compiler)
|
||||
.receive.tap('afterTypeScriptCheck', (diagnostics, lints) => {
|
||||
const allMsgs = [...diagnostics, ...lints];
|
||||
const format = message =>
|
||||
`${message.file}\n${typescriptFormatter(message, true)}`;
|
||||
|
||||
tsMessagesResolver({
|
||||
errors: allMsgs.filter(msg => msg.severity === 'error').map(format),
|
||||
warnings: allMsgs
|
||||
.filter(msg => msg.severity === 'warning')
|
||||
.map(format),
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// "done" event fires when Webpack has finished recompiling the bundle.
|
||||
// Whether or not you have warnings or errors, you will get this event.
|
||||
compiler.hooks.done.tap('done', stats => {
|
||||
compiler.hooks.done.tap('done', async stats => {
|
||||
if (isInteractive) {
|
||||
clearConsole();
|
||||
}
|
||||
@@ -152,9 +173,43 @@ function createCompiler(webpack, config, appName, urls, useYarn) {
|
||||
// them in a readable focused way.
|
||||
// We only construct the warnings and errors for speed:
|
||||
// https://github.com/facebook/create-react-app/issues/4492#issuecomment-421959548
|
||||
const messages = formatWebpackMessages(
|
||||
stats.toJson({ all: false, warnings: true, errors: true })
|
||||
);
|
||||
const statsData = stats.toJson({
|
||||
all: false,
|
||||
warnings: true,
|
||||
errors: true,
|
||||
});
|
||||
|
||||
if (useTypeScript && statsData.errors.length === 0) {
|
||||
const delayedMsg = setTimeout(() => {
|
||||
console.log(
|
||||
chalk.yellow(
|
||||
'Files successfully emitted, waiting for typecheck results...'
|
||||
)
|
||||
);
|
||||
}, 100);
|
||||
|
||||
const messages = await tsMessagesPromise;
|
||||
clearTimeout(delayedMsg);
|
||||
statsData.errors.push(...messages.errors);
|
||||
statsData.warnings.push(...messages.warnings);
|
||||
|
||||
// Push errors and warnings into compilation result
|
||||
// to show them after page refresh triggered by user.
|
||||
stats.compilation.errors.push(...messages.errors);
|
||||
stats.compilation.warnings.push(...messages.warnings);
|
||||
|
||||
if (messages.errors.length > 0) {
|
||||
devSocket.errors(messages.errors);
|
||||
} else if (messages.warnings.length > 0) {
|
||||
devSocket.warnings(messages.warnings);
|
||||
}
|
||||
|
||||
if (isInteractive) {
|
||||
clearConsole();
|
||||
}
|
||||
}
|
||||
|
||||
const messages = formatWebpackMessages(statsData);
|
||||
const isSuccessful = !messages.errors.length && !messages.warnings.length;
|
||||
if (isSuccessful) {
|
||||
console.log(chalk.green('Compiled successfully!'));
|
||||
@@ -194,6 +249,27 @@ function createCompiler(webpack, config, appName, urls, useYarn) {
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
// 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) {
|
||||
compiler.hooks.failed.tap('smokeTest', async () => {
|
||||
await tsMessagesPromise;
|
||||
process.exit(1);
|
||||
});
|
||||
compiler.hooks.done.tap('smokeTest', async stats => {
|
||||
await tsMessagesPromise;
|
||||
if (stats.hasErrors() || stats.hasWarnings()) {
|
||||
process.exit(1);
|
||||
} else {
|
||||
process.exit(0);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return compiler;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user