Skip to content

Commit f0e1b1b

Browse files
committed
fix issues with async type checking
1 parent 9a8fc4d commit f0e1b1b

File tree

3 files changed

+45
-38
lines changed

3 files changed

+45
-38
lines changed

packages/react-dev-utils/WebpackDevServerUtils.js

+37-31
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ function createCompiler(
108108
urls,
109109
useYarn,
110110
useTypeScript,
111-
devSocket
111+
devSocketWrite
112112
) {
113113
// "Compiler" is a low-level interface to Webpack.
114114
// It lets us listen to some events and provide our own custom messages.
@@ -140,6 +140,9 @@ function createCompiler(
140140

141141
if (useTypeScript) {
142142
compiler.hooks.beforeCompile.tap('beforeCompile', () => {
143+
if (!isFirstCompile) {
144+
devSocketWrite('wait-for-types', true);
145+
}
143146
tsMessagesPromise = new Promise(resolve => {
144147
tsMessagesResolver = msgs => resolve(msgs);
145148
});
@@ -164,52 +167,55 @@ function createCompiler(
164167
// "done" event fires when Webpack has finished recompiling the bundle.
165168
// Whether or not you have warnings or errors, you will get this event.
166169
compiler.hooks.done.tap('done', async stats => {
167-
if (isInteractive) {
168-
clearConsole();
170+
if (useTypeScript) {
171+
if (isInteractive) {
172+
clearConsole();
173+
}
174+
175+
console.log(
176+
chalk.yellow(
177+
'Files successfully emitted, waiting for typecheck results...'
178+
)
179+
);
169180
}
170181

171182
// We have switched off the default Webpack output in WebpackDevServer
172183
// options so we are going to "massage" the warnings and errors and present
173184
// them in a readable focused way.
174185
// We only construct the warnings and errors for speed:
175186
// https://github.com/facebook/create-react-app/issues/4492#issuecomment-421959548
176-
const statsData = stats.toJson({
177-
all: false,
178-
warnings: true,
179-
errors: true,
180-
});
181-
182-
if (useTypeScript && statsData.errors.length === 0) {
183-
const delayedMsg = setTimeout(() => {
184-
console.log(
185-
chalk.yellow(
186-
'Files successfully emitted, waiting for typecheck results...'
187-
)
188-
);
189-
}, 100);
187+
const messages = formatWebpackMessages(
188+
stats.toJson({ all: false, warnings: true, errors: true })
189+
);
190190

191-
const messages = await tsMessagesPromise;
192-
clearTimeout(delayedMsg);
193-
statsData.errors.push(...messages.errors);
194-
statsData.warnings.push(...messages.warnings);
191+
if (useTypeScript) {
192+
const asyncMessages = await tsMessagesPromise;
195193

196194
// Push errors and warnings into compilation result
197195
// to show them after page refresh triggered by user.
198-
stats.compilation.errors.push(...messages.errors);
199-
stats.compilation.warnings.push(...messages.warnings);
196+
// This is important for errors on first run in development.
197+
stats.compilation.errors.push(...asyncMessages.errors);
198+
stats.compilation.warnings.push(...asyncMessages.warnings);
200199

201-
if (messages.errors.length > 0) {
202-
devSocket.errors(messages.errors);
203-
} else if (messages.warnings.length > 0) {
204-
devSocket.warnings(messages.warnings);
205-
}
200+
messages.errors.push(...asyncMessages.errors);
201+
messages.warnings.push(...asyncMessages.warnings);
206202

207-
if (isInteractive) {
208-
clearConsole();
203+
if (asyncMessages.errors.length > 0) {
204+
devSocketWrite('errors', asyncMessages.errors);
205+
} else if (asyncMessages.warnings.length > 0) {
206+
devSocketWrite('warnings', asyncMessages.warnings);
207+
} else {
208+
// We have to notify the hot dev client when we are waiting for types
209+
// when `module.hot` is being used.
210+
devSocketWrite('wait-for-types', false);
211+
devSocketWrite('ok');
209212
}
210213
}
211214

212-
const messages = formatWebpackMessages(statsData);
215+
if (useTypeScript && isInteractive) {
216+
clearConsole();
217+
}
218+
213219
const isSuccessful = !messages.errors.length && !messages.warnings.length;
214220
if (isSuccessful) {
215221
console.log(chalk.green('Compiled successfully!'));

packages/react-dev-utils/webpackHotDevClient.js

+5-1
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ connection.onclose = function() {
8383
var isFirstCompilation = true;
8484
var mostRecentCompilationHash = null;
8585
var hasCompileErrors = false;
86+
var isWaitingForTypes = false;
8687

8788
function clearOutdatedErrors() {
8889
// Clean up outdated compile errors, if any.
@@ -203,6 +204,9 @@ connection.onmessage = function(e) {
203204
case 'warnings':
204205
handleWarnings(message.data);
205206
break;
207+
case 'wait-for-types':
208+
isWaitingForTypes = message.data;
209+
break;
206210
case 'errors':
207211
handleErrors(message.data);
208212
break;
@@ -221,7 +225,7 @@ function isUpdateAvailable() {
221225

222226
// Webpack disallows updates in other states.
223227
function canApplyUpdates() {
224-
return module.hot.status() === 'idle';
228+
return module.hot.status() === 'idle' && !isWaitingForTypes;
225229
}
226230

227231
// Attempt to update code on the fly, fall back to a hard reload.

packages/react-scripts/scripts/start.js

+3-6
Original file line numberDiff line numberDiff line change
@@ -96,11 +96,8 @@ checkBrowsers(paths.appPath, isInteractive)
9696
const appName = require(paths.appPackageJson).name;
9797
const useTypeScript = fs.existsSync(paths.appTsConfig);
9898
const urls = prepareUrls(protocol, HOST, port);
99-
const devSocket = {
100-
warnings: warnings =>
101-
devServer.sockWrite(devServer.sockets, 'warnings', warnings),
102-
errors: errors =>
103-
devServer.sockWrite(devServer.sockets, 'errors', errors),
99+
const devSocketWrite = (type, data) => {
100+
devServer.sockWrite(devServer.sockets, type, data);
104101
};
105102
// Create a webpack compiler that is configured with custom messages.
106103
const compiler = createCompiler(
@@ -110,7 +107,7 @@ checkBrowsers(paths.appPath, isInteractive)
110107
urls,
111108
useYarn,
112109
useTypeScript,
113-
devSocket
110+
devSocketWrite
114111
);
115112
// Load proxy config
116113
const proxySetting = require(paths.appPackageJson).proxy;

0 commit comments

Comments
 (0)