From 7d66ba176a879b3ad43b220c5217b848249daa2e Mon Sep 17 00:00:00 2001 From: Matthew Holloway Date: Wed, 21 Dec 2016 13:06:56 +1300 Subject: [PATCH 01/47] Downgrading to compatible version of SockJS-Client (#1274) --- packages/react-dev-utils/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-dev-utils/package.json b/packages/react-dev-utils/package.json index b76605954..f3062c56d 100644 --- a/packages/react-dev-utils/package.json +++ b/packages/react-dev-utils/package.json @@ -28,7 +28,7 @@ "escape-string-regexp": "1.0.5", "html-entities": "1.2.0", "opn": "4.0.2", - "sockjs-client": "1.0.3", + "sockjs-client": "1.0.1", "strip-ansi": "3.0.1" } } From ac6a4c83fd38669b03e183b8e2adc8c4ed7bbd50 Mon Sep 17 00:00:00 2001 From: David Date: Fri, 23 Dec 2016 21:09:39 +0100 Subject: [PATCH 02/47] Updated react-scripts babel-jest && jest packages to 18.0.0 (#1311) --- packages/react-scripts/package.json | 4 ++-- packages/react-scripts/scripts/test.js | 12 ------------ packages/react-scripts/utils/createJestConfig.js | 2 +- 3 files changed, 3 insertions(+), 15 deletions(-) diff --git a/packages/react-scripts/package.json b/packages/react-scripts/package.json index 747c066c4..c1986cd75 100644 --- a/packages/react-scripts/package.json +++ b/packages/react-scripts/package.json @@ -26,7 +26,7 @@ "autoprefixer": "6.5.1", "babel-core": "6.17.0", "babel-eslint": "7.1.1", - "babel-jest": "17.0.2", + "babel-jest": "18.0.0", "babel-loader": "6.2.7", "babel-preset-react-app": "^2.0.1", "case-sensitive-paths-webpack-plugin": "1.1.4", @@ -50,7 +50,7 @@ "gzip-size": "3.0.0", "html-webpack-plugin": "2.24.0", "http-proxy-middleware": "0.17.2", - "jest": "17.0.2", + "jest": "18.0.0", "json-loader": "0.5.4", "object-assign": "4.1.0", "postcss-loader": "1.0.0", diff --git a/packages/react-scripts/scripts/test.js b/packages/react-scripts/scripts/test.js index 13857917e..9de5181d7 100644 --- a/packages/react-scripts/scripts/test.js +++ b/packages/react-scripts/scripts/test.js @@ -26,18 +26,6 @@ if (!process.env.CI && argv.indexOf('--coverage') < 0) { argv.push('--watch'); } -// A temporary hack to clear terminal correctly. -// You can remove this after updating to Jest 18 when it's out. -// https://github.com/facebook/jest/pull/2230 -var realWrite = process.stdout.write; -var CLEAR = process.platform === 'win32' ? '\x1Bc' : '\x1B[2J\x1B[3J\x1B[H'; -process.stdout.write = function(chunk, encoding, callback) { - if (chunk === '\x1B[2J\x1B[H') { - chunk = CLEAR; - } - return realWrite.call(this, chunk, encoding, callback); -}; - // @remove-on-eject-begin // This is not necessary after eject because we embed config into package.json. const createJestConfig = require('../utils/createJestConfig'); diff --git a/packages/react-scripts/utils/createJestConfig.js b/packages/react-scripts/utils/createJestConfig.js index b637b5b1e..f1c67c018 100644 --- a/packages/react-scripts/utils/createJestConfig.js +++ b/packages/react-scripts/utils/createJestConfig.js @@ -24,7 +24,7 @@ module.exports = (resolve, rootDir, isEjecting) => { setupFiles: [resolve('config/polyfills.js')], setupTestFrameworkScriptFile: setupTestsFile, testPathIgnorePatterns: [ - '[/\\\\](build|docs|node_modules)[/\\\\]' + '[/\\\\](build|docs|node_modules|scripts)[/\\\\]' ], testEnvironment: 'node', testURL: 'http://localhost', From e45b08746a5e745fca46977e9e41526b3db205d2 Mon Sep 17 00:00:00 2001 From: Johnny Magrippis Date: Fri, 30 Dec 2016 15:55:31 +0000 Subject: [PATCH 03/47] Fixes duplicate "is" typo (#1306) --- packages/react-scripts/template/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-scripts/template/README.md b/packages/react-scripts/template/README.md index fe4e7b31b..e53830831 100644 --- a/packages/react-scripts/template/README.md +++ b/packages/react-scripts/template/README.md @@ -205,7 +205,7 @@ We recognize that this is suboptimal, but it is currently required due to the wa You can find the source HTML file in the `public` folder of the generated project. You may edit the `` tag in it to change the title from “React App” to anything else. -Note that normally you wouldn't edit files in the `public` folder very often. For example, [adding a stylesheet](#adding-a-stylesheet) is is done without touching the HTML. +Note that normally you wouldn't edit files in the `public` folder very often. For example, [adding a stylesheet](#adding-a-stylesheet) is done without touching the HTML. If you need to dynamically update the page title based on the content, you can use the browser [`document.title`](https://developer.mozilla.org/en-US/docs/Web/API/Document/title) API. For more complex scenarios when you want to change the title from React components, you can use [React Helmet](https://github.com/nfl/react-helmet), a third party library. From a90e2b2eea49a6727013bc9b1ae071e86f88cd21 Mon Sep 17 00:00:00 2001 From: Christian Raidl <christian.raidl@outlook.com> Date: Fri, 30 Dec 2016 16:56:12 +0100 Subject: [PATCH 04/47] fix readme: remove double 'we' (#1312) --- packages/react-scripts/template/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-scripts/template/README.md b/packages/react-scripts/template/README.md index e53830831..047fdfbe0 100644 --- a/packages/react-scripts/template/README.md +++ b/packages/react-scripts/template/README.md @@ -385,7 +385,7 @@ The `<script>` tag with the compiled code will be added to it automatically duri You can also add other assets to the `public` folder. -Note that we normally we encourage you to `import` assets in JavaScript files instead. +Note that we normally encourage you to `import` assets in JavaScript files instead. For example, see the sections on [adding a stylesheet](#adding-a-stylesheet) and [adding images and fonts](#adding-images-and-fonts). This mechanism provides a number of benefits: From 4d7b7544e74db1aaca22e847b233ed1f3b95b72b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20O=E2=80=99Shannessy?= <paul@oshannessy.com> Date: Fri, 30 Dec 2016 07:59:28 -0800 Subject: [PATCH 05/47] Use npm script hooks to avoid && in deploy script (#1324) --- packages/react-scripts/scripts/build.js | 3 ++- packages/react-scripts/template/README.md | 7 ++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/packages/react-scripts/scripts/build.js b/packages/react-scripts/scripts/build.js index 4b568caae..42be50d43 100644 --- a/packages/react-scripts/scripts/build.js +++ b/packages/react-scripts/scripts/build.js @@ -181,7 +181,8 @@ function build(previousSizeMap) { console.log(' ' + chalk.dim('// ...')); console.log(' ' + chalk.yellow('"scripts"') + ': {'); console.log(' ' + chalk.dim('// ...')); - console.log(' ' + chalk.yellow('"deploy"') + ': ' + chalk.yellow('"npm run build&&gh-pages -d build"')); + console.log(' ' + chalk.yellow('"predeploy"') + ': ' + chalk.yellow('"npm run build",')); + console.log(' ' + chalk.yellow('"deploy"') + ': ' + chalk.yellow('"gh-pages -d build"')); console.log(' }'); console.log(); console.log('Then run:'); diff --git a/packages/react-scripts/template/README.md b/packages/react-scripts/template/README.md index 047fdfbe0..e55e6c9f4 100644 --- a/packages/react-scripts/template/README.md +++ b/packages/react-scripts/template/README.md @@ -1132,17 +1132,18 @@ To publish it at [https://myusername.github.io/my-app](https://myusername.github npm install --save-dev gh-pages ``` -Add the following script in your `package.json`: +Add the following scripts in your `package.json`: ```js // ... "scripts": { // ... - "deploy": "npm run build&&gh-pages -d build" + "predeploy": "npm run build", + "deploy": "gh-pages -d build" } ``` -(Note: the lack of whitespace is intentional.) +The `predeploy` script will run automatically before `deploy` is run. #### Step 3: Deploy the site by running `npm run deploy` From 25480273b0224f9260243f7ee727efdec2e7bd94 Mon Sep 17 00:00:00 2001 From: Fatih <frontsideair@users.noreply.github.com> Date: Sun, 8 Jan 2017 15:46:29 +0200 Subject: [PATCH 06/47] Bump babel-loader version (#1009) (#1309) --- packages/react-scripts/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-scripts/package.json b/packages/react-scripts/package.json index c1986cd75..d1a665d06 100644 --- a/packages/react-scripts/package.json +++ b/packages/react-scripts/package.json @@ -27,7 +27,7 @@ "babel-core": "6.17.0", "babel-eslint": "7.1.1", "babel-jest": "18.0.0", - "babel-loader": "6.2.7", + "babel-loader": "6.2.10", "babel-preset-react-app": "^2.0.1", "case-sensitive-paths-webpack-plugin": "1.1.4", "chalk": "1.1.3", From 1b645e2cc4de1f3b140a7306347fd742ba2cb155 Mon Sep 17 00:00:00 2001 From: Ville Immonen <ville.immonen@iki.fi> Date: Mon, 9 Jan 2017 17:25:31 +0200 Subject: [PATCH 07/47] Use yarnpkg alias to run Yarn (#1365) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There’s a common tool included in Hadoop that also has a `yarn` command, which created issues for users who had Hadoop installed: * #1257 * #1363 Yarn also installs the command under `yarnpkg` alias (added in https://github.com/yarnpkg/yarn/commit/cefa9a368dd3df1a1f1ecd9e50de9c5fabefbc92) so we can use `yarnpkg` instead of `yarn` to make it more reliable. This has no effect on users who don't have Hadoop installed, but those who have won't see errors from falsely detecting Hadoop Yarn as Yarn the package manager, and they can now also install Yarn to make use of our Yarn support without the Hadoop Yarn interfering. --- packages/create-react-app/index.js | 4 ++-- packages/react-scripts/scripts/eject.js | 2 +- packages/react-scripts/scripts/init.js | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/create-react-app/index.js b/packages/create-react-app/index.js index ab356d4d7..9ab11a5e9 100644 --- a/packages/create-react-app/index.js +++ b/packages/create-react-app/index.js @@ -135,7 +135,7 @@ function createApp(name, verbose, version) { function shouldUseYarn() { try { - execSync('yarn --version', {stdio: 'ignore'}); + execSync('yarnpkg --version', {stdio: 'ignore'}); return true; } catch (e) { return false; @@ -146,7 +146,7 @@ function install(packageToInstall, verbose, callback) { var command; var args; if (shouldUseYarn()) { - command = 'yarn'; + command = 'yarnpkg'; args = [ 'add', '--dev', '--exact', packageToInstall]; } else { command = 'npm'; diff --git a/packages/react-scripts/scripts/eject.js b/packages/react-scripts/scripts/eject.js index aeed2967d..86dbc15c3 100644 --- a/packages/react-scripts/scripts/eject.js +++ b/packages/react-scripts/scripts/eject.js @@ -146,7 +146,7 @@ prompt( if (fs.existsSync(paths.yarnLockFile)) { console.log(cyan('Running yarn...')); fs.removeSync(ownPath); - spawnSync('yarn', [], {stdio: 'inherit'}); + spawnSync('yarnpkg', [], {stdio: 'inherit'}); } else { console.log(cyan('Running npm install...')); fs.removeSync(ownPath); diff --git a/packages/react-scripts/scripts/init.js b/packages/react-scripts/scripts/init.js index 63daf3452..e438e5a2e 100644 --- a/packages/react-scripts/scripts/init.js +++ b/packages/react-scripts/scripts/init.js @@ -64,7 +64,7 @@ module.exports = function(appPath, appName, verbose, originalDirectory) { var args; if (useYarn) { - command = 'yarn'; + command = 'yarnpkg'; args = ['add']; } else { command = 'npm'; From 24abc5e1542dce86f5f588b81723f262ed757ad6 Mon Sep 17 00:00:00 2001 From: Ville Immonen <ville.immonen@iki.fi> Date: Mon, 9 Jan 2017 17:25:31 +0200 Subject: [PATCH 08/47] Use yarnpkg alias to run Yarn (#1365) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There’s a common tool included in Hadoop that also has a `yarn` command, which created issues for users who had Hadoop installed: * #1257 * #1363 Yarn also installs the command under `yarnpkg` alias (added in https://github.com/yarnpkg/yarn/commit/cefa9a368dd3df1a1f1ecd9e50de9c5fabefbc92) so we can use `yarnpkg` instead of `yarn` to make it more reliable. This has no effect on users who don't have Hadoop installed, but those who have won't see errors from falsely detecting Hadoop Yarn as Yarn the package manager, and they can now also install Yarn to make use of our Yarn support without the Hadoop Yarn interfering. --- packages/create-react-app/index.js | 4 ++-- packages/react-scripts/scripts/eject.js | 2 +- packages/react-scripts/scripts/init.js | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/create-react-app/index.js b/packages/create-react-app/index.js index 7c9394ea3..399bfdd21 100644 --- a/packages/create-react-app/index.js +++ b/packages/create-react-app/index.js @@ -138,7 +138,7 @@ function createApp(name, verbose, version) { function shouldUseYarn() { try { - execSync('yarn --version', {stdio: 'ignore'}); + execSync('yarnpkg --version', {stdio: 'ignore'}); return true; } catch (e) { return false; @@ -149,7 +149,7 @@ function install(packageToInstall, verbose, callback) { var command; var args; if (shouldUseYarn()) { - command = 'yarn'; + command = 'yarnpkg'; args = [ 'add', '--dev', '--exact', packageToInstall]; } else { command = 'npm'; diff --git a/packages/react-scripts/scripts/eject.js b/packages/react-scripts/scripts/eject.js index 2ae89a453..d97f814ec 100644 --- a/packages/react-scripts/scripts/eject.js +++ b/packages/react-scripts/scripts/eject.js @@ -147,7 +147,7 @@ prompt( if (pathExists.sync(paths.yarnLockFile)) { console.log(cyan('Running yarn...')); fs.removeSync(ownPath); - spawnSync('yarn', [], {stdio: 'inherit'}); + spawnSync('yarnpkg', [], {stdio: 'inherit'}); } else { console.log(cyan('Running npm install...')); fs.removeSync(ownPath); diff --git a/packages/react-scripts/scripts/init.js b/packages/react-scripts/scripts/init.js index c9a4ea14a..4d0d91e9f 100644 --- a/packages/react-scripts/scripts/init.js +++ b/packages/react-scripts/scripts/init.js @@ -65,7 +65,7 @@ module.exports = function(appPath, appName, verbose, originalDirectory) { var args; if (useYarn) { - command = 'yarn'; + command = 'yarnpkg'; args = ['add']; } else { command = 'npm'; From ad86746ada20080f6ad51e7b59e8e107d1833206 Mon Sep 17 00:00:00 2001 From: Ville Immonen <ville.immonen@iki.fi> Date: Mon, 9 Jan 2017 17:45:30 +0200 Subject: [PATCH 09/47] Update changelog for 0.8.5 --- CHANGELOG.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e26f4ae5d..613c48c14 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,28 @@ +## 0.8.5 (January 9, 2017) + +#### :bug: Bug Fix +* `create-react-app`, `react-scripts` + * [#1365](https://github.com/facebookincubator/create-react-app/pull/1365) Use yarnpkg alias to run Yarn. ([@fson](https://github.com/fson)) + + Fixes an issue where running `create-react-app` failed on systems with Apache Hadoop installed because it falsely detected Hadoop YARN executable as Yarn package manager. + +#### Committers: 1 +- Ville Immonen ([fson](https://github.com/fson)) + +### Migrating from 0.8.4 to 0.8.5 + +Inside any created project that has not been ejected, run: + +``` +npm install --save-dev --save-exact react-scripts@0.8.5 +``` + +You may also optionally update the global command-line utility: + +``` +npm install -g create-react-app@1.0.3 +``` + ## 0.8.4 (December 11, 2016) #### :bug: Bug Fix From a5b838940eeed1d214b89601268ccf6323e3f968 Mon Sep 17 00:00:00 2001 From: Ville Immonen <ville.immonen@iki.fi> Date: Mon, 9 Jan 2017 17:51:41 +0200 Subject: [PATCH 10/47] Publish - create-react-app@1.0.3 - react-scripts@0.8.5 --- packages/create-react-app/package.json | 2 +- packages/react-scripts/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/create-react-app/package.json b/packages/create-react-app/package.json index 1c466c7f8..ed12d3879 100644 --- a/packages/create-react-app/package.json +++ b/packages/create-react-app/package.json @@ -1,6 +1,6 @@ { "name": "create-react-app", - "version": "1.0.2", + "version": "1.0.3", "keywords": [ "react" ], diff --git a/packages/react-scripts/package.json b/packages/react-scripts/package.json index ac6dc41f3..6f319190a 100644 --- a/packages/react-scripts/package.json +++ b/packages/react-scripts/package.json @@ -1,6 +1,6 @@ { "name": "react-scripts", - "version": "0.8.4", + "version": "0.8.5", "description": "Configuration and scripts for Create React App.", "repository": "facebookincubator/create-react-app", "license": "BSD-3-Clause", From d29fb006c0bcb9524fb3e3e2b67fee2f7c350b52 Mon Sep 17 00:00:00 2001 From: Pedro Nauck <pedronauck@gmail.com> Date: Wed, 11 Jan 2017 13:53:54 -0200 Subject: [PATCH 11/47] Add missing import in react-dev-utils README.md (#1369) --- packages/react-dev-utils/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/react-dev-utils/README.md b/packages/react-dev-utils/README.md index 3c6a10f62..a9adffb66 100644 --- a/packages/react-dev-utils/README.md +++ b/packages/react-dev-utils/README.md @@ -117,6 +117,7 @@ Extracts and prettifies warning and error messages from webpack [stats](https:// ```js var webpack = require('webpack'); var config = require('../config/webpack.config.dev'); +var formatWebpackMessages = require('react-dev-utils/formatWebpackMessages'); var compiler = webpack(config); @@ -184,6 +185,7 @@ You can control the behavior on `<Enter>` with `isYesDefault`. ```js var prompt = require('react-dev-utils/prompt'); + prompt( 'Are you sure you want to eat all the candy?', /* isYesDefault */ false From 3f6937c9569c68217077d61a81e71f2134b62a28 Mon Sep 17 00:00:00 2001 From: Jimmy Miller <jimmyhmiller@gmail.com> Date: Wed, 11 Jan 2017 15:15:58 -0500 Subject: [PATCH 12/47] Change console.log for errors and warnings (#1375) Array.forEach is passed the following parameters: currentValue The current element being processed in the array. index The index of the current element being processed in the array. array - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach console.log takes multiple arguments. We only want to print the first one, the actually message. --- packages/react-dev-utils/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/react-dev-utils/README.md b/packages/react-dev-utils/README.md index a9adffb66..455996fcc 100644 --- a/packages/react-dev-utils/README.md +++ b/packages/react-dev-utils/README.md @@ -133,12 +133,12 @@ compiler.plugin('done', function(stats) { } if (messages.errors.length) { console.log('Failed to compile.'); - messages.errors.forEach(console.log); + messages.errors.forEach(e => console.log(e)); return; } if (messages.warnings.length) { console.log('Compiled with warnings.'); - messages.warnings.forEach(console.log); + messages.warnings.forEach(w => console.log(w)); } }); ``` From 17bb8d420f39386459dd1bbcd3459a5623db5081 Mon Sep 17 00:00:00 2001 From: Robbie H <jayrotek@gmail.com> Date: Thu, 12 Jan 2017 11:27:59 -0700 Subject: [PATCH 13/47] webpack-dev-server patch for 'still-ok' success status (#1377) --- packages/react-dev-utils/webpackHotDevClient.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/react-dev-utils/webpackHotDevClient.js b/packages/react-dev-utils/webpackHotDevClient.js index f15fd06f2..7b1768d8f 100644 --- a/packages/react-dev-utils/webpackHotDevClient.js +++ b/packages/react-dev-utils/webpackHotDevClient.js @@ -248,6 +248,7 @@ connection.onmessage = function(e) { case 'hash': handleAvailableHash(message.data); break; + case 'still-ok': case 'ok': handleSuccess(); break; From 7cd03f9f1a2ce68b55963500dcfda698df848972 Mon Sep 17 00:00:00 2001 From: Daniel Schep <dschep@gmail.com> Date: Thu, 12 Jan 2017 18:30:35 +0000 Subject: [PATCH 14/47] Document Flow support (#1384) * Document Flow support Projects created by Create React App use the `babel-preset-react` which includes Flow babel plugins which introduces new syntax. This is important for users to know as it causes what used to be syntax errors to be silently suppressed because they're valid type annotations in Flow. For example if a user accidentally has `[foo: 'bar']`, Babel will silently convert it to `[foo]`. * Make it a bit clearer --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e9f8c1b60..2c387f6cf 100644 --- a/README.md +++ b/README.md @@ -144,7 +144,7 @@ Please refer to the [User Guide](https://github.com/facebookincubator/create-rea **If you’re getting started** with React, use `create-react-app` to automate the build of your app. There is no configuration file, and `react-scripts` is the only extra build dependency in your `package.json`. Your environment will have everything you need to build a modern React app: -* React, JSX, and ES6 support. +* React, JSX, ES6, and Flow syntax support. * Language extras beyond ES6 like the object spread operator. * A dev server that lints for common errors. * Import CSS and image files directly from JavaScript. From 9099570b94712dc46da322219d659c045e5b7de4 Mon Sep 17 00:00:00 2001 From: Fabrizio Castellarin <f.castellarin@gmail.com> Date: Mon, 23 Jan 2017 20:43:16 +0100 Subject: [PATCH 15/47] Use a more sophisticated template for end-to-end testing. (#1187) * Use a more sophisticated template for end-to-end testing. * Not publish integration tests to npm * Use "commander" for cli argv handling * Handle different scripts version forms and exits without a name given * Prepare the commands for testing with a template * Fix dev "template" path * Add various features to test * Test various features separately * Test language features * Comment unused e2e.sh lines * Add "development" tests * Test environment variables * Test webpack plugins * Replace kitchensink README * Switch integration tests from jest to mocha * Use `fs-extra` * Use the correct folders * Do some cleanup * Print a better message for `--template` * Test `npm start` with and without https * Separate fast e2e testing from kitchensink testing * Hide `--internal-testing-template` (former `--template`) CLI option --- .travis.yml | 20 +- package.json | 2 +- packages/create-react-app/index.js | 21 +- packages/react-scripts/.npmignore | 1 + .../fixtures/kitchensink/.babelrc | 3 + .../react-scripts/fixtures/kitchensink/.env | 1 + .../fixtures/kitchensink/.flowconfig | 8 + .../kitchensink/.template.dependencies.json | 10 + .../fixtures/kitchensink/gitignore | 15 ++ .../kitchensink/integration/env.test.js | 24 ++ .../kitchensink/integration/initDOM.js | 62 +++++ .../kitchensink/integration/syntax.test.js | 96 ++++++++ .../kitchensink/integration/webpack.test.js | 44 ++++ .../fixtures/kitchensink/public/favicon.ico | Bin 0 -> 24838 bytes .../fixtures/kitchensink/public/index.html | 12 + .../fixtures/kitchensink/src/App.js | 103 +++++++++ .../fixtures/kitchensink/src/App.test.js | 8 + .../fixtures/kitchensink/src/absoluteLoad.js | 6 + .../src/features/env/FileEnvVariables.js | 5 + .../src/features/env/FileEnvVariables.test.js | 10 + .../kitchensink/src/features/env/NodePath.js | 25 ++ .../src/features/env/NodePath.test.js | 10 + .../src/features/env/ShellEnvVariables.js | 5 + .../features/env/ShellEnvVariables.test.js | 10 + .../src/features/syntax/ArrayDestructuring.js | 34 +++ .../syntax/ArrayDestructuring.test.js | 10 + .../src/features/syntax/ArraySpread.js | 33 +++ .../src/features/syntax/ArraySpread.test.js | 10 + .../src/features/syntax/AsyncAwait.js | 33 +++ .../src/features/syntax/AsyncAwait.test.js | 10 + .../src/features/syntax/ClassProperties.js | 20 ++ .../features/syntax/ClassProperties.test.js | 10 + .../src/features/syntax/ComputedProperties.js | 33 +++ .../syntax/ComputedProperties.test.js | 10 + .../features/syntax/CustomInterpolation.js | 43 ++++ .../syntax/CustomInterpolation.test.js | 10 + .../src/features/syntax/DefaultParameters.js | 33 +++ .../features/syntax/DefaultParameters.test.js | 10 + .../features/syntax/DestructuringAndAwait.js | 33 +++ .../syntax/DestructuringAndAwait.test.js | 10 + .../src/features/syntax/Generators.js | 35 +++ .../src/features/syntax/Generators.test.js | 10 + .../features/syntax/ObjectDestructuring.js | 34 +++ .../syntax/ObjectDestructuring.test.js | 10 + .../src/features/syntax/ObjectSpread.js | 33 +++ .../src/features/syntax/ObjectSpread.test.js | 10 + .../src/features/syntax/Promises.js | 34 +++ .../src/features/syntax/Promises.test.js | 10 + .../src/features/syntax/RestAndDefault.js | 33 +++ .../features/syntax/RestAndDefault.test.js | 10 + .../src/features/syntax/RestParameters.js | 33 +++ .../features/syntax/RestParameters.test.js | 10 + .../features/syntax/TemplateInterpolation.js | 33 +++ .../syntax/TemplateInterpolation.test.js | 10 + .../src/features/webpack/CssInclusion.js | 6 + .../src/features/webpack/CssInclusion.test.js | 10 + .../src/features/webpack/ImageInclusion.js | 6 + .../features/webpack/ImageInclusion.test.js | 10 + .../src/features/webpack/JsonInclusion.js | 6 + .../features/webpack/JsonInclusion.test.js | 10 + .../src/features/webpack/NoExtInclusion.js | 10 + .../features/webpack/NoExtInclusion.test.js | 10 + .../src/features/webpack/SvgInclusion.js | 6 + .../src/features/webpack/SvgInclusion.test.js | 10 + .../features/webpack/UnknownExtInclusion.js | 10 + .../webpack/UnknownExtInclusion.test.js | 10 + .../webpack/assets/aFileWithExt.unknown | 1 + .../features/webpack/assets/aFileWithoutExt | 1 + .../src/features/webpack/assets/abstract.json | 3 + .../src/features/webpack/assets/logo.svg | 7 + .../src/features/webpack/assets/style.css | 4 + .../features/webpack/assets/tiniest-cat.jpg | Bin 0 -> 691 bytes .../fixtures/kitchensink/src/index.js | 8 + .../fixtures/kitchensink/src/subfolder/lol.js | 1 + packages/react-scripts/scripts/init.js | 20 +- tasks/e2e-installs.sh | 152 ++++++++++++ tasks/e2e-kitchensink.sh | 218 ++++++++++++++++++ tasks/{e2e.sh => e2e-simple.sh} | 60 ----- 78 files changed, 1653 insertions(+), 74 deletions(-) create mode 100644 packages/react-scripts/.npmignore create mode 100644 packages/react-scripts/fixtures/kitchensink/.babelrc create mode 100644 packages/react-scripts/fixtures/kitchensink/.env create mode 100644 packages/react-scripts/fixtures/kitchensink/.flowconfig create mode 100644 packages/react-scripts/fixtures/kitchensink/.template.dependencies.json create mode 100644 packages/react-scripts/fixtures/kitchensink/gitignore create mode 100644 packages/react-scripts/fixtures/kitchensink/integration/env.test.js create mode 100644 packages/react-scripts/fixtures/kitchensink/integration/initDOM.js create mode 100644 packages/react-scripts/fixtures/kitchensink/integration/syntax.test.js create mode 100644 packages/react-scripts/fixtures/kitchensink/integration/webpack.test.js create mode 100644 packages/react-scripts/fixtures/kitchensink/public/favicon.ico create mode 100644 packages/react-scripts/fixtures/kitchensink/public/index.html create mode 100644 packages/react-scripts/fixtures/kitchensink/src/App.js create mode 100644 packages/react-scripts/fixtures/kitchensink/src/App.test.js create mode 100644 packages/react-scripts/fixtures/kitchensink/src/absoluteLoad.js create mode 100644 packages/react-scripts/fixtures/kitchensink/src/features/env/FileEnvVariables.js create mode 100644 packages/react-scripts/fixtures/kitchensink/src/features/env/FileEnvVariables.test.js create mode 100644 packages/react-scripts/fixtures/kitchensink/src/features/env/NodePath.js create mode 100644 packages/react-scripts/fixtures/kitchensink/src/features/env/NodePath.test.js create mode 100644 packages/react-scripts/fixtures/kitchensink/src/features/env/ShellEnvVariables.js create mode 100644 packages/react-scripts/fixtures/kitchensink/src/features/env/ShellEnvVariables.test.js create mode 100644 packages/react-scripts/fixtures/kitchensink/src/features/syntax/ArrayDestructuring.js create mode 100644 packages/react-scripts/fixtures/kitchensink/src/features/syntax/ArrayDestructuring.test.js create mode 100644 packages/react-scripts/fixtures/kitchensink/src/features/syntax/ArraySpread.js create mode 100644 packages/react-scripts/fixtures/kitchensink/src/features/syntax/ArraySpread.test.js create mode 100644 packages/react-scripts/fixtures/kitchensink/src/features/syntax/AsyncAwait.js create mode 100644 packages/react-scripts/fixtures/kitchensink/src/features/syntax/AsyncAwait.test.js create mode 100644 packages/react-scripts/fixtures/kitchensink/src/features/syntax/ClassProperties.js create mode 100644 packages/react-scripts/fixtures/kitchensink/src/features/syntax/ClassProperties.test.js create mode 100644 packages/react-scripts/fixtures/kitchensink/src/features/syntax/ComputedProperties.js create mode 100644 packages/react-scripts/fixtures/kitchensink/src/features/syntax/ComputedProperties.test.js create mode 100644 packages/react-scripts/fixtures/kitchensink/src/features/syntax/CustomInterpolation.js create mode 100644 packages/react-scripts/fixtures/kitchensink/src/features/syntax/CustomInterpolation.test.js create mode 100644 packages/react-scripts/fixtures/kitchensink/src/features/syntax/DefaultParameters.js create mode 100644 packages/react-scripts/fixtures/kitchensink/src/features/syntax/DefaultParameters.test.js create mode 100644 packages/react-scripts/fixtures/kitchensink/src/features/syntax/DestructuringAndAwait.js create mode 100644 packages/react-scripts/fixtures/kitchensink/src/features/syntax/DestructuringAndAwait.test.js create mode 100644 packages/react-scripts/fixtures/kitchensink/src/features/syntax/Generators.js create mode 100644 packages/react-scripts/fixtures/kitchensink/src/features/syntax/Generators.test.js create mode 100644 packages/react-scripts/fixtures/kitchensink/src/features/syntax/ObjectDestructuring.js create mode 100644 packages/react-scripts/fixtures/kitchensink/src/features/syntax/ObjectDestructuring.test.js create mode 100644 packages/react-scripts/fixtures/kitchensink/src/features/syntax/ObjectSpread.js create mode 100644 packages/react-scripts/fixtures/kitchensink/src/features/syntax/ObjectSpread.test.js create mode 100644 packages/react-scripts/fixtures/kitchensink/src/features/syntax/Promises.js create mode 100644 packages/react-scripts/fixtures/kitchensink/src/features/syntax/Promises.test.js create mode 100644 packages/react-scripts/fixtures/kitchensink/src/features/syntax/RestAndDefault.js create mode 100644 packages/react-scripts/fixtures/kitchensink/src/features/syntax/RestAndDefault.test.js create mode 100644 packages/react-scripts/fixtures/kitchensink/src/features/syntax/RestParameters.js create mode 100644 packages/react-scripts/fixtures/kitchensink/src/features/syntax/RestParameters.test.js create mode 100644 packages/react-scripts/fixtures/kitchensink/src/features/syntax/TemplateInterpolation.js create mode 100644 packages/react-scripts/fixtures/kitchensink/src/features/syntax/TemplateInterpolation.test.js create mode 100644 packages/react-scripts/fixtures/kitchensink/src/features/webpack/CssInclusion.js create mode 100644 packages/react-scripts/fixtures/kitchensink/src/features/webpack/CssInclusion.test.js create mode 100644 packages/react-scripts/fixtures/kitchensink/src/features/webpack/ImageInclusion.js create mode 100644 packages/react-scripts/fixtures/kitchensink/src/features/webpack/ImageInclusion.test.js create mode 100644 packages/react-scripts/fixtures/kitchensink/src/features/webpack/JsonInclusion.js create mode 100644 packages/react-scripts/fixtures/kitchensink/src/features/webpack/JsonInclusion.test.js create mode 100644 packages/react-scripts/fixtures/kitchensink/src/features/webpack/NoExtInclusion.js create mode 100644 packages/react-scripts/fixtures/kitchensink/src/features/webpack/NoExtInclusion.test.js create mode 100644 packages/react-scripts/fixtures/kitchensink/src/features/webpack/SvgInclusion.js create mode 100644 packages/react-scripts/fixtures/kitchensink/src/features/webpack/SvgInclusion.test.js create mode 100644 packages/react-scripts/fixtures/kitchensink/src/features/webpack/UnknownExtInclusion.js create mode 100644 packages/react-scripts/fixtures/kitchensink/src/features/webpack/UnknownExtInclusion.test.js create mode 100644 packages/react-scripts/fixtures/kitchensink/src/features/webpack/assets/aFileWithExt.unknown create mode 100644 packages/react-scripts/fixtures/kitchensink/src/features/webpack/assets/aFileWithoutExt create mode 100644 packages/react-scripts/fixtures/kitchensink/src/features/webpack/assets/abstract.json create mode 100644 packages/react-scripts/fixtures/kitchensink/src/features/webpack/assets/logo.svg create mode 100644 packages/react-scripts/fixtures/kitchensink/src/features/webpack/assets/style.css create mode 100644 packages/react-scripts/fixtures/kitchensink/src/features/webpack/assets/tiniest-cat.jpg create mode 100644 packages/react-scripts/fixtures/kitchensink/src/index.js create mode 100644 packages/react-scripts/fixtures/kitchensink/src/subfolder/lol.js create mode 100755 tasks/e2e-installs.sh create mode 100755 tasks/e2e-kitchensink.sh rename tasks/{e2e.sh => e2e-simple.sh} (73%) diff --git a/.travis.yml b/.travis.yml index bb9c81120..8f3582466 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,6 @@ --- language: node_js node_js: - - 0.10 - 4 - 6 cache: @@ -9,7 +8,20 @@ cache: - node_modules - packages/create-react-app/node_modules - packages/react-scripts/node_modules -script: tasks/e2e.sh +script: + - 'if [ $TEST_SUITE = "simple" ]; then tasks/e2e-simple.sh; fi' + - 'if [ $TEST_SUITE = "installs" ]; then tasks/e2e-installs.sh; fi' + - 'if [ $TEST_SUITE = "kitchensink" ]; then tasks/e2e-kitchensink.sh; fi' env: - - USE_YARN=no - - USE_YARN=yes + global: + - USE_YARN=no + matrix: + - TEST_SUITE=simple + - TEST_SUITE=installs + - TEST_SUITE=kitchensink +matrix: + include: + - node_js: 0.10 + env: TEST_SUITE=simple + - node_js: 6 + env: USE_YARN=yes TEST_SUITE=simple diff --git a/package.json b/package.json index 6645ea279..6705e0413 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "build": "node packages/react-scripts/scripts/build.js", "changelog": "lerna-changelog", "create-react-app": "tasks/cra.sh", - "e2e": "tasks/e2e.sh", + "e2e": "tasks/e2e-simple.sh", "postinstall": "lerna bootstrap", "publish": "tasks/release.sh", "start": "node packages/react-scripts/scripts/start.js", diff --git a/packages/create-react-app/index.js b/packages/create-react-app/index.js index 9ab11a5e9..4dbb37f49 100644 --- a/packages/create-react-app/index.js +++ b/packages/create-react-app/index.js @@ -52,6 +52,7 @@ if (currentNodeVersion.split('.')[0] < 4) { process.exit(1); } +var commander = require('commander'); var fs = require('fs-extra'); var path = require('path'); var execSync = require('child_process').execSync; @@ -60,7 +61,7 @@ var semver = require('semver'); var projectName; -var program = require('commander') +var program = commander .version(require('./package.json').version) .arguments('<project-directory>') .usage(chalk.green('<project-directory>') + ' [options]') @@ -69,6 +70,7 @@ var program = require('commander') }) .option('--verbose', 'print additional logs') .option('--scripts-version <alternative-package>', 'use a non-standard version of react-scripts') + .allowUnknownOption() .on('--help', function () { console.log(' Only ' + chalk.green('<project-directory>') + ' is required.'); console.log(); @@ -82,7 +84,7 @@ var program = require('commander') console.log(' ' + chalk.cyan('https://github.com/facebookincubator/create-react-app/issues/new')); console.log(); }) - .parse(process.argv) + .parse(process.argv); if (typeof projectName === 'undefined') { console.error('Please specify the project directory:'); @@ -95,9 +97,14 @@ if (typeof projectName === 'undefined') { process.exit(1); } -createApp(projectName, program.verbose, program.scriptsVersion); +var hiddenProgram = new commander.Command() + .option('--internal-testing-template <path-to-template>', '(internal usage only, DO NOT RELY ON THIS) ' + + 'use a non-standard application template') + .parse(process.argv) + +createApp(projectName, program.verbose, program.scriptsVersion, hiddenProgram.internalTestingTemplate); -function createApp(name, verbose, version) { +function createApp(name, verbose, version, template) { var root = path.resolve(name); var appName = path.basename(root); @@ -130,7 +137,7 @@ function createApp(name, verbose, version) { console.log('Installing ' + chalk.cyan('react-scripts') + '...'); console.log(); - run(root, appName, version, verbose, originalDirectory); + run(root, appName, version, verbose, originalDirectory, template); } function shouldUseYarn() { @@ -163,7 +170,7 @@ function install(packageToInstall, verbose, callback) { }); } -function run(root, appName, version, verbose, originalDirectory) { +function run(root, appName, version, verbose, originalDirectory, template) { var packageToInstall = getInstallPackage(version); var packageName = getPackageName(packageToInstall); @@ -183,7 +190,7 @@ function run(root, appName, version, verbose, originalDirectory) { 'init.js' ); var init = require(scriptsPath); - init(root, appName, verbose, originalDirectory); + init(root, appName, verbose, originalDirectory, template); }); } diff --git a/packages/react-scripts/.npmignore b/packages/react-scripts/.npmignore new file mode 100644 index 000000000..76163ab96 --- /dev/null +++ b/packages/react-scripts/.npmignore @@ -0,0 +1 @@ +/fixtures diff --git a/packages/react-scripts/fixtures/kitchensink/.babelrc b/packages/react-scripts/fixtures/kitchensink/.babelrc new file mode 100644 index 000000000..5686105b9 --- /dev/null +++ b/packages/react-scripts/fixtures/kitchensink/.babelrc @@ -0,0 +1,3 @@ +{ + "presets": ["latest"] +} diff --git a/packages/react-scripts/fixtures/kitchensink/.env b/packages/react-scripts/fixtures/kitchensink/.env new file mode 100644 index 000000000..3e6e8a5a3 --- /dev/null +++ b/packages/react-scripts/fixtures/kitchensink/.env @@ -0,0 +1 @@ +REACT_APP_FILE_ENV_MESSAGE=fromtheenvfile diff --git a/packages/react-scripts/fixtures/kitchensink/.flowconfig b/packages/react-scripts/fixtures/kitchensink/.flowconfig new file mode 100644 index 000000000..c65836228 --- /dev/null +++ b/packages/react-scripts/fixtures/kitchensink/.flowconfig @@ -0,0 +1,8 @@ +[ignore] +<PROJECT_ROOT>/node_modules/fbjs/.* + +[include] + +[libs] + +[options] diff --git a/packages/react-scripts/fixtures/kitchensink/.template.dependencies.json b/packages/react-scripts/fixtures/kitchensink/.template.dependencies.json new file mode 100644 index 000000000..8adac4570 --- /dev/null +++ b/packages/react-scripts/fixtures/kitchensink/.template.dependencies.json @@ -0,0 +1,10 @@ +{ + "dependencies": { + "babel-preset-latest": "6.16.0", + "babel-register": "6.18.0", + "babel-polyfill": "6.20.0", + "chai": "3.5.0", + "jsdom": "9.8.3", + "mocha": "3.2.0" + } +} diff --git a/packages/react-scripts/fixtures/kitchensink/gitignore b/packages/react-scripts/fixtures/kitchensink/gitignore new file mode 100644 index 000000000..6c96c5cff --- /dev/null +++ b/packages/react-scripts/fixtures/kitchensink/gitignore @@ -0,0 +1,15 @@ +# See http://help.github.com/ignore-files/ for more about ignoring files. + +# dependencies +node_modules + +# testing +coverage + +# production +build + +# misc +.DS_Store +.env +npm-debug.log diff --git a/packages/react-scripts/fixtures/kitchensink/integration/env.test.js b/packages/react-scripts/fixtures/kitchensink/integration/env.test.js new file mode 100644 index 000000000..a179aa7cb --- /dev/null +++ b/packages/react-scripts/fixtures/kitchensink/integration/env.test.js @@ -0,0 +1,24 @@ +import { expect } from 'chai' +import initDOM from './initDOM' + +describe('Integration', () => { + describe('Environment variables', () => { + it('NODE_PATH', async () => { + const doc = await initDOM('node-path') + + expect(doc.getElementById('feature-node-path').childElementCount).to.equal(4) + }) + + it('shell env variables', async () => { + const doc = await initDOM('shell-env-variables') + + expect(doc.getElementById('feature-shell-env-variables').textContent).to.equal('fromtheshell.') + }) + + it('file env variables', async () => { + const doc = await initDOM('file-env-variables') + + expect(doc.getElementById('feature-file-env-variables').textContent).to.equal('fromtheenvfile.') + }) + }) +}) diff --git a/packages/react-scripts/fixtures/kitchensink/integration/initDOM.js b/packages/react-scripts/fixtures/kitchensink/integration/initDOM.js new file mode 100644 index 000000000..c04e60d4c --- /dev/null +++ b/packages/react-scripts/fixtures/kitchensink/integration/initDOM.js @@ -0,0 +1,62 @@ +const fs = require('fs') +const http = require('http') +const jsdom = require('jsdom') +const path = require('path') + +let getMarkup +let resourceLoader +// this value could be tweaked in order to let the resource +// retriever get every file and jsdom execute react +let timeToWaitForJsToExecute + +if (process.env.E2E_FILE) { + const file = path.isAbsolute(process.env.E2E_FILE) + ? process.env.E2E_FILE + : path.join(process.cwd(), process.env.E2E_FILE) + + const markup = fs.readFileSync(file, 'utf8') + getMarkup = () => markup + + resourceLoader = (resource, callback) => callback( + null, + fs.readFileSync(path.join(path.dirname(file), resource.url.pathname), 'utf8') + ) + + timeToWaitForJsToExecute = 0 +} else if (process.env.E2E_URL) { + getMarkup = () => new Promise(resolve => { + http.get(process.env.E2E_URL, (res) => { + let rawData = '' + res.on('data', chunk => rawData += chunk) + res.on('end', () => resolve(rawData)) + }) + }) + + resourceLoader = (resource, callback) => { + return resource.defaultFetch(callback) + } + + timeToWaitForJsToExecute = 100 +} else { + it.only('can run jsdom (at least one of "E2E_FILE" or "E2E_URL" environment variables must be provided)', () => { + expect(new Error('This isn\'t the error you are looking for.')).toBeUndefined() + }) +} + +export default feature => new Promise(async resolve => { + const markup = await getMarkup() + const host = process.env.E2E_URL || 'http://localhost:3000' + const doc = jsdom.jsdom(markup, { + features : { + FetchExternalResources : ['script', 'css'], + ProcessExternalResources : ['script'], + }, + resourceLoader, + url: `${host}#${feature}`, + virtualConsole: jsdom.createVirtualConsole().sendTo(console), + }) + + doc.defaultView.addEventListener('load', () => { + setTimeout(() => resolve(doc), timeToWaitForJsToExecute) + }, false) +}) diff --git a/packages/react-scripts/fixtures/kitchensink/integration/syntax.test.js b/packages/react-scripts/fixtures/kitchensink/integration/syntax.test.js new file mode 100644 index 000000000..c8b7fbbc5 --- /dev/null +++ b/packages/react-scripts/fixtures/kitchensink/integration/syntax.test.js @@ -0,0 +1,96 @@ +import { expect } from 'chai' +import initDOM from './initDOM' + +describe('Integration', () => { + describe('Language syntax', () => { + it('array destructuring', async () => { + const doc = await initDOM('array-destructuring') + + expect(doc.getElementById('feature-array-destructuring').childElementCount).to.equal(4) + }) + + it('array spread', async () => { + const doc = await initDOM('array-spread') + + expect(doc.getElementById('feature-array-spread').childElementCount).to.equal(4) + }) + + it('async/await', async () => { + const doc = await initDOM('async-await') + + expect(doc.getElementById('feature-async-await').childElementCount).to.equal(4) + }) + + it('class properties', async () => { + const doc = await initDOM('class-properties') + + expect(doc.getElementById('feature-class-properties').childElementCount).to.equal(4) + }) + + it('computed properties', async () => { + const doc = await initDOM('computed-properties') + + expect(doc.getElementById('feature-computed-properties').childElementCount).to.equal(4) + }) + + it('custom interpolation', async () => { + const doc = await initDOM('custom-interpolation') + + expect(doc.getElementById('feature-custom-interpolation').childElementCount).to.equal(4) + }) + + it('default parameters', async () => { + const doc = await initDOM('default-parameters') + + expect(doc.getElementById('feature-default-parameters').childElementCount).to.equal(4) + }) + + it('destructuring and await', async () => { + const doc = await initDOM('destructuring-and-await') + + expect(doc.getElementById('feature-destructuring-and-await').childElementCount).to.equal(4) + }) + + it('generators', async () => { + const doc = await initDOM('generators') + + expect(doc.getElementById('feature-generators').childElementCount).to.equal(4) + }) + + it('object destructuring', async () => { + const doc = await initDOM('object-destructuring') + + expect(doc.getElementById('feature-object-destructuring').childElementCount).to.equal(4) + }) + + it('object spread', async () => { + const doc = await initDOM('object-spread') + + expect(doc.getElementById('feature-object-spread').childElementCount).to.equal(4) + }) + + it('promises', async () => { + const doc = await initDOM('promises') + + expect(doc.getElementById('feature-promises').childElementCount).to.equal(4) + }) + + it('rest + default', async () => { + const doc = await initDOM('rest-and-default') + + expect(doc.getElementById('feature-rest-and-default').childElementCount).to.equal(4) + }) + + it('rest parameters', async () => { + const doc = await initDOM('rest-parameters') + + expect(doc.getElementById('feature-rest-parameters').childElementCount).to.equal(4) + }) + + it('template interpolation', async () => { + const doc = await initDOM('template-interpolation') + + expect(doc.getElementById('feature-template-interpolation').childElementCount).to.equal(4) + }) + }) +}) diff --git a/packages/react-scripts/fixtures/kitchensink/integration/webpack.test.js b/packages/react-scripts/fixtures/kitchensink/integration/webpack.test.js new file mode 100644 index 000000000..9e2826b8f --- /dev/null +++ b/packages/react-scripts/fixtures/kitchensink/integration/webpack.test.js @@ -0,0 +1,44 @@ +import { expect } from 'chai' +import initDOM from './initDOM' + +describe('Integration', () => { + describe('Webpack plugins', () => { + it('css inclusion', async () => { + const doc = await initDOM('css-inclusion') + + expect(doc.getElementsByTagName('style')[0].textContent.replace(/\s/g, '')) + .to.match(/#feature-css-inclusion\{background:.+;color:.+}/) + }) + + it('image inclusion', async () => { + const doc = await initDOM('image-inclusion') + + expect(doc.getElementById('feature-image-inclusion').src).to.match(/^data:image\/jpeg;base64.+==$/) + }) + + it('no ext inclusion', async () => { + const doc = await initDOM('no-ext-inclusion') + + expect(doc.getElementById('feature-no-ext-inclusion').textContent) + .to.equal('This is just a file without an extension.') + }) + + it('json inclusion', async () => { + const doc = await initDOM('json-inclusion') + + expect(doc.getElementById('feature-json-inclusion').textContent).to.equal('This is an abstract.') + }) + + it('svg inclusion', async () => { + const doc = await initDOM('svg-inclusion') + + expect(doc.getElementById('feature-svg-inclusion').src).to.match(/\/static\/media\/logo\..+\.svg$/) + }) + + it('unknown ext inclusion', async () => { + const doc = await initDOM('unknown-ext-inclusion') + + expect(doc.getElementById('feature-unknown-ext-inclusion').textContent).to.equal('Whoooo, spooky!.') + }) + }) +}) diff --git a/packages/react-scripts/fixtures/kitchensink/public/favicon.ico b/packages/react-scripts/fixtures/kitchensink/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..5c125de5d897c1ff5692a656485b3216123dcd89 GIT binary patch literal 24838 zcmeI4X^>UL6@VY56)S&I{`6Nu0RscWCdj@GJHx(%?6_-;yKy1n;EEf9f}pr1CW5HA zYt$%U#C=}?jWH&%G@BaHBxsWAoUb3}&6%Ei@4Ii_JRa1`RQ23*yU)_wJ$?H0>6gj0 z${d_I^w5kvTW3x<IFlKb$z%>YEc?FvyP3>p$!py@`@T`|dVepIsjbbvR}af%KKy<r zQ!O-7BpkB&^2i9=CVy?(v>7YuQ%SDC^zmNWPYR^7avI5P-@dKev}UZ^aDAOyci9Nn zwR4qEz~tSvrp|#ACvWzo9`3B;`}^{t18dxaH;?xT7#hmJiKAaI;|O=$yxzXNOHGw~ z^!5pE^SW`av%t_$22LFPsM^l%=PSp!3r`>9w%s+^ZQYnnTQ*Ggd9-1~kj_o$YdW@b ztCkJ(ZGYjusqV5L4{^)R9Gt@gzU1t|?xhE&c^q(|(R#oa*}Sj5c({A$mhrB8*Y@tc zr)K#C{KOp-eHl35ZWJ1&zkmI>9DL%!KJE@_!<b=R+`r#n>=W?aH;i?ZDb0O1HPFy6 zcV0Kf)eZ0BHm<I7>z9vowF7EA{z*aue9M)iJP&Zd)qYlfJ-c^sS1qY^?>s)!!Ta@x zr@Lz|80r)7<{QVk9Z$}5SDaVtz*Rc?oH5~Wcjoc^eA&EdJ^h@aZ-BvL{K2s_7Cvfr zFL&(R?D&(9OxsS%z_BzI9^Ai^AOF$PUpGk~oO(=OpMc3@Zh&KH1a9>G%%0rC)t@oQ z4d~M`hX+g^Wf8P>A&&qjq|tZe*44Laq7qVPK#QIc)s*Qj34P`NL`Q{xBI`SnR!RC? zlGdTvC%oVZ@0BgcH>}qc!uzul@{i@sH}L0|=eZBJ9qF!HHaw?`s0(_DJj(v`(memI z6jH}=BfGlS<lCz5(9Y}G6-$SDeZe<M+V!hhjy&`*IN(B)R>lRV4)ouv#h*65yRR>G zo;I#~BVK&l&{+H=_~Nq$d%bFLh7GE5pS&>Fr{RMe>)MM19~z6F1oQo_y>vtlpEZF# zIc82TpMc3z9;{Q)=zG5B#4+96yHCvYy8p4;C%6x`%y$2HccC9|#vGVD)**C0xX|R| z%h)}ze!Tnrvvb@RZ!GX@2lMEq`=`08b`9$%FnN@*zJLo2wD5?MbE&LN)Z>Kty*;m= zt{Cn0>Q3nk)`<?XKA&^a0H1)#qYT{(E;6A-&$G^18FQ!hbgw)(&2_47Slh<SeEagv z1zwkfi$2$N30U*M0ay8T6dv$`r{-OD&Jed;=9s?oY}dAp`^ziy+~Qf;b^SNe-^w2t z9LoMGIN(}Zc-b}#mAUu+)3b7GF}TbX=E<)&P4Tq!pYjI=hcfyIT;)Gf)@XRC?V|at zU(AVHuNvjo6xRCr(|dYbL)R{7Nh*KKhDl<#^z?QC;{h#gi(3onyYo*T;9eA4gt}r! zVK4mgxjCK>bR^{dVf!3ECg6Yz4YcskI>$XH*L8E)MsudhnkP0B>+M(XEcErHUBKi~ z1`fEP&WPhp{@Ew?cPlR(ma9iw8NbJWHqp=btCtM*FnP*@ZwwlJ&-Y|LEjgvJzUtPc zz5CrWNBRV8d0-bpWAl<=zM1PU8lJ<auFSVLADiJ5u&qD1&?ND+W&L_}^tzZnT_kh- z*}JFsu|}tn7*p~nn>seDxBK^QuuCj2fg{&2#*IG5ezf1B(o%lU+OZx7So4D?yi2*h zFBkr5pG3AJs83uy!~C3mQZLp~ss7-N9oAY>t)!eC#s)CrPukK!(!G*)H?v(~JCoj# zfvgTxMV{4?zL1neQ;ITVBAdFDf`1yG$o{g7^1sR_n{RZ7tnXio?tM%240}(z9xFY0 zlz{^-G*RET;-`7`>e0b{{`!2kM)t7Si9ZqD$~wh*hyGC>z~qs@0T&u*;h}hiKGEga zHkJ;%7aNc^o_0(>Z{Gp06<d!oiwkYI9@z4HFzfO!R*h-IQ)!TmJxBu9eEVd72@jiB z2+SIP`!%B@>9H;TwPTUnvvX0SJ+kGGZ0lFBWocl>kaa)AoiMta+x_-J-?#KHFnJ*! zwD1V?)4s#|?O)DlMBhVv4IgZs?d>b<6%xK3<{o91H?-%8?PK!_fm#3d>{{gQ<X0b> z?*8`b{G6?bZKdO{_9IVlz{R$PcGjeL|3*|@upby()_Lf^eQ&XQe)CjsbJ3Uolrgt< zweld3GH|fZpn(=1@PencO_a_)v6tU?WV-w8wfXLbOGae<M=}TTxv_VkkFEV<X@MyN z2V7{Fd+b}_1y6V*Bc$V<eH8m0Xsn%ve~-Ncd(n@dpOe#l=sI|Q`r=&2J`x`2Kya=+ zzt+=O-yl5kg&`x#=ZBrln1yv?kHLJSFLf?4rgqGMXHLwH^SM79;Blb|_b2e?d&Z|2 z%0Y)skMV`6zEc~Xy<sSyJa~eGoo@HZRu=U{mdyihsrJ)H^i^E@>0{<*C?Ead$6v+> z|EQKThJTmwXK!c6AOD+<KQQ<@{@^la?D)eoY5bwjH~(4t^38v6nlt~kz2*G=wGR5k zez5wFeYu@?QTh*@V)UQN=9#4b(fO+XpV^ev|A%*Lm^aWDtN+Wr{-FzRyE@u_*ca=6 z8v94>FgtDv7i<48{-OPce!KDVkzR+XKOcREPha(;$}iUb!*)f-Fb}Y4@r9z-_{OIg z`xn^T#ZtEPv_T$M*Sr+=Z{q#~8$|7Y{0!*2u${D*Jj%dfOrS~FzpH*_|55J!7kl4w z?LT!7T(!3!632pmZh?dh`n-z$_ts42pn6;c`}hx;TSYd0idsqal5&0uGV=UM{c9xQ z1KK6&TS+a^H|6B<wY1?KNwleRT=S(2ztn0;|CLnE`j%2QZCfX)(aE8_)AlDNl~VTp z#QQ1QtaCx&H5Jr$9fvivU)tSS(tj$j{j{03Ut57~*ExVr+*!fxXI=QFg4>_hPo1W3 zh+Dun!`UkP%H3}*@IE18q{7&MH2f3?T6o}Jf+xI@fh=SyUOArw`*w1_-PUlHZTHc@ z--yqIxPtI}IjPRzLIZ8cPv4P=>?A&=E~~0)>&J#V;TwAR*6}`01iu~U$@prtzW6YS ze}E>gUX+0YuF}B+Uhw2x7a7Q+oOzMNFHTNN<)40Rzg#`pABKF18@l}5A>RL`?Ri;Z zC8ExD$)im1@R{N7(wIog8$Yn(6%q$yd9(zKe};OnH%;<E6IVx!rq-Dls&Jo8o|c0< zuy5@7x0i)X@To&fw53oU#K*E9rw;0;PU1oT;M+!rL4$AO=p(c7O~B+)22N66stja8 zLmiT0brrv*pZHXfPf{Ow8X2@%^#b3ye(U5>mWBs7)>ls~T3Wi6!Xqw6+dpJLVS1P| z9qV%io-nE*rYcPxiS<?aaq&fI_%s)XSYMT&^sPqm$A6{c4iDfIKCMP$j7*hZC~Z`o z3eB_QUx<xEycp-_)Sah=HMTrWU685mFUR=P4wY|pc~adutHaL<osPMk3zXS2!X#eA zQmK56!Art#=`!NBRQ}0}8{+lj<e<}^zH?HJ#;)7I$_tz{`u|6Z8)$57Y@Ga3<m;M! z?b2b5zRf6E_G}ZMeu#tbU;9AgHA5Wxj!f{WgU#QUu-Y`l-Nnh}4h83xs_!^=pf9is zZ6c2{+5|2%arZBfg-mccFN>31>U_>mbPTXxkC*!?*zefr#2vF|qr8{|4|u^7-pD|f z&OPc->UKu)=iHgIpysp<ozGa?r0YPT{HTLHSC6V|OXXo_ayN;&#~E={T{+X=e(w~2 zw~0Nh;&4Wvrk?&hU(QFB4j$Z-f+xH+-#)1eb)s&iu!V^~AfA{w1uGX=?Rm}#S-&+l zgncRJ)Zh@ylBVrCPT)cVEj)CO3vXl~%gP4UL>;Lsbyj}GJWoBkufOA={CRTUjr%af zc5pUH9{pg?M5%+)oN`q9yBb<oyS@>Bt@+3xHV)qGm8b)Cp-w7~CwEhtBUk0rbjrqM zTb|tQ3-5-pw^cul`T+X&s?O;?V(FD<p-*U$j}C+<^vEC&nfC4)HUsx3hzYZGCbpcm z6e64X$6Y|>!(Q9Qg@(LTCNz{0-vBM^SX5lti3|GpxFn4;Ax6pGc~t)R!Bo${lYH(* z!F&5X*?S&}YoDCyzwv1H+XI(+rL`;RN9}iLxlfr-r&vGG8OQa@=>+a)+Ij)sd_{wu z1Am(+3-RFr4&N8N6+hqo19S#;SA1-hG<GH5jM5~<MA>>07p3}&*j4CR+rqdV)^6n; z_vFr!<qZ$Di!AT7`VHNnve0FgcNDC1nRsh^hbs!#=B-+mwMSJJ_g-u{F!6C(9`}rj zp@WyjXIw+xaqqN&wm`3UqvCMM*H~D5k4bo8S)U`Sb2ctKqWtsfFSBh4VQ@m;@X~sr z`v>(a%-=#=kb{pY<Q=}Noc+1|5qFyt+f_*W)u&sj^WW+}&Yr^g5%rG#;~pt<%<8C6 z|8W;TobTZ~I?~E0R{zlkm666CYO?;xU4uf_KXk0x#D%VZQTTTKvty&bKVbXH!qmAr z>mNL@6|DWkw~%E2V2jYl*e1}c{e$fib?(O+hs}eoBLRo&9(<zgA7XHk#X4o%Yhmmk z)%oBSV*e<g{mK4CZ|_U{SNnixv-dx;XDQ^nvoeA0T(|zPeYO9w^}*Jn4%|!DHtAEp zb?%3Z9@-^mGnHchi!Fl;WFcQ=Yh8F!N9vl^KD6!32cuK+`9GMe&)qxK-!FUQwr2W2 z#8;wi!vDctHF&~X^X;?L{*S1BVUJj8{;#kftpAfc-q!z#-zILn?AYal;Q=q}|3p@~ z{h#zj8vi$U_xSw+>;J}YV}0Mi<mo;y>;LZA<ldj{|NX)Ltz*y<=O3Jj=v>e{U$(s= zT<-IaV$Z+q-P!~3{HxN>Kbw30jXzM&I(S<6Ksx^}HvU2Vntb!<yFz0a_NVv<Vo^f< zl=P0zzDfLx<R#IBWyIX5zAQ)l1A8--U&vi>etSsm0>)j}Me^+L5{2yz--)?W`Q?az z!WLG4UNP}+#C+NKH+ZG-Q<ppbjq%{@oiSjqt>=E>IPp%LuKLx$$8NAOGr(#~P>!EA zDYlpXDR=xM?Xv5(-qp74Cw3LzBeASHSBY`OezkbO<VD55M#Z-5FY&MJafv~uZ8rWH z`;FiF)bE^fzVqhBKl3|r@GMdMb5Zvn(!{^B503JKg>yjP!G%WSymju_C$VBl--z<c z^Q7%X-+y6_@;es({)3!PFz);&9_MF;#0G|Sg%%$0f+uGm$Us)qcM;O3c&F`^eE*5I zbKkX6@4waTy#rW@_a9fA`=1qk|8?&isM!0@IuG{tLnqM(D<q*C_eg4Ds~li?v|)!N z+SJLm6?jiJ;|CvQpNDMCKKbne{#w=h$G-m^gRI#9|8H&&)Mp8E<F_^Ye$YqR=OH@o F{{x|jBbfjI literal 0 HcmV?d00001 diff --git a/packages/react-scripts/fixtures/kitchensink/public/index.html b/packages/react-scripts/fixtures/kitchensink/public/index.html new file mode 100644 index 000000000..ce76aae90 --- /dev/null +++ b/packages/react-scripts/fixtures/kitchensink/public/index.html @@ -0,0 +1,12 @@ +<!doctype html> +<html lang="en"> + <head> + <meta charset="utf-8"> + <meta name="viewport" content="width=device-width, initial-scale=1"> + <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico"> + <title>React App + + +
+ + diff --git a/packages/react-scripts/fixtures/kitchensink/src/App.js b/packages/react-scripts/fixtures/kitchensink/src/App.js new file mode 100644 index 000000000..66cd45541 --- /dev/null +++ b/packages/react-scripts/fixtures/kitchensink/src/App.js @@ -0,0 +1,103 @@ +import React from 'react'; + +class App extends React.Component { + constructor(props) { + super(props); + + this.state = { feature: null }; + + this.setFeature = this.setFeature.bind(this); + } + + componentDidMount() { + switch (location.hash.slice(1)) { + case 'array-destructuring': + require.ensure([], () => this.setFeature(require('./features/syntax/ArrayDestructuring').default)); + break; + case 'array-spread': + require.ensure([], () => this.setFeature(require('./features/syntax/ArraySpread').default)); + break; + case 'async-await': + require.ensure([], () => this.setFeature(require('./features/syntax/AsyncAwait').default)); + break; + case 'class-properties': + require.ensure([], () => this.setFeature(require('./features/syntax/ClassProperties').default)); + break; + case 'computed-properties': + require.ensure([], () => this.setFeature(require('./features/syntax/ComputedProperties').default)); + break; + case 'css-inclusion': + require.ensure([], () => this.setFeature(require('./features/webpack/CssInclusion').default)); + break; + case 'custom-interpolation': + require.ensure([], () => this.setFeature(require('./features/syntax/CustomInterpolation').default)); + break; + case 'default-parameters': + require.ensure([], () => this.setFeature(require('./features/syntax/DefaultParameters').default)); + break; + case 'destructuring-and-await': + require.ensure([], () => this.setFeature(require('./features/syntax/DestructuringAndAwait').default)); + break; + case 'file-env-variables': + require.ensure([], () => this.setFeature(require('./features/env/FileEnvVariables').default)); + break; + case 'generators': + require.ensure([], () => this.setFeature(require('./features/syntax/Generators').default)); + break; + case 'image-inclusion': + require.ensure([], () => this.setFeature(require('./features/webpack/ImageInclusion').default)); + break; + case 'json-inclusion': + require.ensure([], () => this.setFeature(require('./features/webpack/JsonInclusion').default)); + break; + case 'node-path': + require.ensure([], () => this.setFeature(require('./features/env/NodePath').default)); + break; + case 'no-ext-inclusion': + require.ensure([], () => this.setFeature(require('./features/webpack/NoExtInclusion').default)); + break; + case 'object-destructuring': + require.ensure([], () => this.setFeature(require('./features/syntax/ObjectDestructuring').default)); + break; + case 'object-spread': + require.ensure([], () => this.setFeature(require('./features/syntax/ObjectSpread').default)); + break; + case 'promises': + require.ensure([], () => this.setFeature(require('./features/syntax/Promises').default)); + break; + case 'rest-and-default': + require.ensure([], () => this.setFeature(require('./features/syntax/RestAndDefault').default)); + break; + case 'rest-parameters': + require.ensure([], () => this.setFeature(require('./features/syntax/RestParameters').default)); + break; + case 'shell-env-variables': + require.ensure([], () => this.setFeature(require('./features/env/ShellEnvVariables').default)); + break; + case 'svg-inclusion': + require.ensure([], () => this.setFeature(require('./features/webpack/SvgInclusion').default)); + break; + case 'template-interpolation': + require.ensure([], () => this.setFeature(require('./features/syntax/TemplateInterpolation').default)); + break; + case 'unknown-ext-inclusion': + require.ensure([], () => this.setFeature(require('./features/webpack/UnknownExtInclusion').default) + ); + break; + default: + this.setFeature(null); + break; + } + } + + setFeature(feature) { + this.setState({ feature }); + } + + render() { + const Feature = this.state.feature; + return Feature ? : null; + } +} + +export default App; diff --git a/packages/react-scripts/fixtures/kitchensink/src/App.test.js b/packages/react-scripts/fixtures/kitchensink/src/App.test.js new file mode 100644 index 000000000..b84af98d7 --- /dev/null +++ b/packages/react-scripts/fixtures/kitchensink/src/App.test.js @@ -0,0 +1,8 @@ +import React from 'react'; +import ReactDOM from 'react-dom'; +import App from './App'; + +it('renders without crashing', () => { + const div = document.createElement('div'); + ReactDOM.render(, div); +}); diff --git a/packages/react-scripts/fixtures/kitchensink/src/absoluteLoad.js b/packages/react-scripts/fixtures/kitchensink/src/absoluteLoad.js new file mode 100644 index 000000000..dc769fe1e --- /dev/null +++ b/packages/react-scripts/fixtures/kitchensink/src/absoluteLoad.js @@ -0,0 +1,6 @@ +export default () => [ + { id: 1, name: '1' }, + { id: 2, name: '2' }, + { id: 3, name: '3' }, + { id: 4, name: '4' } +] diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/env/FileEnvVariables.js b/packages/react-scripts/fixtures/kitchensink/src/features/env/FileEnvVariables.js new file mode 100644 index 000000000..c7b7c5d53 --- /dev/null +++ b/packages/react-scripts/fixtures/kitchensink/src/features/env/FileEnvVariables.js @@ -0,0 +1,5 @@ +import React from 'react' + +export default () => ( + {process.env.REACT_APP_FILE_ENV_MESSAGE}. +) diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/env/FileEnvVariables.test.js b/packages/react-scripts/fixtures/kitchensink/src/features/env/FileEnvVariables.test.js new file mode 100644 index 000000000..c9d802be9 --- /dev/null +++ b/packages/react-scripts/fixtures/kitchensink/src/features/env/FileEnvVariables.test.js @@ -0,0 +1,10 @@ +import React from 'react'; +import ReactDOM from 'react-dom'; +import FileEnvVariables from './FileEnvVariables'; + +describe('.env variables', () => { + it('renders without crashing', () => { + const div = document.createElement('div'); + ReactDOM.render(, div); + }); +}); diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/env/NodePath.js b/packages/react-scripts/fixtures/kitchensink/src/features/env/NodePath.js new file mode 100644 index 000000000..2d2f474f1 --- /dev/null +++ b/packages/react-scripts/fixtures/kitchensink/src/features/env/NodePath.js @@ -0,0 +1,25 @@ +import React from 'react' +import load from 'absoluteLoad' + +export default class extends React.Component { + constructor(props) { + super(props); + + this.state = { users: [] }; + } + + async componentDidMount() { + const users = load(); + this.setState({ users }); + } + + render() { + return ( +
+ {this.state.users.map(user => ( +
{user.name}
+ ))} +
+ ); + } +} diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/env/NodePath.test.js b/packages/react-scripts/fixtures/kitchensink/src/features/env/NodePath.test.js new file mode 100644 index 000000000..05b981853 --- /dev/null +++ b/packages/react-scripts/fixtures/kitchensink/src/features/env/NodePath.test.js @@ -0,0 +1,10 @@ +import React from 'react'; +import ReactDOM from 'react-dom'; +import NodePath from './NodePath'; + +describe('NODE_PATH', () => { + it('renders without crashing', () => { + const div = document.createElement('div'); + ReactDOM.render(, div); + }); +}); diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/env/ShellEnvVariables.js b/packages/react-scripts/fixtures/kitchensink/src/features/env/ShellEnvVariables.js new file mode 100644 index 000000000..37b80ec60 --- /dev/null +++ b/packages/react-scripts/fixtures/kitchensink/src/features/env/ShellEnvVariables.js @@ -0,0 +1,5 @@ +import React from 'react' + +export default () => ( + {process.env.REACT_APP_SHELL_ENV_MESSAGE}. +) diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/env/ShellEnvVariables.test.js b/packages/react-scripts/fixtures/kitchensink/src/features/env/ShellEnvVariables.test.js new file mode 100644 index 000000000..981bee67c --- /dev/null +++ b/packages/react-scripts/fixtures/kitchensink/src/features/env/ShellEnvVariables.test.js @@ -0,0 +1,10 @@ +import React from 'react'; +import ReactDOM from 'react-dom'; +import ShellEnvVariables from './ShellEnvVariables'; + +describe('shell env variables', () => { + it('renders without crashing', () => { + const div = document.createElement('div'); + ReactDOM.render(, div); + }); +}); diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ArrayDestructuring.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ArrayDestructuring.js new file mode 100644 index 000000000..38e351209 --- /dev/null +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ArrayDestructuring.js @@ -0,0 +1,34 @@ +import React from 'react' + +function load() { + return [ + [1, '1'], + [2, '2'], + [3, '3'], + [4, '4'] + ]; +} + +export default class extends React.Component { + constructor(props) { + super(props); + + this.state = { users: [] }; + } + + async componentDidMount() { + const users = load(); + this.setState({ users }); + } + + render() { + return ( +
+ {this.state.users.map(user => { + const [id, name] = user; + return
{name}
+ })} +
+ ); + } +} diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ArrayDestructuring.test.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ArrayDestructuring.test.js new file mode 100644 index 000000000..617df2a6c --- /dev/null +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ArrayDestructuring.test.js @@ -0,0 +1,10 @@ +import React from 'react'; +import ReactDOM from 'react-dom'; +import ArrayDestructuring from './ArrayDestructuring'; + +describe('array destructuring', () => { + it('renders without crashing', () => { + const div = document.createElement('div'); + ReactDOM.render(, div); + }); +}); diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ArraySpread.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ArraySpread.js new file mode 100644 index 000000000..d7d9a4591 --- /dev/null +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ArraySpread.js @@ -0,0 +1,33 @@ +import React from 'react' + +function load(users) { + return [ + { id: 1, name: '1' }, + { id: 2, name: '2' }, + { id: 3, name: '3' }, + ...users + ]; +} + +export default class extends React.Component { + constructor(props) { + super(props); + + this.state = { users: [] }; + } + + async componentDidMount() { + const users = load([{ id: 42, name: '42' }]); + this.setState({ users }); + } + + render() { + return ( +
+ {this.state.users.map(user => ( +
{user.name}
+ ))} +
+ ); + } +} diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ArraySpread.test.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ArraySpread.test.js new file mode 100644 index 000000000..85fade6e3 --- /dev/null +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ArraySpread.test.js @@ -0,0 +1,10 @@ +import React from 'react'; +import ReactDOM from 'react-dom'; +import ArraySpread from './ArraySpread'; + +describe('array spread', () => { + it('renders without crashing', () => { + const div = document.createElement('div'); + ReactDOM.render(, div); + }); +}); diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/AsyncAwait.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/AsyncAwait.js new file mode 100644 index 000000000..01c686405 --- /dev/null +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/AsyncAwait.js @@ -0,0 +1,33 @@ +import React from 'react' + +async function load() { + return [ + { id: 1, name: '1' }, + { id: 2, name: '2' }, + { id: 3, name: '3' }, + { id: 4, name: '4' } + ]; +} + +export default class extends React.Component { + constructor(props) { + super(props); + + this.state = { users: [] }; + } + + async componentDidMount() { + const users = await load(); + this.setState({ users }); + } + + render() { + return ( +
+ {this.state.users.map(user => ( +
{user.name}
+ ))} +
+ ); + } +} diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/AsyncAwait.test.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/AsyncAwait.test.js new file mode 100644 index 000000000..072f16fff --- /dev/null +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/AsyncAwait.test.js @@ -0,0 +1,10 @@ +import React from 'react'; +import ReactDOM from 'react-dom'; +import AsyncAwait from './AsyncAwait'; + +describe('async/await', () => { + it('renders without crashing', () => { + const div = document.createElement('div'); + ReactDOM.render(, div); + }); +}); diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ClassProperties.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ClassProperties.js new file mode 100644 index 000000000..65e500d64 --- /dev/null +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ClassProperties.js @@ -0,0 +1,20 @@ +import React from 'react' + +export default class extends React.Component { + users = [ + { id: 1, name: '1' }, + { id: 2, name: '2' }, + { id: 3, name: '3' }, + { id: 4, name: '4' } + ]; + + render() { + return ( +
+ {this.users.map(user => ( +
{user.name}
+ ))} +
+ ); + } +} diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ClassProperties.test.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ClassProperties.test.js new file mode 100644 index 000000000..71d851dd2 --- /dev/null +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ClassProperties.test.js @@ -0,0 +1,10 @@ +import React from 'react'; +import ReactDOM from 'react-dom'; +import ClassProperties from './ClassProperties'; + +describe('class properties', () => { + it('renders without crashing', () => { + const div = document.createElement('div'); + ReactDOM.render(, div); + }); +}); diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ComputedProperties.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ComputedProperties.js new file mode 100644 index 000000000..c7a24cb7f --- /dev/null +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ComputedProperties.js @@ -0,0 +1,33 @@ +import React from 'react' + +function load(prefix) { + return [ + { id: 1, [prefix + 'name']: '1' }, + { id: 2, [prefix + 'name']: '2' }, + { id: 3, [prefix + 'name']: '3' }, + { id: 4, [prefix + 'name']: '4' } + ]; +} + +export default class extends React.Component { + constructor(props) { + super(props); + + this.state = { users: [] }; + } + + async componentDidMount() { + const users = load('user_'); + this.setState({ users }); + } + + render() { + return ( +
+ {this.state.users.map(user => ( +
{user.user_name}
+ ))} +
+ ); + } +} diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ComputedProperties.test.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ComputedProperties.test.js new file mode 100644 index 000000000..4e9aaf17a --- /dev/null +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ComputedProperties.test.js @@ -0,0 +1,10 @@ +import React from 'react'; +import ReactDOM from 'react-dom'; +import ComputedProperties from './ComputedProperties'; + +describe('computed properties', () => { + it('renders without crashing', () => { + const div = document.createElement('div'); + ReactDOM.render(, div); + }); +}); diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/CustomInterpolation.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/CustomInterpolation.js new file mode 100644 index 000000000..032989683 --- /dev/null +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/CustomInterpolation.js @@ -0,0 +1,43 @@ +import React from 'react' + +const styled = ([style]) => style.trim() + .split(/\s*;\s*/) + .map(rule => rule.split(/\s*:\s*/)) + .reduce((rules, rule) => ({ ...rules, [rule[0]]: rule[1] }), {}); + +function load() { + return [ + { id: 1, name: '1' }, + { id: 2, name: '2' }, + { id: 3, name: '3' }, + { id: 4, name: '4' } + ]; +} + +export default class extends React.Component { + constructor(props) { + super(props); + + this.state = { users: [] }; + } + + async componentDidMount() { + const users = load(); + this.setState({ users }); + } + + render() { + const veryInlineStyle = styled` + background: palevioletred; + color: papayawhip; + `; + + return ( +
+ {this.state.users.map(user => ( +
{user.name}
+ ))} +
+ ); + } +} diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/CustomInterpolation.test.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/CustomInterpolation.test.js new file mode 100644 index 000000000..10b1df278 --- /dev/null +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/CustomInterpolation.test.js @@ -0,0 +1,10 @@ +import React from 'react'; +import ReactDOM from 'react-dom'; +import CustomInterpolation from './CustomInterpolation'; + +describe('custom interpolation', () => { + it('renders without crashing', () => { + const div = document.createElement('div'); + ReactDOM.render(, div); + }); +}); diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/DefaultParameters.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/DefaultParameters.js new file mode 100644 index 000000000..3a676358a --- /dev/null +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/DefaultParameters.js @@ -0,0 +1,33 @@ +import React from 'react' + +function load(id = 0) { + return [ + { id: id + 1, name: '1' }, + { id: id + 2, name: '2' }, + { id: id + 3, name: '3' }, + { id: id + 4, name: '4' } + ]; +} + +export default class extends React.Component { + constructor(props) { + super(props); + + this.state = { users: [] }; + } + + async componentDidMount() { + const users = load(); + this.setState({ users }); + } + + render() { + return ( +
+ {this.state.users.map(user => ( +
{user.name}
+ ))} +
+ ); + } +} diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/DefaultParameters.test.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/DefaultParameters.test.js new file mode 100644 index 000000000..b5ece2446 --- /dev/null +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/DefaultParameters.test.js @@ -0,0 +1,10 @@ +import React from 'react'; +import ReactDOM from 'react-dom'; +import DefaultParameters from './DefaultParameters'; + +describe('default parameters', () => { + it('renders without crashing', () => { + const div = document.createElement('div'); + ReactDOM.render(, div); + }); +}); diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/DestructuringAndAwait.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/DestructuringAndAwait.js new file mode 100644 index 000000000..291ed3bcc --- /dev/null +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/DestructuringAndAwait.js @@ -0,0 +1,33 @@ +import React from 'react' + +async function load() { + return { users: [ + { id: 1, name: '1' }, + { id: 2, name: '2' }, + { id: 3, name: '3' }, + { id: 4, name: '4' } + ] }; +} + +export default class extends React.Component { + constructor(props) { + super(props); + + this.state = { users: [] }; + } + + async componentDidMount() { + const { users } = await load(); + this.setState({ users }); + } + + render() { + return ( +
+ {this.state.users.map(user => ( +
{user.name}
+ ))} +
+ ); + } +} diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/DestructuringAndAwait.test.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/DestructuringAndAwait.test.js new file mode 100644 index 000000000..14521e307 --- /dev/null +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/DestructuringAndAwait.test.js @@ -0,0 +1,10 @@ +import React from 'react'; +import ReactDOM from 'react-dom'; +import DestructuringAndAwait from './DestructuringAndAwait'; + +describe('destructuring and await', () => { + it('renders without crashing', () => { + const div = document.createElement('div'); + ReactDOM.render(, div); + }); +}); diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/Generators.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/Generators.js new file mode 100644 index 000000000..4f2fc95ca --- /dev/null +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/Generators.js @@ -0,0 +1,35 @@ +import React from 'react' + +function * load(limit) { + let i = 1; + while (i <= limit) { + yield { id: i, name: i }; + i++; + } +} + +export default class extends React.Component { + constructor(props) { + super(props); + + this.state = { users: [] }; + } + + componentDidMount() { + const users = []; + for (let user of load(4)) { + users.push(user); + } + this.setState({ users }); + } + + render() { + return ( +
+ {this.state.users.map(user => ( +
{user.name}
+ ))} +
+ ); + } +} diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/Generators.test.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/Generators.test.js new file mode 100644 index 000000000..1fd36cdbe --- /dev/null +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/Generators.test.js @@ -0,0 +1,10 @@ +import React from 'react'; +import ReactDOM from 'react-dom'; +import Generators from './Generators'; + +describe('generators', () => { + it('renders without crashing', () => { + const div = document.createElement('div'); + ReactDOM.render(, div); + }); +}); diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ObjectDestructuring.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ObjectDestructuring.js new file mode 100644 index 000000000..c6edbee27 --- /dev/null +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ObjectDestructuring.js @@ -0,0 +1,34 @@ +import React from 'react' + +function load() { + return [ + { id: 1, name: '1' }, + { id: 2, name: '2' }, + { id: 3, name: '3' }, + { id: 4, name: '4' } + ]; +} + +export default class extends React.Component { + constructor(props) { + super(props); + + this.state = { users: [] }; + } + + async componentDidMount() { + const users = load(); + this.setState({ users }); + } + + render() { + return ( +
+ {this.state.users.map(user => { + const { id, name } = user; + return
{name}
+ })} +
+ ); + } +} diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ObjectDestructuring.test.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ObjectDestructuring.test.js new file mode 100644 index 000000000..7ed28147d --- /dev/null +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ObjectDestructuring.test.js @@ -0,0 +1,10 @@ +import React from 'react'; +import ReactDOM from 'react-dom'; +import ObjectDestructuring from './ObjectDestructuring'; + +describe('object destructuring', () => { + it('renders without crashing', () => { + const div = document.createElement('div'); + ReactDOM.render(, div); + }); +}); diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ObjectSpread.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ObjectSpread.js new file mode 100644 index 000000000..ca41004f9 --- /dev/null +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ObjectSpread.js @@ -0,0 +1,33 @@ +import React from 'react' + +function load(baseUser) { + return [ + { id: 1, name: '1', ...baseUser }, + { id: 2, name: '2', ...baseUser }, + { id: 3, name: '3', ...baseUser }, + { id: 4, name: '4', ...baseUser } + ]; +} + +export default class extends React.Component { + constructor(props) { + super(props); + + this.state = { users: [] }; + } + + async componentDidMount() { + const users = load({ age: 42 }); + this.setState({ users }); + } + + render() { + return ( +
+ {this.state.users.map(user => ( +
{user.name}: {user.age}
+ ))} +
+ ); + } +} diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ObjectSpread.test.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ObjectSpread.test.js new file mode 100644 index 000000000..9de96c264 --- /dev/null +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ObjectSpread.test.js @@ -0,0 +1,10 @@ +import React from 'react'; +import ReactDOM from 'react-dom'; +import ObjectSpread from './ObjectSpread'; + +describe('object spread', () => { + it('renders without crashing', () => { + const div = document.createElement('div'); + ReactDOM.render(, div); + }); +}); diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/Promises.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/Promises.js new file mode 100644 index 000000000..c0e13c81e --- /dev/null +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/Promises.js @@ -0,0 +1,34 @@ +import React from 'react' + +function load() { + return Promise.resolve([ + { id: 1, name: '1' }, + { id: 2, name: '2' }, + { id: 3, name: '3' }, + { id: 4, name: '4' } + ]); +} + +export default class extends React.Component { + constructor(props) { + super(props); + + this.state = { users: [] }; + } + + componentDidMount() { + load().then(users => { + this.setState({ users }); + }); + } + + render() { + return ( +
+ {this.state.users.map(user => ( +
{user.name}
+ ))} +
+ ); + } +} diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/Promises.test.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/Promises.test.js new file mode 100644 index 000000000..96b4d298d --- /dev/null +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/Promises.test.js @@ -0,0 +1,10 @@ +import React from 'react'; +import ReactDOM from 'react-dom'; +import Promises from './Promises'; + +describe('promises', () => { + it('renders without crashing', () => { + const div = document.createElement('div'); + ReactDOM.render(, div); + }); +}); diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/RestAndDefault.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/RestAndDefault.js new file mode 100644 index 000000000..a977e8c83 --- /dev/null +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/RestAndDefault.js @@ -0,0 +1,33 @@ +import React from 'react' + +function load({ id, ...rest } = { id: 0, user: { id: 42, name: '42' } }) { + return [ + { id: id + 1, name: '1' }, + { id: id + 2, name: '2' }, + { id: id + 3, name: '3' }, + rest.user + ]; +} + +export default class extends React.Component { + constructor(props) { + super(props); + + this.state = { users: [] }; + } + + async componentDidMount() { + const users = load(); + this.setState({ users }); + } + + render() { + return ( +
+ {this.state.users.map(user => ( +
{user.name}
+ ))} +
+ ); + } +} diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/RestAndDefault.test.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/RestAndDefault.test.js new file mode 100644 index 000000000..95f4a19fa --- /dev/null +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/RestAndDefault.test.js @@ -0,0 +1,10 @@ +import React from 'react'; +import ReactDOM from 'react-dom'; +import RestAndDefault from './RestAndDefault'; + +describe('rest + default', () => { + it('renders without crashing', () => { + const div = document.createElement('div'); + ReactDOM.render(, div); + }); +}); diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/RestParameters.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/RestParameters.js new file mode 100644 index 000000000..9dcc33fa0 --- /dev/null +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/RestParameters.js @@ -0,0 +1,33 @@ +import React from 'react' + +function load({ id = 0, ...rest }) { + return [ + { id: id + 1, name: '1' }, + { id: id + 2, name: '2' }, + { id: id + 3, name: '3' }, + rest.user + ]; +} + +export default class extends React.Component { + constructor(props) { + super(props); + + this.state = { users: [] }; + } + + async componentDidMount() { + const users = load({ id: 0, user: { id: 42, name: '42' } }); + this.setState({ users }); + } + + render() { + return ( +
+ {this.state.users.map(user => ( +
{user.name}
+ ))} +
+ ); + } +} diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/RestParameters.test.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/RestParameters.test.js new file mode 100644 index 000000000..8e0977133 --- /dev/null +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/RestParameters.test.js @@ -0,0 +1,10 @@ +import React from 'react'; +import ReactDOM from 'react-dom'; +import RestParameters from './RestParameters'; + +describe('rest parameters', () => { + it('renders without crashing', () => { + const div = document.createElement('div'); + ReactDOM.render(, div); + }); +}); diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/TemplateInterpolation.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/TemplateInterpolation.js new file mode 100644 index 000000000..505ee6173 --- /dev/null +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/TemplateInterpolation.js @@ -0,0 +1,33 @@ +import React from 'react' + +function load(name) { + return [ + { id: 1, name: `${name}1` }, + { id: 2, name: `${name}2` }, + { id: 3, name: `${name}3` }, + { id: 4, name: `${name}4` } + ]; +} + +export default class extends React.Component { + constructor(props) { + super(props); + + this.state = { users: [] }; + } + + async componentDidMount() { + const users = load('user_'); + this.setState({ users }); + } + + render() { + return ( +
+ {this.state.users.map(user => ( +
{user.name}
+ ))} +
+ ); + } +} diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/TemplateInterpolation.test.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/TemplateInterpolation.test.js new file mode 100644 index 000000000..b49af029a --- /dev/null +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/TemplateInterpolation.test.js @@ -0,0 +1,10 @@ +import React from 'react'; +import ReactDOM from 'react-dom'; +import TemplateInterpolation from './TemplateInterpolation'; + +describe('template interpolation', () => { + it('renders without crashing', () => { + const div = document.createElement('div'); + ReactDOM.render(, div); + }); +}); diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/webpack/CssInclusion.js b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/CssInclusion.js new file mode 100644 index 000000000..f35d11e0a --- /dev/null +++ b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/CssInclusion.js @@ -0,0 +1,6 @@ +import React from 'react' +import './assets/style.css' + +export default () => ( +

We love useless text.

+) diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/webpack/CssInclusion.test.js b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/CssInclusion.test.js new file mode 100644 index 000000000..f3e10a441 --- /dev/null +++ b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/CssInclusion.test.js @@ -0,0 +1,10 @@ +import React from 'react'; +import ReactDOM from 'react-dom'; +import CssInclusion from './CssInclusion'; + +describe('css inclusion', () => { + it('renders without crashing', () => { + const div = document.createElement('div'); + ReactDOM.render(, div); + }); +}); diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/webpack/ImageInclusion.js b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/ImageInclusion.js new file mode 100644 index 000000000..d793408a5 --- /dev/null +++ b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/ImageInclusion.js @@ -0,0 +1,6 @@ +import React from 'react' +import tiniestCat from './assets/tiniest-cat.jpg' + +export default () => ( + tiniest cat +) diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/webpack/ImageInclusion.test.js b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/ImageInclusion.test.js new file mode 100644 index 000000000..85e68d51e --- /dev/null +++ b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/ImageInclusion.test.js @@ -0,0 +1,10 @@ +import React from 'react'; +import ReactDOM from 'react-dom'; +import ImageInclusion from './ImageInclusion'; + +describe('image inclusion', () => { + it('renders without crashing', () => { + const div = document.createElement('div'); + ReactDOM.render(, div); + }); +}); diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/webpack/JsonInclusion.js b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/JsonInclusion.js new file mode 100644 index 000000000..8050b9cfd --- /dev/null +++ b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/JsonInclusion.js @@ -0,0 +1,6 @@ +import React from 'react' +import { abstract } from './assets/abstract.json' + +export default () => ( + {abstract} +) diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/webpack/JsonInclusion.test.js b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/JsonInclusion.test.js new file mode 100644 index 000000000..70043bd05 --- /dev/null +++ b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/JsonInclusion.test.js @@ -0,0 +1,10 @@ +import React from 'react'; +import ReactDOM from 'react-dom'; +import JsonInclusion from './JsonInclusion'; + +describe('JSON inclusion', () => { + it('renders without crashing', () => { + const div = document.createElement('div'); + ReactDOM.render(, div); + }); +}); diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/webpack/NoExtInclusion.js b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/NoExtInclusion.js new file mode 100644 index 000000000..70b2d2b21 --- /dev/null +++ b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/NoExtInclusion.js @@ -0,0 +1,10 @@ +import React from 'react' +import aFileWithoutExt from './assets/aFileWithoutExt' + +const text = aFileWithoutExt.includes('base64') + ? atob(aFileWithoutExt.split('base64,')[1]).trim() + : aFileWithoutExt + +export default () => ( +

{text}.

+) diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/webpack/NoExtInclusion.test.js b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/NoExtInclusion.test.js new file mode 100644 index 000000000..666f94f38 --- /dev/null +++ b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/NoExtInclusion.test.js @@ -0,0 +1,10 @@ +import React from 'react'; +import ReactDOM from 'react-dom'; +import NoExtInclusion from './NoExtInclusion'; + +describe('no ext inclusion', () => { + it('renders without crashing', () => { + const div = document.createElement('div'); + ReactDOM.render(, div); + }); +}); diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/webpack/SvgInclusion.js b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/SvgInclusion.js new file mode 100644 index 000000000..7c2fdb2e4 --- /dev/null +++ b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/SvgInclusion.js @@ -0,0 +1,6 @@ +import React from 'react' +import logo from './assets/logo.svg' + +export default () => ( + logo +) diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/webpack/SvgInclusion.test.js b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/SvgInclusion.test.js new file mode 100644 index 000000000..507da0140 --- /dev/null +++ b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/SvgInclusion.test.js @@ -0,0 +1,10 @@ +import React from 'react'; +import ReactDOM from 'react-dom'; +import SvgInclusion from './SvgInclusion'; + +describe('svg inclusion', () => { + it('renders without crashing', () => { + const div = document.createElement('div'); + ReactDOM.render(, div); + }); +}); diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/webpack/UnknownExtInclusion.js b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/UnknownExtInclusion.js new file mode 100644 index 000000000..30aeccd6f --- /dev/null +++ b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/UnknownExtInclusion.js @@ -0,0 +1,10 @@ +import React from 'react' +import aFileWithExtUnknown from './assets/aFileWithExt.unknown' + +const text = aFileWithExtUnknown.includes('base64') + ? atob(aFileWithExtUnknown.split('base64,')[1]).trim() + : aFileWithExtUnknown + +export default () => ( +

{text}.

+) diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/webpack/UnknownExtInclusion.test.js b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/UnknownExtInclusion.test.js new file mode 100644 index 000000000..46724e0a2 --- /dev/null +++ b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/UnknownExtInclusion.test.js @@ -0,0 +1,10 @@ +import React from 'react'; +import ReactDOM from 'react-dom'; +import UnknownExtInclusion from './UnknownExtInclusion'; + +describe('unknown ext inclusion', () => { + it('renders without crashing', () => { + const div = document.createElement('div'); + ReactDOM.render(, div); + }); +}); diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/webpack/assets/aFileWithExt.unknown b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/assets/aFileWithExt.unknown new file mode 100644 index 000000000..a5de8eb32 --- /dev/null +++ b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/assets/aFileWithExt.unknown @@ -0,0 +1 @@ +Whoooo, spooky! diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/webpack/assets/aFileWithoutExt b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/assets/aFileWithoutExt new file mode 100644 index 000000000..dbcc1afda --- /dev/null +++ b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/assets/aFileWithoutExt @@ -0,0 +1 @@ +This is just a file without an extension diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/webpack/assets/abstract.json b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/assets/abstract.json new file mode 100644 index 000000000..5d21a7168 --- /dev/null +++ b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/assets/abstract.json @@ -0,0 +1,3 @@ +{ + "abstract": "This is an abstract." +} diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/webpack/assets/logo.svg b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/assets/logo.svg new file mode 100644 index 000000000..6b60c1042 --- /dev/null +++ b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/assets/logo.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/webpack/assets/style.css b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/assets/style.css new file mode 100644 index 000000000..c399d1aca --- /dev/null +++ b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/assets/style.css @@ -0,0 +1,4 @@ +#feature-css-inclusion { + background: palevioletred; + color: papayawhip; +} diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/webpack/assets/tiniest-cat.jpg b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/assets/tiniest-cat.jpg new file mode 100644 index 0000000000000000000000000000000000000000..c658e9922a765fa62442f996a1c4fa028c731f45 GIT binary patch literal 691 zcmex=_1P|rX?qqI0P zFI~aY%U!`Mz|~!$%*;qrN1?DZF(OKUqjJ5@awPiGqsb6Y!WkRgm* z+}wP;d@=$8GS(VO8rCF({|6WZIT#oj7?~NB7?=bZnFSgDA7PMZU|?hgdKKhbC}3n_ zW?^Mx=iubx1}fMpz`(@F%*@2X%*x8b0#scKlxJWOWEE00bYv3_Ok`Io6ftU?xR68H zY2!iBpoX!XqN1l2cOC z(lau%ic3n%$}1|Xnp;}i+B-VCCQY6)b=ve9GiNPYykzOJeA&aSFc^aar4&0M~|O8efIpt%U2&ieg5+G+xH(oe}VkP$iNKo7TjlO z{t^WGi;0DWnS~wXFGi+vAZ8Y1VO2C_6LJh>Pb?HxGHT=yahkYr<3UbkKb$@|Xn~>>0YcG#2pxzX<@98RLln literal 0 HcmV?d00001 diff --git a/packages/react-scripts/fixtures/kitchensink/src/index.js b/packages/react-scripts/fixtures/kitchensink/src/index.js new file mode 100644 index 000000000..0ea36197b --- /dev/null +++ b/packages/react-scripts/fixtures/kitchensink/src/index.js @@ -0,0 +1,8 @@ +import React from 'react'; +import ReactDOM from 'react-dom'; +import App from './App'; + +ReactDOM.render( + , + document.getElementById('root') +); diff --git a/packages/react-scripts/fixtures/kitchensink/src/subfolder/lol.js b/packages/react-scripts/fixtures/kitchensink/src/subfolder/lol.js new file mode 100644 index 000000000..6c7375d54 --- /dev/null +++ b/packages/react-scripts/fixtures/kitchensink/src/subfolder/lol.js @@ -0,0 +1 @@ +module.exports = function() { return `haha` } diff --git a/packages/react-scripts/scripts/init.js b/packages/react-scripts/scripts/init.js index e438e5a2e..864005eca 100644 --- a/packages/react-scripts/scripts/init.js +++ b/packages/react-scripts/scripts/init.js @@ -12,7 +12,7 @@ var path = require('path'); var spawn = require('cross-spawn'); var chalk = require('chalk'); -module.exports = function(appPath, appName, verbose, originalDirectory) { +module.exports = function(appPath, appName, verbose, originalDirectory, template) { var ownPackageName = require(path.join(__dirname, '..', 'package.json')).name; var ownPath = path.join(appPath, 'node_modules', ownPackageName); var appPackage = require(path.join(appPath, 'package.json')); @@ -41,7 +41,13 @@ module.exports = function(appPath, appName, verbose, originalDirectory) { } // Copy the files for the user - fs.copySync(path.join(ownPath, 'template'), appPath); + var templatePath = template ? path.resolve(originalDirectory, template) : path.join(ownPath, 'template'); + if (fs.existsSync(templatePath)) { + fs.copySync(templatePath, appPath); + } else { + console.error('Could not locate supplied template: ' + chalk.green(templatePath)); + return; + } // Rename gitignore after the fact to prevent npm from renaming it to .npmignore // See: https://github.com/npm/npm/issues/1862 @@ -76,6 +82,16 @@ module.exports = function(appPath, appName, verbose, originalDirectory) { } args.push('react', 'react-dom'); + // Install additional template dependencies, if present + var templateDependenciesPath = path.join(appPath, '.template.dependencies.json'); + if (fs.existsSync(templateDependenciesPath)) { + var templateDependencies = require(templateDependenciesPath).dependencies; + args = args.concat(Object.keys(templateDependencies).map(function (key) { + return key + '@' + templateDependencies[key]; + })); + fs.unlinkSync(templateDependenciesPath); + } + console.log('Installing react and react-dom using ' + command + '...'); console.log(); diff --git a/tasks/e2e-installs.sh b/tasks/e2e-installs.sh new file mode 100755 index 000000000..f3c1d8d3b --- /dev/null +++ b/tasks/e2e-installs.sh @@ -0,0 +1,152 @@ +#!/bin/bash +# Copyright (c) 2015-present, Facebook, Inc. +# All rights reserved. +# +# This source code is licensed under the BSD-style license found in the +# LICENSE file in the root directory of this source tree. An additional grant +# of patent rights can be found in the PATENTS file in the same directory. + +# ****************************************************************************** +# This is an end-to-end test intended to run on CI. +# You can also run it locally but it's slow. +# ****************************************************************************** + +# Start in tasks/ even if run from root directory +cd "$(dirname "$0")" + +# CLI and app temporary locations +# http://unix.stackexchange.com/a/84980 +temp_cli_path=`mktemp -d 2>/dev/null || mktemp -d -t 'temp_cli_path'` +temp_app_path=`mktemp -d 2>/dev/null || mktemp -d -t 'temp_app_path'` + +function cleanup { + echo 'Cleaning up.' + cd $root_path + # Uncomment when snapshot testing is enabled by default: + # rm ./packages/react-scripts/template/src/__snapshots__/App.test.js.snap + rm -rf $temp_cli_path $temp_app_path +} + +# Error messages are redirected to stderr +function handle_error { + echo "$(basename $0): ERROR! An error was encountered executing line $1." 1>&2; + cleanup + echo 'Exiting with error.' 1>&2; + exit 1 +} + +function handle_exit { + cleanup + echo 'Exiting without error.' 1>&2; + exit +} + +function create_react_app { + node "$temp_cli_path"/node_modules/create-react-app/index.js $* +} + +# Exit the script with a helpful error message when any error is encountered +trap 'set +x; handle_error $LINENO $BASH_COMMAND' ERR + +# Cleanup before exit on any termination signal +trap 'set +x; handle_exit' SIGQUIT SIGTERM SIGINT SIGKILL SIGHUP + +# Echo every command being executed +set -x + +# Go to root +cd .. +root_path=$PWD + +npm install + +# If the node version is < 4, the script should just give an error. +if [ `node --version | sed -e 's/^v//' -e 's/\..\+//g'` -lt 4 ] +then + cd $temp_app_path + err_output=`node "$root_path"/packages/create-react-app/index.js test-node-version 2>&1 > /dev/null || echo ''` + [[ $err_output =~ You\ are\ running\ Node ]] && exit 0 || exit 1 +fi + +if [ "$USE_YARN" = "yes" ] +then + # Install Yarn so that the test can use it to install packages. + npm install -g yarn@0.17.10 # TODO: remove version when https://github.com/yarnpkg/yarn/issues/2142 is fixed. + yarn cache clean +fi + +# ****************************************************************************** +# First, pack and install create-react-app. +# ****************************************************************************** + +# Pack CLI +cd $root_path/packages/create-react-app +cli_path=$PWD/`npm pack` + +# Install the CLI in a temporary location +cd $temp_cli_path +npm install $cli_path + +# ****************************************************************************** +# Test --scripts-version with a version number +# ****************************************************************************** + +cd $temp_app_path +create_react_app --scripts-version=0.4.0 test-app-version-number +cd test-app-version-number + +# Check corresponding scripts version is installed. +test -e node_modules/react-scripts +grep '"version": "0.4.0"' node_modules/react-scripts/package.json + +# ****************************************************************************** +# Test --scripts-version with a tarball url +# ****************************************************************************** + +cd $temp_app_path +create_react_app --scripts-version=https://registry.npmjs.org/react-scripts/-/react-scripts-0.4.0.tgz test-app-tarball-url +cd test-app-tarball-url + +# Check corresponding scripts version is installed. +test -e node_modules/react-scripts +grep '"version": "0.4.0"' node_modules/react-scripts/package.json + +# ****************************************************************************** +# Test --scripts-version with a custom fork of react-scripts +# ****************************************************************************** + +cd $temp_app_path +create_react_app --scripts-version=react-scripts-fork test-app-fork +cd test-app-fork + +# Check corresponding scripts version is installed. +test -e node_modules/react-scripts-fork + +# ****************************************************************************** +# Test nested folder path as the project name +# ****************************************************************************** + +#Testing a path that exists +cd $temp_app_path +mkdir test-app-nested-paths-t1 +cd test-app-nested-paths-t1 +mkdir -p test-app-nested-paths-t1/aa/bb/cc/dd +create_react_app test-app-nested-paths-t1/aa/bb/cc/dd +cd test-app-nested-paths-t1/aa/bb/cc/dd +npm start -- --smoke-test + +#Testing a path that does not exist +cd $temp_app_path +create_react_app test-app-nested-paths-t2/aa/bb/cc/dd +cd test-app-nested-paths-t2/aa/bb/cc/dd +npm start -- --smoke-test + +#Testing a path that is half exists +cd $temp_app_path +mkdir -p test-app-nested-paths-t3/aa +create_react_app test-app-nested-paths-t3/aa/bb/cc/dd +cd test-app-nested-paths-t3/aa/bb/cc/dd +npm start -- --smoke-test + +# Cleanup +cleanup diff --git a/tasks/e2e-kitchensink.sh b/tasks/e2e-kitchensink.sh new file mode 100755 index 000000000..eecd6ed62 --- /dev/null +++ b/tasks/e2e-kitchensink.sh @@ -0,0 +1,218 @@ +#!/bin/bash +# Copyright (c) 2015-present, Facebook, Inc. +# All rights reserved. +# +# This source code is licensed under the BSD-style license found in the +# LICENSE file in the root directory of this source tree. An additional grant +# of patent rights can be found in the PATENTS file in the same directory. + +# ****************************************************************************** +# This is an end-to-end kitchensink test intended to run on CI. +# You can also run it locally but it's slow. +# ****************************************************************************** + +# Start in tasks/ even if run from root directory +cd "$(dirname "$0")" + +# CLI and app temporary locations +# http://unix.stackexchange.com/a/84980 +temp_cli_path=`mktemp -d 2>/dev/null || mktemp -d -t 'temp_cli_path'` +temp_app_path=`mktemp -d 2>/dev/null || mktemp -d -t 'temp_app_path'` + +function cleanup { + echo 'Cleaning up.' + cd $root_path + # Uncomment when snapshot testing is enabled by default: + # rm ./packages/react-scripts/template/src/__snapshots__/App.test.js.snap + rm -rf $temp_cli_path $temp_app_path +} + +# Error messages are redirected to stderr +function handle_error { + echo "$(basename $0): ERROR! An error was encountered executing line $1." 1>&2; + cleanup + echo 'Exiting with error.' 1>&2; + exit 1 +} + +function handle_exit { + cleanup + echo 'Exiting without error.' 1>&2; + exit +} + +function create_react_app { + node "$temp_cli_path"/node_modules/create-react-app/index.js $* +} + +# Exit the script with a helpful error message when any error is encountered +trap 'set +x; handle_error $LINENO $BASH_COMMAND' ERR + +# Cleanup before exit on any termination signal +trap 'set +x; handle_exit' SIGQUIT SIGTERM SIGINT SIGKILL SIGHUP + +# Echo every command being executed +set -x + +# Go to root +cd .. +root_path=$PWD + +npm install + +# If the node version is < 4, the script should just give an error. +if [ `node --version | sed -e 's/^v//' -e 's/\..\+//g'` -lt 4 ] +then + cd $temp_app_path + err_output=`node "$root_path"/packages/create-react-app/index.js test-node-version 2>&1 > /dev/null || echo ''` + [[ $err_output =~ You\ are\ running\ Node ]] && exit 0 || exit 1 +fi + +if [ "$USE_YARN" = "yes" ] +then + # Install Yarn so that the test can use it to install packages. + npm install -g yarn@0.17.10 # TODO: remove version when https://github.com/yarnpkg/yarn/issues/2142 is fixed. + yarn cache clean +fi + +# ****************************************************************************** +# First, pack react-scripts and create-react-app so we can use them. +# ****************************************************************************** + +# Pack CLI +cd $root_path/packages/create-react-app +cli_path=$PWD/`npm pack` + +# Go to react-scripts +cd $root_path/packages/react-scripts + +# Save package.json because we're going to touch it +cp package.json package.json.orig + +# Replace own dependencies (those in the `packages` dir) with the local paths +# of those packages. +node $root_path/tasks/replace-own-deps.js + +# Remove .npmignore so the test template is added +rm $root_path/packages/react-scripts/.npmignore + +# Finally, pack react-scripts +scripts_path=$root_path/packages/react-scripts/`npm pack` + +# Restore package.json +rm package.json +mv package.json.orig package.json + +# ****************************************************************************** +# Now that we have packed them, create a clean app folder and install them. +# ****************************************************************************** + +# Install the CLI in a temporary location +cd $temp_cli_path +npm install $cli_path + +# Install the app in a temporary location +cd $temp_app_path +create_react_app --scripts-version=$scripts_path --internal-testing-template=$root_path/packages/react-scripts/fixtures/kitchensink test-kitchensink + +# ****************************************************************************** +# Now that we used create-react-app to create an app depending on react-scripts, +# let's make sure all npm scripts are in the working state. +# ****************************************************************************** + +# Enter the app directory +cd test-kitchensink + +# Test the build +NODE_PATH=src REACT_APP_SHELL_ENV_MESSAGE=fromtheshell npm run build +# Check for expected output +test -e build/*.html +test -e build/static/js/main.*.js + +# Unit tests +REACT_APP_SHELL_ENV_MESSAGE=fromtheshell \ + CI=true \ + NODE_PATH=src \ + npm test -- --no-cache --testPathPattern="/src/" + +# Test "development" environment +tmp_server_log=`mktemp` +PORT=3001 \ + REACT_APP_SHELL_ENV_MESSAGE=fromtheshell \ + NODE_PATH=src \ + nohup npm start &>$tmp_server_log & +grep -q 'The app is running at:' <(tail -f $tmp_server_log) +E2E_URL="http://localhost:3001" \ + REACT_APP_SHELL_ENV_MESSAGE=fromtheshell \ + CI=true NODE_PATH=src \ + node node_modules/.bin/mocha --require babel-register --require babel-polyfill integration/*.test.js + +# Test "production" environment +E2E_FILE=./build/index.html \ + CI=true \ + NODE_PATH=src \ + node_modules/.bin/mocha --require babel-register --require babel-polyfill integration/*.js + +# Uncomment when snapshot testing is enabled by default: +# test -e src/__snapshots__/App.test.js.snap + +# Test the server +REACT_APP_SHELL_ENV_MESSAGE=fromtheshell NODE_PATH=src npm start -- --smoke-test +REACT_APP_SHELL_ENV_MESSAGE=fromtheshell HTTPS=true NODE_PATH=src npm start -- --smoke-test + +# ****************************************************************************** +# Finally, let's check that everything still works after ejecting. +# ****************************************************************************** + +# Eject... +echo yes | npm run eject + +# ...but still link to the local packages +npm link $root_path/packages/babel-preset-react-app +npm link $root_path/packages/eslint-config-react-app +npm link $root_path/packages/react-dev-utils +npm link $root_path/packages/react-scripts + +# ...and we need to remove template's .babelrc +rm .babelrc + +# Test the build +NODE_PATH=src REACT_APP_SHELL_ENV_MESSAGE=fromtheshell npm run build +# Check for expected output +test -e build/*.html +test -e build/static/js/main.*.js + +# Unit tests +REACT_APP_SHELL_ENV_MESSAGE=fromtheshell \ + CI=true \ + NODE_PATH=src \ + npm test -- --no-cache --testPathPattern="/src/" + +# Test "development" environment +tmp_server_log=`mktemp` +PORT=3002 \ + REACT_APP_SHELL_ENV_MESSAGE=fromtheshell \ + NODE_PATH=src \ + nohup npm start &>$tmp_server_log & +grep -q 'The app is running at:' <(tail -f $tmp_server_log) +E2E_URL="http://localhost:3002" \ + REACT_APP_SHELL_ENV_MESSAGE=fromtheshell \ + CI=true NODE_PATH=src \ + NODE_ENV=production \ + node_modules/.bin/mocha --require babel-register --require babel-polyfill integration/*.js + +# Test "production" environment +E2E_FILE=./build/index.html \ + CI=true \ + NODE_ENV=production \ + NODE_PATH=src \ + node_modules/.bin/mocha --require babel-register --require babel-polyfill integration/*.js + +# Uncomment when snapshot testing is enabled by default: +# test -e src/__snapshots__/App.test.js.snap + +# Test the server +REACT_APP_SHELL_ENV_MESSAGE=fromtheshell NODE_PATH=src npm start -- --smoke-test + +# Cleanup +cleanup diff --git a/tasks/e2e.sh b/tasks/e2e-simple.sh similarity index 73% rename from tasks/e2e.sh rename to tasks/e2e-simple.sh index 27cd0ae45..f8baf743d 100755 --- a/tasks/e2e.sh +++ b/tasks/e2e-simple.sh @@ -195,66 +195,6 @@ npm test -- --watch=no # Test the server npm start -- --smoke-test -# ****************************************************************************** -# Test --scripts-version with a version number -# ****************************************************************************** - -cd $temp_app_path -create_react_app --scripts-version=0.4.0 test-app-version-number -cd test-app-version-number - -# Check corresponding scripts version is installed. -test -e node_modules/react-scripts -grep '"version": "0.4.0"' node_modules/react-scripts/package.json - -# ****************************************************************************** -# Test --scripts-version with a tarball url -# ****************************************************************************** - -cd $temp_app_path -create_react_app --scripts-version=https://registry.npmjs.org/react-scripts/-/react-scripts-0.4.0.tgz test-app-tarball-url -cd test-app-tarball-url - -# Check corresponding scripts version is installed. -test -e node_modules/react-scripts -grep '"version": "0.4.0"' node_modules/react-scripts/package.json - -# ****************************************************************************** -# Test --scripts-version with a custom fork of react-scripts -# ****************************************************************************** - -cd $temp_app_path -create_react_app --scripts-version=react-scripts-fork test-app-fork -cd test-app-fork - -# Check corresponding scripts version is installed. -test -e node_modules/react-scripts-fork - -# ****************************************************************************** -# Test nested folder path as the project name -# ****************************************************************************** - -#Testing a path that exists -cd $temp_app_path -mkdir test-app-nested-paths-t1 -cd test-app-nested-paths-t1 -mkdir -p test-app-nested-paths-t1/aa/bb/cc/dd -create_react_app test-app-nested-paths-t1/aa/bb/cc/dd -cd test-app-nested-paths-t1/aa/bb/cc/dd -npm start -- --smoke-test - -#Testing a path that does not exist -cd $temp_app_path -create_react_app test-app-nested-paths-t2/aa/bb/cc/dd -cd test-app-nested-paths-t2/aa/bb/cc/dd -npm start -- --smoke-test - -#Testing a path that is half exists -cd $temp_app_path -mkdir -p test-app-nested-paths-t3/aa -create_react_app test-app-nested-paths-t3/aa/bb/cc/dd -cd test-app-nested-paths-t3/aa/bb/cc/dd -npm start -- --smoke-test # Cleanup cleanup From adce379187a57f2e16321c28419594c7f56a5421 Mon Sep 17 00:00:00 2001 From: soo Date: Tue, 24 Jan 2017 04:47:40 +0900 Subject: [PATCH 16/47] replace two space syntax with
tag (#1393) for consistency :) --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 2c387f6cf..ed755a202 100644 --- a/README.md +++ b/README.md @@ -82,7 +82,7 @@ You will see the build errors and lint warnings in the console. ### `npm test` -Runs the test watcher in an interactive mode. +Runs the test watcher in an interactive mode.
By default, runs tests related to files changes since the last commit. [Read more about testing.](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#running-tests) @@ -205,7 +205,7 @@ We are grateful to the authors of existing related projects for their ideas and ## Alternatives -If you don’t agree with the choices made in this project, you might want to explore alternatives with different tradeoffs. +If you don’t agree with the choices made in this project, you might want to explore alternatives with different tradeoffs.
Some of the more popular and actively maintained ones are: * [insin/nwb](https://github.com/insin/nwb) From 65bde543061e944d797272ea9a6bd0c6347303e3 Mon Sep 17 00:00:00 2001 From: Vasiliy Taranov Date: Mon, 23 Jan 2017 23:22:55 +0300 Subject: [PATCH 17/47] Add causes of dev server not detecting changes (#1422) * Add causes of dev server not detecting changes Add causes of `npm start` not detecting changes to Troubleshooting chapter of User Guide * Reworded slightly * Update README.md --- packages/react-scripts/template/README.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/packages/react-scripts/template/README.md b/packages/react-scripts/template/README.md index e55e6c9f4..4c6119ca6 100644 --- a/packages/react-scripts/template/README.md +++ b/packages/react-scripts/template/README.md @@ -62,6 +62,7 @@ You can find the most recent version of this guide [here](https://github.com/fac - [S3 and CloudFront](#s3-and-cloudfront) - [Surge](#surge) - [Troubleshooting](#troubleshooting) + - [`npm start` doesn’t detect changes](#npm-start-doesnt-detect-changes) - [`npm test` hangs on macOS Sierra](#npm-test-hangs-on-macos-sierra) - [`npm run build` silently fails](#npm-run-build-silently-fails) - [`npm run build` fails on Heroku](#npm-run-build-fails-on-heroku) @@ -1253,6 +1254,19 @@ Note that in order to support routers that use HTML5 `pushState` API, you may wa ## Troubleshooting +### `npm start` doesn’t detect changes + +When you save a file while `npm start` is running, the browser should refresh with the updated code.
+If this doesn’t happen, try one of the following workarounds: + +* If your project is in a Dropbox folder, try moving it out. +* If the watcher doesn’t see a file called `index.js` and you’re referencing it by the folder name, you [need to restart the watcher](https://github.com/facebookincubator/create-react-app/issues/1164) due to a Webpack bug. +* Some editors like Vim and IntelliJ have a “safe write” feature that currently breaks the watcher. You will need to disable it. Follow the instructions in [“Working with editors supporting safe write”](https://webpack.github.io/docs/webpack-dev-server.html#working-with-editors-ides-supporting-safe-write). +* If your project path contains parentheses, try moving the project to a path without them. This is caused by a [Webpack watcher bug](https://github.com/webpack/watchpack/issues/42). +* On Linux and OS X, you might need to [tweak system settings](https://webpack.github.io/docs/troubleshooting.html#not-enough-watchers) to allow more watchers. + +If none of these solutions help please leave a comment [in this thread](https://github.com/facebookincubator/create-react-app/issues/659). + ### `npm test` hangs on macOS Sierra If you run `npm test` and the console gets stuck after printing `react-scripts test --env=jsdom` to the console there might be a problem with your [Watchman](https://facebook.github.io/watchman/) installation as described in [facebookincubator/create-react-app#713](https://github.com/facebookincubator/create-react-app/issues/713). From 3bb31ccb0f7230292611d0e031321a2662e3083a Mon Sep 17 00:00:00 2001 From: Alex Driaguine Date: Tue, 24 Jan 2017 12:12:01 +0100 Subject: [PATCH 18/47] Added links to tutorials for integrating cra with an api backend (#1437) * Added Rails link to User Guide * docs: unify sections for rails and node backend integration * docs: fix faulty link and indentation --- README.md | 2 +- packages/react-scripts/template/README.md | 18 +++++++++++++++--- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index ed755a202..85a23174d 100644 --- a/README.md +++ b/README.md @@ -116,7 +116,7 @@ The [User Guide](https://github.com/facebookincubator/create-react-app/blob/mast - [Adding Flow](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#adding-flow) - [Adding Custom Environment Variables](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#adding-custom-environment-variables) - [Can I Use Decorators?](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#can-i-use-decorators) -- [Integrating with a Node Backend](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#integrating-with-a-node-backend) +- [Integrating with an API Backend](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#integrating-with-an-api-backend) - [Proxying API Requests in Development](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#proxying-api-requests-in-development) - [Using HTTPS in Development](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#using-https-in-development) - [Generating Dynamic `` Tags on the Server](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#generating-dynamic-meta-tags-on-the-server) diff --git a/packages/react-scripts/template/README.md b/packages/react-scripts/template/README.md index 4c6119ca6..141d800b6 100644 --- a/packages/react-scripts/template/README.md +++ b/packages/react-scripts/template/README.md @@ -30,7 +30,9 @@ You can find the most recent version of this guide [here](https://github.com/fac - [Adding Flow](#adding-flow) - [Adding Custom Environment Variables](#adding-custom-environment-variables) - [Can I Use Decorators?](#can-i-use-decorators) -- [Integrating with a Node Backend](#integrating-with-a-node-backend) +- [Integrating with an API Backend](#integrating-with-an-api-backend) + - [Node](#node) + - [Ruby on Rails](#ruby-on-rails) - [Proxying API Requests in Development](#proxying-api-requests-in-development) - [Using HTTPS in Development](#using-https-in-development) - [Generating Dynamic `` Tags on the Server](#generating-dynamic-meta-tags-on-the-server) @@ -603,9 +605,19 @@ Please refer to these two threads for reference: Create React App will add decorator support when the specification advances to a stable stage. -## Integrating with a Node Backend +## Integrating with an API Backend -Check out [this tutorial](https://www.fullstackreact.com/articles/using-create-react-app-with-a-server/) for instructions on integrating an app with a Node backend running on another port, and using `fetch()` to access it. You can find the companion GitHub repository [here](https://github.com/fullstackreact/food-lookup-demo). +These tutorials will help you to integrate your app with an API backend running on another port, +using `fetch()` to access it. + +### Node +Check out [this tutorial](https://www.fullstackreact.com/articles/using-create-react-app-with-a-server/). +You can find the companion GitHub repository [here](https://github.com/fullstackreact/food-lookup-demo). + +### Ruby on Rails + +Check out [this tutorial](https://www.fullstackreact.com/articles/how-to-get-create-react-app-to-work-with-your-rails-api/). +You can find the companion GitHub repository [here](https://github.com/fullstackreact/food-lookup-demo-rails). ## Proxying API Requests in Development From dbb7ffe6a50e5c231d37a32ec7274660c4e15aed Mon Sep 17 00:00:00 2001 From: Jonathan Kim Date: Tue, 24 Jan 2017 17:20:57 +0000 Subject: [PATCH 19/47] Added babel-runtime dependency to deduplicate dependencies when using yarn (#1441) --- packages/react-scripts/package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/react-scripts/package.json b/packages/react-scripts/package.json index 38a6f86db..fdc384f52 100644 --- a/packages/react-scripts/package.json +++ b/packages/react-scripts/package.json @@ -28,6 +28,7 @@ "babel-eslint": "7.1.1", "babel-jest": "18.0.0", "babel-loader": "6.2.10", + "babel-runtime": "^6.20.0", "babel-preset-react-app": "^2.0.1", "case-sensitive-paths-webpack-plugin": "1.1.4", "chalk": "1.1.3", From da321b2433f84401015ce566c597beaf7bd6948c Mon Sep 17 00:00:00 2001 From: Dan Abramov Date: Tue, 24 Jan 2017 23:39:42 +0000 Subject: [PATCH 20/47] Bump Jest version (#1432) --- packages/react-scripts/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-scripts/package.json b/packages/react-scripts/package.json index fdc384f52..c3f7d2bdd 100644 --- a/packages/react-scripts/package.json +++ b/packages/react-scripts/package.json @@ -51,7 +51,7 @@ "gzip-size": "3.0.0", "html-webpack-plugin": "2.24.0", "http-proxy-middleware": "0.17.2", - "jest": "18.0.0", + "jest": "18.1.0", "json-loader": "0.5.4", "object-assign": "4.1.0", "postcss-loader": "1.0.0", From dd788b672aa0c4a30a0db82968fe44d312f720b4 Mon Sep 17 00:00:00 2001 From: Anthony F Date: Thu, 26 Jan 2017 11:40:12 -0700 Subject: [PATCH 21/47] Readme: Removes experimental from Jest snapshot (#1453) Per final comment in #372 `Snapshot rendering should actually be pretty stable / useable after React 15.4.1. See this post for more info.` --- packages/react-scripts/template/README.md | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/packages/react-scripts/template/README.md b/packages/react-scripts/template/README.md index 141d800b6..0eb5cda38 100644 --- a/packages/react-scripts/template/README.md +++ b/packages/react-scripts/template/README.md @@ -48,7 +48,7 @@ You can find the most recent version of this guide [here](https://github.com/fac - [Coverage Reporting](#coverage-reporting) - [Continuous Integration](#continuous-integration) - [Disabling jsdom](#disabling-jsdom) - - [Experimental Snapshot Testing](#experimental-snapshot-testing) + - [Snapshot Testing](#snapshot-testing) - [Editor Integration](#editor-integration) - [Developing Components in Isolation](#developing-components-in-isolation) - [Making a Progressive Web App](#making-a-progressive-web-app) @@ -941,13 +941,11 @@ In contrast, **jsdom is not needed** for the following APIs: * [`TestUtils.createRenderer()`](https://facebook.github.io/react/docs/test-utils.html#shallow-rendering) (shallow rendering) * [`shallow()`](http://airbnb.io/enzyme/docs/api/shallow.html) in [Enzyme](http://airbnb.io/enzyme/index.html) -Finally, jsdom is also not needed for [snapshot testing](http://facebook.github.io/jest/blog/2016/07/27/jest-14.html). Longer term, this is the direction we are interested in exploring, but snapshot testing is [not fully baked yet](https://github.com/facebookincubator/create-react-app/issues/372) so we don’t officially encourage its usage yet. +Finally, jsdom is also not needed for [snapshot testing](http://facebook.github.io/jest/blog/2016/07/27/jest-14.html). -### Experimental Snapshot Testing +### Snapshot Testing -Snapshot testing is a new feature of Jest that automatically generates text snapshots of your components and saves them on the disk so if the UI output changes, you get notified without manually writing any assertions on the component output. - -This feature is experimental and still [has major usage issues](https://github.com/facebookincubator/create-react-app/issues/372) so we only encourage you to use it if you like experimental technology. We intend to gradually improve it over time and eventually offer it as the default solution for testing React components, but this will take time. [Read more about snapshot testing.](http://facebook.github.io/jest/blog/2016/07/27/jest-14.html) +Snapshot testing is a feature of Jest that automatically generates text snapshots of your components and saves them on the disk so if the UI output changes, you get notified without manually writing any assertions on the component output. [Read more about snapshot testing.](http://facebook.github.io/jest/blog/2016/07/27/jest-14.html) ### Editor Integration From bc2fc8089816161b7e8b08b3c529cdb8e3344009 Mon Sep 17 00:00:00 2001 From: creynders Date: Fri, 27 Jan 2017 17:26:35 +0100 Subject: [PATCH 22/47] eject: Additionally remove `react-scripts` from dependencies (#1458) ATM if react-scripts is (erroneously) declared in `dependencies` instead of `devDependencies` or isn't declared at all, the `eject` script will fail half-way. This change makes it more robust, react-scripts will be removed from either, if present. --- packages/react-scripts/scripts/eject.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/packages/react-scripts/scripts/eject.js b/packages/react-scripts/scripts/eject.js index 86dbc15c3..b8f9d3131 100644 --- a/packages/react-scripts/scripts/eject.js +++ b/packages/react-scripts/scripts/eject.js @@ -93,8 +93,14 @@ prompt( console.log(cyan('Updating the dependencies')); var ownPackageName = ownPackage.name; - console.log(' Removing ' + cyan(ownPackageName) + ' from devDependencies'); - delete appPackage.devDependencies[ownPackageName]; + if (appPackage.devDependencies[ownPackageName]) { + console.log(' Removing ' + cyan(ownPackageName) + ' from devDependencies'); + delete appPackage.devDependencies[ownPackageName]; + } + if (appPackage.dependencies[ownPackageName]) { + console.log(' Removing ' + cyan(ownPackageName) + ' from dependencies'); + delete appPackage.dependencies[ownPackageName]; + } Object.keys(ownPackage.dependencies).forEach(function (key) { // For some reason optionalDependencies end up in dependencies after install From 1d586aaf311e2e482c7ff2acc0fc051907a60039 Mon Sep 17 00:00:00 2001 From: Fabrizio Castellarin Date: Mon, 30 Jan 2017 20:24:12 +0100 Subject: [PATCH 23/47] E2e jsdom fix (#1470) * E2E: run tests when react is ready * Entangle e2e with callbacks * Remove unused e2e lines --- .../kitchensink/.template.dependencies.json | 2 +- .../kitchensink/integration/initDOM.js | 23 ++++--------- .../fixtures/kitchensink/src/App.js | 24 +++++++++++++- .../kitchensink/src/features/env/NodePath.js | 7 +++- .../src/features/syntax/ArrayDestructuring.js | 7 +++- .../src/features/syntax/ArraySpread.js | 7 +++- .../src/features/syntax/AsyncAwait.js | 7 +++- .../src/features/syntax/ComputedProperties.js | 7 +++- .../features/syntax/CustomInterpolation.js | 7 +++- .../src/features/syntax/DefaultParameters.js | 7 +++- .../features/syntax/DestructuringAndAwait.js | 7 +++- .../src/features/syntax/Generators.js | 7 +++- .../features/syntax/ObjectDestructuring.js | 7 +++- .../src/features/syntax/ObjectSpread.js | 7 +++- .../src/features/syntax/Promises.js | 7 +++- .../src/features/syntax/RestAndDefault.js | 7 +++- .../src/features/syntax/RestParameters.js | 7 +++- .../features/syntax/TemplateInterpolation.js | 7 +++- tasks/e2e-installs.sh | 10 ------ tasks/e2e-kitchensink.sh | 32 ++----------------- 20 files changed, 124 insertions(+), 72 deletions(-) diff --git a/packages/react-scripts/fixtures/kitchensink/.template.dependencies.json b/packages/react-scripts/fixtures/kitchensink/.template.dependencies.json index 8adac4570..62e0d34a3 100644 --- a/packages/react-scripts/fixtures/kitchensink/.template.dependencies.json +++ b/packages/react-scripts/fixtures/kitchensink/.template.dependencies.json @@ -1,7 +1,7 @@ { "dependencies": { "babel-preset-latest": "6.16.0", - "babel-register": "6.18.0", + "babel-register": "6.22.0", "babel-polyfill": "6.20.0", "chai": "3.5.0", "jsdom": "9.8.3", diff --git a/packages/react-scripts/fixtures/kitchensink/integration/initDOM.js b/packages/react-scripts/fixtures/kitchensink/integration/initDOM.js index c04e60d4c..21e9c701a 100644 --- a/packages/react-scripts/fixtures/kitchensink/integration/initDOM.js +++ b/packages/react-scripts/fixtures/kitchensink/integration/initDOM.js @@ -5,9 +5,6 @@ const path = require('path') let getMarkup let resourceLoader -// this value could be tweaked in order to let the resource -// retriever get every file and jsdom execute react -let timeToWaitForJsToExecute if (process.env.E2E_FILE) { const file = path.isAbsolute(process.env.E2E_FILE) @@ -21,8 +18,6 @@ if (process.env.E2E_FILE) { null, fs.readFileSync(path.join(path.dirname(file), resource.url.pathname), 'utf8') ) - - timeToWaitForJsToExecute = 0 } else if (process.env.E2E_URL) { getMarkup = () => new Promise(resolve => { http.get(process.env.E2E_URL, (res) => { @@ -32,11 +27,7 @@ if (process.env.E2E_FILE) { }) }) - resourceLoader = (resource, callback) => { - return resource.defaultFetch(callback) - } - - timeToWaitForJsToExecute = 100 + resourceLoader = (resource, callback) => resource.defaultFetch(callback) } else { it.only('can run jsdom (at least one of "E2E_FILE" or "E2E_URL" environment variables must be provided)', () => { expect(new Error('This isn\'t the error you are looking for.')).toBeUndefined() @@ -47,16 +38,16 @@ export default feature => new Promise(async resolve => { const markup = await getMarkup() const host = process.env.E2E_URL || 'http://localhost:3000' const doc = jsdom.jsdom(markup, { - features : { - FetchExternalResources : ['script', 'css'], - ProcessExternalResources : ['script'], + features: { + FetchExternalResources: ['script', 'css'], + ProcessExternalResources: ['script'], }, + created: (_, win) => win.addEventListener('ReactFeatureDidMount', () => resolve(doc), true), + deferClose: true, resourceLoader, url: `${host}#${feature}`, virtualConsole: jsdom.createVirtualConsole().sendTo(console), }) - doc.defaultView.addEventListener('load', () => { - setTimeout(() => resolve(doc), timeToWaitForJsToExecute) - }, false) + doc.close() }) diff --git a/packages/react-scripts/fixtures/kitchensink/src/App.js b/packages/react-scripts/fixtures/kitchensink/src/App.js index 66cd45541..04641535a 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/App.js +++ b/packages/react-scripts/fixtures/kitchensink/src/App.js @@ -1,5 +1,27 @@ import React from 'react'; +class BuiltEmitter extends React.Component { + constructor(props) { + super(props) + + this.callWhenDone = done => done(); + } + + componentDidMount() { + this.callWhenDone(() => document.dispatchEvent(new Event('ReactFeatureDidMount'))); + } + + render() { + const feature = React.cloneElement(React.Children.only(this.props.children), { + setCallWhenDone: done => { + this.callWhenDone = done; + } + }); + + return
{feature}
; + } +} + class App extends React.Component { constructor(props) { super(props); @@ -96,7 +118,7 @@ class App extends React.Component { render() { const Feature = this.state.feature; - return Feature ? : null; + return Feature ? : null; } } diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/env/NodePath.js b/packages/react-scripts/fixtures/kitchensink/src/features/env/NodePath.js index 2d2f474f1..1644b49ca 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/features/env/NodePath.js +++ b/packages/react-scripts/fixtures/kitchensink/src/features/env/NodePath.js @@ -5,12 +5,17 @@ export default class extends React.Component { constructor(props) { super(props); + this.done = () => {}; + this.props.setCallWhenDone && this.props.setCallWhenDone((done) => { + this.done = done; + }); + this.state = { users: [] }; } async componentDidMount() { const users = load(); - this.setState({ users }); + this.setState({ users }, () => this.done()); } render() { diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ArrayDestructuring.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ArrayDestructuring.js index 38e351209..1ee751af7 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ArrayDestructuring.js +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ArrayDestructuring.js @@ -13,12 +13,17 @@ export default class extends React.Component { constructor(props) { super(props); + this.done = () => {}; + this.props.setCallWhenDone && this.props.setCallWhenDone((done) => { + this.done = done; + }); + this.state = { users: [] }; } async componentDidMount() { const users = load(); - this.setState({ users }); + this.setState({ users }, () => this.done()); } render() { diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ArraySpread.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ArraySpread.js index d7d9a4591..be6311980 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ArraySpread.js +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ArraySpread.js @@ -13,12 +13,17 @@ export default class extends React.Component { constructor(props) { super(props); + this.done = () => {}; + this.props.setCallWhenDone && this.props.setCallWhenDone((done) => { + this.done = done; + }); + this.state = { users: [] }; } async componentDidMount() { const users = load([{ id: 42, name: '42' }]); - this.setState({ users }); + this.setState({ users }, () => this.done()); } render() { diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/AsyncAwait.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/AsyncAwait.js index 01c686405..84dd42e0a 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/AsyncAwait.js +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/AsyncAwait.js @@ -13,12 +13,17 @@ export default class extends React.Component { constructor(props) { super(props); + this.done = () => {}; + this.props.setCallWhenDone && this.props.setCallWhenDone((done) => { + this.done = done; + }); + this.state = { users: [] }; } async componentDidMount() { const users = await load(); - this.setState({ users }); + this.setState({ users }, () => this.done()); } render() { diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ComputedProperties.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ComputedProperties.js index c7a24cb7f..b6111a149 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ComputedProperties.js +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ComputedProperties.js @@ -13,12 +13,17 @@ export default class extends React.Component { constructor(props) { super(props); + this.done = () => {}; + this.props.setCallWhenDone && this.props.setCallWhenDone((done) => { + this.done = done; + }); + this.state = { users: [] }; } async componentDidMount() { const users = load('user_'); - this.setState({ users }); + this.setState({ users }, () => this.done()); } render() { diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/CustomInterpolation.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/CustomInterpolation.js index 032989683..8184d3bd4 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/CustomInterpolation.js +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/CustomInterpolation.js @@ -18,12 +18,17 @@ export default class extends React.Component { constructor(props) { super(props); + this.done = () => {}; + this.props.setCallWhenDone && this.props.setCallWhenDone((done) => { + this.done = done; + }); + this.state = { users: [] }; } async componentDidMount() { const users = load(); - this.setState({ users }); + this.setState({ users }, () => this.done()); } render() { diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/DefaultParameters.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/DefaultParameters.js index 3a676358a..637a239d7 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/DefaultParameters.js +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/DefaultParameters.js @@ -13,12 +13,17 @@ export default class extends React.Component { constructor(props) { super(props); + this.done = () => {}; + this.props.setCallWhenDone && this.props.setCallWhenDone((done) => { + this.done = done; + }); + this.state = { users: [] }; } async componentDidMount() { const users = load(); - this.setState({ users }); + this.setState({ users }, () => this.done()); } render() { diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/DestructuringAndAwait.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/DestructuringAndAwait.js index 291ed3bcc..e28e0bb36 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/DestructuringAndAwait.js +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/DestructuringAndAwait.js @@ -13,12 +13,17 @@ export default class extends React.Component { constructor(props) { super(props); + this.done = () => {}; + this.props.setCallWhenDone && this.props.setCallWhenDone((done) => { + this.done = done; + }); + this.state = { users: [] }; } async componentDidMount() { const { users } = await load(); - this.setState({ users }); + this.setState({ users }, () => this.done()); } render() { diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/Generators.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/Generators.js index 4f2fc95ca..a20fc19b7 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/Generators.js +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/Generators.js @@ -12,6 +12,11 @@ export default class extends React.Component { constructor(props) { super(props); + this.done = () => {}; + this.props.setCallWhenDone && this.props.setCallWhenDone((done) => { + this.done = done; + }); + this.state = { users: [] }; } @@ -20,7 +25,7 @@ export default class extends React.Component { for (let user of load(4)) { users.push(user); } - this.setState({ users }); + this.setState({ users }, () => this.done()); } render() { diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ObjectDestructuring.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ObjectDestructuring.js index c6edbee27..db377cee5 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ObjectDestructuring.js +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ObjectDestructuring.js @@ -13,12 +13,17 @@ export default class extends React.Component { constructor(props) { super(props); + this.done = () => {}; + this.props.setCallWhenDone && this.props.setCallWhenDone((done) => { + this.done = done; + }); + this.state = { users: [] }; } async componentDidMount() { const users = load(); - this.setState({ users }); + this.setState({ users }, () => this.done()); } render() { diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ObjectSpread.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ObjectSpread.js index ca41004f9..72356fb94 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ObjectSpread.js +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ObjectSpread.js @@ -13,12 +13,17 @@ export default class extends React.Component { constructor(props) { super(props); + this.done = () => {}; + this.props.setCallWhenDone && this.props.setCallWhenDone((done) => { + this.done = done; + }); + this.state = { users: [] }; } async componentDidMount() { const users = load({ age: 42 }); - this.setState({ users }); + this.setState({ users }, () => this.done()); } render() { diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/Promises.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/Promises.js index c0e13c81e..9eb8c20f7 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/Promises.js +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/Promises.js @@ -13,12 +13,17 @@ export default class extends React.Component { constructor(props) { super(props); + this.done = () => {}; + this.props.setCallWhenDone && this.props.setCallWhenDone((done) => { + this.done = done; + }); + this.state = { users: [] }; } componentDidMount() { load().then(users => { - this.setState({ users }); + this.setState({ users }, () => this.done()); }); } diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/RestAndDefault.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/RestAndDefault.js index a977e8c83..94b759808 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/RestAndDefault.js +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/RestAndDefault.js @@ -13,12 +13,17 @@ export default class extends React.Component { constructor(props) { super(props); + this.done = () => {}; + this.props.setCallWhenDone && this.props.setCallWhenDone((done) => { + this.done = done; + }); + this.state = { users: [] }; } async componentDidMount() { const users = load(); - this.setState({ users }); + this.setState({ users }, () => this.done()); } render() { diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/RestParameters.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/RestParameters.js index 9dcc33fa0..c1cd63e88 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/RestParameters.js +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/RestParameters.js @@ -13,12 +13,17 @@ export default class extends React.Component { constructor(props) { super(props); + this.done = () => {}; + this.props.setCallWhenDone && this.props.setCallWhenDone((done) => { + this.done = done; + }); + this.state = { users: [] }; } async componentDidMount() { const users = load({ id: 0, user: { id: 42, name: '42' } }); - this.setState({ users }); + this.setState({ users }, () => this.done()); } render() { diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/TemplateInterpolation.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/TemplateInterpolation.js index 505ee6173..33b004722 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/TemplateInterpolation.js +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/TemplateInterpolation.js @@ -13,12 +13,17 @@ export default class extends React.Component { constructor(props) { super(props); + this.done = () => {}; + this.props.setCallWhenDone && this.props.setCallWhenDone((done) => { + this.done = done; + }); + this.state = { users: [] }; } async componentDidMount() { const users = load('user_'); - this.setState({ users }); + this.setState({ users }, () => this.done()); } render() { diff --git a/tasks/e2e-installs.sh b/tasks/e2e-installs.sh index f3c1d8d3b..7bb4c0392 100755 --- a/tasks/e2e-installs.sh +++ b/tasks/e2e-installs.sh @@ -22,8 +22,6 @@ temp_app_path=`mktemp -d 2>/dev/null || mktemp -d -t 'temp_app_path'` function cleanup { echo 'Cleaning up.' cd $root_path - # Uncomment when snapshot testing is enabled by default: - # rm ./packages/react-scripts/template/src/__snapshots__/App.test.js.snap rm -rf $temp_cli_path $temp_app_path } @@ -60,14 +58,6 @@ root_path=$PWD npm install -# If the node version is < 4, the script should just give an error. -if [ `node --version | sed -e 's/^v//' -e 's/\..\+//g'` -lt 4 ] -then - cd $temp_app_path - err_output=`node "$root_path"/packages/create-react-app/index.js test-node-version 2>&1 > /dev/null || echo ''` - [[ $err_output =~ You\ are\ running\ Node ]] && exit 0 || exit 1 -fi - if [ "$USE_YARN" = "yes" ] then # Install Yarn so that the test can use it to install packages. diff --git a/tasks/e2e-kitchensink.sh b/tasks/e2e-kitchensink.sh index eecd6ed62..892230ab7 100755 --- a/tasks/e2e-kitchensink.sh +++ b/tasks/e2e-kitchensink.sh @@ -22,8 +22,6 @@ temp_app_path=`mktemp -d 2>/dev/null || mktemp -d -t 'temp_app_path'` function cleanup { echo 'Cleaning up.' cd $root_path - # Uncomment when snapshot testing is enabled by default: - # rm ./packages/react-scripts/template/src/__snapshots__/App.test.js.snap rm -rf $temp_cli_path $temp_app_path } @@ -60,14 +58,6 @@ root_path=$PWD npm install -# If the node version is < 4, the script should just give an error. -if [ `node --version | sed -e 's/^v//' -e 's/\..\+//g'` -lt 4 ] -then - cd $temp_app_path - err_output=`node "$root_path"/packages/create-react-app/index.js test-node-version 2>&1 > /dev/null || echo ''` - [[ $err_output =~ You\ are\ running\ Node ]] && exit 0 || exit 1 -fi - if [ "$USE_YARN" = "yes" ] then # Install Yarn so that the test can use it to install packages. @@ -93,9 +83,6 @@ cp package.json package.json.orig # of those packages. node $root_path/tasks/replace-own-deps.js -# Remove .npmignore so the test template is added -rm $root_path/packages/react-scripts/.npmignore - # Finally, pack react-scripts scripts_path=$root_path/packages/react-scripts/`npm pack` @@ -151,14 +138,7 @@ E2E_URL="http://localhost:3001" \ E2E_FILE=./build/index.html \ CI=true \ NODE_PATH=src \ - node_modules/.bin/mocha --require babel-register --require babel-polyfill integration/*.js - -# Uncomment when snapshot testing is enabled by default: -# test -e src/__snapshots__/App.test.js.snap - -# Test the server -REACT_APP_SHELL_ENV_MESSAGE=fromtheshell NODE_PATH=src npm start -- --smoke-test -REACT_APP_SHELL_ENV_MESSAGE=fromtheshell HTTPS=true NODE_PATH=src npm start -- --smoke-test + node_modules/.bin/mocha --require babel-register --require babel-polyfill integration/*.test.js # ****************************************************************************** # Finally, let's check that everything still works after ejecting. @@ -199,20 +179,14 @@ E2E_URL="http://localhost:3002" \ REACT_APP_SHELL_ENV_MESSAGE=fromtheshell \ CI=true NODE_PATH=src \ NODE_ENV=production \ - node_modules/.bin/mocha --require babel-register --require babel-polyfill integration/*.js + node_modules/.bin/mocha --require babel-register --require babel-polyfill integration/*.test.js # Test "production" environment E2E_FILE=./build/index.html \ CI=true \ NODE_ENV=production \ NODE_PATH=src \ - node_modules/.bin/mocha --require babel-register --require babel-polyfill integration/*.js - -# Uncomment when snapshot testing is enabled by default: -# test -e src/__snapshots__/App.test.js.snap - -# Test the server -REACT_APP_SHELL_ENV_MESSAGE=fromtheshell NODE_PATH=src npm start -- --smoke-test + node_modules/.bin/mocha --require babel-register --require babel-polyfill integration/*.test.js # Cleanup cleanup From 8964dd6f134a71494a3271c26e017717e7941e9b Mon Sep 17 00:00:00 2001 From: Valerii Date: Mon, 30 Jan 2017 22:28:16 +0300 Subject: [PATCH 24/47] - import expect and expect flow (#1463) - code style --- .../react-scripts/fixtures/kitchensink/integration/initDOM.js | 3 ++- packages/react-scripts/fixtures/kitchensink/src/App.js | 3 +-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/react-scripts/fixtures/kitchensink/integration/initDOM.js b/packages/react-scripts/fixtures/kitchensink/integration/initDOM.js index 21e9c701a..cec022274 100644 --- a/packages/react-scripts/fixtures/kitchensink/integration/initDOM.js +++ b/packages/react-scripts/fixtures/kitchensink/integration/initDOM.js @@ -2,6 +2,7 @@ const fs = require('fs') const http = require('http') const jsdom = require('jsdom') const path = require('path') +const { expect } = require('chai') let getMarkup let resourceLoader @@ -30,7 +31,7 @@ if (process.env.E2E_FILE) { resourceLoader = (resource, callback) => resource.defaultFetch(callback) } else { it.only('can run jsdom (at least one of "E2E_FILE" or "E2E_URL" environment variables must be provided)', () => { - expect(new Error('This isn\'t the error you are looking for.')).toBeUndefined() + expect(new Error('This isn\'t the error you are looking for.')).to.be.undefined() }) } diff --git a/packages/react-scripts/fixtures/kitchensink/src/App.js b/packages/react-scripts/fixtures/kitchensink/src/App.js index 04641535a..cf93b4c13 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/App.js +++ b/packages/react-scripts/fixtures/kitchensink/src/App.js @@ -103,8 +103,7 @@ class App extends React.Component { require.ensure([], () => this.setFeature(require('./features/syntax/TemplateInterpolation').default)); break; case 'unknown-ext-inclusion': - require.ensure([], () => this.setFeature(require('./features/webpack/UnknownExtInclusion').default) - ); + require.ensure([], () => this.setFeature(require('./features/webpack/UnknownExtInclusion').default)); break; default: this.setFeature(null); From 6424232dc14ba1d4e75f492c23167d459e5af403 Mon Sep 17 00:00:00 2001 From: Fatih Date: Sat, 4 Feb 2017 17:18:54 +0200 Subject: [PATCH 25/47] Reflect websocket proxy support on README (#1013) (#1483) * Reflect websocket proxy support on README * Add 'the' --- packages/react-scripts/template/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-scripts/template/README.md b/packages/react-scripts/template/README.md index 0eb5cda38..2e7b76e18 100644 --- a/packages/react-scripts/template/README.md +++ b/packages/react-scripts/template/README.md @@ -650,7 +650,7 @@ Fetch API cannot load http://localhost:4000/api/todos. No 'Access-Control-Allow- Keep in mind that `proxy` only has effect in development (with `npm start`), and it is up to you to ensure that URLs like `/api/todos` point to the right thing in production. You don’t have to use the `/api` prefix. Any unrecognized request without a `text/html` accept header will be redirected to the specified `proxy`. -Currently the `proxy` option only handles HTTP requests, and it won’t proxy WebSocket connections.
+The `proxy` option supports HTTP, HTTPS and WebSocket connections.
If the `proxy` option is **not** flexible enough for you, alternatively you can: * Enable CORS on your server ([here’s how to do it for Express](http://enable-cors.org/server_expressjs.html)). From 65e63403952f4f3c7e872f707fb3736e339254d9 Mon Sep 17 00:00:00 2001 From: vulong23 Date: Sat, 4 Feb 2017 23:47:19 +0700 Subject: [PATCH 26/47] Edit User Guide: Add ESLint config for VS Code users (#1482) * Add ESLint config for VS Code users * Update VSC ESLint note to a better solution Update VSC ESLint note to a better solution as discussed in Pull Request --- packages/react-scripts/template/README.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/packages/react-scripts/template/README.md b/packages/react-scripts/template/README.md index 2e7b76e18..2f4e2fdf1 100644 --- a/packages/react-scripts/template/README.md +++ b/packages/react-scripts/template/README.md @@ -185,6 +185,18 @@ You would need to install an ESLint plugin for your editor first. > + +>**For Visual Studio Code users** + +>VS Code ESLint plugin automatically detects Create React App's configuration file. So you do not need to create `eslintrc.json` at the root directory, except when you want to add your own rules. In that case, you should include CRA's config by adding this line: + +>```js +{ + // ... + "extends": "react-app" +} +``` + Then add this block to the `package.json` file of your project: ```js From adab23fa0093846e0ec5349c0f8f7ad6e66fcb5d Mon Sep 17 00:00:00 2001 From: Joe Haddad Date: Sat, 4 Feb 2017 12:43:27 -0500 Subject: [PATCH 27/47] e2e: Reduce complexity of e2e and improve Jest coverage (#1484) --- .../fixtures/kitchensink/.babelrc | 2 +- .../kitchensink/.template.dependencies.json | 1 - .../fixtures/kitchensink/src/App.js | 53 ++++++++++++------- .../fixtures/kitchensink/src/App.test.js | 8 --- .../kitchensink/src/features/env/NodePath.js | 20 +++---- .../src/features/env/NodePath.test.js | 4 +- .../src/features/syntax/ArrayDestructuring.js | 20 +++---- .../syntax/ArrayDestructuring.test.js | 4 +- .../src/features/syntax/ArraySpread.js | 20 +++---- .../src/features/syntax/ArraySpread.test.js | 4 +- .../src/features/syntax/AsyncAwait.js | 20 +++---- .../src/features/syntax/AsyncAwait.test.js | 4 +- .../src/features/syntax/ClassProperties.js | 12 ++++- .../features/syntax/ClassProperties.test.js | 4 +- .../src/features/syntax/ComputedProperties.js | 20 +++---- .../syntax/ComputedProperties.test.js | 4 +- .../features/syntax/CustomInterpolation.js | 20 +++---- .../syntax/CustomInterpolation.test.js | 4 +- .../src/features/syntax/DefaultParameters.js | 20 +++---- .../features/syntax/DefaultParameters.test.js | 4 +- .../features/syntax/DestructuringAndAwait.js | 20 +++---- .../syntax/DestructuringAndAwait.test.js | 4 +- .../src/features/syntax/Generators.js | 20 +++---- .../src/features/syntax/Generators.test.js | 4 +- .../features/syntax/ObjectDestructuring.js | 20 +++---- .../syntax/ObjectDestructuring.test.js | 4 +- .../src/features/syntax/ObjectSpread.js | 20 +++---- .../src/features/syntax/ObjectSpread.test.js | 4 +- .../src/features/syntax/Promises.js | 20 +++---- .../src/features/syntax/Promises.test.js | 4 +- .../src/features/syntax/RestAndDefault.js | 20 +++---- .../features/syntax/RestAndDefault.test.js | 4 +- .../src/features/syntax/RestParameters.js | 20 +++---- .../features/syntax/RestParameters.test.js | 4 +- .../features/syntax/TemplateInterpolation.js | 20 +++---- .../syntax/TemplateInterpolation.test.js | 4 +- tasks/e2e-kitchensink.sh | 14 ++++- 37 files changed, 269 insertions(+), 185 deletions(-) delete mode 100644 packages/react-scripts/fixtures/kitchensink/src/App.test.js diff --git a/packages/react-scripts/fixtures/kitchensink/.babelrc b/packages/react-scripts/fixtures/kitchensink/.babelrc index 5686105b9..c14b2828d 100644 --- a/packages/react-scripts/fixtures/kitchensink/.babelrc +++ b/packages/react-scripts/fixtures/kitchensink/.babelrc @@ -1,3 +1,3 @@ { - "presets": ["latest"] + "presets": ["react-app"] } diff --git a/packages/react-scripts/fixtures/kitchensink/.template.dependencies.json b/packages/react-scripts/fixtures/kitchensink/.template.dependencies.json index 62e0d34a3..50511b3d1 100644 --- a/packages/react-scripts/fixtures/kitchensink/.template.dependencies.json +++ b/packages/react-scripts/fixtures/kitchensink/.template.dependencies.json @@ -1,6 +1,5 @@ { "dependencies": { - "babel-preset-latest": "6.16.0", "babel-register": "6.22.0", "babel-polyfill": "6.20.0", "chai": "3.5.0", diff --git a/packages/react-scripts/fixtures/kitchensink/src/App.js b/packages/react-scripts/fixtures/kitchensink/src/App.js index cf93b4c13..fa297133f 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/App.js +++ b/packages/react-scripts/fixtures/kitchensink/src/App.js @@ -1,28 +1,40 @@ -import React from 'react'; +import React, { Component, PropTypes, createElement } from 'react'; -class BuiltEmitter extends React.Component { - constructor(props) { - super(props) - - this.callWhenDone = done => done(); +class BuiltEmitter extends Component { + static propTypes = { + feature: PropTypes.func.isRequired } componentDidMount() { - this.callWhenDone(() => document.dispatchEvent(new Event('ReactFeatureDidMount'))); + const { feature } = this.props + + // Class components must call this.props.onReady when they're ready for the test. + // We will assume functional components are ready immediately after mounting. + if (!Component.isPrototypeOf(feature)) { + this.handleReady(); + } } - render() { - const feature = React.cloneElement(React.Children.only(this.props.children), { - setCallWhenDone: done => { - this.callWhenDone = done; - } - }); + handleReady() { + document.dispatchEvent(new Event('ReactFeatureDidMount')); + } - return
{feature}
; + render() { + const { + props: { feature }, + handleReady + } = this; + return ( +
+ {createElement(feature, { + onReady: handleReady + })} +
+ ); } } -class App extends React.Component { +class App extends Component { constructor(props) { super(props); @@ -105,9 +117,7 @@ class App extends React.Component { case 'unknown-ext-inclusion': require.ensure([], () => this.setFeature(require('./features/webpack/UnknownExtInclusion').default)); break; - default: - this.setFeature(null); - break; + default: throw new Error('Unknown feature!'); } } @@ -116,8 +126,11 @@ class App extends React.Component { } render() { - const Feature = this.state.feature; - return Feature ? : null; + const { feature } = this.state; + if (feature !== null) { + return ; + } + return null; } } diff --git a/packages/react-scripts/fixtures/kitchensink/src/App.test.js b/packages/react-scripts/fixtures/kitchensink/src/App.test.js deleted file mode 100644 index b84af98d7..000000000 --- a/packages/react-scripts/fixtures/kitchensink/src/App.test.js +++ /dev/null @@ -1,8 +0,0 @@ -import React from 'react'; -import ReactDOM from 'react-dom'; -import App from './App'; - -it('renders without crashing', () => { - const div = document.createElement('div'); - ReactDOM.render(, div); -}); diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/env/NodePath.js b/packages/react-scripts/fixtures/kitchensink/src/features/env/NodePath.js index 1644b49ca..deef80d20 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/features/env/NodePath.js +++ b/packages/react-scripts/fixtures/kitchensink/src/features/env/NodePath.js @@ -1,21 +1,23 @@ -import React from 'react' +import React, { Component, PropTypes } from 'react' import load from 'absoluteLoad' -export default class extends React.Component { +export default class extends Component { + static propTypes = { + onReady: PropTypes.func.isRequired + } + constructor(props) { super(props); - - this.done = () => {}; - this.props.setCallWhenDone && this.props.setCallWhenDone((done) => { - this.done = done; - }); - this.state = { users: [] }; } async componentDidMount() { const users = load(); - this.setState({ users }, () => this.done()); + this.setState({ users }); + } + + componentDidUpdate() { + this.props.onReady(); } render() { diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/env/NodePath.test.js b/packages/react-scripts/fixtures/kitchensink/src/features/env/NodePath.test.js index 05b981853..81487d559 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/features/env/NodePath.test.js +++ b/packages/react-scripts/fixtures/kitchensink/src/features/env/NodePath.test.js @@ -5,6 +5,8 @@ import NodePath from './NodePath'; describe('NODE_PATH', () => { it('renders without crashing', () => { const div = document.createElement('div'); - ReactDOM.render(, div); + return new Promise(resolve => { + ReactDOM.render(, div); + }); }); }); diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ArrayDestructuring.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ArrayDestructuring.js index 1ee751af7..d07271ed6 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ArrayDestructuring.js +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ArrayDestructuring.js @@ -1,4 +1,4 @@ -import React from 'react' +import React, { Component, PropTypes } from 'react' function load() { return [ @@ -9,21 +9,23 @@ function load() { ]; } -export default class extends React.Component { +export default class extends Component { + static propTypes = { + onReady: PropTypes.func.isRequired + } + constructor(props) { super(props); - - this.done = () => {}; - this.props.setCallWhenDone && this.props.setCallWhenDone((done) => { - this.done = done; - }); - this.state = { users: [] }; } async componentDidMount() { const users = load(); - this.setState({ users }, () => this.done()); + this.setState({ users }); + } + + componentDidUpdate() { + this.props.onReady(); } render() { diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ArrayDestructuring.test.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ArrayDestructuring.test.js index 617df2a6c..05d14263d 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ArrayDestructuring.test.js +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ArrayDestructuring.test.js @@ -5,6 +5,8 @@ import ArrayDestructuring from './ArrayDestructuring'; describe('array destructuring', () => { it('renders without crashing', () => { const div = document.createElement('div'); - ReactDOM.render(, div); + return new Promise(resolve => { + ReactDOM.render(, div); + }); }); }); diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ArraySpread.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ArraySpread.js index be6311980..6cb2f6162 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ArraySpread.js +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ArraySpread.js @@ -1,4 +1,4 @@ -import React from 'react' +import React, { Component, PropTypes } from 'react' function load(users) { return [ @@ -9,21 +9,23 @@ function load(users) { ]; } -export default class extends React.Component { +export default class extends Component { + static propTypes = { + onReady: PropTypes.func.isRequired + } + constructor(props) { super(props); - - this.done = () => {}; - this.props.setCallWhenDone && this.props.setCallWhenDone((done) => { - this.done = done; - }); - this.state = { users: [] }; } async componentDidMount() { const users = load([{ id: 42, name: '42' }]); - this.setState({ users }, () => this.done()); + this.setState({ users }); + } + + componentDidUpdate() { + this.props.onReady(); } render() { diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ArraySpread.test.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ArraySpread.test.js index 85fade6e3..a2191cf1c 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ArraySpread.test.js +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ArraySpread.test.js @@ -5,6 +5,8 @@ import ArraySpread from './ArraySpread'; describe('array spread', () => { it('renders without crashing', () => { const div = document.createElement('div'); - ReactDOM.render(, div); + return new Promise(resolve => { + ReactDOM.render(, div); + }); }); }); diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/AsyncAwait.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/AsyncAwait.js index 84dd42e0a..9fe920514 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/AsyncAwait.js +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/AsyncAwait.js @@ -1,4 +1,4 @@ -import React from 'react' +import React, { Component, PropTypes } from 'react' async function load() { return [ @@ -9,21 +9,23 @@ async function load() { ]; } -export default class extends React.Component { +export default class extends Component { + static propTypes = { + onReady: PropTypes.func.isRequired + } + constructor(props) { super(props); - - this.done = () => {}; - this.props.setCallWhenDone && this.props.setCallWhenDone((done) => { - this.done = done; - }); - this.state = { users: [] }; } async componentDidMount() { const users = await load(); - this.setState({ users }, () => this.done()); + this.setState({ users }); + } + + componentDidUpdate() { + this.props.onReady(); } render() { diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/AsyncAwait.test.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/AsyncAwait.test.js index 072f16fff..bc60c5b58 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/AsyncAwait.test.js +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/AsyncAwait.test.js @@ -5,6 +5,8 @@ import AsyncAwait from './AsyncAwait'; describe('async/await', () => { it('renders without crashing', () => { const div = document.createElement('div'); - ReactDOM.render(, div); + return new Promise(resolve => { + ReactDOM.render(, div); + }); }); }); diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ClassProperties.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ClassProperties.js index 65e500d64..726eba152 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ClassProperties.js +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ClassProperties.js @@ -1,6 +1,10 @@ -import React from 'react' +import React, { Component, PropTypes } from 'react' + +export default class extends Component { + static propTypes = { + onReady: PropTypes.func.isRequired + } -export default class extends React.Component { users = [ { id: 1, name: '1' }, { id: 2, name: '2' }, @@ -8,6 +12,10 @@ export default class extends React.Component { { id: 4, name: '4' } ]; + componentDidMount() { + this.props.onReady() + } + render() { return (
diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ClassProperties.test.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ClassProperties.test.js index 71d851dd2..898916b2f 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ClassProperties.test.js +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ClassProperties.test.js @@ -5,6 +5,8 @@ import ClassProperties from './ClassProperties'; describe('class properties', () => { it('renders without crashing', () => { const div = document.createElement('div'); - ReactDOM.render(, div); + return new Promise(resolve => { + ReactDOM.render(, div); + }); }); }); diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ComputedProperties.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ComputedProperties.js index b6111a149..04dc7ba10 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ComputedProperties.js +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ComputedProperties.js @@ -1,4 +1,4 @@ -import React from 'react' +import React, { Component, PropTypes } from 'react' function load(prefix) { return [ @@ -9,21 +9,23 @@ function load(prefix) { ]; } -export default class extends React.Component { +export default class extends Component { + static propTypes = { + onReady: PropTypes.func.isRequired + } + constructor(props) { super(props); - - this.done = () => {}; - this.props.setCallWhenDone && this.props.setCallWhenDone((done) => { - this.done = done; - }); - this.state = { users: [] }; } async componentDidMount() { const users = load('user_'); - this.setState({ users }, () => this.done()); + this.setState({ users }); + } + + componentDidUpdate() { + this.props.onReady(); } render() { diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ComputedProperties.test.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ComputedProperties.test.js index 4e9aaf17a..0aa3d4d7e 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ComputedProperties.test.js +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ComputedProperties.test.js @@ -5,6 +5,8 @@ import ComputedProperties from './ComputedProperties'; describe('computed properties', () => { it('renders without crashing', () => { const div = document.createElement('div'); - ReactDOM.render(, div); + return new Promise(resolve => { + ReactDOM.render(, div); + }); }); }); diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/CustomInterpolation.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/CustomInterpolation.js index 8184d3bd4..c80f14dc8 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/CustomInterpolation.js +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/CustomInterpolation.js @@ -1,4 +1,4 @@ -import React from 'react' +import React, { Component, PropTypes } from 'react' const styled = ([style]) => style.trim() .split(/\s*;\s*/) @@ -14,21 +14,23 @@ function load() { ]; } -export default class extends React.Component { +export default class extends Component { + static propTypes = { + onReady: PropTypes.func.isRequired + } + constructor(props) { super(props); - - this.done = () => {}; - this.props.setCallWhenDone && this.props.setCallWhenDone((done) => { - this.done = done; - }); - this.state = { users: [] }; } async componentDidMount() { const users = load(); - this.setState({ users }, () => this.done()); + this.setState({ users }); + } + + componentDidUpdate() { + this.props.onReady(); } render() { diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/CustomInterpolation.test.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/CustomInterpolation.test.js index 10b1df278..79af8dc5f 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/CustomInterpolation.test.js +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/CustomInterpolation.test.js @@ -5,6 +5,8 @@ import CustomInterpolation from './CustomInterpolation'; describe('custom interpolation', () => { it('renders without crashing', () => { const div = document.createElement('div'); - ReactDOM.render(, div); + return new Promise(resolve => { + ReactDOM.render(, div); + }); }); }); diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/DefaultParameters.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/DefaultParameters.js index 637a239d7..0d7b77d87 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/DefaultParameters.js +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/DefaultParameters.js @@ -1,4 +1,4 @@ -import React from 'react' +import React, { Component, PropTypes } from 'react' function load(id = 0) { return [ @@ -9,21 +9,23 @@ function load(id = 0) { ]; } -export default class extends React.Component { +export default class extends Component { + static propTypes = { + onReady: PropTypes.func.isRequired + } + constructor(props) { super(props); - - this.done = () => {}; - this.props.setCallWhenDone && this.props.setCallWhenDone((done) => { - this.done = done; - }); - this.state = { users: [] }; } async componentDidMount() { const users = load(); - this.setState({ users }, () => this.done()); + this.setState({ users }); + } + + componentDidUpdate() { + this.props.onReady(); } render() { diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/DefaultParameters.test.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/DefaultParameters.test.js index b5ece2446..c4a336563 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/DefaultParameters.test.js +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/DefaultParameters.test.js @@ -5,6 +5,8 @@ import DefaultParameters from './DefaultParameters'; describe('default parameters', () => { it('renders without crashing', () => { const div = document.createElement('div'); - ReactDOM.render(, div); + return new Promise(resolve => { + ReactDOM.render(, div); + }); }); }); diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/DestructuringAndAwait.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/DestructuringAndAwait.js index e28e0bb36..40f517542 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/DestructuringAndAwait.js +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/DestructuringAndAwait.js @@ -1,4 +1,4 @@ -import React from 'react' +import React, { Component, PropTypes } from 'react' async function load() { return { users: [ @@ -9,21 +9,23 @@ async function load() { ] }; } -export default class extends React.Component { +export default class extends Component { + static propTypes = { + onReady: PropTypes.func.isRequired + } + constructor(props) { super(props); - - this.done = () => {}; - this.props.setCallWhenDone && this.props.setCallWhenDone((done) => { - this.done = done; - }); - this.state = { users: [] }; } async componentDidMount() { const { users } = await load(); - this.setState({ users }, () => this.done()); + this.setState({ users }); + } + + componentDidUpdate() { + this.props.onReady(); } render() { diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/DestructuringAndAwait.test.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/DestructuringAndAwait.test.js index 14521e307..96b361c74 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/DestructuringAndAwait.test.js +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/DestructuringAndAwait.test.js @@ -5,6 +5,8 @@ import DestructuringAndAwait from './DestructuringAndAwait'; describe('destructuring and await', () => { it('renders without crashing', () => { const div = document.createElement('div'); - ReactDOM.render(, div); + return new Promise(resolve => { + ReactDOM.render(, div); + }); }); }); diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/Generators.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/Generators.js index a20fc19b7..6bb64f910 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/Generators.js +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/Generators.js @@ -1,4 +1,4 @@ -import React from 'react' +import React, { Component, PropTypes } from 'react' function * load(limit) { let i = 1; @@ -8,15 +8,13 @@ function * load(limit) { } } -export default class extends React.Component { +export default class extends Component { + static propTypes = { + onReady: PropTypes.func.isRequired + } + constructor(props) { super(props); - - this.done = () => {}; - this.props.setCallWhenDone && this.props.setCallWhenDone((done) => { - this.done = done; - }); - this.state = { users: [] }; } @@ -25,7 +23,11 @@ export default class extends React.Component { for (let user of load(4)) { users.push(user); } - this.setState({ users }, () => this.done()); + this.setState({ users }); + } + + componentDidUpdate() { + this.props.onReady(); } render() { diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/Generators.test.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/Generators.test.js index 1fd36cdbe..4e6b8d1d9 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/Generators.test.js +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/Generators.test.js @@ -5,6 +5,8 @@ import Generators from './Generators'; describe('generators', () => { it('renders without crashing', () => { const div = document.createElement('div'); - ReactDOM.render(, div); + return new Promise(resolve => { + ReactDOM.render(, div); + }); }); }); diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ObjectDestructuring.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ObjectDestructuring.js index db377cee5..3235a9910 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ObjectDestructuring.js +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ObjectDestructuring.js @@ -1,4 +1,4 @@ -import React from 'react' +import React, { Component, PropTypes } from 'react' function load() { return [ @@ -9,21 +9,23 @@ function load() { ]; } -export default class extends React.Component { +export default class extends Component { + static propTypes = { + onReady: PropTypes.func.isRequired + } + constructor(props) { super(props); - - this.done = () => {}; - this.props.setCallWhenDone && this.props.setCallWhenDone((done) => { - this.done = done; - }); - this.state = { users: [] }; } async componentDidMount() { const users = load(); - this.setState({ users }, () => this.done()); + this.setState({ users }); + } + + componentDidUpdate() { + this.props.onReady(); } render() { diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ObjectDestructuring.test.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ObjectDestructuring.test.js index 7ed28147d..0a21b291b 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ObjectDestructuring.test.js +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ObjectDestructuring.test.js @@ -5,6 +5,8 @@ import ObjectDestructuring from './ObjectDestructuring'; describe('object destructuring', () => { it('renders without crashing', () => { const div = document.createElement('div'); - ReactDOM.render(, div); + return new Promise(resolve => { + ReactDOM.render(, div); + }); }); }); diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ObjectSpread.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ObjectSpread.js index 72356fb94..fb43bf867 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ObjectSpread.js +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ObjectSpread.js @@ -1,4 +1,4 @@ -import React from 'react' +import React, { Component, PropTypes } from 'react' function load(baseUser) { return [ @@ -9,21 +9,23 @@ function load(baseUser) { ]; } -export default class extends React.Component { +export default class extends Component { + static propTypes = { + onReady: PropTypes.func.isRequired + } + constructor(props) { super(props); - - this.done = () => {}; - this.props.setCallWhenDone && this.props.setCallWhenDone((done) => { - this.done = done; - }); - this.state = { users: [] }; } async componentDidMount() { const users = load({ age: 42 }); - this.setState({ users }, () => this.done()); + this.setState({ users }); + } + + componentDidUpdate() { + this.props.onReady(); } render() { diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ObjectSpread.test.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ObjectSpread.test.js index 9de96c264..4ca5d2b9a 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ObjectSpread.test.js +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ObjectSpread.test.js @@ -5,6 +5,8 @@ import ObjectSpread from './ObjectSpread'; describe('object spread', () => { it('renders without crashing', () => { const div = document.createElement('div'); - ReactDOM.render(, div); + return new Promise(resolve => { + ReactDOM.render(, div); + }); }); }); diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/Promises.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/Promises.js index 9eb8c20f7..63f38fed4 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/Promises.js +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/Promises.js @@ -1,4 +1,4 @@ -import React from 'react' +import React, { Component, PropTypes } from 'react' function load() { return Promise.resolve([ @@ -9,24 +9,26 @@ function load() { ]); } -export default class extends React.Component { +export default class extends Component { + static propTypes = { + onReady: PropTypes.func.isRequired + } + constructor(props) { super(props); - - this.done = () => {}; - this.props.setCallWhenDone && this.props.setCallWhenDone((done) => { - this.done = done; - }); - this.state = { users: [] }; } componentDidMount() { load().then(users => { - this.setState({ users }, () => this.done()); + this.setState({ users }); }); } + componentDidUpdate() { + this.props.onReady(); + } + render() { return (
diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/Promises.test.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/Promises.test.js index 96b4d298d..36c5984a4 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/Promises.test.js +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/Promises.test.js @@ -5,6 +5,8 @@ import Promises from './Promises'; describe('promises', () => { it('renders without crashing', () => { const div = document.createElement('div'); - ReactDOM.render(, div); + return new Promise(resolve => { + ReactDOM.render(, div); + }); }); }); diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/RestAndDefault.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/RestAndDefault.js index 94b759808..7783868ab 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/RestAndDefault.js +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/RestAndDefault.js @@ -1,4 +1,4 @@ -import React from 'react' +import React, { Component, PropTypes } from 'react' function load({ id, ...rest } = { id: 0, user: { id: 42, name: '42' } }) { return [ @@ -9,21 +9,23 @@ function load({ id, ...rest } = { id: 0, user: { id: 42, name: '42' } }) { ]; } -export default class extends React.Component { +export default class extends Component { + static propTypes = { + onReady: PropTypes.func.isRequired + } + constructor(props) { super(props); - - this.done = () => {}; - this.props.setCallWhenDone && this.props.setCallWhenDone((done) => { - this.done = done; - }); - this.state = { users: [] }; } async componentDidMount() { const users = load(); - this.setState({ users }, () => this.done()); + this.setState({ users }); + } + + componentDidUpdate() { + this.props.onReady(); } render() { diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/RestAndDefault.test.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/RestAndDefault.test.js index 95f4a19fa..22a91be08 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/RestAndDefault.test.js +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/RestAndDefault.test.js @@ -5,6 +5,8 @@ import RestAndDefault from './RestAndDefault'; describe('rest + default', () => { it('renders without crashing', () => { const div = document.createElement('div'); - ReactDOM.render(, div); + return new Promise(resolve => { + ReactDOM.render(, div); + }); }); }); diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/RestParameters.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/RestParameters.js index c1cd63e88..cf216ce01 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/RestParameters.js +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/RestParameters.js @@ -1,4 +1,4 @@ -import React from 'react' +import React, { Component, PropTypes } from 'react' function load({ id = 0, ...rest }) { return [ @@ -9,21 +9,23 @@ function load({ id = 0, ...rest }) { ]; } -export default class extends React.Component { +export default class extends Component { + static propTypes = { + onReady: PropTypes.func.isRequired + } + constructor(props) { super(props); - - this.done = () => {}; - this.props.setCallWhenDone && this.props.setCallWhenDone((done) => { - this.done = done; - }); - this.state = { users: [] }; } async componentDidMount() { const users = load({ id: 0, user: { id: 42, name: '42' } }); - this.setState({ users }, () => this.done()); + this.setState({ users }); + } + + componentDidUpdate() { + this.props.onReady(); } render() { diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/RestParameters.test.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/RestParameters.test.js index 8e0977133..f1f8e35e3 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/RestParameters.test.js +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/RestParameters.test.js @@ -5,6 +5,8 @@ import RestParameters from './RestParameters'; describe('rest parameters', () => { it('renders without crashing', () => { const div = document.createElement('div'); - ReactDOM.render(, div); + return new Promise(resolve => { + ReactDOM.render(, div); + }); }); }); diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/TemplateInterpolation.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/TemplateInterpolation.js index 33b004722..dd6bf49b1 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/TemplateInterpolation.js +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/TemplateInterpolation.js @@ -1,4 +1,4 @@ -import React from 'react' +import React, { Component, PropTypes } from 'react' function load(name) { return [ @@ -9,21 +9,23 @@ function load(name) { ]; } -export default class extends React.Component { +export default class extends Component { + static propTypes = { + onReady: PropTypes.func.isRequired + } + constructor(props) { super(props); - - this.done = () => {}; - this.props.setCallWhenDone && this.props.setCallWhenDone((done) => { - this.done = done; - }); - this.state = { users: [] }; } async componentDidMount() { const users = load('user_'); - this.setState({ users }, () => this.done()); + this.setState({ users }); + } + + componentDidUpdate() { + this.props.onReady(); } render() { diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/TemplateInterpolation.test.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/TemplateInterpolation.test.js index b49af029a..41a5fad2c 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/TemplateInterpolation.test.js +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/TemplateInterpolation.test.js @@ -5,6 +5,8 @@ import TemplateInterpolation from './TemplateInterpolation'; describe('template interpolation', () => { it('renders without crashing', () => { const div = document.createElement('div'); - ReactDOM.render(, div); + return new Promise(resolve => { + ReactDOM.render(, div); + }); }); }); diff --git a/tasks/e2e-kitchensink.sh b/tasks/e2e-kitchensink.sh index 892230ab7..c681580b0 100755 --- a/tasks/e2e-kitchensink.sh +++ b/tasks/e2e-kitchensink.sh @@ -110,6 +110,9 @@ create_react_app --scripts-version=$scripts_path --internal-testing-template=$ro # Enter the app directory cd test-kitchensink +# Link to our preset +npm link $root_path/packages/babel-preset-react-app + # Test the build NODE_PATH=src REACT_APP_SHELL_ENV_MESSAGE=fromtheshell npm run build # Check for expected output @@ -120,6 +123,7 @@ test -e build/static/js/main.*.js REACT_APP_SHELL_ENV_MESSAGE=fromtheshell \ CI=true \ NODE_PATH=src \ + NODE_ENV=test \ npm test -- --no-cache --testPathPattern="/src/" # Test "development" environment @@ -132,18 +136,23 @@ grep -q 'The app is running at:' <(tail -f $tmp_server_log) E2E_URL="http://localhost:3001" \ REACT_APP_SHELL_ENV_MESSAGE=fromtheshell \ CI=true NODE_PATH=src \ + NODE_ENV=development \ node node_modules/.bin/mocha --require babel-register --require babel-polyfill integration/*.test.js # Test "production" environment E2E_FILE=./build/index.html \ CI=true \ NODE_PATH=src \ + NODE_ENV=production \ node_modules/.bin/mocha --require babel-register --require babel-polyfill integration/*.test.js # ****************************************************************************** # Finally, let's check that everything still works after ejecting. # ****************************************************************************** +# Unlink our preset +npm unlink $root_path/packages/babel-preset-react-app + # Eject... echo yes | npm run eject @@ -153,7 +162,7 @@ npm link $root_path/packages/eslint-config-react-app npm link $root_path/packages/react-dev-utils npm link $root_path/packages/react-scripts -# ...and we need to remove template's .babelrc +# ...and we need to remove template's .babelrc rm .babelrc # Test the build @@ -166,6 +175,7 @@ test -e build/static/js/main.*.js REACT_APP_SHELL_ENV_MESSAGE=fromtheshell \ CI=true \ NODE_PATH=src \ + NODE_ENV=test \ npm test -- --no-cache --testPathPattern="/src/" # Test "development" environment @@ -178,7 +188,7 @@ grep -q 'The app is running at:' <(tail -f $tmp_server_log) E2E_URL="http://localhost:3002" \ REACT_APP_SHELL_ENV_MESSAGE=fromtheshell \ CI=true NODE_PATH=src \ - NODE_ENV=production \ + NODE_ENV=development \ node_modules/.bin/mocha --require babel-register --require babel-polyfill integration/*.test.js # Test "production" environment From 9e0e18fd2e42e469e81b3b9f4aa3bd717ca1b317 Mon Sep 17 00:00:00 2001 From: Jay Phelps Date: Thu, 5 Jan 2017 12:14:36 -0800 Subject: [PATCH 28/47] UX: Explain why build is failing (#1352) --- packages/react-scripts/scripts/build.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-scripts/scripts/build.js b/packages/react-scripts/scripts/build.js index 42be50d43..1e1b62170 100644 --- a/packages/react-scripts/scripts/build.js +++ b/packages/react-scripts/scripts/build.js @@ -144,7 +144,7 @@ function build(previousSizeMap) { } if (process.env.CI && stats.compilation.warnings.length) { - printErrors('Failed to compile.', stats.compilation.warnings); + printErrors('Failed to compile. When process.env.CI = true, warnings are treated as failures. Most CI servers set this automatically.', stats.compilation.warnings); process.exit(1); } From 0ac0d116b90d308149e538fbabe06091431a09d5 Mon Sep 17 00:00:00 2001 From: Ro Savage Date: Thu, 9 Feb 2017 03:21:13 +1300 Subject: [PATCH 29/47] Update comments for webpack loaders --- .../config/webpack.config.dev.js | 24 ++++++++----------- .../config/webpack.config.prod.js | 22 ++++++++--------- 2 files changed, 20 insertions(+), 26 deletions(-) diff --git a/packages/react-scripts/config/webpack.config.dev.js b/packages/react-scripts/config/webpack.config.dev.js index 96fd632b7..ac63ba2f3 100644 --- a/packages/react-scripts/config/webpack.config.dev.js +++ b/packages/react-scripts/config/webpack.config.dev.js @@ -112,20 +112,14 @@ module.exports = { } ], loaders: [ - // Default loader: load all assets that are not handled - // by other loaders with the url loader. - // Note: This list needs to be updated with every change of extensions - // the other loaders match. - // E.g., when adding a loader for a new supported file extension, - // we need to add the supported extension to this loader too. - // Add one new line in `exclude` for each loader. - // - // "file" loader makes sure those assets get served by WebpackDevServer. - // When you `import` an asset, you get its (virtual) filename. - // In production, they would get copied to the `build` folder. - // "url" loader works like "file" loader except that it embeds assets - // smaller than specified limit in bytes as data URLs to avoid requests. - // A missing `test` is equivalent to a match. + // ** ADDING/UPDATING LOADERS ** + // The "url" loader handles all assets unless explicitly excluded. + // The `exclude` list *must* be updated with every change to loader extensions. + // When adding a new loader, you must add its `test` + // as a new entry in the `exclude` list for "url" loader. + + // "url" loader embeds assets smaller than specified size as data URLs to avoid requests. + // Otherwise, it acts like the "file" loader. { exclude: [ /\.html$/, @@ -179,6 +173,8 @@ module.exports = { name: 'static/media/[name].[hash:8].[ext]' } } + // ** STOP ** Are you adding a new loader? + // Remember to add the new extension(s) to the "url" loader exclusion list. ] }, // @remove-on-eject-begin diff --git a/packages/react-scripts/config/webpack.config.prod.js b/packages/react-scripts/config/webpack.config.prod.js index 058db0d79..7181c4cca 100644 --- a/packages/react-scripts/config/webpack.config.prod.js +++ b/packages/react-scripts/config/webpack.config.prod.js @@ -120,18 +120,14 @@ module.exports = { } ], loaders: [ - // Default loader: load all assets that are not handled - // by other loaders with the url loader. - // Note: This list needs to be updated with every change of extensions - // the other loaders match. - // E.g., when adding a loader for a new supported file extension, - // we need to add the supported extension to this loader too. - // Add one new line in `exclude` for each loader. - // - // "file" loader makes sure those assets end up in the `build` folder. - // When you `import` an asset, you get its filename. - // "url" loader works just like "file" loader but it also embeds - // assets smaller than specified size as data URLs to avoid requests. + // ** ADDING/UPDATING LOADERS ** + // The "url" loader handles all assets unless explicitly excluded. + // The `exclude` list *must* be updated with every change to loader extensions. + // When adding a new loader, you must add its `test` + // as a new entry in the `exclude` list in the "url" loader. + + // "url" loader embeds assets smaller than specified size as data URLs to avoid requests. + // Otherwise, it acts like the "file" loader. { exclude: [ /\.html$/, @@ -189,6 +185,8 @@ module.exports = { name: 'static/media/[name].[hash:8].[ext]' } } + // ** STOP ** Are you adding a new loader? + // Remember to add the new extension(s) to the "url" loader exclusion list. ] }, // @remove-on-eject-begin From c811a31622860367985bd0a1e9b523bfc8c52585 Mon Sep 17 00:00:00 2001 From: RodrigoHahn Date: Thu, 9 Feb 2017 12:41:24 -0200 Subject: [PATCH 30/47] Change "OS X" references to "macOS" (#1511) Updated README.md to refer to the current rebranding. --- packages/react-scripts/template/README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/react-scripts/template/README.md b/packages/react-scripts/template/README.md index 2f4e2fdf1..75e10517f 100644 --- a/packages/react-scripts/template/README.md +++ b/packages/react-scripts/template/README.md @@ -578,7 +578,7 @@ set REACT_APP_SECRET_CODE=abcdef&&npm start (Note: the lack of whitespace is intentional.) -#### Linux, OS X (Bash) +#### Linux, macOS (Bash) ```bash REACT_APP_SECRET_CODE=abcdef npm start @@ -684,7 +684,7 @@ set HTTPS=true&&npm start (Note: the lack of whitespace is intentional.) -#### Linux, OS X (Bash) +#### Linux, macOS (Bash) ```bash HTTPS=true npm start @@ -912,7 +912,7 @@ set CI=true&&npm run build (Note: the lack of whitespace is intentional.) -##### Linux, OS X (Bash) +##### Linux, macOS (Bash) ```bash CI=true npm test @@ -1285,7 +1285,7 @@ If this doesn’t happen, try one of the following workarounds: * If the watcher doesn’t see a file called `index.js` and you’re referencing it by the folder name, you [need to restart the watcher](https://github.com/facebookincubator/create-react-app/issues/1164) due to a Webpack bug. * Some editors like Vim and IntelliJ have a “safe write” feature that currently breaks the watcher. You will need to disable it. Follow the instructions in [“Working with editors supporting safe write”](https://webpack.github.io/docs/webpack-dev-server.html#working-with-editors-ides-supporting-safe-write). * If your project path contains parentheses, try moving the project to a path without them. This is caused by a [Webpack watcher bug](https://github.com/webpack/watchpack/issues/42). -* On Linux and OS X, you might need to [tweak system settings](https://webpack.github.io/docs/troubleshooting.html#not-enough-watchers) to allow more watchers. +* On Linux and macOS, you might need to [tweak system settings](https://webpack.github.io/docs/troubleshooting.html#not-enough-watchers) to allow more watchers. If none of these solutions help please leave a comment [in this thread](https://github.com/facebookincubator/create-react-app/issues/659). From de6e0590b27c438250527ad1eaf410abada86a97 Mon Sep 17 00:00:00 2001 From: Chandan Rai Date: Fri, 10 Feb 2017 01:38:52 +0530 Subject: [PATCH 31/47] corrected minor typo (#1514) --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 113bf6413..4734d5ea8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -439,7 +439,7 @@ npm install --save-dev --save-exact react-scripts@0.8.0 ### Babel Preset (`babel-preset-react-app`) -* The preset now detects the Node.js version in test environment and disables unnecessary ES2015 transforms using using `babel-preset-env`. ([@shubheksha](https://github.com/shubheksha) in [#878](https://github.com/facebookincubator/create-react-app/pull/878), [@JeffreyATW](https://github.com/JeffreyATW) in [#927 +* The preset now detects the Node.js version in test environment and disables unnecessary ES2015 transforms using `babel-preset-env`. ([@shubheksha](https://github.com/shubheksha) in [#878](https://github.com/facebookincubator/create-react-app/pull/878), [@JeffreyATW](https://github.com/JeffreyATW) in [#927 ](https://github.com/facebookincubator/create-react-app/pull/927)) * Fixes a duplicate dependency on `babel-plugin-transform-regenerator`. ([@akofman](https://github.com/akofman) in [#864](https://github.com/facebookincubator/create-react-app/pull/864)) From 160d8d13ef92c3dae7d1b2b82f954f89d0677780 Mon Sep 17 00:00:00 2001 From: Calvin Webster Date: Thu, 9 Feb 2017 15:46:47 -0500 Subject: [PATCH 32/47] clarifying the use of custom environment variables (#1513) * clarifying the use of custom environment variables * Tweak --- packages/react-scripts/template/README.md | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/packages/react-scripts/template/README.md b/packages/react-scripts/template/README.md index 75e10517f..357df8d5d 100644 --- a/packages/react-scripts/template/README.md +++ b/packages/react-scripts/template/README.md @@ -495,7 +495,7 @@ Now you are ready to use the imported React Bootstrap components within your com Flow is a static type checker that helps you write code with fewer bugs. Check out this [introduction to using static types in JavaScript](https://medium.com/@preethikasireddy/why-use-static-types-in-javascript-part-1-8382da1e0adb) if you are new to this concept. -Recent versions of [Flow](http://flowtype.org/) work with Create React App projects out of the box. +Recent versions of [Flow](http://flowtype.org/) work with Create React App projects out of the box. To add Flow to a Create React App project, follow these steps: @@ -515,7 +515,11 @@ To learn more about Flow, check out [its documentation](https://flowtype.org/). Your project can consume variables declared in your environment as if they were declared locally in your JS files. By default you will have `NODE_ENV` defined for you, and any other environment variables starting with -`REACT_APP_`. These environment variables will be defined for you on `process.env`. For example, having an environment +`REACT_APP_`. + +>Note: You must create custom environment variables beginning with `REACT_APP_`. Any other variables except `NODE_ENV` will be ignored to avoid accidentally [exposing a private key on the machine that could have the same name](https://github.com/facebookincubator/create-react-app/issues/865#issuecomment-252199527). + +These environment variables will be defined for you on `process.env`. For example, having an environment variable named `REACT_APP_SECRET_CODE` will be exposed in your JS as `process.env.REACT_APP_SECRET_CODE`, in addition to `process.env.NODE_ENV`. @@ -623,12 +627,12 @@ These tutorials will help you to integrate your app with an API backend running using `fetch()` to access it. ### Node -Check out [this tutorial](https://www.fullstackreact.com/articles/using-create-react-app-with-a-server/). +Check out [this tutorial](https://www.fullstackreact.com/articles/using-create-react-app-with-a-server/). You can find the companion GitHub repository [here](https://github.com/fullstackreact/food-lookup-demo). ### Ruby on Rails -Check out [this tutorial](https://www.fullstackreact.com/articles/how-to-get-create-react-app-to-work-with-your-rails-api/). +Check out [this tutorial](https://www.fullstackreact.com/articles/how-to-get-create-react-app-to-work-with-your-rails-api/). You can find the companion GitHub repository [here](https://github.com/fullstackreact/food-lookup-demo-rails). ## Proxying API Requests in Development @@ -961,7 +965,7 @@ Snapshot testing is a feature of Jest that automatically generates text snapshot ### Editor Integration -If you use [Visual Studio Code](https://code.visualstudio.com), there is a [Jest extension](https://github.com/orta/vscode-jest) which works with Create React App out of the box. This provides a lot of IDE-like features while using a text editor: showing the status of a test run with potential fail messages inline, starting and stopping the watcher automatically, and offering one-click snapshot updates. +If you use [Visual Studio Code](https://code.visualstudio.com), there is a [Jest extension](https://github.com/orta/vscode-jest) which works with Create React App out of the box. This provides a lot of IDE-like features while using a text editor: showing the status of a test run with potential fail messages inline, starting and stopping the watcher automatically, and offering one-click snapshot updates. ![VS Code Jest Preview](https://cloud.githubusercontent.com/assets/49038/20795349/a032308a-b7c8-11e6-9b34-7eeac781003f.png) @@ -1196,7 +1200,7 @@ GitHub Pages doesn't support routers that use the HTML5 `pushState` history API ### Heroku Use the [Heroku Buildpack for Create React App](https://github.com/mars/create-react-app-buildpack).
-You can find instructions in [Deploying React with Zero Configuration](https://blog.heroku.com/deploying-react-with-zero-configuration). +You can find instructions in [Deploying React with Zero Configuration](https://blog.heroku.com/deploying-react-with-zero-configuration). #### Resolving "Module not found: Error: Cannot resolve 'file' or 'directory'" @@ -1204,7 +1208,7 @@ Sometimes `npm run build` works locally but fails during deploy via Heroku with ``` remote: Failed to create a production build. Reason: -remote: Module not found: Error: Cannot resolve 'file' or 'directory' +remote: Module not found: Error: Cannot resolve 'file' or 'directory' MyDirectory in /tmp/build_1234/src ``` From b999405c671d0061910ae89ba58731dc1b71762c Mon Sep 17 00:00:00 2001 From: pd4d10 Date: Fri, 10 Feb 2017 05:36:20 +0800 Subject: [PATCH 33/47] Add missing '\n' to the end of `package.json` file (#1510) --- packages/react-scripts/scripts/eject.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-scripts/scripts/eject.js b/packages/react-scripts/scripts/eject.js index b8f9d3131..a8ee0fc31 100644 --- a/packages/react-scripts/scripts/eject.js +++ b/packages/react-scripts/scripts/eject.js @@ -145,7 +145,7 @@ prompt( fs.writeFileSync( path.join(appPath, 'package.json'), - JSON.stringify(appPackage, null, 2) + JSON.stringify(appPackage, null, 2) + '\n' ); console.log(); From 1d9159de230da8bb1e24744c4581038b91f43b09 Mon Sep 17 00:00:00 2001 From: Jih-Chi Lee Date: Fri, 10 Feb 2017 11:41:03 +0800 Subject: [PATCH 34/47] Make all react app vars accessible in index.html (#1440) * Make all vars accessiable in index.html * Fix wrong env provieded to DefinePlugin * Separate results from getClientEnvironment * The `string` should be object instead of string * Fix accessing wrong field * Changed variables naming to `raw` and `stringified` * Remove trailing commas --- packages/react-scripts/config/env.js | 22 +++++++++++++------ .../config/webpack.config.dev.js | 9 ++++---- .../config/webpack.config.prod.js | 11 +++++----- 3 files changed, 24 insertions(+), 18 deletions(-) diff --git a/packages/react-scripts/config/env.js b/packages/react-scripts/config/env.js index 66ba341b3..168e1e644 100644 --- a/packages/react-scripts/config/env.js +++ b/packages/react-scripts/config/env.js @@ -15,25 +15,33 @@ var REACT_APP = /^REACT_APP_/i; function getClientEnvironment(publicUrl) { - var processEnv = Object + var raw = Object .keys(process.env) .filter(key => REACT_APP.test(key)) .reduce((env, key) => { - env[key] = JSON.stringify(process.env[key]); + env[key] = process.env[key]; return env; }, { // Useful for determining whether we’re running in production mode. // Most importantly, it switches React into the correct mode. - 'NODE_ENV': JSON.stringify( - process.env.NODE_ENV || 'development' - ), + 'NODE_ENV': process.env.NODE_ENV || 'development', // Useful for resolving the correct path to static assets in `public`. // For example, . // This should only be used as an escape hatch. Normally you would put // images into the `src` and `import` them in code to get their paths. - 'PUBLIC_URL': JSON.stringify(publicUrl) + 'PUBLIC_URL': publicUrl }); - return {'process.env': processEnv}; + // Stringify all values so we can feed into Webpack DefinePlugin + var stringified = { + 'process.env': Object + .keys(raw) + .reduce((env, key) => { + env[key] = JSON.stringify(raw[key]); + return env; + }, {}) + }; + + return { raw, stringified }; } module.exports = getClientEnvironment; diff --git a/packages/react-scripts/config/webpack.config.dev.js b/packages/react-scripts/config/webpack.config.dev.js index ac63ba2f3..b984ec3e4 100644 --- a/packages/react-scripts/config/webpack.config.dev.js +++ b/packages/react-scripts/config/webpack.config.dev.js @@ -198,12 +198,11 @@ module.exports = { ]; }, plugins: [ - // Makes the public URL available as %PUBLIC_URL% in index.html, e.g.: + // Makes some environment variables available in index.html. + // The public URL is available as %PUBLIC_URL% in index.html, e.g.: // // In development, this will be an empty string. - new InterpolateHtmlPlugin({ - PUBLIC_URL: publicUrl - }), + new InterpolateHtmlPlugin(env.raw), // Generates an `index.html` file with the