From a1f8c0195d05b009b77edf6d2679dac3ca1aec40 Mon Sep 17 00:00:00 2001 From: Joe Haddad Date: Mon, 22 Oct 2018 12:18:34 -0400 Subject: [PATCH] Add TypeScript error formatting --- packages/react-dev-utils/package.json | 1 + .../react-dev-utils/typescriptFormatter.js | 46 +++++++++++++++++++ .../config/webpack.config.dev.js | 3 ++ .../config/webpack.config.prod.js | 3 ++ 4 files changed, 53 insertions(+) create mode 100644 packages/react-dev-utils/typescriptFormatter.js diff --git a/packages/react-dev-utils/package.json b/packages/react-dev-utils/package.json index e70d4b57ac8..d7bb290de2c 100644 --- a/packages/react-dev-utils/package.json +++ b/packages/react-dev-utils/package.json @@ -36,6 +36,7 @@ "openChrome.applescript", "printBuildError.js", "printHostingInstructions.js", + "typescriptFormatter.js", "WatchMissingNodeModulesPlugin.js", "WebpackDevServerUtils.js", "webpackHotDevClient.js" diff --git a/packages/react-dev-utils/typescriptFormatter.js b/packages/react-dev-utils/typescriptFormatter.js new file mode 100644 index 00000000000..ab1ca9b0706 --- /dev/null +++ b/packages/react-dev-utils/typescriptFormatter.js @@ -0,0 +1,46 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +'use strict'; + +const os = require('os'); +const codeFrame = require('@babel/code-frame').codeFrameColumns; +const chalk = require('chalk'); +const fs = require('fs'); + +function formatter(message, useColors) { + const colors = new chalk.constructor({ enabled: useColors }); + const messageColor = message.isWarningSeverity() ? colors.yellow : colors.red; + + const source = + message.getFile() && + fs.existsSync(message.getFile()) && + fs.readFileSync(message.getFile(), 'utf-8'); + let frame = ''; + + if (source) { + frame = codeFrame( + source, + { start: { line: message.line, column: message.character } }, + { highlightCode: useColors } + ) + .split('\n') + .map(str => ' ' + str) + .join(os.EOL); + } + + return [ + messageColor.bold(`Type ${message.getSeverity().toLowerCase()}: `) + + message.getContent() + + ' ' + + messageColor.underline(`TS${message.code}`), + '', + frame, + ].join(os.EOL); +} + +module.exports = formatter; diff --git a/packages/react-scripts/config/webpack.config.dev.js b/packages/react-scripts/config/webpack.config.dev.js index 7a68c14811e..4716345b75c 100644 --- a/packages/react-scripts/config/webpack.config.dev.js +++ b/packages/react-scripts/config/webpack.config.dev.js @@ -24,6 +24,7 @@ const paths = require('./paths'); const ManifestPlugin = require('webpack-manifest-plugin'); const ModuleNotFoundPlugin = require('react-dev-utils/ModuleNotFoundPlugin'); const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin-alt'); +const typescriptFormatter = require('react-dev-utils/typescriptFormatter'); // @remove-on-eject-begin const getCacheIdentifier = require('react-dev-utils/getCacheIdentifier'); // @remove-on-eject-end @@ -419,6 +420,8 @@ module.exports = { checkSyntacticErrors: true, tsconfig: paths.appTsConfig, watch: paths.appSrc, + silent: true, + formatter: typescriptFormatter, }), ].filter(Boolean), diff --git a/packages/react-scripts/config/webpack.config.prod.js b/packages/react-scripts/config/webpack.config.prod.js index 41be0d05778..bbe9842fd68 100644 --- a/packages/react-scripts/config/webpack.config.prod.js +++ b/packages/react-scripts/config/webpack.config.prod.js @@ -28,6 +28,7 @@ const paths = require('./paths'); const getClientEnvironment = require('./env'); const ModuleNotFoundPlugin = require('react-dev-utils/ModuleNotFoundPlugin'); const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin-alt'); +const typescriptFormatter = require('react-dev-utils/typescriptFormatter'); // @remove-on-eject-begin const getCacheIdentifier = require('react-dev-utils/getCacheIdentifier'); // @remove-on-eject-end @@ -539,6 +540,8 @@ module.exports = { checkSyntacticErrors: true, tsconfig: paths.appTsConfig, watch: paths.appSrc, + silent: true, + formatter: typescriptFormatter, }), ].filter(Boolean), // Some libraries import Node modules but don't use them in the browser.