In the default TypeScript based create-react-app
project, only the first TS error is shown when the project is built with react-scripts
but all errors are shown when running tsc
.
The project was initialized with create-react-app foo --typescript
and only src/index.tsx
was modified after initialization:
src/index.tsx src/index.tsx
console.log(typeof nonExistentVar);
console.log(typeof nonExistentVar);
console.log(typeof nonExistentVar2);
console.log(typeof nonExistentVar2);
export {};
package.json
export {};
{
"name": "foo",
"version": "0.1.0",
"private": true,
"dependencies": {
"@types/jest": "24.0.15",
"@types/node": "12.6.8",
"@types/react": "16.8.23",
"@types/react-dom": "16.8.5",
"react": "^16.8.6",
"react-dom": "^16.8.6",
"react-scripts": "3.0.1",
"typescript": "3.5.3"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}
tsconfig.json
{
"compilerOptions": {
"target": "es5",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "preserve"
},
"include": [
"src"
]
}
npm start
shows only the first error:
Failed to compile.
C:/foo/src/index.tsx
TypeScript error in C:/foo/src/index.tsx(1,20):
Cannot find name 'nonExistentVar'. TS2304
> 1 | console.log(typeof nonExistentVar);
| ^
2 | console.log(typeof nonExistentVar2);
3 | export {};
And tsc
shows all errors at once:
src/index.tsx:1:20 - error TS2304: Cannot find name 'nonExistentVar'.
1 console.log(typeof nonExistentVar);
~~~~~~~~~~~~~~
src/index.tsx:2:20 - error TS2304: Cannot find name 'nonExistentVar2'.
2 console.log(typeof nonExistentVar2);
~~~~~~~~~~~~~~~
Found 2 errors.
How can I force start
and build
scripts to show all errors?
Found a better solution. No forking or ejecting necessary. You can write a very simple plugin that hooks into fork-ts-checker-webpack-plugin
to get all the errors and print them. Edit craco.config.js
to create the plugin class in my example I called it PrintAllWebpackErrorsPlugin
. Then instantiate the class in the webpack
section of the module.exports
. Don't forget to reset craco start
to apply the changes. The craco.config.js
file should look something like the following:
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
// This plugin uses a hook on the ForkTSCheckedWebpackPlugin to extract the errors and print them to console
class PrintAllWebpackErrorsPlugin {
apply(compiler) {
const hooks = ForkTsCheckerWebpackPlugin.getCompilerHooks(compiler);
hooks.done.tap("PrintAllWebpackErrorsPlugin", function(errors) {
errors.forEach(err => {
console.log(err.file)
console.log(`Typescript error in ${err.file}(${err.line},${err.character})`)
console.log(`${err.message} TS${err.code}`)
})
})
}
}
module.exports = {
reactScriptsVersion: "react-scripts" /* (default value) */,
style: {
modules: {
localIdentName: ""
},
css: {
loaderOptions: { /* Any css-loader configuration options: https://github.com/webpack-contrib/css-loader. */ },
loaderOptions: (cssLoaderOptions, { env, paths }) => { return cssLoaderOptions; }
},
sass: {
loaderOptions: { /* Any sass-loader configuration options: https://github.com/webpack-contrib/sass-loader. */ },
loaderOptions: (sassLoaderOptions, { env, paths }) => { return sassLoaderOptions; }
},
postcss: {
}
},
eslint: {
enable: false /* (default value) */,
mode: "extends" /* (default value) */ || "file",
configure: { /* Any eslint configuration options: https://eslint.org/docs/user-guide/configuring */ },
configure: (eslintConfig, { env, paths }) => { return eslintConfig; },
pluginOptions: { /* Any eslint plugin configuration options: https://github.com/webpack-contrib/eslint-webpack-plugin#options. */ },
pluginOptions: (eslintOptions, { env, paths }) => { return eslintOptions; }
},
babel: {
presets: [],
plugins: [],
loaderOptions: { /* Any babel-loader configuration options: https://github.com/babel/babel-loader. */ },
loaderOptions: (babelLoaderOptions, { env, paths }) => { return babelLoaderOptions; }
},
typescript: {
enableTypeChecking: true /* (default value) */
},
webpack: {
alias: {},
plugins: {
add: [
// Notice I'm instantiating the plugin here to include it.
new PrintAllWebpackErrorsPlugin(),
], /* An array of plugins */
remove: [], /* An array of plugin constructor's names (i.e. "StyleLintPlugin", "ESLintWebpackPlugin" ) */
},
configure: { /* Any webpack configuration options: https://webpack.js.org/configuration */ },
configure: (webpackConfig, { env, paths }) => { return webpackConfig; }
},
jest: {
babel: {
addPresets: true, /* (default value) */
addPlugins: true /* (default value) */
},
configure: { /* Any Jest configuration options: https://jestjs.io/docs/en/configuration */ },
configure: (jestConfig, { env, paths, resolve, rootDir }) => { return jestConfig; }
},
devServer: { /* Any devServer configuration options: https://webpack.js.org/configuration/dev-server/#devserver */ },
devServer: (devServerConfig, { env, paths, proxy, allowedHost }) => { return devServerConfig; },
plugins: [
{
plugin: {
overrideCracoConfig: ({ cracoConfig, pluginOptions, context: { env, paths } }) => { return cracoConfig; },
overrideWebpackConfig: ({ webpackConfig, cracoConfig, pluginOptions, context: { env, paths } }) => { return webpackConfig; },
overrideDevServerConfig: ({ devServerConfig, cracoConfig, pluginOptions, context: { env, paths, proxy, allowedHost } }) => { return devServerConfig; },
overrideJestConfig: ({ jestConfig, cracoConfig, pluginOptions, context: { env, paths, resolve, rootDir } }) => { return jestConfig },
},
options: {}
}
]
};