From f348ca9d7e41a9940d9f225ea99c17ee21db206c Mon Sep 17 00:00:00 2001 From: leeight Date: Mon, 14 May 2018 14:31:47 +0800 Subject: [PATCH 01/15] Update react-scripts Change-Id: I6480d421a15cdc83c69f0049faf8ce3c1356d18b --- packages/react-scripts/config/webpack.config.prod.js | 8 ++++++++ packages/react-scripts/package.json | 3 ++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/packages/react-scripts/config/webpack.config.prod.js b/packages/react-scripts/config/webpack.config.prod.js index c8d1f3b13d9..377e08c6d7a 100644 --- a/packages/react-scripts/config/webpack.config.prod.js +++ b/packages/react-scripts/config/webpack.config.prod.js @@ -68,6 +68,14 @@ const postCSSLoaderOptions = { autoprefixer({ flexbox: 'no-2009', }), + require('postcss-url')({ + url: function (asset) { + if (asset.url.charAt(0) === '/') { + return publicUrl + asset.url; + } + return asset.url; + } + }) ], sourceMap: shouldUseSourceMap, }; diff --git a/packages/react-scripts/package.json b/packages/react-scripts/package.json index e61fcade8bf..cc07dd57674 100644 --- a/packages/react-scripts/package.json +++ b/packages/react-scripts/package.json @@ -1,5 +1,5 @@ { - "name": "react-scripts", + "name": "@leeight/react-scripts", "version": "1.1.0", "description": "Configuration and scripts for Create React App.", "repository": "facebook/create-react-app", @@ -54,6 +54,7 @@ "object-assign": "4.1.1", "postcss-flexbugs-fixes": "3.2.0", "postcss-loader": "2.0.10", + "postcss-url": "^7.3.2", "promise": "8.0.1", "raf": "3.4.0", "react-dev-utils": "^5.0.0", From 0ce8e1af29829b6795ec05ae7196bb34659a4c05 Mon Sep 17 00:00:00 2001 From: leeight Date: Mon, 14 May 2018 15:15:02 +0800 Subject: [PATCH 02/15] Release 2.0.1 Change-Id: If75730807d1aa0af025b1cd47764e3bd16ab6403 --- packages/react-scripts/package.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/react-scripts/package.json b/packages/react-scripts/package.json index cc07dd57674..04e7055bfb2 100644 --- a/packages/react-scripts/package.json +++ b/packages/react-scripts/package.json @@ -1,6 +1,6 @@ { - "name": "@leeight/react-scripts", - "version": "1.1.0", + "name": "byted-react-scripts", + "version": "2.0.1", "description": "Configuration and scripts for Create React App.", "repository": "facebook/create-react-app", "license": "MIT", @@ -28,15 +28,15 @@ "babel-eslint": "8.2.2", "babel-jest": "22.4.1", "babel-loader": "8.0.0-beta.0", - "babel-plugin-named-asset-import": "^0.1.0", - "babel-preset-react-app": "^3.1.1", + "babel-plugin-named-asset-import": "1.0.0-next.66cc7a90", + "babel-preset-react-app": "4.0.0-next.66cc7a90", "case-sensitive-paths-webpack-plugin": "2.1.1", "chalk": "2.3.0", "css-loader": "0.28.9", "dotenv": "5.0.0", "dotenv-expand": "4.2.0", "eslint": "4.15.0", - "eslint-config-react-app": "^2.1.0", + "eslint-config-react-app": "3.0.0-next.66cc7a90", "eslint-loader": "1.9.0", "eslint-plugin-flowtype": "2.41.0", "eslint-plugin-import": "2.8.0", @@ -57,7 +57,7 @@ "postcss-url": "^7.3.2", "promise": "8.0.1", "raf": "3.4.0", - "react-dev-utils": "^5.0.0", + "react-dev-utils": "6.0.0-next.66cc7a90", "resolve": "1.6.0", "sass-loader": "7.0.1", "style-loader": "0.19.1", From ccd2ae159e03d2e6f51796ff95cb37d992833abe Mon Sep 17 00:00:00 2001 From: leeight Date: Mon, 14 May 2018 15:18:38 +0800 Subject: [PATCH 03/15] Release to 2.0.2 Change-Id: I0cbbd0c730de4f3ae8ccd871d2827db087bf0395 --- packages/react-scripts/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/react-scripts/package.json b/packages/react-scripts/package.json index 04e7055bfb2..c44285e71c4 100644 --- a/packages/react-scripts/package.json +++ b/packages/react-scripts/package.json @@ -1,6 +1,6 @@ { "name": "byted-react-scripts", - "version": "2.0.1", + "version": "2.0.2", "description": "Configuration and scripts for Create React App.", "repository": "facebook/create-react-app", "license": "MIT", @@ -18,7 +18,7 @@ "utils" ], "bin": { - "react-scripts": "./bin/react-scripts.js" + "byted-react-scripts": "./bin/react-scripts.js" }, "dependencies": { "@babel/core": "7.0.0-beta.46", From 0ed6cee17c77b28d8d6a664f86165dbe26a763c3 Mon Sep 17 00:00:00 2001 From: majunchen Date: Wed, 18 Jul 2018 11:33:06 +0800 Subject: [PATCH 04/15] feat(typescript-support): add typescript solution Change-Id: I7a7a682d5329cf60ec79532ce22a3232c7cd0614 --- packages/react-scripts/README.md | 12 +- packages/react-scripts/bin/react-scripts.js | 5 +- .../config/jest/typescriptTransform.js | 7 + packages/react-scripts/config/paths.js | 26 +- .../config/webpack.config.dev.js | 212 +++++++---- .../config/webpack.config.prod.js | 238 ++++++++----- packages/react-scripts/package.json | 16 +- packages/react-scripts/scripts/init.js | 337 ++++++++++-------- .../scripts/utils/createDotEnv.js | 41 +++ .../scripts/utils/createJestConfig.js | 24 +- .../react-scripts/template/_js/eslintrc.json | 8 + .../react-scripts/template/_js/jsconfig.json | 14 + .../template/{ => _js}/src/App.css | 0 .../template/{ => _js}/src/App.js | 0 .../template/{ => _js}/src/App.test.js | 0 .../template/{ => _js}/src/index.css | 0 .../template/{ => _js}/src/index.js | 0 .../template/{ => _js}/src/logo.svg | 0 .../template/{ => _js}/src/serviceWorker.js | 0 .../react-scripts/template/_ts/src/App.css | 32 ++ .../template/_ts/src/App.test.tsx | 9 + .../react-scripts/template/_ts/src/App.tsx | 28 ++ .../react-scripts/template/_ts/src/index.css | 14 + .../react-scripts/template/_ts/src/index.tsx | 12 + .../react-scripts/template/_ts/src/logo.svg | 7 + .../template/_ts/src/serviceWorker.ts | 135 +++++++ .../react-scripts/template/_ts/tsconfig.json | 38 ++ .../template/_ts/tsconfig.prod.json | 3 + .../template/_ts/tsconfig.test.json | 7 + .../react-scripts/template/_ts/tslint.json | 13 + .../template/_ts/typings/index.d.ts | 4 + packages/react-scripts/template/gitignore | 251 ++++++++++++- 32 files changed, 1172 insertions(+), 321 deletions(-) create mode 100644 packages/react-scripts/config/jest/typescriptTransform.js create mode 100644 packages/react-scripts/scripts/utils/createDotEnv.js create mode 100644 packages/react-scripts/template/_js/eslintrc.json create mode 100644 packages/react-scripts/template/_js/jsconfig.json rename packages/react-scripts/template/{ => _js}/src/App.css (100%) rename packages/react-scripts/template/{ => _js}/src/App.js (100%) rename packages/react-scripts/template/{ => _js}/src/App.test.js (100%) rename packages/react-scripts/template/{ => _js}/src/index.css (100%) rename packages/react-scripts/template/{ => _js}/src/index.js (100%) rename packages/react-scripts/template/{ => _js}/src/logo.svg (100%) rename packages/react-scripts/template/{ => _js}/src/serviceWorker.js (100%) create mode 100644 packages/react-scripts/template/_ts/src/App.css create mode 100644 packages/react-scripts/template/_ts/src/App.test.tsx create mode 100644 packages/react-scripts/template/_ts/src/App.tsx create mode 100644 packages/react-scripts/template/_ts/src/index.css create mode 100644 packages/react-scripts/template/_ts/src/index.tsx create mode 100644 packages/react-scripts/template/_ts/src/logo.svg create mode 100644 packages/react-scripts/template/_ts/src/serviceWorker.ts create mode 100644 packages/react-scripts/template/_ts/tsconfig.json create mode 100644 packages/react-scripts/template/_ts/tsconfig.prod.json create mode 100644 packages/react-scripts/template/_ts/tsconfig.test.json create mode 100644 packages/react-scripts/template/_ts/tslint.json create mode 100644 packages/react-scripts/template/_ts/typings/index.d.ts diff --git a/packages/react-scripts/README.md b/packages/react-scripts/README.md index f2a2994f00c..8a1ce5035d5 100644 --- a/packages/react-scripts/README.md +++ b/packages/react-scripts/README.md @@ -1,6 +1,14 @@ -# react-scripts +# byted-react-scripts -This package includes scripts and configuration used by [Create React App](https://github.com/facebook/create-react-app).
+__usage:__ + +```sh +create-react-app --scripts-version=byted-react-scripts dirname +``` + + + +This package includes scripts and configuration forked from [Create React App](https://github.com/facebook/create-react-app).
Please refer to its documentation: * [Getting Started](https://github.com/facebook/create-react-app/blob/master/README.md#getting-started) – How to create a new app. diff --git a/packages/react-scripts/bin/react-scripts.js b/packages/react-scripts/bin/react-scripts.js index 9ad5fccff88..7030eec0214 100755 --- a/packages/react-scripts/bin/react-scripts.js +++ b/packages/react-scripts/bin/react-scripts.js @@ -57,9 +57,6 @@ switch (script) { } default: console.log('Unknown script "' + script + '".'); - console.log('Perhaps you need to update react-scripts?'); - console.log( - 'See: https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/template/README.md#updating-to-new-releases' - ); + console.log('Perhaps you need to update byted-react-scripts?'); break; } diff --git a/packages/react-scripts/config/jest/typescriptTransform.js b/packages/react-scripts/config/jest/typescriptTransform.js new file mode 100644 index 00000000000..9b138ac8ecb --- /dev/null +++ b/packages/react-scripts/config/jest/typescriptTransform.js @@ -0,0 +1,7 @@ +// Copyright 2004-present Facebook. All Rights Reserved. + +'use strict'; + +const tsJestPreprocessor = require('ts-jest/preprocessor'); + +module.exports = tsJestPreprocessor; diff --git a/packages/react-scripts/config/paths.js b/packages/react-scripts/config/paths.js index d7f55b6f638..d1179209193 100644 --- a/packages/react-scripts/config/paths.js +++ b/packages/react-scripts/config/paths.js @@ -13,6 +13,9 @@ const fs = require('fs'); const url = require('url'); const findMonorepo = require('react-dev-utils/workspaceUtils').findMonorepo; +const LANG = process.env.DEV_LANG || 'javascript'; +const EXT = LANG === 'javascript' ? '.js' : '.tsx'; + // Make sure any symlinks in the project folder are resolved: // https://github.com/facebook/create-react-app/issues/637 const appDirectory = fs.realpathSync(process.cwd()); @@ -54,12 +57,15 @@ module.exports = { appBuild: resolveApp('build'), appPublic: resolveApp('public'), appHtml: resolveApp('public/index.html'), - appIndexJs: resolveApp('src/index.js'), + appIndexJs: resolveApp(`src/index${EXT}`), appPackageJson: resolveApp('package.json'), appSrc: resolveApp('src'), - testsSetup: resolveApp('src/setupTests.js'), + testsSetup: resolveApp(`src/setupTests${EXT}`), appNodeModules: resolveApp('node_modules'), publicUrl: getPublicUrl(resolveApp('package.json')), + appTsConfig: resolveApp('tsconfig.json'), + appTsProdConfig: resolveApp('tsconfig.prod.json'), + appTsLint: resolveApp('tslint.json'), servedPath: getServedPath(resolveApp('package.json')), }; @@ -75,12 +81,16 @@ module.exports = { appBuild: resolveApp('build'), appPublic: resolveApp('public'), appHtml: resolveApp('public/index.html'), - appIndexJs: resolveApp('src/index.js'), + appIndexJs: resolveApp(`src/index${EXT}`), appPackageJson: resolveApp('package.json'), appSrc: resolveApp('src'), - testsSetup: resolveApp('src/setupTests.js'), + testsSetup: resolveApp(`src/setupTests${EXT}`), appNodeModules: resolveApp('node_modules'), publicUrl: getPublicUrl(resolveApp('package.json')), + appTsConfig: resolveApp('tsconfig.json'), + appTsTestConfig: resolveApp('tsconfig.test.json'), + appTsProdConfig: resolveApp('tsconfig.prod.json'), + appTsLint: resolveApp('tslint.json'), servedPath: getServedPath(resolveApp('package.json')), // These properties only exist before ejecting: ownPath: resolveOwn('.'), @@ -100,11 +110,15 @@ if (useTemplate) { appBuild: resolveOwn('../../build'), appPublic: resolveOwn('template/public'), appHtml: resolveOwn('template/public/index.html'), - appIndexJs: resolveOwn('template/src/index.js'), + appIndexJs: resolveOwn(`template/src/index${EXT}`), appPackageJson: resolveOwn('package.json'), appSrc: resolveOwn('template/src'), - testsSetup: resolveOwn('template/src/setupTests.js'), + testsSetup: resolveOwn(`template/src/setupTests${EXT}`), appNodeModules: resolveOwn('node_modules'), + appTsConfig: resolveOwn('template/tsconfig.json'), + appTsProdConfig: resolveOwn('template/tsconfig.prod.json'), + appTsLint: resolveOwn('template/tslint.json'), + appTsTestConfig: resolveOwn('template/tsconfig.test.json'), publicUrl: getPublicUrl(resolveOwn('package.json')), servedPath: getServedPath(resolveOwn('package.json')), // These properties only exist before ejecting: diff --git a/packages/react-scripts/config/webpack.config.dev.js b/packages/react-scripts/config/webpack.config.dev.js index 7a1b66803bc..3748ab700f1 100644 --- a/packages/react-scripts/config/webpack.config.dev.js +++ b/packages/react-scripts/config/webpack.config.dev.js @@ -8,6 +8,7 @@ // @remove-on-eject-end 'use strict'; +const LANG = process.env.DEV_LANG; const autoprefixer = require('autoprefixer'); const path = require('path'); const webpack = require('webpack'); @@ -20,7 +21,8 @@ const ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin'); const getCSSModuleLocalIdent = require('react-dev-utils/getCSSModuleLocalIdent'); const getClientEnvironment = require('./env'); const paths = require('./paths'); - +const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin'); +const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin'); // Webpack uses `publicPath` to determine where the app is being served from. // In development, we always serve from the root. This makes config easier. const publicPath = '/'; @@ -41,9 +43,9 @@ const postCSSLoaderOptions = { plugins: () => [ require('postcss-flexbugs-fixes'), autoprefixer({ - flexbox: 'no-2009', - }), - ], + flexbox: 'no-2009' + }) + ] }; // style files regexes @@ -58,12 +60,12 @@ const getStyleLoaders = (cssOptions, preProcessor) => { require.resolve('style-loader'), { loader: require.resolve('css-loader'), - options: cssOptions, + options: cssOptions }, { loader: require.resolve('postcss-loader'), - options: postCSSLoaderOptions, - }, + options: postCSSLoaderOptions + } ]; if (preProcessor) { loaders.push(require.resolve(preProcessor)); @@ -96,7 +98,7 @@ module.exports = { // require.resolve('webpack/hot/dev-server'), require.resolve('react-dev-utils/webpackHotDevClient'), // Finally, this is your app's code: - paths.appIndexJs, + paths.appIndexJs // We include the app code last so that if there is a runtime error during // initialization, it doesn't blow up the WebpackDevServer client, and // changing JS code would still trigger a refresh. @@ -114,7 +116,7 @@ module.exports = { publicPath: publicPath, // Point sourcemap entries to original disk location (format as URL on Windows) devtoolModuleFilenameTemplate: info => - path.resolve(info.absoluteResourcePath).replace(/\\/g, '/'), + path.resolve(info.absoluteResourcePath).replace(/\\/g, '/') }, resolve: { // This allows you to set a fallback for where Webpack should look for modules. @@ -131,7 +133,21 @@ module.exports = { // https://github.com/facebook/create-react-app/issues/290 // `web` extension prefixes have been added for better support // for React Native Web. - extensions: ['.web.js', '.mjs', '.js', '.json', '.web.jsx', '.jsx'], + extensions: + LANG === 'typescript' + ? [ + '.mjs', + '.web.ts', + '.ts', + '.web.tsx', + '.tsx', + '.web.js', + '.js', + '.json', + '.web.jsx', + '.jsx' + ] + : ['.web.js', '.mjs', '.js', '.json', '.web.jsx', '.jsx'], alias: { // @remove-on-eject-begin // Resolve Babel runtime relative to react-scripts. @@ -144,7 +160,7 @@ module.exports = { // @remove-on-eject-end // Support React Native Web // https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/ - 'react-native': 'react-native-web', + 'react-native': 'react-native-web' }, plugins: [ // Prevents users from importing files from outside of src/ (or node_modules/). @@ -152,8 +168,12 @@ module.exports = { // To fix this, we prevent you from importing files out of src/ -- if you'd like to, // please link the files into your node_modules/ and let module-resolution kick in. // Make sure your source files are compiled, as they will not be processed in any way. - new ModuleScopePlugin(paths.appSrc, [paths.appPackageJson]), - ], + new ModuleScopePlugin(paths.appSrc, [paths.appPackageJson]) + ].concat( + LANG === 'typescript' + ? [new TsconfigPathsPlugin({ configFile: paths.appTsConfig })] + : [] + ) }, module: { strictExportPresence: true, @@ -167,23 +187,27 @@ module.exports = { test: /\.(js|jsx|mjs)$/, enforce: 'pre', use: [ - { - options: { - formatter: eslintFormatter, - eslintPath: require.resolve('eslint'), - baseConfig: { - extends: [require.resolve('eslint-config-react-app')], - }, - // @remove-on-eject-begin - ignore: false, - useEslintrc: false, - // @remove-on-eject-end - }, - loader: require.resolve('eslint-loader'), - }, + LANG === 'javascript' + ? { + options: { + formatter: eslintFormatter, + eslintPath: require.resolve('eslint'), + baseConfig: { + extends: [require.resolve('eslint-config-react-app')] + }, + // @remove-on-eject-begin + ignore: false, + useEslintrc: false + // @remove-on-eject-end + }, + loader: require.resolve('eslint-loader') + } + : { + loader: require.resolve('source-map-loader') + } ], include: paths.srcPaths, - exclude: [/[/\\\\]node_modules[/\\\\]/], + exclude: [/[/\\\\]node_modules[/\\\\]/] }, { // "oneOf" will traverse all following loaders until one will @@ -198,8 +222,8 @@ module.exports = { loader: require.resolve('url-loader'), options: { limit: 10000, - name: 'static/media/[name].[hash:8].[ext]', - }, + name: 'static/media/[name].[hash:8].[ext]' + } }, // Process application JS with Babel. // The preset includes JSX, Flow, and some ESnext features. @@ -218,26 +242,44 @@ module.exports = { babelrc: false, // @remove-on-eject-end presets: [require.resolve('babel-preset-react-app')], - plugins: [ - [ - require.resolve('babel-plugin-named-asset-import'), - { - loaderMap: { - svg: { - ReactComponent: 'svgr/webpack![path]', - }, - }, - }, - ], - ], // This is a feature of `babel-loader` for webpack (not Babel itself). // It enables caching results in ./node_modules/.cache/babel-loader/ // directory for faster rebuilds. cacheDirectory: true, - highlightCode: true, - }, + highlightCode: true + } + } + ] + }, + { + test: /\.(ts|tsx)$/, + include: paths.srcPaths, + exclude: [/[/\\\\]node_modules[/\\\\]/], + use: [ + // This loader parallelizes code compilation, it is optional but + // improves compile time on larger projects + // require.resolve('thread-loader'), + { + loader: require.resolve('babel-loader'), + options: { + // @remove-on-eject-begin + babelrc: false, + // @remove-on-eject-end + presets: [require.resolve('babel-preset-react-app')], + // This is a feature of `babel-loader` for webpack (not Babel itself). + // It enables caching results in ./node_modules/.cache/babel-loader/ + // directory for faster rebuilds. + cacheDirectory: true, + highlightCode: true + } }, - ], + { + loader: 'ts-loader', + options: { + transpileOnly: true + } + } + ] }, // Process any JS outside of the app with Babel. // Unlike the application JS, we only compile the standard ES features. @@ -253,13 +295,13 @@ module.exports = { babelrc: false, compact: false, presets: [ - require.resolve('babel-preset-react-app/dependencies'), + require.resolve('babel-preset-react-app/dependencies') ], cacheDirectory: true, - highlightCode: true, - }, - }, - ], + highlightCode: true + } + } + ] }, // "postcss" loader applies autoprefixer to our CSS. // "css" loader resolves paths in CSS and adds assets as dependencies. @@ -271,8 +313,8 @@ module.exports = { test: cssRegex, exclude: cssModuleRegex, use: getStyleLoaders({ - importLoaders: 1, - }), + importLoaders: 1 + }) }, // Adds support for CSS Modules (https://github.com/css-modules/css-modules) // using the extension .module.css @@ -281,8 +323,8 @@ module.exports = { use: getStyleLoaders({ importLoaders: 1, modules: true, - getLocalIdent: getCSSModuleLocalIdent, - }), + getLocalIdent: getCSSModuleLocalIdent + }) }, // Opt-in support for SASS (using .scss or .sass extensions). // Chains the sass-loader with the css-loader and the style-loader @@ -292,7 +334,7 @@ module.exports = { { test: sassRegex, exclude: sassModuleRegex, - use: getStyleLoaders({ importLoaders: 2 }, 'sass-loader'), + use: getStyleLoaders({ importLoaders: 2 }, 'sass-loader') }, // Adds support for CSS Modules, but using SASS // using the extension .module.scss or .module.sass @@ -302,15 +344,33 @@ module.exports = { { importLoaders: 2, modules: true, - getLocalIdent: getCSSModuleLocalIdent, + getLocalIdent: getCSSModuleLocalIdent }, 'sass-loader' - ), + ) + }, + { + test: /\.less$/, + exclude: sassModuleRegex, + use: getStyleLoaders({ importLoaders: 2 }, 'less-loader') + }, + // Adds support for CSS Modules, but using SASS + // using the extension .module.scss or .module.sass + { + test: /\.module\.less$/, + use: getStyleLoaders( + { + importLoaders: 2, + modules: true, + getLocalIdent: getCSSModuleLocalIdent + }, + 'less-loader' + ) }, // The GraphQL loader preprocesses GraphQL queries in .graphql files. { test: /\.(graphql)$/, - loader: 'graphql-tag/loader', + loader: 'graphql-tag/loader' }, // "file" loader makes sure those assets get served by WebpackDevServer. // When you `import` an asset, you get its (virtual) filename. @@ -325,14 +385,14 @@ module.exports = { exclude: [/\.(js|jsx|mjs)$/, /\.html$/, /\.json$/], loader: require.resolve('file-loader'), options: { - name: 'static/media/[name].[hash:8].[ext]', - }, - }, - ], - }, + name: 'static/media/[name].[hash:8].[ext]' + } + } + ] + } // ** STOP ** Are you adding a new loader? // Make sure to add the new loader(s) before the "file" loader. - ], + ] }, plugins: [ // Makes some environment variables available in index.html. @@ -343,7 +403,7 @@ module.exports = { // Generates an `index.html` file with the