Skip to content

Commit ad0afee

Browse files
deftomatianschmitz
authored andcommittedFeb 8, 2019
Speed up TypeScript projects (#5903)
As a lot of [people](https://hackernoon.com/why-i-no-longer-use-typescript-with-react-and-why-you-shouldnt-either-e744d27452b4) is complaining about TypeScript performance in CRA, I decided to enable `async` mode in TypeScript checker. These changes basically brings the JS compilation times to TS projects. So, recompilation took less than 1 second instead of 3 seconds in medium size project. The problem with async mode is that type-errors are reported after Webpack ends up recompilation as TypeScript could be slower than Babel. PR allows to emit files compiled by Babel immediately and then wait for TS and show type errors in terminal later. Also, if there was no compilation errors and any type error occurs, we trigger a hot-reload with new errors to show error overlay in browser. Also, I wanted to start a discussion about `skipLibCheck: false` option in default `tsconfig.json`. This makes recompilations really slow and we should consider to set it to `true` or at least give users a big warning to let them know that it could be really slow. The following video is showing the updated workflow with a forced 2.5 second delay for type-check to give you an idea how it works. ![nov-26-2018 15-47-01](https://user-images.githubusercontent.com/5549148/49021284-9446fe80-f192-11e8-952b-8f83d77d5fbc.gif) I'm pretty sure that PR needs some polishing and improvements but it should works as it is. Especially a "hack" with reloading the browser after type-check looks ugly to me. cc @brunolemos as he is an initiator of an original TypeScript PR. Should fix facebook/create-react-app#5820
1 parent 6732c15 commit ad0afee

File tree

3 files changed

+22
-13
lines changed

3 files changed

+22
-13
lines changed
 

Diff for: ‎config/webpack.config.js

+5-11
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ const getCSSModuleLocalIdent = require('react-dev-utils/getCSSModuleLocalIdent')
2929
const paths = require('./paths');
3030
const getClientEnvironment = require('./env');
3131
const ModuleNotFoundPlugin = require('react-dev-utils/ModuleNotFoundPlugin');
32-
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin-alt');
32+
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
3333
const typescriptFormatter = require('react-dev-utils/typescriptFormatter');
3434
// @remove-on-eject-begin
3535
const getCacheIdentifier = require('react-dev-utils/getCacheIdentifier');
@@ -617,17 +617,10 @@ module.exports = function(webpackEnv) {
617617
typescript: resolve.sync('typescript', {
618618
basedir: paths.appNodeModules,
619619
}),
620-
async: false,
620+
async: isEnvDevelopment,
621+
useTypescriptIncrementalApi: true,
621622
checkSyntacticErrors: true,
622623
tsconfig: paths.appTsConfig,
623-
compilerOptions: {
624-
module: 'esnext',
625-
moduleResolution: 'node',
626-
resolveJsonModule: true,
627-
isolatedModules: true,
628-
noEmit: true,
629-
jsx: 'preserve',
630-
},
631624
reportFiles: [
632625
'**',
633626
'!**/*.json',
@@ -638,7 +631,8 @@ module.exports = function(webpackEnv) {
638631
],
639632
watch: paths.appSrc,
640633
silent: true,
641-
formatter: typescriptFormatter,
634+
// The formatter is invoked directly in WebpackDevServerUtils during development
635+
formatter: isEnvProduction ? typescriptFormatter : undefined,
642636
}),
643637
].filter(Boolean),
644638
// Some libraries import Node modules but don't use them in the browser.

Diff for: ‎package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
"eslint-plugin-jsx-a11y": "6.1.2",
4646
"eslint-plugin-react": "7.12.3",
4747
"file-loader": "2.0.0",
48-
"fork-ts-checker-webpack-plugin-alt": "0.4.14",
48+
"fork-ts-checker-webpack-plugin": "1.0.0-alpha.6",
4949
"fs-extra": "7.0.1",
5050
"html-webpack-plugin": "4.0.0-alpha.2",
5151
"identity-obj-proxy": "3.0.0",

Diff for: ‎scripts/start.js

+16-1
Original file line numberDiff line numberDiff line change
@@ -94,9 +94,24 @@ checkBrowsers(paths.appPath, isInteractive)
9494
const config = configFactory('development');
9595
const protocol = process.env.HTTPS === 'true' ? 'https' : 'http';
9696
const appName = require(paths.appPackageJson).name;
97+
const useTypeScript = fs.existsSync(paths.appTsConfig);
9798
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),
104+
};
98105
// Create a webpack compiler that is configured with custom messages.
99-
const compiler = createCompiler(webpack, config, appName, urls, useYarn);
106+
const compiler = createCompiler(
107+
webpack,
108+
config,
109+
appName,
110+
urls,
111+
useYarn,
112+
useTypeScript,
113+
devSocket
114+
);
100115
// Load proxy config
101116
const proxySetting = require(paths.appPackageJson).proxy;
102117
const proxyConfig = prepareProxy(proxySetting, paths.appPublic);

0 commit comments

Comments
 (0)
Please sign in to comment.