From 9e4589f48eb30f356a71912a4786d8624650da9f Mon Sep 17 00:00:00 2001 From: Will Monk Date: Mon, 27 Nov 2017 17:10:02 +0000 Subject: [PATCH] Merge pull request #165 from johnnyreilly/master Add support for fork-ts-checker-webpack-plugin --- packages/react-scripts/config/paths.js | 10 ++-- .../config/webpack.config.dev.js | 26 +++++---- .../config/webpack.config.prod.js | 20 +++++-- packages/react-scripts/package.json | 54 +++++++++++-------- 4 files changed, 71 insertions(+), 39 deletions(-) diff --git a/packages/react-scripts/config/paths.js b/packages/react-scripts/config/paths.js index e860d9b04..76c165ba4 100644 --- a/packages/react-scripts/config/paths.js +++ b/packages/react-scripts/config/paths.js @@ -43,8 +43,8 @@ const getPublicUrl = appPackageJson => // like /todos/42/static/js/bundle.7289d.js. We have to know the root. function getServedPath(appPackageJson) { const publicUrl = getPublicUrl(appPackageJson); - const servedUrl = - envPublicUrl || (publicUrl ? url.parse(publicUrl).pathname : '/'); + const servedUrl = envPublicUrl || + (publicUrl ? url.parse(publicUrl).pathname : '/'); return ensureSlash(servedUrl, true); } @@ -61,6 +61,7 @@ module.exports = { testsSetup: resolveApp('src/setupTests.ts'), appNodeModules: resolveApp('node_modules'), appTsConfig: resolveApp('tsconfig.json'), + appTsLint: resolveApp('tslint.json'), publicUrl: getPublicUrl(resolveApp('package.json')), servedPath: getServedPath(resolveApp('package.json')), }; @@ -83,6 +84,7 @@ module.exports = { appNodeModules: resolveApp('node_modules'), appTsConfig: resolveApp('tsconfig.json'), appTsTestConfig: resolveApp('tsconfig.test.json'), + appTsLint: resolveApp('tslint.json'), publicUrl: getPublicUrl(resolveApp('package.json')), servedPath: getServedPath(resolveApp('package.json')), // These properties only exist before ejecting: @@ -92,8 +94,7 @@ module.exports = { const ownPackageJson = require('../package.json'); const reactScriptsPath = resolveApp(`node_modules/${ownPackageJson.name}`); -const reactScriptsLinked = - fs.existsSync(reactScriptsPath) && +const reactScriptsLinked = fs.existsSync(reactScriptsPath) && fs.lstatSync(reactScriptsPath).isSymbolicLink(); // config before publish: we're in ./packages/react-scripts/config/ @@ -114,6 +115,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..366dcd108 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'); @@ -137,7 +138,6 @@ module.exports = { // TODO: Disable require.ensure as it's not a standard language feature. // 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. { @@ -167,11 +167,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 +349,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 01bb852f5..e299a11b7 100644 --- a/packages/react-scripts/package.json +++ b/packages/react-scripts/package.json @@ -1,9 +1,9 @@ { "name": "react-scripts-ts", - "version": "2.8.0", + "version": "2.9.0", "description": "Configuration and scripts for Create React App.", "repository": "wmonk/create-react-app", - "license": "BSD-3-Clause", + "license": "MIT", "engines": { "node": ">=6" }, @@ -21,41 +21,49 @@ "react-scripts-ts": "./bin/react-scripts-ts.js" }, "dependencies": { - "autoprefixer": "7.1.2", + "autoprefixer": "7.1.6", + "babel-core": "6.26.0", + "babel-eslint": "7.2.3", + "babel-jest": "20.0.3", + "babel-loader": "7.1.2", + "babel-preset-react-app": "^3.1.0", + "babel-runtime": "6.26.0", "case-sensitive-paths-webpack-plugin": "2.1.1", "chalk": "1.1.3", - "css-loader": "0.28.4", + "css-loader": "0.28.7", "dotenv": "4.0.0", - "extract-text-webpack-plugin": "3.0.0", - "file-loader": "0.11.2", + "extract-text-webpack-plugin": "3.0.2", + "file-loader": "1.1.5", + "fork-ts-checker-webpack-plugin": "^0.2.8", "fs-extra": "3.0.1", "html-webpack-plugin": "2.29.0", "jest": "20.0.4", "object-assign": "4.1.1", "postcss-flexbugs-fixes": "3.2.0", - "postcss-loader": "2.0.6", + "postcss-loader": "2.0.8", "promise": "8.0.1", - "react-dev-utils": "^4.0.1", - "style-loader": "0.18.2", - "ts-jest": "^20.0.7", - "ts-loader": "^2.3.7", - "tslint": "^5.7.0", - "tslint-loader": "^3.5.3", - "tslint-react": "^3.2.0", - "typescript": "~2.5.3", - "source-map-loader": "^0.2.1", + "raf": "3.4.0", + "react-dev-utils": "^4.2.1", + "style-loader": "0.19.0", "sw-precache-webpack-plugin": "0.11.4", - "url-loader": "0.5.9", - "webpack": "3.5.1", - "webpack-dev-server": "2.7.1", - "webpack-manifest-plugin": "1.2.1", - "whatwg-fetch": "2.0.3" + "url-loader": "0.6.2", + "webpack": "3.8.1", + "webpack-dev-server": "2.9.4", + "webpack-manifest-plugin": "1.3.2", + "whatwg-fetch": "2.0.3", + "ts-jest": "^21.1.4", + "ts-loader": "^3.1.1", + "tslint": "^5.8.0", + "tslint-react": "^3.2.0", + "typescript": "~2.6.1", + "source-map-loader": "^0.2.3" }, "devDependencies": { - "react": "^15.5.4", - "react-dom": "^15.5.4" + "react": "^16.0.0", + "react-dom": "^16.0.0" }, "optionalDependencies": { "fsevents": "1.1.2" } } +