diff --git a/packages/create-react-app/createReactApp.js b/packages/create-react-app/createReactApp.js index 4a1b7901d..594f81154 100755 --- a/packages/create-react-app/createReactApp.js +++ b/packages/create-react-app/createReactApp.js @@ -455,7 +455,9 @@ function checkNpmVersion() { let hasMinNpm = false; let npmVersion = null; try { - npmVersion = execSync('npm --version').toString().trim(); + npmVersion = execSync('npm --version') + .toString() + .trim(); hasMinNpm = semver.gte(npmVersion, '3.0.0'); } catch (err) { // ignore diff --git a/packages/react-dev-utils/launchEditor.js b/packages/react-dev-utils/launchEditor.js index e1ea29c88..95ae1cddf 100644 --- a/packages/react-dev-utils/launchEditor.js +++ b/packages/react-dev-utils/launchEditor.js @@ -43,7 +43,7 @@ const COMMON_EDITORS_OSX = { '/Applications/CLion.app/Contents/MacOS/clion': '/Applications/CLion.app/Contents/MacOS/clion', '/Applications/IntelliJ IDEA.app/Contents/MacOS/idea': - '/Applications/IntelliJ IDEA.app/Contents/MacOS/idea', + '/Applications/IntelliJ IDEA.app/Contents/MacOS/idea', '/Applications/PhpStorm.app/Contents/MacOS/phpstorm': '/Applications/PhpStorm.app/Contents/MacOS/phpstorm', '/Applications/PyCharm.app/Contents/MacOS/pycharm': @@ -53,7 +53,7 @@ const COMMON_EDITORS_OSX = { '/Applications/RubyMine.app/Contents/MacOS/rubymine': '/Applications/RubyMine.app/Contents/MacOS/rubymine', '/Applications/WebStorm.app/Contents/MacOS/webstorm': - '/Applications/WebStorm.app/Contents/MacOS/webstorm', + '/Applications/WebStorm.app/Contents/MacOS/webstorm', }; const COMMON_EDITORS_WIN = [ diff --git a/packages/react-error-overlay/src/components/Header.js b/packages/react-error-overlay/src/components/Header.js index a2f40973d..227162343 100644 --- a/packages/react-error-overlay/src/components/Header.js +++ b/packages/react-error-overlay/src/components/Header.js @@ -29,11 +29,7 @@ type HeaderPropType = {| |}; function Header(props: HeaderPropType) { - return ( -
- {props.headerText} -
- ); + return
{props.headerText}
; } export default Header; diff --git a/packages/react-error-overlay/src/containers/RuntimeErrorContainer.js b/packages/react-error-overlay/src/containers/RuntimeErrorContainer.js index 9c41aa381..1e09724df 100644 --- a/packages/react-error-overlay/src/containers/RuntimeErrorContainer.js +++ b/packages/react-error-overlay/src/containers/RuntimeErrorContainer.js @@ -54,13 +54,14 @@ class RuntimeErrorContainer extends PureComponent { return ( - {totalErrors > 1 && + {totalErrors > 1 && ( } + /> + )} -
- {functionName} -
+
{functionName}
- {codeBlockProps && + {codeBlockProps && ( {'View ' + (compiled ? 'source' : 'compiled')} - } + + )} ); } diff --git a/packages/react-error-overlay/src/containers/StackTrace.js b/packages/react-error-overlay/src/containers/StackTrace.js index 4cb20bce1..8d81cc942 100644 --- a/packages/react-error-overlay/src/containers/StackTrace.js +++ b/packages/react-error-overlay/src/containers/StackTrace.js @@ -84,11 +84,7 @@ class StackTrace extends Component { } render() { - return ( -
- {this.renderFrames()} -
- ); + return
{this.renderFrames()}
; } } diff --git a/packages/react-error-overlay/src/utils/parser.js b/packages/react-error-overlay/src/utils/parser.js index 1cbee1d1c..6bc65ed8d 100644 --- a/packages/react-error-overlay/src/utils/parser.js +++ b/packages/react-error-overlay/src/utils/parser.js @@ -13,13 +13,16 @@ import StackFrame from './stack-frame'; const regexExtractLocation = /\(?(.+?)(?::(\d+))?(?::(\d+))?\)?$/; function extractLocation(token: string): [string, number, number] { - return regexExtractLocation.exec(token).slice(1).map(v => { - const p = Number(v); - if (!isNaN(p)) { - return p; - } - return v; - }); + return regexExtractLocation + .exec(token) + .slice(1) + .map(v => { + const p = Number(v); + if (!isNaN(p)) { + return p; + } + return v; + }); } const regexValidFrame_Chrome = /^\s*(at|in)\s.+(:\d+)/; @@ -55,7 +58,10 @@ function parseStack(stack: string[]): StackFrame[] { if (e.indexOf('(at ') !== -1) { e = e.replace(/\(at /, '('); } - const data = e.trim().split(/\s+/g).slice(1); + const data = e + .trim() + .split(/\s+/g) + .slice(1); const last = data.pop(); return new StackFrame(data.join(' ') || null, ...extractLocation(last)); } diff --git a/packages/react-error-overlay/src/utils/warnings.js b/packages/react-error-overlay/src/utils/warnings.js index bcc54ceb7..1cdb53dc0 100644 --- a/packages/react-error-overlay/src/utils/warnings.js +++ b/packages/react-error-overlay/src/utils/warnings.js @@ -11,7 +11,10 @@ import type { ReactFrame } from '../effects/proxyConsole'; function stripInlineStacktrace(message: string): string { - return message.split('\n').filter(line => !line.match(/^\s*in/)).join('\n'); // " in Foo" + return message + .split('\n') + .filter(line => !line.match(/^\s*in/)) + .join('\n'); // " in Foo" } function massage( diff --git a/packages/react-scripts/config/paths.js b/packages/react-scripts/config/paths.js index e860d9b04..0d85ff15b 100644 --- a/packages/react-scripts/config/paths.js +++ b/packages/react-scripts/config/paths.js @@ -114,6 +114,7 @@ if ( testsSetup: resolveOwn('template/src/setupTests.ts'), appNodeModules: resolveOwn('node_modules'), appTsConfig: resolveOwn('template/tsconfig.json'), + appTsLint: resolveOwn('template/tslint.json'), appTsTestConfig: resolveOwn('template/tsconfig.test.json'), publicUrl: getPublicUrl(resolveOwn('package.json')), servedPath: getServedPath(resolveOwn('package.json')), diff --git a/packages/react-scripts/config/webpack.config.dev.js b/packages/react-scripts/config/webpack.config.dev.js index 07c0a3adf..6c619f4f4 100644 --- a/packages/react-scripts/config/webpack.config.dev.js +++ b/packages/react-scripts/config/webpack.config.dev.js @@ -18,6 +18,7 @@ const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin'); const InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin'); const WatchMissingNodeModulesPlugin = require('react-dev-utils/WatchMissingNodeModulesPlugin'); const ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin'); +const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin'); const getClientEnvironment = require('./env'); const paths = require('./paths'); @@ -134,14 +135,6 @@ module.exports = { // We are waiting for https://github.com/facebookincubator/create-react-app/issues/2176. // { parser: { requireEnsure: false } }, - // First, run the linter. - // It's important to do this before Babel processes the JS. - { - test: /\.(ts|tsx)$/, - loader: require.resolve('tslint-loader'), - enforce: 'pre', - include: paths.appSrc, - }, { test: /\.js$/, loader: require.resolve('source-map-loader'), @@ -168,7 +161,15 @@ module.exports = { { test: /\.(ts|tsx)$/, include: paths.appSrc, - loader: require.resolve('ts-loader'), + use: [ + { + loader: require.resolve('ts-loader'), + options: { + // disable type checker - we will use it in fork plugin + transpileOnly: true, + }, + }, + ], }, // "postcss" loader applies autoprefixer to our CSS. // "css" loader resolves paths in CSS and adds assets as dependencies. @@ -262,6 +263,13 @@ module.exports = { // https://github.com/jmblog/how-to-optimize-momentjs-with-webpack // You can remove this if you don't use Moment.js: new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/), + // Perform type checking and linting in a separate process to speed up compilation + new ForkTsCheckerWebpackPlugin({ + async: false, + watch: paths.appSrc, + tsconfig: paths.appTsConfig, + tslint: paths.appTsLint, + }), ], // Some libraries import Node modules but don't use them in the browser. // Tell Webpack to provide empty mocks for them so importing them works. diff --git a/packages/react-scripts/config/webpack.config.prod.js b/packages/react-scripts/config/webpack.config.prod.js index 9582ee731..a3a3da9ca 100644 --- a/packages/react-scripts/config/webpack.config.prod.js +++ b/packages/react-scripts/config/webpack.config.prod.js @@ -19,6 +19,7 @@ const ManifestPlugin = require('webpack-manifest-plugin'); const InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin'); const SWPrecacheWebpackPlugin = require('sw-precache-webpack-plugin'); const ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin'); +const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin'); const paths = require('./paths'); const getClientEnvironment = require('./env'); @@ -138,14 +139,6 @@ module.exports = { // We are waiting for https://github.com/facebookincubator/create-react-app/issues/2176. // { parser: { requireEnsure: false } }, - // First, run the linter. - // It's important to do this before Typescript runs. - { - test: /\.(ts|tsx)$/, - loader: require.resolve('tslint-loader'), - enforce: 'pre', - include: paths.appSrc, - }, { test: /\.js$/, loader: require.resolve('source-map-loader'), @@ -167,11 +160,19 @@ module.exports = { name: 'static/media/[name].[hash:8].[ext]', }, }, - //Compile .tsx? + // Compile .tsx? { test: /\.(ts|tsx)$/, include: paths.appSrc, - loader: require.resolve('ts-loader') + use: [ + { + loader: require.resolve('ts-loader'), + options: { + // disable type checker - we will use it in fork plugin + transpileOnly: true, + }, + }, + ], }, // The notation here is somewhat confusing. // "postcss" loader applies autoprefixer to our CSS. @@ -341,6 +342,12 @@ module.exports = { // https://github.com/jmblog/how-to-optimize-momentjs-with-webpack // You can remove this if you don't use Moment.js: new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/), + // Perform type checking and linting in a separate process to speed up compilation + new ForkTsCheckerWebpackPlugin({ + async: false, + tsconfig: paths.appTsConfig, + tslint: paths.appTsLint, + }), ], // Some libraries import Node modules but don't use them in the browser. // Tell Webpack to provide empty mocks for them so importing them works. diff --git a/packages/react-scripts/package.json b/packages/react-scripts/package.json index 7d690ff5e..8af214eb6 100644 --- a/packages/react-scripts/package.json +++ b/packages/react-scripts/package.json @@ -28,6 +28,7 @@ "dotenv": "4.0.0", "extract-text-webpack-plugin": "3.0.0", "file-loader": "0.11.2", + "fork-ts-checker-webpack-plugin": "^0.2.8", "fs-extra": "3.0.1", "html-webpack-plugin": "2.29.0", "jest": "20.0.4", @@ -40,7 +41,6 @@ "ts-jest": "^20.0.7", "ts-loader": "^2.2.1", "tslint": "^5.2.0", - "tslint-loader": "^3.5.3", "tslint-react": "^3.0.0", "typescript": "~2.4.0", "source-map-loader": "^0.2.1", diff --git a/packages/react-scripts/scripts/utils/createJestConfig.js b/packages/react-scripts/scripts/utils/createJestConfig.js index c5886ce0c..f584331fd 100644 --- a/packages/react-scripts/scripts/utils/createJestConfig.js +++ b/packages/react-scripts/scripts/utils/createJestConfig.js @@ -54,13 +54,13 @@ module.exports = (resolve, rootDir) => { 'web.jsx', 'jsx', 'json', - 'node' + 'node', ], globals: { 'ts-jest': { tsConfigFile: paths.appTsTestConfig, }, - } + }, }; if (rootDir) { config.rootDir = rootDir;