From 5a045b4933ba73e8c4df5aa10a3429025577103e Mon Sep 17 00:00:00 2001 From: btnwtn Date: Thu, 4 Aug 2016 14:24:05 -0700 Subject: [PATCH 001/105] Improve `npm run eject` description I feel as if the description for `npm run eject` is incredibly vague. `eject` does more than just removing the tool and that should be explained to the user. --- scripts/init.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/init.js b/scripts/init.js index 50cc9d25ba7..41fbdfa842a 100644 --- a/scripts/init.js +++ b/scripts/init.js @@ -82,7 +82,7 @@ module.exports = function(appPath, appName, verbose, originalDirectory) { console.log(); console.log(' * npm start: Starts the development server.'); console.log(' * npm run build: Bundles the app into static files for production.'); - console.log(' * npm run eject: Removes this tool. If you do this, you can’t go back!'); + console.log(' * npm run eject: Removes this tool and copies build dependencies, configs, and scripts into the app directory. If you do this, you can’t go back!'); console.log(); console.log('We suggest that you begin by typing:'); console.log(); From 4dbe43bcb6eb34567b9b026f8e7d41f6e9f5612f Mon Sep 17 00:00:00 2001 From: Brandon Newton Date: Fri, 9 Sep 2016 21:57:02 -0700 Subject: [PATCH 002/105] Better formatting of command descriptions --- npm-debug.log | 45 +++++++++++++++++++++++++++++++++++++++++++++ scripts/init.js | 15 +++++++++++---- 2 files changed, 56 insertions(+), 4 deletions(-) create mode 100644 npm-debug.log diff --git a/npm-debug.log b/npm-debug.log new file mode 100644 index 00000000000..8a04fe28be2 --- /dev/null +++ b/npm-debug.log @@ -0,0 +1,45 @@ +0 info it worked if it ends with ok +1 verbose cli [ '/usr/local/bin/node', '/usr/local/bin/npm', 'start' ] +2 info using npm@3.10.3 +3 info using node@v6.3.1 +4 verbose run-script [ 'prestart', 'start', 'poststart' ] +5 info lifecycle react-scripts@0.3.0-alpha~prestart: react-scripts@0.3.0-alpha +6 silly lifecycle react-scripts@0.3.0-alpha~prestart: no script for prestart, continuing +7 info lifecycle react-scripts@0.3.0-alpha~start: react-scripts@0.3.0-alpha +8 verbose lifecycle react-scripts@0.3.0-alpha~start: unsafe-perm in lifecycle true +9 verbose lifecycle react-scripts@0.3.0-alpha~start: PATH: /usr/local/lib/node_modules/npm/bin/node-gyp-bin:/Users/newton/Science/create-react-app/node_modules/.bin:/usr/local/bin:.git/safe/../../bin:/Users/newton/.rbenv/shims:/Users/newton/.bin:/usr/local/sbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/go/bin +10 verbose lifecycle react-scripts@0.3.0-alpha~start: CWD: /Users/newton/Science/create-react-app +11 silly lifecycle react-scripts@0.3.0-alpha~start: Args: [ '-c', 'node scripts/start.js --debug-template' ] +12 silly lifecycle react-scripts@0.3.0-alpha~start: Returned: code: 1 signal: null +13 info lifecycle react-scripts@0.3.0-alpha~start: Failed to exec start script +14 verbose stack Error: react-scripts@0.3.0-alpha start: `node scripts/start.js --debug-template` +14 verbose stack Exit status 1 +14 verbose stack at EventEmitter. (/usr/local/lib/node_modules/npm/lib/utils/lifecycle.js:242:16) +14 verbose stack at emitTwo (events.js:106:13) +14 verbose stack at EventEmitter.emit (events.js:191:7) +14 verbose stack at ChildProcess. (/usr/local/lib/node_modules/npm/lib/utils/spawn.js:40:14) +14 verbose stack at emitTwo (events.js:106:13) +14 verbose stack at ChildProcess.emit (events.js:191:7) +14 verbose stack at maybeClose (internal/child_process.js:852:16) +14 verbose stack at Process.ChildProcess._handle.onexit (internal/child_process.js:215:5) +15 verbose pkgid react-scripts@0.3.0-alpha +16 verbose cwd /Users/newton/Science/create-react-app +17 error Darwin 15.6.0 +18 error argv "/usr/local/bin/node" "/usr/local/bin/npm" "start" +19 error node v6.3.1 +20 error npm v3.10.3 +21 error code ELIFECYCLE +22 error react-scripts@0.3.0-alpha start: `node scripts/start.js --debug-template` +22 error Exit status 1 +23 error Failed at the react-scripts@0.3.0-alpha start script 'node scripts/start.js --debug-template'. +23 error Make sure you have the latest version of node.js and npm installed. +23 error If you do, this is most likely a problem with the react-scripts package, +23 error not with npm itself. +23 error Tell the author that this fails on your system: +23 error node scripts/start.js --debug-template +23 error You can get information on how to open an issue for this project with: +23 error npm bugs react-scripts +23 error Or if that isn't available, you can get their info via: +23 error npm owner ls react-scripts +23 error There is likely additional logging output above. +24 verbose exit [ 1, true ] diff --git a/scripts/init.js b/scripts/init.js index 41fbdfa842a..7aafa51f53b 100644 --- a/scripts/init.js +++ b/scripts/init.js @@ -7,6 +7,7 @@ * of patent rights can be found in the PATENTS file in the same directory. */ +var chalk = require('chalk'); var fs = require('fs-extra'); var path = require('path'); var spawn = require('cross-spawn'); @@ -80,14 +81,20 @@ module.exports = function(appPath, appName, verbose, originalDirectory) { console.log('Success! Created ' + appName + ' at ' + appPath + '.'); console.log('Inside that directory, you can run several commands:'); console.log(); - console.log(' * npm start: Starts the development server.'); - console.log(' * npm run build: Bundles the app into static files for production.'); - console.log(' * npm run eject: Removes this tool and copies build dependencies, configs, and scripts into the app directory. If you do this, you can’t go back!'); + console.log(chalk.cyan('npm start')); + console.log(' Starts the development server.'); + console.log(); + console.log(chalk.cyan('npm run build')); + console.log(' Bundles the app into static files for production.'); + console.log(); + console.log(chalk.cyan('npm run eject')); + console.log(' Removes this tool and copies build dependencies, configs, and scripts into the app directory.') + console.log(' If you do this, you can’t go back!'); console.log(); console.log('We suggest that you begin by typing:'); console.log(); console.log(' cd', cdpath); - console.log(' npm start'); + console.log(' ' + chalk.cyan('npm start')); console.log(); console.log('Happy hacking!'); }); From 5261af2d76c0a572097c0d383cc3562b62dbfd69 Mon Sep 17 00:00:00 2001 From: Brandon Newton Date: Sun, 11 Sep 2016 09:56:43 -0700 Subject: [PATCH 003/105] Fit npm script descriptions to 80 character width --- scripts/init.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/init.js b/scripts/init.js index 7aafa51f53b..10e009d21ec 100644 --- a/scripts/init.js +++ b/scripts/init.js @@ -88,7 +88,8 @@ module.exports = function(appPath, appName, verbose, originalDirectory) { console.log(' Bundles the app into static files for production.'); console.log(); console.log(chalk.cyan('npm run eject')); - console.log(' Removes this tool and copies build dependencies, configs, and scripts into the app directory.') + console.log(' Removes this tool and copies build dependencies, configs,') + console.log(' and scripts into the app directory.') console.log(' If you do this, you can’t go back!'); console.log(); console.log('We suggest that you begin by typing:'); From c1e56656ddb69a936f52a73da445ecb065c435c0 Mon Sep 17 00:00:00 2001 From: Brandon Newton Date: Sun, 11 Sep 2016 09:57:00 -0700 Subject: [PATCH 004/105] Delete npm-debug.log --- npm-debug.log | 45 --------------------------------------------- 1 file changed, 45 deletions(-) delete mode 100644 npm-debug.log diff --git a/npm-debug.log b/npm-debug.log deleted file mode 100644 index 8a04fe28be2..00000000000 --- a/npm-debug.log +++ /dev/null @@ -1,45 +0,0 @@ -0 info it worked if it ends with ok -1 verbose cli [ '/usr/local/bin/node', '/usr/local/bin/npm', 'start' ] -2 info using npm@3.10.3 -3 info using node@v6.3.1 -4 verbose run-script [ 'prestart', 'start', 'poststart' ] -5 info lifecycle react-scripts@0.3.0-alpha~prestart: react-scripts@0.3.0-alpha -6 silly lifecycle react-scripts@0.3.0-alpha~prestart: no script for prestart, continuing -7 info lifecycle react-scripts@0.3.0-alpha~start: react-scripts@0.3.0-alpha -8 verbose lifecycle react-scripts@0.3.0-alpha~start: unsafe-perm in lifecycle true -9 verbose lifecycle react-scripts@0.3.0-alpha~start: PATH: /usr/local/lib/node_modules/npm/bin/node-gyp-bin:/Users/newton/Science/create-react-app/node_modules/.bin:/usr/local/bin:.git/safe/../../bin:/Users/newton/.rbenv/shims:/Users/newton/.bin:/usr/local/sbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/go/bin -10 verbose lifecycle react-scripts@0.3.0-alpha~start: CWD: /Users/newton/Science/create-react-app -11 silly lifecycle react-scripts@0.3.0-alpha~start: Args: [ '-c', 'node scripts/start.js --debug-template' ] -12 silly lifecycle react-scripts@0.3.0-alpha~start: Returned: code: 1 signal: null -13 info lifecycle react-scripts@0.3.0-alpha~start: Failed to exec start script -14 verbose stack Error: react-scripts@0.3.0-alpha start: `node scripts/start.js --debug-template` -14 verbose stack Exit status 1 -14 verbose stack at EventEmitter. (/usr/local/lib/node_modules/npm/lib/utils/lifecycle.js:242:16) -14 verbose stack at emitTwo (events.js:106:13) -14 verbose stack at EventEmitter.emit (events.js:191:7) -14 verbose stack at ChildProcess. (/usr/local/lib/node_modules/npm/lib/utils/spawn.js:40:14) -14 verbose stack at emitTwo (events.js:106:13) -14 verbose stack at ChildProcess.emit (events.js:191:7) -14 verbose stack at maybeClose (internal/child_process.js:852:16) -14 verbose stack at Process.ChildProcess._handle.onexit (internal/child_process.js:215:5) -15 verbose pkgid react-scripts@0.3.0-alpha -16 verbose cwd /Users/newton/Science/create-react-app -17 error Darwin 15.6.0 -18 error argv "/usr/local/bin/node" "/usr/local/bin/npm" "start" -19 error node v6.3.1 -20 error npm v3.10.3 -21 error code ELIFECYCLE -22 error react-scripts@0.3.0-alpha start: `node scripts/start.js --debug-template` -22 error Exit status 1 -23 error Failed at the react-scripts@0.3.0-alpha start script 'node scripts/start.js --debug-template'. -23 error Make sure you have the latest version of node.js and npm installed. -23 error If you do, this is most likely a problem with the react-scripts package, -23 error not with npm itself. -23 error Tell the author that this fails on your system: -23 error node scripts/start.js --debug-template -23 error You can get information on how to open an issue for this project with: -23 error npm bugs react-scripts -23 error Or if that isn't available, you can get their info via: -23 error npm owner ls react-scripts -23 error There is likely additional logging output above. -24 verbose exit [ 1, true ] From 6517ea33a7418656e8667fa4b0daf46ec0ba3058 Mon Sep 17 00:00:00 2001 From: Brandon Newton Date: Sun, 11 Sep 2016 10:07:18 -0700 Subject: [PATCH 005/105] Resolve rebase --- scripts/init.js | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/init.js b/scripts/init.js index 10e009d21ec..767d1a97a49 100644 --- a/scripts/init.js +++ b/scripts/init.js @@ -87,6 +87,7 @@ module.exports = function(appPath, appName, verbose, originalDirectory) { console.log(chalk.cyan('npm run build')); console.log(' Bundles the app into static files for production.'); console.log(); + //.. console.log(chalk.cyan('npm run eject')); console.log(' Removes this tool and copies build dependencies, configs,') console.log(' and scripts into the app directory.') From 5767ccc743a15fb0f300168c8005b459b035d016 Mon Sep 17 00:00:00 2001 From: Brandon Newton Date: Sun, 11 Sep 2016 10:07:42 -0700 Subject: [PATCH 006/105] Remove stray comment --- scripts/init.js | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/init.js b/scripts/init.js index 767d1a97a49..10e009d21ec 100644 --- a/scripts/init.js +++ b/scripts/init.js @@ -87,7 +87,6 @@ module.exports = function(appPath, appName, verbose, originalDirectory) { console.log(chalk.cyan('npm run build')); console.log(' Bundles the app into static files for production.'); console.log(); - //.. console.log(chalk.cyan('npm run eject')); console.log(' Removes this tool and copies build dependencies, configs,') console.log(' and scripts into the app directory.') From 02e9b20e176a9fe513f774c0754eb1a3bdf53bf6 Mon Sep 17 00:00:00 2001 From: Brandon Newton Date: Sun, 11 Sep 2016 10:18:08 -0700 Subject: [PATCH 007/105] Merge master --- scripts/init.js | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/init.js b/scripts/init.js index 10e009d21ec..3da6919938a 100644 --- a/scripts/init.js +++ b/scripts/init.js @@ -91,6 +91,7 @@ module.exports = function(appPath, appName, verbose, originalDirectory) { console.log(' Removes this tool and copies build dependencies, configs,') console.log(' and scripts into the app directory.') console.log(' If you do this, you can’t go back!'); + // ... console.log(); console.log('We suggest that you begin by typing:'); console.log(); From e84287a94960d9f7d75b46f54c0159bfe57c4481 Mon Sep 17 00:00:00 2001 From: Brandon Newton Date: Sun, 11 Sep 2016 10:18:44 -0700 Subject: [PATCH 008/105] Remove comment --- scripts/init.js | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/init.js b/scripts/init.js index 3da6919938a..10e009d21ec 100644 --- a/scripts/init.js +++ b/scripts/init.js @@ -91,7 +91,6 @@ module.exports = function(appPath, appName, verbose, originalDirectory) { console.log(' Removes this tool and copies build dependencies, configs,') console.log(' and scripts into the app directory.') console.log(' If you do this, you can’t go back!'); - // ... console.log(); console.log('We suggest that you begin by typing:'); console.log(); From ec3819ba26ad34955abff30e73c18ea2b87bfad5 Mon Sep 17 00:00:00 2001 From: Anton Kaminsky Date: Fri, 5 Aug 2016 09:33:57 -0400 Subject: [PATCH 009/105] Small grammatical correction (#367) * Small grammatical correction * Fix another grammatical error for consistency --- scripts/start.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/start.js b/scripts/start.js index d76390084b6..fcd1338d3c3 100644 --- a/scripts/start.js +++ b/scripts/start.js @@ -265,8 +265,8 @@ detect(DEFAULT_PORT).then(port => { clearConsole(); var question = - chalk.yellow('Something is already running at port ' + DEFAULT_PORT + '.') + - '\n\nWould you like to run the app at another port instead?'; + chalk.yellow('Something is already running on port ' + DEFAULT_PORT + '.') + + '\n\nWould you like to run the app on another port instead?'; prompt(question, true).then(shouldChangePort => { if (shouldChangePort) { From 6d2314ef84d86efab80c0d8811f0212d2e3acb86 Mon Sep 17 00:00:00 2001 From: Dan Abramov Date: Fri, 5 Aug 2016 17:15:49 +0100 Subject: [PATCH 010/105] Clarify why we only need css?-autoprefixer in development Fixes #377 --- config/webpack.config.prod.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/config/webpack.config.prod.js b/config/webpack.config.prod.js index dbac03f1aaf..2a3b1a81868 100644 --- a/config/webpack.config.prod.js +++ b/config/webpack.config.prod.js @@ -116,7 +116,12 @@ module.exports = { include: [paths.appSrc, paths.appNodeModules], // "?-autoprefixer" disables autoprefixer in css-loader itself: // https://github.com/webpack/css-loader/issues/281 - // We already have it thanks to postcss. + // We already have it thanks to postcss. We only pass this flag in + // production because "css" loader only enables autoprefixer-powered + // removal of unnecessary prefixes when Uglify plugin is enabled. + // Webpack 1.x uses Uglify plugin as a signal to minify *all* the assets + // including CSS. This is confusing and will be removed in Webpack 2: + // https://github.com/webpack/webpack/issues/283 loader: ExtractTextPlugin.extract('style', 'css?-autoprefixer!postcss') // Note: this won't work without `new ExtractTextPlugin()` in `plugins`. }, From bf574e585a34be8e8b0adeb1c7be76bd21e3d5a5 Mon Sep 17 00:00:00 2001 From: Matt Brennan Date: Fri, 5 Aug 2016 17:27:25 +0100 Subject: [PATCH 011/105] add shebang to tasks scripts (#376) --- tasks/e2e.sh | 1 + tasks/release.sh | 1 + 2 files changed, 2 insertions(+) diff --git a/tasks/e2e.sh b/tasks/e2e.sh index 8189847f7f7..a1566a85bdb 100755 --- a/tasks/e2e.sh +++ b/tasks/e2e.sh @@ -1,3 +1,4 @@ +#!/bin/bash # Copyright (c) 2015-present, Facebook, Inc. # All rights reserved. # diff --git a/tasks/release.sh b/tasks/release.sh index b30ab86abd5..c52d7c40bef 100755 --- a/tasks/release.sh +++ b/tasks/release.sh @@ -1,3 +1,4 @@ +#!/bin/bash # Copyright (c) 2015-present, Facebook, Inc. # All rights reserved. # From 1fc930ae1f45fbd19a212a3314a9b37ef45595a7 Mon Sep 17 00:00:00 2001 From: Dan Abramov Date: Fri, 5 Aug 2016 18:39:50 +0100 Subject: [PATCH 012/105] Tweak Jest default settings (#378) Disable timer mocking and enable verbose output. --- config/jest/environment.js | 7 +++++++ scripts/eject.js | 1 + scripts/utils/createJestConfig.js | 4 +++- 3 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 config/jest/environment.js diff --git a/config/jest/environment.js b/config/jest/environment.js new file mode 100644 index 00000000000..e7c1df906c6 --- /dev/null +++ b/config/jest/environment.js @@ -0,0 +1,7 @@ +// Currently, Jest mocks setTimeout() and similar functions by default: +// https://facebook.github.io/jest/docs/timer-mocks.html +// We think this is confusing, so we disable this feature. +// If you see value in it, run `jest.useFakeTimers()` in individual tests. +beforeEach(() => { + jest.useRealTimers(); +}); diff --git a/scripts/eject.js b/scripts/eject.js index 82202d6eed9..55661d19285 100644 --- a/scripts/eject.js +++ b/scripts/eject.js @@ -41,6 +41,7 @@ prompt( path.join('config', 'webpack.config.prod.js'), path.join('config', 'jest', 'CSSStub.js'), path.join('config', 'jest', 'FileStub.js'), + path.join('config', 'jest', 'environment.js'), path.join('config', 'jest', 'transform.js'), path.join('scripts', 'build.js'), path.join('scripts', 'start.js'), diff --git a/scripts/utils/createJestConfig.js b/scripts/utils/createJestConfig.js index 282705f0dd3..d4ee867f473 100644 --- a/scripts/utils/createJestConfig.js +++ b/scripts/utils/createJestConfig.js @@ -19,7 +19,9 @@ module.exports = (resolve, rootDir) => { setupFiles: [ resolve('config/polyfills.js') ], - testEnvironment: 'node' + setupTestFrameworkScriptFile: resolve('config/jest/environment.js'), + testEnvironment: 'node', + verbose: true }; if (rootDir) { config.rootDir = rootDir; From 50b207be920b4dbc8d99599eda7e0f435482d9de Mon Sep 17 00:00:00 2001 From: Kamil Burzynski Date: Sat, 6 Aug 2016 10:54:22 +0200 Subject: [PATCH 013/105] Fixed typo (#382) --- template/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/template/README.md b/template/README.md index 441953eef69..65984ecafb9 100644 --- a/template/README.md +++ b/template/README.md @@ -489,7 +489,7 @@ This way, when you `fetch('/api/todos')` in development, the development server Conveniently, this avoids [CORS issues](http://stackoverflow.com/questions/21854516/understanding-ajax-cors-and-security-considerations) and error messages like this in development: ``` -Fetch API cannot load http://localhost:400/api/todos. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled. +Fetch API cannot load http://localhost:4000/api/todos. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled. ``` 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 will be redirected to the specified `proxy`. From 4c5f6ab026441e354c02a187f3bfbb91a4b6c3f7 Mon Sep 17 00:00:00 2001 From: Rifat Nabi Date: Mon, 8 Aug 2016 10:05:58 +0600 Subject: [PATCH 014/105] Creating a new app in the current directory (#368) * Creating a new app in the current directory * Fixed style mistakes --- global-cli/index.js | 24 ++++++++++++++++++------ global-cli/package.json | 1 + package.json | 1 + scripts/init.js | 24 +++++++++++++++++++++++- 4 files changed, 43 insertions(+), 7 deletions(-) diff --git a/global-cli/index.js b/global-cli/index.js index d1319aba06f..e8dc5a7184a 100644 --- a/global-cli/index.js +++ b/global-cli/index.js @@ -41,6 +41,7 @@ var spawn = require('cross-spawn'); var chalk = require('chalk'); var semver = require('semver'); var argv = require('minimist')(process.argv.slice(2)); +var pathExists = require('path-exists'); /** * Arguments: @@ -67,21 +68,20 @@ if (commands.length === 0) { createApp(commands[0], argv.verbose, argv['scripts-version']); function createApp(name, verbose, version) { - if (fs.existsSync(name)) { - console.log('The directory `' + name + '` already exists. Aborting.'); + var root = path.resolve(name); + if (!pathExists.sync(name)) { + fs.mkdirSync(root); + } else if (!isGitHubBoilerplate(root)) { + console.log('The directory `' + name + '` contains file(s) that could conflict. Aborting.'); process.exit(1); } - var root = path.resolve(name); var appName = path.basename(root); - console.log( 'Creating a new React app in ' + root + '.' ); console.log(); - fs.mkdirSync(root); - var packageJson = { name: appName, version: '0.0.1', @@ -166,3 +166,15 @@ function checkNodeVersion() { process.exit(1); } } + +// Check if GitHub boilerplate compatible +// https://github.com/facebookincubator/create-react-app/pull/368#issuecomment-237875655 +function isGitHubBoilerplate(root) { + var validFiles = [ + '.DS_Store', 'Thumbs.db', '.git', '.gitignore', 'README.md', 'LICENSE' + ]; + return fs.readdirSync(root) + .every(function(file) { + return validFiles.indexOf(file) >= 0; + }); +} diff --git a/global-cli/package.json b/global-cli/package.json index 3e98c4c939a..8d038be6783 100644 --- a/global-cli/package.json +++ b/global-cli/package.json @@ -20,6 +20,7 @@ "chalk": "^1.1.1", "cross-spawn": "^4.0.0", "minimist": "^1.2.0", + "path-exists": "^3.0.0", "semver": "^5.0.3" } } diff --git a/package.json b/package.json index bf3d853af2a..accba6a051f 100644 --- a/package.json +++ b/package.json @@ -66,6 +66,7 @@ "jest": "14.1.0", "json-loader": "0.5.4", "opn": "4.0.2", + "path-exists": "^3.0.0", "postcss-loader": "0.9.1", "promise": "7.1.1", "recursive-readdir": "2.0.0", diff --git a/scripts/init.js b/scripts/init.js index 10e009d21ec..5f1ca5a12ba 100644 --- a/scripts/init.js +++ b/scripts/init.js @@ -11,6 +11,8 @@ var chalk = require('chalk'); var fs = require('fs-extra'); var path = require('path'); var spawn = require('cross-spawn'); +var pathExists = require('path-exists'); +var chalk = require('chalk'); module.exports = function(appPath, appName, verbose, originalDirectory) { var ownPath = path.join(appPath, 'node_modules', 'react-scripts'); @@ -44,12 +46,28 @@ module.exports = function(appPath, appName, verbose, originalDirectory) { JSON.stringify(appPackage, null, 2) ); + var readmeExists = pathExists.sync(path.join(appPath, 'README.md')); + if (readmeExists) { + fs.renameSync(path.join(appPath, 'README.md'), path.join(appPath, 'README.old.md')); + } + // Copy the files for the user fs.copySync(path.join(ownPath, 'template'), appPath); // Rename gitignore after the fact to prevent npm from renaming it to .npmignore // See: https://github.com/npm/npm/issues/1862 - fs.move(path.join(appPath, 'gitignore'), path.join(appPath, '.gitignore'), []); + fs.move(path.join(appPath, 'gitignore'), path.join(appPath, '.gitignore'), [], function (err) { + if (err) { + // Append if there's already a `.gitignore` file there + if (err.code === 'EEXIST') { + var data = fs.readFileSync(path.join(appPath, 'gitignore')); + fs.appendFileSync(path.join(appPath, '.gitignore'), data); + fs.unlinkSync(path.join(appPath, 'gitignore')); + } else { + throw err; + } + } + }); // Run another npm install for react and react-dom console.log('Installing react and react-dom from npm...'); @@ -96,6 +114,10 @@ module.exports = function(appPath, appName, verbose, originalDirectory) { console.log(); console.log(' cd', cdpath); console.log(' ' + chalk.cyan('npm start')); + if (readmeExists) { + console.log(); + console.log(chalk.yellow('You had a `README.md` file, we renamed it to `README.old.md`')); + } console.log(); console.log('Happy hacking!'); }); From 08771190165ae61782e6c553daa7a85baf393652 Mon Sep 17 00:00:00 2001 From: Gregory Shehet Date: Mon, 8 Aug 2016 14:53:38 +0300 Subject: [PATCH 015/105] Update package.json (#397) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index accba6a051f..4f82dd29a13 100644 --- a/package.json +++ b/package.json @@ -66,7 +66,7 @@ "jest": "14.1.0", "json-loader": "0.5.4", "opn": "4.0.2", - "path-exists": "^3.0.0", + "path-exists": "3.0.0", "postcss-loader": "0.9.1", "promise": "7.1.1", "recursive-readdir": "2.0.0", From c00791dc7d46295da08c8d68f2daf08c163b0a37 Mon Sep 17 00:00:00 2001 From: Dan Abramov Date: Mon, 8 Aug 2016 13:50:49 +0100 Subject: [PATCH 016/105] Add Object.assign() polyfill (#399) --- config/polyfills.js | 4 ++++ package.json | 1 + 2 files changed, 5 insertions(+) diff --git a/config/polyfills.js b/config/polyfills.js index 1f71e4ac4f2..7e601502b24 100644 --- a/config/polyfills.js +++ b/config/polyfills.js @@ -8,3 +8,7 @@ if (typeof Promise === 'undefined') { // fetch() polyfill for making API calls. require('whatwg-fetch'); + +// Object.assign() is commonly used with React. +// It will use the native implementation if it's present and isn't buggy. +Object.assign = require('object-assign'); diff --git a/package.json b/package.json index 4f82dd29a13..4dafc9670e7 100644 --- a/package.json +++ b/package.json @@ -65,6 +65,7 @@ "http-proxy-middleware": "0.17.0", "jest": "14.1.0", "json-loader": "0.5.4", + "object-assign": "4.1.0", "opn": "4.0.2", "path-exists": "3.0.0", "postcss-loader": "0.9.1", From 457afbf7da9903a57ff64b3c6a5f3470398c14a5 Mon Sep 17 00:00:00 2001 From: Dan Abramov Date: Mon, 8 Aug 2016 13:58:40 +0100 Subject: [PATCH 017/105] Bump case-sensitive-paths-webpack-plugin Fixes #391 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 4dafc9670e7..4b83b1343fd 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,7 @@ "babel-preset-es2016": "6.11.3", "babel-preset-react": "6.11.1", "babel-runtime": "6.11.6", - "case-sensitive-paths-webpack-plugin": "1.1.2", + "case-sensitive-paths-webpack-plugin": "1.1.3", "chalk": "1.1.3", "connect-history-api-fallback": "1.2.0", "cross-spawn": "4.0.0", From 32d3b317b56ed25ffb5e981e68afe1f412a733ec Mon Sep 17 00:00:00 2001 From: Marco Botto Date: Mon, 8 Aug 2016 15:19:17 +0200 Subject: [PATCH 018/105] Add Surge.sh to deploy instructions (#379) * Add Surge.sh to deploy instructions * Add it also to the Table of Contents --- template/README.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/template/README.md b/template/README.md index 65984ecafb9..6245d730885 100644 --- a/template/README.md +++ b/template/README.md @@ -24,6 +24,7 @@ You can find the most recent version of this guide [here](https://github.com/fac - [Deployment](#deployment) - [Now](#now) - [Heroku](#heroku) + - [Surge](#surge) - [GitHub Pages](#github-pages) - [Something Missing?](#something-missing) @@ -519,6 +520,27 @@ See [this example](https://github.com/xkawi/create-react-app-now) for a zero-con Use the [Heroku Buildpack for create-react-app](https://github.com/mars/create-react-app-buildpack). +### Surge + +Install the Surge CLI if you haven't already by running `npm install -g surge`. Run the `surge` command and log in you or create a new account. You just need to specify the *build* folder and your custom domain, and you are done. + +```sh + email: email@domain.com + password: ******** + project path: /path/to/project/build + size: 7 files, 1.8 MB + domain: create-react-app.surge.sh + upload: [====================] 100%, eta: 0.0s + propagate on CDN: [====================] 100% + plan: Free + users: email@domain.com + IP Address: X.X.X.X + + Success! Project is published and running at create-react-app.surge.sh +``` + +Note that in order to support routers that use html5 `pushState` API, you may want to rename the `index.html` in your build folder to `200.html` before deploying to Surge. This [ensures that every URL falls back to that file](https://surge.sh/help/adding-a-200-page-for-client-side-routing). + ### GitHub Pages >Note: this feature is available with `react-scripts@0.2.0` and higher. From f44110c451a24f2cd7f2372af62dc88926c2fb55 Mon Sep 17 00:00:00 2001 From: Dan Abramov Date: Mon, 8 Aug 2016 14:23:12 +0100 Subject: [PATCH 019/105] Allow popular test path conventions (#400) --- scripts/utils/createJestConfig.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/scripts/utils/createJestConfig.js b/scripts/utils/createJestConfig.js index d4ee867f473..3072074807e 100644 --- a/scripts/utils/createJestConfig.js +++ b/scripts/utils/createJestConfig.js @@ -20,6 +20,12 @@ module.exports = (resolve, rootDir) => { resolve('config/polyfills.js') ], setupTestFrameworkScriptFile: resolve('config/jest/environment.js'), + testPathIgnorePatterns: ['/node_modules/', '/build/'], + // Allow three popular conventions: + // **/__tests__/*.js + // **/*.test.js + // **/*.spec.js + testRegex: '(__tests__/.*|\\.(test|spec))\\.js$', testEnvironment: 'node', verbose: true }; From 60d7321d6e2cb51747d2132aebacc8807989ae6b Mon Sep 17 00:00:00 2001 From: Dan Abramov Date: Mon, 8 Aug 2016 18:49:51 +0100 Subject: [PATCH 020/105] Make build output more chill --- scripts/build.js | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/scripts/build.js b/scripts/build.js index 1f3079f2594..b02d8dc3200 100644 --- a/scripts/build.js +++ b/scripts/build.js @@ -130,13 +130,13 @@ function build(previousSizeMap) { console.log('The ' + chalk.cyan('build') + ' folder is ready to be deployed.'); console.log('To publish it at ' + chalk.green(homepagePath) + ', run:'); console.log(); - console.log(' ' + chalk.blue('git') + chalk.cyan(' commit -am ') + chalk.yellow('"Save local changes"')); - console.log(' ' + chalk.blue('git') + chalk.cyan(' checkout -B gh-pages')); - console.log(' ' + chalk.blue('git') + chalk.cyan(' add -f build')); - console.log(' ' + chalk.blue('git') + chalk.cyan(' commit -am ' + chalk.yellow('"Rebuild website"'))); - console.log(' ' + chalk.blue('git') + chalk.cyan(' filter-branch -f --prune-empty --subdirectory-filter build')); - console.log(' ' + chalk.blue('git') + chalk.cyan(' push -f origin gh-pages')); - console.log(' ' + chalk.blue('git') + chalk.cyan(' checkout -')); + console.log(' ' + chalk.cyan('git') + ' commit -am ' + chalk.yellow('"Save local changes"')); + console.log(' ' + chalk.cyan('git') + ' checkout -B gh-pages'); + console.log(' ' + chalk.cyan('git') + ' add -f build'); + console.log(' ' + chalk.cyan('git') + ' commit -am ' + chalk.yellow('"Rebuild website"')); + console.log(' ' + chalk.cyan('git') + ' filter-branch -f --prune-empty --subdirectory-filter build'); + console.log(' ' + chalk.cyan('git') + ' push -f origin gh-pages'); + console.log(' ' + chalk.cyan('git') + ' checkout -'); console.log(); } else if (publicPath !== '/') { // "homepage": "http://mywebsite.com/project" @@ -163,9 +163,9 @@ function build(previousSizeMap) { console.log('The ' + chalk.cyan('build') + ' folder is ready to be deployed.'); console.log('You may also serve it locally with a static server:') console.log(); - console.log(' ' + chalk.blue('npm') + chalk.cyan(' install -g pushstate-server')); - console.log(' ' + chalk.blue('pushstate-server') + chalk.cyan(' build')); - console.log(' ' + chalk.blue(openCommand) + chalk.cyan(' http://localhost:9000')); + console.log(' ' + chalk.cyan('npm') + ' install -g pushstate-server'); + console.log(' ' + chalk.cyan('pushstate-server') + ' build'); + console.log(' ' + chalk.cyan(openCommand) + ' http://localhost:9000'); console.log(); } }); From 652757d2e34ed0efe0d3d1c4d52d673e02989db2 Mon Sep 17 00:00:00 2001 From: Dan Abramov Date: Mon, 8 Aug 2016 18:58:32 +0100 Subject: [PATCH 021/105] Make missing module output slimmer Thanks to @geowarin for the tip in https://github.com/facebookincubator/create-react-app/issues/401#issuecomment-238291901 --- scripts/start.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/scripts/start.js b/scripts/start.js index fcd1338d3c3..84cf4f71272 100644 --- a/scripts/start.js +++ b/scripts/start.js @@ -108,7 +108,9 @@ function setupCompiler(port) { // We have switched off the default Webpack output in WebpackDevServer // options so we are going to "massage" the warnings and errors and present // them in a readable focused way. - var json = stats.toJson(); + // We use stats.toJson({}, true) to make output more compact and readable: + // https://github.com/facebookincubator/create-react-app/issues/401#issuecomment-238291901 + var json = stats.toJson({}, true); var formattedErrors = json.errors.map(message => 'Error in ' + formatMessage(message) ); From 06cd148414fedb8f061efde32fde7af31146971a Mon Sep 17 00:00:00 2001 From: Luigi Maselli Date: Tue, 9 Aug 2016 12:42:37 +0200 Subject: [PATCH 022/105] Add React Native Web support (#407) --- config/webpack.config.dev.js | 3 ++- config/webpack.config.prod.js | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/config/webpack.config.dev.js b/config/webpack.config.dev.js index a3db11f8ec7..ae95e0d92b8 100644 --- a/config/webpack.config.dev.js +++ b/config/webpack.config.dev.js @@ -76,7 +76,8 @@ module.exports = { // if we don't have a good solution, we should just make `babel-runtime` // a dependency in generated projects. // See https://github.com/facebookincubator/create-react-app/issues/255 - 'babel-runtime/regenerator': require.resolve('babel-runtime/regenerator') + 'babel-runtime/regenerator': require.resolve('babel-runtime/regenerator'), + 'react-native': 'react-native-web' } }, // Resolve loaders (webpack plugins for CSS, images, transpilation) from the diff --git a/config/webpack.config.prod.js b/config/webpack.config.prod.js index 2a3b1a81868..66ca7a8cec1 100644 --- a/config/webpack.config.prod.js +++ b/config/webpack.config.prod.js @@ -71,7 +71,8 @@ module.exports = { // if we don't have a good solution, we should just make `babel-runtime` // a dependency in generated projects. // See https://github.com/facebookincubator/create-react-app/issues/255 - 'babel-runtime/regenerator': require.resolve('babel-runtime/regenerator') + 'babel-runtime/regenerator': require.resolve('babel-runtime/regenerator'), + 'react-native': 'react-native-web' } }, // Resolve loaders (webpack plugins for CSS, images, transpilation) from the From 82a72cc9f0183dbd556ec078048e4aa8fc787d78 Mon Sep 17 00:00:00 2001 From: Max Stoiber Date: Thu, 11 Aug 2016 23:04:29 +0200 Subject: [PATCH 023/105] Disable dot rule of connect-history-api-fallback (#422) Ref #387 --- package.json | 2 +- scripts/start.js | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 4b83b1343fd..77910fcf349 100644 --- a/package.json +++ b/package.json @@ -46,7 +46,7 @@ "babel-runtime": "6.11.6", "case-sensitive-paths-webpack-plugin": "1.1.3", "chalk": "1.1.3", - "connect-history-api-fallback": "1.2.0", + "connect-history-api-fallback": "1.3.0", "cross-spawn": "4.0.0", "css-loader": "0.23.1", "detect-port": "1.0.0", diff --git a/scripts/start.js b/scripts/start.js index 84cf4f71272..aa68ab40ff3 100644 --- a/scripts/start.js +++ b/scripts/start.js @@ -173,6 +173,8 @@ function addMiddleware(devServer) { // Every unrecognized request will be forwarded to it. var proxy = require(paths.appPackageJson).proxy; devServer.use(historyApiFallback({ + // Allow paths with dots in them to be loaded, reference issue #387 + disableDotRule: true, // For single page apps, we generally want to fallback to /index.html. // However we also want to respect `proxy` for API calls. // So if `proxy` is specified, we need to decide which fallback to use. From b3de3165c7736cf7237259ae86f4637f298219af Mon Sep 17 00:00:00 2001 From: Andrey Popp <8mayday@gmail.com> Date: Sat, 13 Aug 2016 00:37:54 +0300 Subject: [PATCH 024/105] Load favicon through html-loader. (#428) * Load favicon through html-loader. Fixes #291. * Add test for *.ico in e2e test suite * Configure html-loader to process * Address feedback on html-loader inclusion. * Place favicon.ico at the root of the build dir * Make comment style consistent between prod and dev webpack configs * Fix html-loader config in dev mode --- config/paths.js | 3 --- config/webpack.config.dev.js | 22 ++++++++++++++++++++-- config/webpack.config.prod.js | 30 ++++++++++++++++++++++++------ package.json | 1 + tasks/e2e.sh | 3 +++ template/index.html | 1 + template/{ => src}/favicon.ico | Bin 7 files changed, 49 insertions(+), 11 deletions(-) rename template/{ => src}/favicon.ico (100%) diff --git a/config/paths.js b/config/paths.js index 7645917fbc9..e6f2ff6cb3a 100644 --- a/config/paths.js +++ b/config/paths.js @@ -36,7 +36,6 @@ if (isInCreateReactAppSource) { module.exports = { appBuild: resolveOwn('../build'), appHtml: resolveOwn('../template/index.html'), - appFavicon: resolveOwn('../template/favicon.ico'), appPackageJson: resolveOwn('../package.json'), appSrc: resolveOwn('../template/src'), appNodeModules: resolveOwn('../node_modules'), @@ -47,7 +46,6 @@ if (isInCreateReactAppSource) { module.exports = { appBuild: resolveApp('build'), appHtml: resolveApp('index.html'), - appFavicon: resolveApp('favicon.ico'), appPackageJson: resolveApp('package.json'), appSrc: resolveApp('src'), appNodeModules: resolveApp('node_modules'), @@ -59,7 +57,6 @@ if (isInCreateReactAppSource) { module.exports = { appBuild: resolveApp('build'), appHtml: resolveApp('index.html'), - appFavicon: resolveApp('favicon.ico'), appPackageJson: resolveApp('package.json'), appSrc: resolveApp('src'), appNodeModules: resolveApp('node_modules'), diff --git a/config/webpack.config.dev.js b/config/webpack.config.dev.js index ae95e0d92b8..5e28bb7c916 100644 --- a/config/webpack.config.dev.js +++ b/config/webpack.config.dev.js @@ -126,13 +126,23 @@ module.exports = { // When you `import` an asset, you get its (virtual) filename. // In production, they would get copied to the `build` folder. { - test: /\.(jpg|png|gif|eot|svg|ttf|woff|woff2)(\?.*)?$/, + test: /\.(ico|jpg|png|gif|eot|svg|ttf|woff|woff2)(\?.*)?$/, include: [paths.appSrc, paths.appNodeModules], + exclude: /\/favicon.ico$/, loader: 'file', query: { name: 'static/media/[name].[ext]' } }, + // A special case for favicon.ico to place it into build root directory. + { + test: /\/favicon.ico$/, + include: [paths.appSrc], + loader: 'file', + query: { + name: 'favicon.ico?[hash:8]' + } + }, // "url" loader works just like "file" loader but it also embeds // assets smaller than specified size as data URLs to avoid requests. { @@ -143,6 +153,15 @@ module.exports = { limit: 10000, name: 'static/media/[name].[ext]' } + }, + // "html" loader is used to process template page (index.html) to resolve + // resources linked with HTML tags. + { + test: /\.html$/, + loader: 'html', + query: { + attrs: ['link:href'], + } } ] }, @@ -169,7 +188,6 @@ module.exports = { new HtmlWebpackPlugin({ inject: true, template: paths.appHtml, - favicon: paths.appFavicon, }), // Makes some environment variables available to the JS code, for example: // if (process.env.NODE_ENV === 'development') { ... }. See `env.js`. diff --git a/config/webpack.config.prod.js b/config/webpack.config.prod.js index 66ca7a8cec1..ffeb75a9488 100644 --- a/config/webpack.config.prod.js +++ b/config/webpack.config.prod.js @@ -126,23 +126,33 @@ module.exports = { loader: ExtractTextPlugin.extract('style', 'css?-autoprefixer!postcss') // Note: this won't work without `new ExtractTextPlugin()` in `plugins`. }, + // JSON is not enabled by default in Webpack but both Node and Browserify + // allow it implicitly so we also enable it. { - // JSON is not enabled by default in Webpack but both Node and Browserify - // allow it implicitly so we also enable it. test: /\.json$/, include: [paths.appSrc, paths.appNodeModules], loader: 'json' }, + // "file" loader makes sure those assets end up in the `build` folder. + // When you `import` an asset, you get its filename. { - // "file" loader makes sure those assets end up in the `build` folder. - // When you `import` an asset, you get its filename. - test: /\.(jpg|png|gif|eot|svg|ttf|woff|woff2)(\?.*)?$/, + test: /\.(ico|jpg|png|gif|eot|svg|ttf|woff|woff2)(\?.*)?$/, + exclude: /\/favicon.ico$/, include: [paths.appSrc, paths.appNodeModules], loader: 'file', query: { name: 'static/media/[name].[hash:8].[ext]' } }, + // A special case for favicon.ico to place it into build root directory. + { + test: /\/favicon.ico$/, + include: [paths.appSrc], + loader: 'file', + query: { + name: 'favicon.ico?[hash:8]' + } + }, // "url" loader works just like "file" loader but it also embeds // assets smaller than specified size as data URLs to avoid requests. { @@ -153,6 +163,15 @@ module.exports = { limit: 10000, name: 'static/media/[name].[hash:8].[ext]' } + }, + // "html" loader is used to process template page (index.html) to resolve + // resources linked with HTML tags. + { + test: /\.html$/, + loader: 'html', + query: { + attrs: ['link:href'], + } } ] }, @@ -181,7 +200,6 @@ module.exports = { new HtmlWebpackPlugin({ inject: true, template: paths.appHtml, - favicon: paths.appFavicon, minify: { removeComments: true, collapseWhitespace: true, diff --git a/package.json b/package.json index 77910fcf349..1b389da8005 100644 --- a/package.json +++ b/package.json @@ -61,6 +61,7 @@ "filesize": "3.3.0", "fs-extra": "0.30.0", "gzip-size": "3.0.0", + "html-loader": "0.4.3", "html-webpack-plugin": "2.22.0", "http-proxy-middleware": "0.17.0", "jest": "14.1.0", diff --git a/tasks/e2e.sh b/tasks/e2e.sh index a1566a85bdb..6e6c20c9420 100755 --- a/tasks/e2e.sh +++ b/tasks/e2e.sh @@ -67,6 +67,7 @@ test -e build/*.html test -e build/static/js/*.js test -e build/static/css/*.css test -e build/static/media/*.svg +test -e build/favicon.ico # Run tests npm run test @@ -96,6 +97,7 @@ test -e build/*.html test -e build/static/js/*.js test -e build/static/css/*.css test -e build/static/media/*.svg +test -e build/favicon.ico # Run tests npm run test @@ -113,6 +115,7 @@ test -e build/*.html test -e build/static/js/*.js test -e build/static/css/*.css test -e build/static/media/*.svg +test -e build/favicon.ico # Run tests npm run test diff --git a/template/index.html b/template/index.html index 72e10e94c6c..f89671553eb 100644 --- a/template/index.html +++ b/template/index.html @@ -3,6 +3,7 @@ + React App diff --git a/template/favicon.ico b/template/src/favicon.ico similarity index 100% rename from template/favicon.ico rename to template/src/favicon.ico From adb052980099bf9c97997a72e2bfc7b6f54e0250 Mon Sep 17 00:00:00 2001 From: Arunoda Susiripala Date: Tue, 16 Aug 2016 00:23:19 +0530 Subject: [PATCH 025/105] Add a hash to media files even in the devmode. (#446) This will work correctly when there are duplicate filenames in different paths. Fixes: #445 --- config/webpack.config.dev.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/webpack.config.dev.js b/config/webpack.config.dev.js index 5e28bb7c916..397acd315e9 100644 --- a/config/webpack.config.dev.js +++ b/config/webpack.config.dev.js @@ -131,7 +131,7 @@ module.exports = { exclude: /\/favicon.ico$/, loader: 'file', query: { - name: 'static/media/[name].[ext]' + name: 'static/media/[name].[hash:8].[ext]' } }, // A special case for favicon.ico to place it into build root directory. @@ -151,7 +151,7 @@ module.exports = { loader: 'url', query: { limit: 10000, - name: 'static/media/[name].[ext]' + name: 'static/media/[name].[hash:8].[ext]' } }, // "html" loader is used to process template page (index.html) to resolve From cda93e045141b47eb7084fb4b4c4c452ad982a31 Mon Sep 17 00:00:00 2001 From: Gregory Shehet Date: Thu, 18 Aug 2016 21:47:39 +0300 Subject: [PATCH 026/105] add otf font format to loaders (#434) * add off font format to loaders * add otf format support --- config/eslint.js | 2 +- config/webpack.config.dev.js | 2 +- config/webpack.config.prod.js | 2 +- scripts/utils/createJestConfig.js | 2 +- template/README.md | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/config/eslint.js b/config/eslint.js index 513ad2de02f..761add0f718 100644 --- a/config/eslint.js +++ b/config/eslint.js @@ -45,7 +45,7 @@ module.exports = { settings: { 'import/ignore': [ 'node_modules', - '\\.(json|css|jpg|png|gif|eot|svg|ttf|woff|woff2|mp4|webm)$', + '\\.(json|css|jpg|png|gif|eot|otf|svg|ttf|woff|woff2|mp4|webm)$', ], 'import/extensions': ['.js'], 'import/resolver': { diff --git a/config/webpack.config.dev.js b/config/webpack.config.dev.js index 397acd315e9..2b6da367f79 100644 --- a/config/webpack.config.dev.js +++ b/config/webpack.config.dev.js @@ -126,7 +126,7 @@ module.exports = { // When you `import` an asset, you get its (virtual) filename. // In production, they would get copied to the `build` folder. { - test: /\.(ico|jpg|png|gif|eot|svg|ttf|woff|woff2)(\?.*)?$/, + test: /\.(ico|jpg|png|gif|eot|otf|svg|ttf|woff|woff2)(\?.*)?$/, include: [paths.appSrc, paths.appNodeModules], exclude: /\/favicon.ico$/, loader: 'file', diff --git a/config/webpack.config.prod.js b/config/webpack.config.prod.js index ffeb75a9488..5781ae8636b 100644 --- a/config/webpack.config.prod.js +++ b/config/webpack.config.prod.js @@ -136,7 +136,7 @@ module.exports = { // "file" loader makes sure those assets end up in the `build` folder. // When you `import` an asset, you get its filename. { - test: /\.(ico|jpg|png|gif|eot|svg|ttf|woff|woff2)(\?.*)?$/, + test: /\.(ico|jpg|png|gif|eot|otf|svg|ttf|woff|woff2)(\?.*)?$/, exclude: /\/favicon.ico$/, include: [paths.appSrc, paths.appNodeModules], loader: 'file', diff --git a/scripts/utils/createJestConfig.js b/scripts/utils/createJestConfig.js index 3072074807e..a420e6fd6bc 100644 --- a/scripts/utils/createJestConfig.js +++ b/scripts/utils/createJestConfig.js @@ -11,7 +11,7 @@ module.exports = (resolve, rootDir) => { const config = { automock: false, moduleNameMapper: { - '^[./a-zA-Z0-9$_-]+\\.(jpg|png|gif|eot|svg|ttf|woff|woff2|mp4|webm)$': resolve('config/jest/FileStub.js'), + '^[./a-zA-Z0-9$_-]+\\.(jpg|png|gif|eot|otf|svg|ttf|woff|woff2|mp4|webm)$': resolve('config/jest/FileStub.js'), '^[./a-zA-Z0-9$_-]+\\.css$': resolve('config/jest/CSSStub.js') }, persistModuleRegistryBetweenSpecs: true, diff --git a/template/README.md b/template/README.md index 6245d730885..821b0b68a67 100644 --- a/template/README.md +++ b/template/README.md @@ -373,7 +373,7 @@ esproposal.class_static_fields=enable esproposal.class_instance_fields=enable module.name_mapper='^\(.*\)\.css$' -> 'react-scripts/config/flow/css' -module.name_mapper='^\(.*\)\.\(jpg\|png\|gif\|eot\|svg\|ttf\|woff\|woff2\|mp4\|webm\)$' -> 'react-scripts/config/flow/file' +module.name_mapper='^\(.*\)\.\(jpg\|png\|gif\|eot\|otf\|svg\|ttf\|woff\|woff2\|mp4\|webm\)$' -> 'react-scripts/config/flow/file' suppress_type=$FlowIssue suppress_type=$FlowFixMe @@ -385,7 +385,7 @@ If you later `eject`, you’ll need to replace `react-scripts` references with t ```ini module.name_mapper='^\(.*\)\.css$' -> '/config/flow/css' -module.name_mapper='^\(.*\)\.\(jpg\|png\|gif\|eot\|svg\|ttf\|woff\|woff2\|mp4\|webm\)$' -> '/config/flow/file' +module.name_mapper='^\(.*\)\.\(jpg\|png\|gif\|eot\|otf\|svg\|ttf\|woff\|woff2\|mp4\|webm\)$' -> '/config/flow/file' ``` We will consider integrating more tightly with Flow in the future so that you don’t have to do this. From ec9ff209a480f5d79029cf393dc4b5420194860d Mon Sep 17 00:00:00 2001 From: Robin Ricard Date: Mon, 22 Aug 2016 14:51:20 +0200 Subject: [PATCH 027/105] Deactivate the `new-cap` rule in ESLint (#470) This rule is considered dangerous in certain situations. This is especially true for Immutable.js users. See the discussion at issue #465 for more information about this. --- config/eslint.js | 1 - 1 file changed, 1 deletion(-) diff --git a/config/eslint.js b/config/eslint.js index 761add0f718..b2fb7dd7bdc 100644 --- a/config/eslint.js +++ b/config/eslint.js @@ -62,7 +62,6 @@ module.exports = { 'dot-location': ['warn', 'property'], eqeqeq: ['warn', 'allow-null'], 'guard-for-in': 'warn', - 'new-cap': ['warn', { newIsCap: true }], 'new-parens': 'warn', 'no-array-constructor': 'warn', 'no-caller': 'warn', From 230e10f5301b2ff3a01ecf403356cbc9535ecb4c Mon Sep 17 00:00:00 2001 From: Dan Abramov Date: Mon, 22 Aug 2016 19:47:49 +0100 Subject: [PATCH 028/105] Add 0.2.2 changelog (#475) --- CHANGELOG.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 04129633274..8f3786f6b6f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,16 @@ +## 0.2.2 (August 22, 2016) + +### Build Dependency (`react-scripts`) + +* `npm install`ing a missing dependency now forces a rebuild. ([@gaearon](https://github.com/gaearon) in [#349](https://github.com/facebookincubator/create-react-app/pull/349)) +* Autoprefixer config now includes more commonly supported browsers. ([@kripod](https://github.com/kripod) in [#345](https://github.com/facebookincubator/create-react-app/pull/345)) +* All the configuration is now documented inline so ejecting doesn’t leave you in the dark. ([@gaearon](https://github.com/gaearon) in [#362](https://github.com/facebookincubator/create-react-app/pull/362)) +* `Object.assign()` polyfill is now bundled by default. ([@gaearon](https://github.com/gaearon) in [#399](https://github.com/facebookincubator/create-react-app/pull/399)) +* [React Native Web](https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/) now works out of the box. ([@grigio](https://github.com/grigio) in [#407](https://github.com/facebookincubator/create-react-app/pull/407)) +* Same asset filenames in different folders don’t confuse the server now. ([@arunoda](https://github.com/arunoda) in [#446](https://github.com/facebookincubator/create-react-app/pull/446)) +* The `otf` font format is now supported. ([@A-gambit](https://github.com/A-gambit) in [#434](https://github.com/facebookincubator/create-react-app/pull/434)) +* The `new-cap` linting rule has been disabled thanks to feedback from Immutable.js users. ([@rricard](https://github.com/rricard) in [#470](https://github.com/facebookincubator/create-react-app/pull/470)) + ## 0.2.1 (August 1, 2016) ### Build Dependency (`react-scripts`) From 0feaf5ba71957323acb286f7c73717f2e5dd5652 Mon Sep 17 00:00:00 2001 From: Dan Abramov Date: Mon, 22 Aug 2016 19:48:59 +0100 Subject: [PATCH 029/105] Add migration instructions --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f3786f6b6f..066065fc0f8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,13 @@ * The `otf` font format is now supported. ([@A-gambit](https://github.com/A-gambit) in [#434](https://github.com/facebookincubator/create-react-app/pull/434)) * The `new-cap` linting rule has been disabled thanks to feedback from Immutable.js users. ([@rricard](https://github.com/rricard) in [#470](https://github.com/facebookincubator/create-react-app/pull/470)) +### Migrating from 0.2.1 to 0.2.2 + +Update `react-scripts` to point to `0.2.2` in your `package.json` and run `npm install`. You shouldn’t need to do anything else. + +Newly created projects will use `0.2.2` automatically. You **don’t** need to update the global `create-react-app` CLI itself. It stays at `0.2.0` for now because it doesn’t have any changes. + + ## 0.2.1 (August 1, 2016) ### Build Dependency (`react-scripts`) From f41439d3cbbb3f00bb40cfd79326e9fdf1a7c56a Mon Sep 17 00:00:00 2001 From: Dan Abramov Date: Mon, 22 Aug 2016 20:21:35 +0100 Subject: [PATCH 030/105] Link to Heroku article --- template/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/template/README.md b/template/README.md index 821b0b68a67..37800052b31 100644 --- a/template/README.md +++ b/template/README.md @@ -518,7 +518,8 @@ See [this example](https://github.com/xkawi/create-react-app-now) for a zero-con ### Heroku -Use the [Heroku Buildpack for create-react-app](https://github.com/mars/create-react-app-buildpack). +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). ### Surge From e528bd23197d2a4f1c2673e13300b6883ea864ba Mon Sep 17 00:00:00 2001 From: Felipe Moyano Date: Tue, 23 Aug 2016 10:13:13 -0500 Subject: [PATCH 031/105] Added support for webp images in #442 (#458) --- config/eslint.js | 2 +- config/webpack.config.dev.js | 2 +- config/webpack.config.prod.js | 2 +- scripts/utils/createJestConfig.js | 2 +- template/README.md | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/config/eslint.js b/config/eslint.js index b2fb7dd7bdc..eb2a87ce135 100644 --- a/config/eslint.js +++ b/config/eslint.js @@ -45,7 +45,7 @@ module.exports = { settings: { 'import/ignore': [ 'node_modules', - '\\.(json|css|jpg|png|gif|eot|otf|svg|ttf|woff|woff2|mp4|webm)$', + '\\.(json|css|jpg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm)$', ], 'import/extensions': ['.js'], 'import/resolver': { diff --git a/config/webpack.config.dev.js b/config/webpack.config.dev.js index 2b6da367f79..b93abcdad20 100644 --- a/config/webpack.config.dev.js +++ b/config/webpack.config.dev.js @@ -126,7 +126,7 @@ module.exports = { // When you `import` an asset, you get its (virtual) filename. // In production, they would get copied to the `build` folder. { - test: /\.(ico|jpg|png|gif|eot|otf|svg|ttf|woff|woff2)(\?.*)?$/, + test: /\.(ico|jpg|png|gif|eot|otf|webp|svg|ttf|woff|woff2)(\?.*)?$/, include: [paths.appSrc, paths.appNodeModules], exclude: /\/favicon.ico$/, loader: 'file', diff --git a/config/webpack.config.prod.js b/config/webpack.config.prod.js index 5781ae8636b..8b04ec4b650 100644 --- a/config/webpack.config.prod.js +++ b/config/webpack.config.prod.js @@ -136,7 +136,7 @@ module.exports = { // "file" loader makes sure those assets end up in the `build` folder. // When you `import` an asset, you get its filename. { - test: /\.(ico|jpg|png|gif|eot|otf|svg|ttf|woff|woff2)(\?.*)?$/, + test: /\.(ico|jpg|png|gif|eot|otf|webp|svg|ttf|woff|woff2)(\?.*)?$/, exclude: /\/favicon.ico$/, include: [paths.appSrc, paths.appNodeModules], loader: 'file', diff --git a/scripts/utils/createJestConfig.js b/scripts/utils/createJestConfig.js index a420e6fd6bc..8b6bfd52492 100644 --- a/scripts/utils/createJestConfig.js +++ b/scripts/utils/createJestConfig.js @@ -11,7 +11,7 @@ module.exports = (resolve, rootDir) => { const config = { automock: false, moduleNameMapper: { - '^[./a-zA-Z0-9$_-]+\\.(jpg|png|gif|eot|otf|svg|ttf|woff|woff2|mp4|webm)$': resolve('config/jest/FileStub.js'), + '^[./a-zA-Z0-9$_-]+\\.(jpg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm)$': resolve('config/jest/FileStub.js'), '^[./a-zA-Z0-9$_-]+\\.css$': resolve('config/jest/CSSStub.js') }, persistModuleRegistryBetweenSpecs: true, diff --git a/template/README.md b/template/README.md index 37800052b31..0395c0f496a 100644 --- a/template/README.md +++ b/template/README.md @@ -373,7 +373,7 @@ esproposal.class_static_fields=enable esproposal.class_instance_fields=enable module.name_mapper='^\(.*\)\.css$' -> 'react-scripts/config/flow/css' -module.name_mapper='^\(.*\)\.\(jpg\|png\|gif\|eot\|otf\|svg\|ttf\|woff\|woff2\|mp4\|webm\)$' -> 'react-scripts/config/flow/file' +module.name_mapper='^\(.*\)\.\(jpg\|png\|gif\|eot\|otf\|webp\|svg\|ttf\|woff\|woff2\|mp4\|webm\)$' -> 'react-scripts/config/flow/file' suppress_type=$FlowIssue suppress_type=$FlowFixMe @@ -385,7 +385,7 @@ If you later `eject`, you’ll need to replace `react-scripts` references with t ```ini module.name_mapper='^\(.*\)\.css$' -> '/config/flow/css' -module.name_mapper='^\(.*\)\.\(jpg\|png\|gif\|eot\|otf\|svg\|ttf\|woff\|woff2\|mp4\|webm\)$' -> '/config/flow/file' +module.name_mapper='^\(.*\)\.\(jpg\|png\|gif\|eot\|otf\|webp\|svg\|ttf\|woff\|woff2\|mp4\|webm\)$' -> '/config/flow/file' ``` We will consider integrating more tightly with Flow in the future so that you don’t have to do this. From 6965a3812d44d64715960823d7dcc5c04a942d27 Mon Sep 17 00:00:00 2001 From: Dan Abramov Date: Tue, 23 Aug 2016 23:19:37 +0100 Subject: [PATCH 032/105] Clarify "homepage" field has special meaning --- template/README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/template/README.md b/template/README.md index 0395c0f496a..e98584eaccc 100644 --- a/template/README.md +++ b/template/README.md @@ -552,6 +552,9 @@ Open your `package.json` and add a `homepage` field: "homepage": "http://myusername.github.io/my-app", ``` +**The above step is important!** +Create React App uses the `homepage` field to determine the root URL in the built HTML file. + Now, whenever you run `npm run build`, you will see a cheat sheet with a sequence of commands to deploy to GitHub pages: ```sh From fccf0c5e9c691ce23a98d99447a69c7cb8f49c49 Mon Sep 17 00:00:00 2001 From: Gautier Date: Wed, 24 Aug 2016 11:46:54 +0200 Subject: [PATCH 033/105] Correcting typo on README.md (#479) Small typo line 572 "becasue" to "because" --- template/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/template/README.md b/template/README.md index e98584eaccc..d6a97de9186 100644 --- a/template/README.md +++ b/template/README.md @@ -569,7 +569,7 @@ git checkout - You may copy and paste them, or put them into a custom shell script. You may also customize them for another hosting provider. -Note that GitHub Pages doesn't support routers that use the HTML5 `pushState` history API under the hood (for example, React Router using `browserHistory`). This is becasue when there is a fresh page load for a url like `http://user.github.io/todomvc/todos/42`, where `/todos/42` is a frontend route, the GitHub Pages server returns 404 because it knows nothing of `/todos/42`. If you want to add a router to a project hosted on GitHub Pages, here are a couple of solutions: +Note that GitHub Pages doesn't support routers that use the HTML5 `pushState` history API under the hood (for example, React Router using `browserHistory`). This is because when there is a fresh page load for a url like `http://user.github.io/todomvc/todos/42`, where `/todos/42` is a frontend route, the GitHub Pages server returns 404 because it knows nothing of `/todos/42`. If you want to add a router to a project hosted on GitHub Pages, here are a couple of solutions: * You could switch from using HTML5 history API to routing with hashes. If you use React Router, you can switch to `hashHistory` for this effect, but the URL will be longer and more verbose (for example, `http://user.github.io/todomvc/#/todos/42?_k=yknaj`). [Read more](https://github.com/reactjs/react-router/blob/master/docs/guides/Histories.md#histories) about different history implementations in React Router. * Alternatively, you can use a trick to teach GitHub Pages to handle 404 by redirecting to your `index.html` page with a special redirect parameter. You would need to add a `404.html` file with the redirection code to the `build` folder before deploying your project, and you’ll need to add code handling the redirect parameter to `index.html`. You can find a detailed explanation of this technique [in this guide](https://github.com/rafrex/spa-github-pages). From 087184d14e45c6445c70bba026228e35cc571bb5 Mon Sep 17 00:00:00 2001 From: Dan Abramov Date: Thu, 25 Aug 2016 11:10:49 +0100 Subject: [PATCH 034/105] Clarify 0.3.0 is not out yet --- template/README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/template/README.md b/template/README.md index d6a97de9186..ed745e73c9e 100644 --- a/template/README.md +++ b/template/README.md @@ -392,7 +392,8 @@ We will consider integrating more tightly with Flow in the future so that you do ## Adding Custom Environment Variables -> Note: this feature is available with `react-scripts@0.3.0` and higher. +**Note: this feature will be available with `react-scripts@0.3.0` and higher.** +**It is not released yet, but it will be a part of a future release.** 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 @@ -466,7 +467,8 @@ Check out [this tutorial](https://www.fullstackreact.com/articles/using-create-r ## Proxying API Requests in Development ->Note: this feature is available with `react-scripts@0.3.0` and higher. +**Note: this feature will be available with `react-scripts@0.3.0` and higher.** +**It is not released yet, but it will be a part of a future release.** People often serve the front-end React app from the same host and port as their backend implementation. For example, a production setup might look like this after the app is deployed: From 342cde9de42c60681d0574220c63a594d7f743b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krist=C3=B3f=20Poduszl=C3=B3?= Date: Thu, 25 Aug 2016 12:20:00 +0200 Subject: [PATCH 035/105] Fix default package version added by global CLI (#491) According to the official SemVer FAQ, versioning should start at 0.1.0 (http://semver.org/#how-should-i-deal-with-revisions-in-the-0yz-initial-development-phase) --- global-cli/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/global-cli/index.js b/global-cli/index.js index e8dc5a7184a..9a298b83a61 100644 --- a/global-cli/index.js +++ b/global-cli/index.js @@ -84,7 +84,7 @@ function createApp(name, verbose, version) { var packageJson = { name: appName, - version: '0.0.1', + version: '0.1.0', private: true, }; fs.writeFileSync( From 56b3f688ecca5bb4b5cb411ae790db16f0749af9 Mon Sep 17 00:00:00 2001 From: William Horton Date: Thu, 25 Aug 2016 06:32:11 -0400 Subject: [PATCH 036/105] Use most recent React version (#477) * Get latest version numbers of react and react-dom from npm before install. * Run separate npm installs for react, react-dom, and react-test-renderer. * Consolidate into a single npm install. * Fix misplaced parenthesis, add missing semicolon. * Add missing semicolon. --- scripts/init.js | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/scripts/init.js b/scripts/init.js index 5f1ca5a12ba..33279c156da 100644 --- a/scripts/init.js +++ b/scripts/init.js @@ -18,17 +18,10 @@ module.exports = function(appPath, appName, verbose, originalDirectory) { var ownPath = path.join(appPath, 'node_modules', 'react-scripts'); var appPackage = require(path.join(appPath, 'package.json')); - var ownPackage = require(path.join(ownPath, 'package.json')); // Copy over some of the devDependencies appPackage.dependencies = appPackage.dependencies || {}; appPackage.devDependencies = appPackage.devDependencies || {}; - ['react', 'react-dom'].forEach(function (key) { - appPackage.dependencies[key] = ownPackage.devDependencies[key]; - }); - ['react-test-renderer'].forEach(function (key) { - appPackage.devDependencies[key] = ownPackage.devDependencies[key]; - }); // Setup the script rules appPackage.scripts = {}; @@ -75,6 +68,10 @@ module.exports = function(appPath, appName, verbose, originalDirectory) { // TODO: having to do two npm installs is bad, can we avoid it? var args = [ 'install', + 'react', + 'react-dom', + 'react-test-renderer', + '--save', verbose && '--verbose' ].filter(function(e) { return e; }); var proc = spawn('npm', args, {stdio: 'inherit'}); From 219ce3339d43cbc548b333b20106382c55d91b2c Mon Sep 17 00:00:00 2001 From: Dan Abramov Date: Thu, 25 Aug 2016 13:34:27 +0100 Subject: [PATCH 037/105] =?UTF-8?q?Add=20missing=20Changelog=20entry?= =?UTF-8?q?=E2=80=94thanks=20@elijahmanor!?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 066065fc0f8..add65d9c673 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ### Build Dependency (`react-scripts`) +* When the bundle size changes, we now display the difference after build. ([@elijahmanor](https://github.com/elijahmanor) in [#340](https://github.com/facebookincubator/create-react-app/pull/340)) * `npm install`ing a missing dependency now forces a rebuild. ([@gaearon](https://github.com/gaearon) in [#349](https://github.com/facebookincubator/create-react-app/pull/349)) * Autoprefixer config now includes more commonly supported browsers. ([@kripod](https://github.com/kripod) in [#345](https://github.com/facebookincubator/create-react-app/pull/345)) * All the configuration is now documented inline so ejecting doesn’t leave you in the dark. ([@gaearon](https://github.com/gaearon) in [#362](https://github.com/facebookincubator/create-react-app/pull/362)) From b2d6d76ee9bc90b21636e592b46721bcade2e99b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krist=C3=B3f=20Poduszl=C3=B3?= Date: Thu, 25 Aug 2016 14:52:16 +0200 Subject: [PATCH 038/105] Started using babel-preset-latest (#490) * Started using babel-preset-latest * Updated babel dependencies * Remove redundant babel-plugin-syntax-async-functions * Disabled redundant regenerator transform --- config/babel.dev.js | 15 ++++++--------- config/babel.prod.js | 15 ++++++--------- package.json | 11 ++++------- 3 files changed, 16 insertions(+), 25 deletions(-) diff --git a/config/babel.dev.js b/config/babel.dev.js index 89096734713..56533109097 100644 --- a/config/babel.dev.js +++ b/config/babel.dev.js @@ -14,24 +14,21 @@ module.exports = { // It enables caching results in OS temporary directory for faster rebuilds. cacheDirectory: true, presets: [ - // let, const, destructuring, classes, modules - require.resolve('babel-preset-es2015'), - // exponentiation - require.resolve('babel-preset-es2016'), + // Latest stable ECMAScript features + require.resolve('babel-preset-latest'), // JSX, Flow require.resolve('babel-preset-react') ], plugins: [ - // function x(a, b, c,) { } - require.resolve('babel-plugin-syntax-trailing-function-commas'), - // await fetch() - require.resolve('babel-plugin-syntax-async-functions'), // class { handleClick = () => { } } require.resolve('babel-plugin-transform-class-properties'), // { ...todo, completed: true } require.resolve('babel-plugin-transform-object-rest-spread'), // function* () { yield 42; yield 43; } - require.resolve('babel-plugin-transform-regenerator'), + [require.resolve('babel-plugin-transform-regenerator'), { + // Async functions are converted to generators by babel-preset-latest + async: false + }], // Polyfills the runtime needed for async/await and generators [require.resolve('babel-plugin-transform-runtime'), { helpers: false, diff --git a/config/babel.prod.js b/config/babel.prod.js index 92491bfcacb..32f4bd66583 100644 --- a/config/babel.prod.js +++ b/config/babel.prod.js @@ -11,24 +11,21 @@ module.exports = { // Don't try to find .babelrc because we want to force this configuration. babelrc: false, presets: [ - // let, const, destructuring, classes, modules - require.resolve('babel-preset-es2015'), - // exponentiation - require.resolve('babel-preset-es2016'), + // Latest stable ECMAScript features + require.resolve('babel-preset-latest'), // JSX, Flow require.resolve('babel-preset-react') ], plugins: [ - // function x(a, b, c,) { } - require.resolve('babel-plugin-syntax-trailing-function-commas'), - // await fetch() - require.resolve('babel-plugin-syntax-async-functions'), // class { handleClick = () => { } } require.resolve('babel-plugin-transform-class-properties'), // { ...todo, completed: true } require.resolve('babel-plugin-transform-object-rest-spread'), // function* () { yield 42; yield 43; } - require.resolve('babel-plugin-transform-regenerator'), + [require.resolve('babel-plugin-transform-regenerator'), { + // Async functions are converted to generators by babel-preset-latest + async: false + }], // Polyfills the runtime needed for async/await and generators [require.resolve('babel-plugin-transform-runtime'), { helpers: false, diff --git a/package.json b/package.json index 1b389da8005..1694ded2b12 100644 --- a/package.json +++ b/package.json @@ -29,19 +29,16 @@ }, "dependencies": { "autoprefixer": "6.4.0", - "babel-core": "6.11.4", + "babel-core": "6.14.0", "babel-eslint": "6.1.2", "babel-jest": "14.1.0", - "babel-loader": "6.2.4", - "babel-plugin-syntax-async-functions": "6.8.0", - "babel-plugin-syntax-trailing-function-commas": "6.8.0", + "babel-loader": "6.2.5", "babel-plugin-transform-class-properties": "6.11.5", "babel-plugin-transform-object-rest-spread": "6.8.0", "babel-plugin-transform-react-constant-elements": "6.9.1", - "babel-plugin-transform-regenerator": "6.11.4", + "babel-plugin-transform-regenerator": "6.14.0", "babel-plugin-transform-runtime": "6.12.0", - "babel-preset-es2015": "6.9.0", - "babel-preset-es2016": "6.11.3", + "babel-preset-latest": "6.14.0", "babel-preset-react": "6.11.1", "babel-runtime": "6.11.6", "case-sensitive-paths-webpack-plugin": "1.1.3", From 459d6a316474daaddf7194fc71c1721fee1d8ab1 Mon Sep 17 00:00:00 2001 From: Dan Abramov Date: Thu, 25 Aug 2016 14:40:49 +0100 Subject: [PATCH 039/105] Prepare for 0.2.3 release --- template/README.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/template/README.md b/template/README.md index ed745e73c9e..4dd68fcd621 100644 --- a/template/README.md +++ b/template/README.md @@ -392,8 +392,7 @@ We will consider integrating more tightly with Flow in the future so that you do ## Adding Custom Environment Variables -**Note: this feature will be available with `react-scripts@0.3.0` and higher.** -**It is not released yet, but it will be a part of a future release.** +>Note: this feature is available with `react-scripts@0.2.3` and higher. 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 @@ -467,8 +466,7 @@ Check out [this tutorial](https://www.fullstackreact.com/articles/using-create-r ## Proxying API Requests in Development -**Note: this feature will be available with `react-scripts@0.3.0` and higher.** -**It is not released yet, but it will be a part of a future release.** +>Note: this feature is available with `react-scripts@0.2.3` and higher. People often serve the front-end React app from the same host and port as their backend implementation. For example, a production setup might look like this after the app is deployed: From 0fafa4659589979c1dcd90b490caa28e06a52a57 Mon Sep 17 00:00:00 2001 From: Dan Abramov Date: Thu, 25 Aug 2016 14:57:12 +0100 Subject: [PATCH 040/105] Update CHANGELOG.md (#492) --- CHANGELOG.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index add65d9c673..fb5fea84c92 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,21 @@ +## 0.2.3 (August 25, 2016) + +### Build Dependency (`react-scripts`) + +* You can now [proxy requests to an API server](https://github.com/facebookincubator/create-react-app/blob/ef94b0561d5afb9b50b905fa5cd3f94e965c69c0/template/README.md#proxying-api-requests-in-development) without worrying about CORS. ([@gaearon](https://github.com/gaearon) in [#282](https://github.com/facebookincubator/create-react-app/pull/282)) +* You can now [pass custom environment variables](https://github.com/facebookincubator/create-react-app/blob/ef94b0561d5afb9b50b905fa5cd3f94e965c69c0/template/README.md#adding-custom-environment-variables) to your application. ([@eliperelman](https://github.com/eliperelman) in [#342](https://github.com/facebookincubator/create-react-app/pull/342)) +* You can now [use `async` and `await`](https://ponyfoo.com/articles/understanding-javascript-async-await) syntax. ([@gaearon](https://github.com/gaearon) in [#327](https://github.com/facebookincubator/create-react-app/pull/327), [@fson](https://github.com/fson) in [#332](https://github.com/facebookincubator/create-react-app/pull/332)) +* Paths with period in them now load successfully on the development server. ([@mxstbr](https://github.com/mxstbr) in [#422](https://github.com/facebookincubator/create-react-app/pull/422)) +* Images with `.webp` extension are now supported. ([@gafemoyano](https://github.com/gafemoyano) in [#458](https://github.com/facebookincubator/create-react-app/pull/458)) +* The most recent version of React is now added to `package.json`. ([@wdhorton](https://github.com/wdhorton) in [#477](https://github.com/facebookincubator/create-react-app/pull/477)) +* Babel configuration is simplified. ([@kripod](https://github.com/kripod) in [#490](https://github.com/facebookincubator/create-react-app/pull/490)) + +### Migrating from 0.2.2 to 0.2.3 + +Update `react-scripts` to point to `0.2.3` in your `package.json` and run `npm install`. You shouldn’t need to do anything else. + +Newly created projects will use `0.2.3` automatically. You **don’t** need to update the global `create-react-app` CLI itself. It stays at `0.2.0` for now because it doesn’t have any changes. + ## 0.2.2 (August 22, 2016) ### Build Dependency (`react-scripts`) From cff9fcf54d9b74246731178757b0b2304ada556e Mon Sep 17 00:00:00 2001 From: Dan Abramov Date: Sun, 28 Aug 2016 13:32:17 +0100 Subject: [PATCH 041/105] Mark react-scripts as executable --- bin/react-scripts.js | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 bin/react-scripts.js diff --git a/bin/react-scripts.js b/bin/react-scripts.js old mode 100644 new mode 100755 From 85be952400a5c7404a0f14907f043fbd45595da9 Mon Sep 17 00:00:00 2001 From: Ville Immonen Date: Sun, 28 Aug 2016 20:49:25 +0300 Subject: [PATCH 042/105] Allow importing static file outside src and node_modules folders (#504) Remove the `include` setting from webpack loaders for CSS, JSON and other static assets. This way it's possible to import files from a separate config folder, a parent directory etc. --- config/webpack.config.dev.js | 4 ---- config/webpack.config.prod.js | 4 ---- 2 files changed, 8 deletions(-) diff --git a/config/webpack.config.dev.js b/config/webpack.config.dev.js index b93abcdad20..2a66d3dd816 100644 --- a/config/webpack.config.dev.js +++ b/config/webpack.config.dev.js @@ -112,14 +112,12 @@ module.exports = { // in development "style" loader enables hot editing of CSS. { test: /\.css$/, - include: [paths.appSrc, paths.appNodeModules], loader: 'style!css!postcss' }, // JSON is not enabled by default in Webpack but both Node and Browserify // allow it implicitly so we also enable it. { test: /\.json$/, - include: [paths.appSrc, paths.appNodeModules], loader: 'json' }, // "file" loader makes sure those assets get served by WebpackDevServer. @@ -127,7 +125,6 @@ module.exports = { // In production, they would get copied to the `build` folder. { test: /\.(ico|jpg|png|gif|eot|otf|webp|svg|ttf|woff|woff2)(\?.*)?$/, - include: [paths.appSrc, paths.appNodeModules], exclude: /\/favicon.ico$/, loader: 'file', query: { @@ -147,7 +144,6 @@ module.exports = { // assets smaller than specified size as data URLs to avoid requests. { test: /\.(mp4|webm)(\?.*)?$/, - include: [paths.appSrc, paths.appNodeModules], loader: 'url', query: { limit: 10000, diff --git a/config/webpack.config.prod.js b/config/webpack.config.prod.js index 8b04ec4b650..48a37d04e61 100644 --- a/config/webpack.config.prod.js +++ b/config/webpack.config.prod.js @@ -114,7 +114,6 @@ module.exports = { // in the main CSS file. { test: /\.css$/, - include: [paths.appSrc, paths.appNodeModules], // "?-autoprefixer" disables autoprefixer in css-loader itself: // https://github.com/webpack/css-loader/issues/281 // We already have it thanks to postcss. We only pass this flag in @@ -130,7 +129,6 @@ module.exports = { // allow it implicitly so we also enable it. { test: /\.json$/, - include: [paths.appSrc, paths.appNodeModules], loader: 'json' }, // "file" loader makes sure those assets end up in the `build` folder. @@ -138,7 +136,6 @@ module.exports = { { test: /\.(ico|jpg|png|gif|eot|otf|webp|svg|ttf|woff|woff2)(\?.*)?$/, exclude: /\/favicon.ico$/, - include: [paths.appSrc, paths.appNodeModules], loader: 'file', query: { name: 'static/media/[name].[hash:8].[ext]' @@ -157,7 +154,6 @@ module.exports = { // assets smaller than specified size as data URLs to avoid requests. { test: /\.(mp4|webm)(\?.*)?$/, - include: [paths.appSrc, paths.appNodeModules], loader: 'url', query: { limit: 10000, From 4aceb3ca468df512c33e56d25de2a245ed166037 Mon Sep 17 00:00:00 2001 From: Geoffroy Warin Date: Tue, 30 Aug 2016 01:32:43 +0200 Subject: [PATCH 043/105] Add tarec to the alternatives (#516) Shameless plug of course. If you want hot reloading and the best DX experience (friendly errors, desktop notifications, decorators, very fast reload times with dlls...) you should really check out [The Awsesom REact Cli](https://github.com/geowarin/tarec) (tarec). I have used it in numerous projects that now run in production and I continue to make it better day after day with a lot of love :smile: Typescript and SSR are on the roadmap! Thanks for create-react-app, it's an awesome project and a great source of inspiration :heart: --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index aac5d0b0f18..fcc1f93e18e 100644 --- a/README.md +++ b/README.md @@ -174,6 +174,7 @@ If you don’t agree with the choices made in this project, you might want to ex * [react-app](https://github.com/kriasoft/react-app) * [dev-toolkit](https://github.com/stoikerty/dev-toolkit) * [mozilla-neo](https://github.com/mozilla/neo) +* [tarec](https://github.com/geowarin/tarec) You can also use module bundlers like [webpack](http://webpack.github.io) and [Browserify](http://browserify.org/) directly.
React documentation includes [a walkthrough](https://facebook.github.io/react/docs/package-management.html) on this topic. From 0c0f57ce418b716871a01078b1f28e17be4785c4 Mon Sep 17 00:00:00 2001 From: Dan Abramov Date: Wed, 31 Aug 2016 12:31:10 +0100 Subject: [PATCH 044/105] Add instructions on tags --- template/README.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/template/README.md b/template/README.md index 4dd68fcd621..2e7c5df09cb 100644 --- a/template/README.md +++ b/template/README.md @@ -21,6 +21,7 @@ You can find the most recent version of this guide [here](https://github.com/fac - [Adding Custom Environment Variables](#adding-custom-environment-variables) - [Integrating with a Node Backend](#integrating-with-a-node-backend) - [Proxying API Requests in Development](#proxying-api-requests-in-development) +- [Adding `` Tags](#adding-meta-tags) - [Deployment](#deployment) - [Now](#now) - [Heroku](#heroku) @@ -501,6 +502,24 @@ 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)). * Use [environment variables](#adding-custom-environment-variables) to inject the right server host and port into your app. +## Adding `` Tags + +You can edit the generated `index.html` and add any tags you’d like to it. However, since Create React App doesn’t support server rendering, you might be wondering how to make `` tags dynamic and reflect the current URL. + +To solve this, we recommend to add placeholders into the HTML, like this: + +```html + + + + + +``` + +Then, on the server, regardless of the backend you use, you can read `index.html` into memory and replace `$OG_TITLE`, `$OG_DESCRIPTION`, and any other placeholders with values depending on the current URL. Just make sure to sanitize and escape the interpolated values so that they are safe to embed into HTML! + +If you use a Node server, you can even share the route matching logic between the client and the server. However duplicating it also works fine in simple cases. + ## Deployment By default, Create React App produces a build assuming your app is hosted at the server root. From 9a32f6d69b80e72ba4cc7fd3f34f3736718e4e98 Mon Sep 17 00:00:00 2001 From: Dan Abramov Date: Wed, 31 Aug 2016 14:00:57 +0100 Subject: [PATCH 045/105] Add a link back to CRA --- template/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/template/README.md b/template/README.md index 2e7c5df09cb..31c2802d041 100644 --- a/template/README.md +++ b/template/README.md @@ -1,3 +1,5 @@ +This project was bootstrapped with [Create React App](https://github.com/facebookincubator/create-react-app). + Below you will find some information on how to perform common tasks. You can find the most recent version of this guide [here](https://github.com/facebookincubator/create-react-app/blob/master/template/README.md). From 9488f55e6fe248d926e9c55c3b2afcfdf7e0b4c8 Mon Sep 17 00:00:00 2001 From: Dennis Ushakov Date: Wed, 31 Aug 2016 17:21:57 +0400 Subject: [PATCH 046/105] ignore .idea folder (#522) * ignore .idea folder this change is requred for IntelliJ-based products because project information files are written before actual generator is invoked * better method name and explanation --- global-cli/index.js | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/global-cli/index.js b/global-cli/index.js index 9a298b83a61..dc6262b71ac 100644 --- a/global-cli/index.js +++ b/global-cli/index.js @@ -71,7 +71,7 @@ function createApp(name, verbose, version) { var root = path.resolve(name); if (!pathExists.sync(name)) { fs.mkdirSync(root); - } else if (!isGitHubBoilerplate(root)) { + } else if (!isSafeToCreateProjectIn(root)) { console.log('The directory `' + name + '` contains file(s) that could conflict. Aborting.'); process.exit(1); } @@ -167,11 +167,12 @@ function checkNodeVersion() { } } -// Check if GitHub boilerplate compatible -// https://github.com/facebookincubator/create-react-app/pull/368#issuecomment-237875655 -function isGitHubBoilerplate(root) { +// If project only contains files generated by GH, it’s safe. +// We also special case IJ-based products .idea because it integrates with CRA: +// https://github.com/facebookincubator/create-react-app/pull/368#issuecomment-243446094 +function isSafeToCreateProjectIn(root) { var validFiles = [ - '.DS_Store', 'Thumbs.db', '.git', '.gitignore', 'README.md', 'LICENSE' + '.DS_Store', 'Thumbs.db', '.git', '.gitignore', '.idea', 'README.md', 'LICENSE' ]; return fs.readdirSync(root) .every(function(file) { From 7500793eec1f7a70869ba39f6938c1007f90374a Mon Sep 17 00:00:00 2001 From: Ville Immonen Date: Wed, 31 Aug 2016 16:58:46 +0300 Subject: [PATCH 047/105] Add a more prominent link to the guide (#524) * Add a more prominent link to the guide As a contributor, I know where to find the documentation/guide since know the codebase, but I've seen people miss the link to it in the README, because it's not very prominent. Let's try to make it more discoverable by including a link to it right on top of the page. * Make the wording of links more obvious * Rename the "How Do I...?" section to "User Guide" for consistency --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index fcc1f93e18e..2fa9f43d158 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,9 @@ Create React apps with no build configuration. +* [Getting Started](#getting-started) – How to create a new app. +* [User Guide](https://github.com/facebookincubator/create-react-app/blob/master/template/README.md) – How to develop apps bootstrapped with Create React App. + ## tl;dr ```sh @@ -81,7 +84,7 @@ It correctly bundles React in production mode and optimizes the build for the be The build is minified and the filenames include the hashes.
Your app is ready to be deployed! -## How Do I…? +## User Guide The generated project will include a guide in its README.
You can also read its latest version [here](https://github.com/facebookincubator/create-react-app/blob/master/template/README.md). From 46dd3b919905572d02d6ff9eb57b19b13a5ccd1a Mon Sep 17 00:00:00 2001 From: Cory House Date: Wed, 31 Aug 2016 10:28:19 -0500 Subject: [PATCH 048/105] Typo fix (#526) --- config/eslint.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/eslint.js b/config/eslint.js index eb2a87ce135..502cdfa4cf6 100644 --- a/config/eslint.js +++ b/config/eslint.js @@ -21,7 +21,7 @@ module.exports = { parser: 'babel-eslint', - // import plugin is termporarily disabled, scroll below to see why + // import plugin is temporarily disabled, scroll below to see why plugins: [/*'import', */'flowtype', 'jsx-a11y', 'react'], env: { From d2a01dc5a587e128fe2818ff2e92283bc904dbc6 Mon Sep 17 00:00:00 2001 From: Sophia Date: Wed, 31 Aug 2016 14:24:34 -0700 Subject: [PATCH 049/105] removing no-return-assign lint rule (#528) (#529) --- config/eslint.js | 1 - 1 file changed, 1 deletion(-) diff --git a/config/eslint.js b/config/eslint.js index 502cdfa4cf6..8eaeacbd73d 100644 --- a/config/eslint.js +++ b/config/eslint.js @@ -115,7 +115,6 @@ module.exports = { 'LabeledStatement', 'WithStatement', ], - 'no-return-assign': 'warn', 'no-script-url': 'warn', 'no-self-assign': 'warn', 'no-self-compare': 'warn', From ebf8a0db60bad0bcefc68ad5a8394f1edf42cf06 Mon Sep 17 00:00:00 2001 From: Dan Abramov Date: Thu, 1 Sep 2016 02:08:27 +0100 Subject: [PATCH 050/105] Update Jest (#530) * Update Jest * Remove default snapshot test * Fix a few things * Add a simple default test * App.spec.js -> App.test.js * Fix e2e test * Bump Jest --- config/jest/environment.js | 7 ------- package.json | 9 ++++----- scripts/eject.js | 11 +++++----- scripts/init.js | 11 +++++----- scripts/test.js | 7 ++++--- scripts/utils/createJestConfig.js | 17 +++------------- tasks/e2e.sh | 32 +++++++++++++++++------------- template/src/App.test.js | 10 ++++++++++ template/src/__tests__/App-test.js | 11 ---------- 9 files changed, 51 insertions(+), 64 deletions(-) delete mode 100644 config/jest/environment.js create mode 100644 template/src/App.test.js delete mode 100644 template/src/__tests__/App-test.js diff --git a/config/jest/environment.js b/config/jest/environment.js deleted file mode 100644 index e7c1df906c6..00000000000 --- a/config/jest/environment.js +++ /dev/null @@ -1,7 +0,0 @@ -// Currently, Jest mocks setTimeout() and similar functions by default: -// https://facebook.github.io/jest/docs/timer-mocks.html -// We think this is confusing, so we disable this feature. -// If you see value in it, run `jest.useFakeTimers()` in individual tests. -beforeEach(() => { - jest.useRealTimers(); -}); diff --git a/package.json b/package.json index 1694ded2b12..ee3f741fabc 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ "create-react-app": "node global-cli/index.js --scripts-version \"$PWD/`npm pack`\"", "e2e": "tasks/e2e.sh", "start": "node scripts/start.js --debug-template", - "test": "node scripts/test.js --debug-template" + "test": "node scripts/test.js --debug-template --watch --env=jsdom" }, "files": [ "PATENTS", @@ -31,7 +31,7 @@ "autoprefixer": "6.4.0", "babel-core": "6.14.0", "babel-eslint": "6.1.2", - "babel-jest": "14.1.0", + "babel-jest": "15.0.0", "babel-loader": "6.2.5", "babel-plugin-transform-class-properties": "6.11.5", "babel-plugin-transform-object-rest-spread": "6.8.0", @@ -61,7 +61,7 @@ "html-loader": "0.4.3", "html-webpack-plugin": "2.22.0", "http-proxy-middleware": "0.17.0", - "jest": "14.1.0", + "jest": "15.0.1", "json-loader": "0.5.4", "object-assign": "4.1.0", "opn": "4.0.2", @@ -80,8 +80,7 @@ "devDependencies": { "bundle-deps": "1.0.0", "react": "^15.3.0", - "react-dom": "^15.3.0", - "react-test-renderer": "^15.3.0" + "react-dom": "^15.3.0" }, "optionalDependencies": { "fsevents": "1.0.14" diff --git a/scripts/eject.js b/scripts/eject.js index 55661d19285..74d1cf09f12 100644 --- a/scripts/eject.js +++ b/scripts/eject.js @@ -41,7 +41,6 @@ prompt( path.join('config', 'webpack.config.prod.js'), path.join('config', 'jest', 'CSSStub.js'), path.join('config', 'jest', 'FileStub.js'), - path.join('config', 'jest', 'environment.js'), path.join('config', 'jest', 'transform.js'), path.join('scripts', 'build.js'), path.join('scripts', 'start.js'), @@ -99,17 +98,19 @@ prompt( }); console.log('Updating scripts'); + delete appPackage.scripts['eject']; Object.keys(appPackage.scripts).forEach(function (key) { - appPackage.scripts[key] = 'node ./scripts/' + key + '.js' + appPackage.scripts[key] = appPackage.scripts[key] + .replace(/react-scripts test/g, 'jest') + .replace(/react-scripts (\w+)/g, 'node scripts/$1.js'); }); - delete appPackage.scripts['eject']; - appPackage.scripts.test = 'jest'; + // Add Jest config appPackage.jest = createJestConfig( filePath => path.join('', filePath) ); - // explicitly specify ESLint config path for editor plugins + // Explicitly specify ESLint config path for editor plugins appPackage.eslintConfig = { extends: './config/eslint.js', }; diff --git a/scripts/init.js b/scripts/init.js index 33279c156da..e79e3fdbfaa 100644 --- a/scripts/init.js +++ b/scripts/init.js @@ -24,10 +24,12 @@ module.exports = function(appPath, appName, verbose, originalDirectory) { appPackage.devDependencies = appPackage.devDependencies || {}; // Setup the script rules - appPackage.scripts = {}; - ['start', 'build', 'eject', 'test'].forEach(function(command) { - appPackage.scripts[command] = 'react-scripts ' + command; - }); + appPackage.scripts = { + 'start': 'react-scripts start', + 'build': 'react-scripts build', + 'test': 'react-scripts test --watch --env=jsdom', + 'eject': 'react-scripts eject' + }; // explicitly specify ESLint config path for editor plugins appPackage.eslintConfig = { @@ -70,7 +72,6 @@ module.exports = function(appPath, appName, verbose, originalDirectory) { 'install', 'react', 'react-dom', - 'react-test-renderer', '--save', verbose && '--verbose' ].filter(function(e) { return e; }); diff --git a/scripts/test.js b/scripts/test.js index f11cda5a428..b173656b5db 100644 --- a/scripts/test.js +++ b/scripts/test.js @@ -16,9 +16,10 @@ const paths = require('../config/paths'); const argv = process.argv.slice(2); -const index = argv.indexOf('--debug-template'); -if (index !== -1) { - argv.splice(index, 1); +// Don't pass this option to Jest +const debugTemplateIndex = argv.indexOf('--debug-template'); +if (debugTemplateIndex !== -1) { + argv.splice(debugTemplateIndex, 1); } argv.push('--config', JSON.stringify(createJestConfig( diff --git a/scripts/utils/createJestConfig.js b/scripts/utils/createJestConfig.js index 8b6bfd52492..21b8ca54364 100644 --- a/scripts/utils/createJestConfig.js +++ b/scripts/utils/createJestConfig.js @@ -9,25 +9,14 @@ module.exports = (resolve, rootDir) => { const config = { - automock: false, moduleNameMapper: { '^[./a-zA-Z0-9$_-]+\\.(jpg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm)$': resolve('config/jest/FileStub.js'), '^[./a-zA-Z0-9$_-]+\\.css$': resolve('config/jest/CSSStub.js') }, - persistModuleRegistryBetweenSpecs: true, scriptPreprocessor: resolve('config/jest/transform.js'), - setupFiles: [ - resolve('config/polyfills.js') - ], - setupTestFrameworkScriptFile: resolve('config/jest/environment.js'), - testPathIgnorePatterns: ['/node_modules/', '/build/'], - // Allow three popular conventions: - // **/__tests__/*.js - // **/*.test.js - // **/*.spec.js - testRegex: '(__tests__/.*|\\.(test|spec))\\.js$', - testEnvironment: 'node', - verbose: true + setupFiles: [resolve('config/polyfills.js')], + testPathIgnorePatterns: ['/(build|docs|node_modules)/'], + testEnvironment: 'node' }; if (rootDir) { config.rootDir = rootDir; diff --git a/tasks/e2e.sh b/tasks/e2e.sh index 6e6c20c9420..1e841d8699a 100755 --- a/tasks/e2e.sh +++ b/tasks/e2e.sh @@ -12,7 +12,8 @@ cd "$(dirname "$0")" function cleanup { echo 'Cleaning up.' cd $initial_path - rm ../template/src/__tests__/__snapshots__/App-test.js.snap + # Uncomment when snapshot testing is enabled by default: + # rm ../template/src/__snapshots__/App.test.js.snap rm -rf $temp_cli_path $temp_app_path } @@ -53,12 +54,9 @@ perl -i -p0e 's/bundledDependencies.*?]/bundledDependencies": []/s' package.json npm install scripts_path=$PWD/`npm pack` -# lint +# Lint ./node_modules/.bin/eslint --ignore-path .gitignore ./ -# Test local start command -npm start -- --smoke-test - # Test local build command npm run build @@ -69,9 +67,13 @@ test -e build/static/css/*.css test -e build/static/media/*.svg test -e build/favicon.ico -# Run tests -npm run test -test -e template/src/__tests__/__snapshots__/App-test.js.snap +# Run tests, overriding watch option to disable it +npm test -- --watch=no +# Uncomment when snapshot testing is enabled by default: +# test -e template/src/__snapshots__/App.test.js.snap + +# Test local start command +npm start -- --smoke-test # Pack CLI cd global-cli @@ -99,9 +101,10 @@ test -e build/static/css/*.css test -e build/static/media/*.svg test -e build/favicon.ico -# Run tests -npm run test -test -e src/__tests__/__snapshots__/App-test.js.snap +# Run tests, overriding watch option to disable it +npm test -- --watch=no +# Uncomment when snapshot testing is enabled by default: +# test -e src/__snapshots__/App.test.js.snap # Test the server npm start -- --smoke-test @@ -117,9 +120,10 @@ test -e build/static/css/*.css test -e build/static/media/*.svg test -e build/favicon.ico -# Run tests -npm run test -test -e src/__tests__/__snapshots__/App-test.js.snap +# Run tests, overriding watch option to disable it +npm test -- --watch=no +# Uncomment when snapshot testing is enabled by default: +# test -e src/__snapshots__/App.test.js.snap # Test the server npm start -- --smoke-test diff --git a/template/src/App.test.js b/template/src/App.test.js new file mode 100644 index 00000000000..55dbf38ce2c --- /dev/null +++ b/template/src/App.test.js @@ -0,0 +1,10 @@ +import React from 'react'; +import ReactDOM from 'react-dom'; +import App from './App'; + +describe('App', () => { + it('renders without crashing', () => { + const div = document.createElement('div'); + ReactDOM.render(, div); + }); +}); diff --git a/template/src/__tests__/App-test.js b/template/src/__tests__/App-test.js deleted file mode 100644 index 7d36ff192a2..00000000000 --- a/template/src/__tests__/App-test.js +++ /dev/null @@ -1,11 +0,0 @@ -import React from 'react'; -import App from '../App'; -import renderer from 'react-test-renderer'; - -describe('App', () => { - it('renders a welcome view', () => { - const instance = renderer.create(); - const tree = instance.toJSON(); - expect(tree).toMatchSnapshot(); - }); -}); From 1086150d6fbfb5488bc72794513e2d4bc15eb3ec Mon Sep 17 00:00:00 2001 From: Dan Abramov Date: Thu, 1 Sep 2016 02:09:00 +0100 Subject: [PATCH 051/105] 0.3.0-beta --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ee3f741fabc..08901febcb7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-scripts", - "version": "0.3.0-alpha", + "version": "0.3.0-beta", "description": "Configuration and scripts for Create React App.", "repository": "facebookincubator/create-react-app", "license": "BSD-3-Clause", From 95dcae8f82a38132514697524924d9d23dbdaaf2 Mon Sep 17 00:00:00 2001 From: Dan Abramov Date: Thu, 1 Sep 2016 17:25:21 +0100 Subject: [PATCH 052/105] Enable watch implicitly unless on CI (#533) Fixes #532 --- package.json | 2 +- scripts/eject.js | 2 +- scripts/init.js | 2 +- scripts/test.js | 5 +++++ tasks/e2e.sh | 11 ++++++----- 5 files changed, 14 insertions(+), 8 deletions(-) diff --git a/package.json b/package.json index 08901febcb7..1899f89b5cb 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ "create-react-app": "node global-cli/index.js --scripts-version \"$PWD/`npm pack`\"", "e2e": "tasks/e2e.sh", "start": "node scripts/start.js --debug-template", - "test": "node scripts/test.js --debug-template --watch --env=jsdom" + "test": "node scripts/test.js --debug-template --env=jsdom" }, "files": [ "PATENTS", diff --git a/scripts/eject.js b/scripts/eject.js index 74d1cf09f12..7fef22687b3 100644 --- a/scripts/eject.js +++ b/scripts/eject.js @@ -101,7 +101,7 @@ prompt( delete appPackage.scripts['eject']; Object.keys(appPackage.scripts).forEach(function (key) { appPackage.scripts[key] = appPackage.scripts[key] - .replace(/react-scripts test/g, 'jest') + .replace(/react-scripts test/g, 'jest --watch') .replace(/react-scripts (\w+)/g, 'node scripts/$1.js'); }); diff --git a/scripts/init.js b/scripts/init.js index e79e3fdbfaa..c618d2ea109 100644 --- a/scripts/init.js +++ b/scripts/init.js @@ -27,7 +27,7 @@ module.exports = function(appPath, appName, verbose, originalDirectory) { appPackage.scripts = { 'start': 'react-scripts start', 'build': 'react-scripts build', - 'test': 'react-scripts test --watch --env=jsdom', + 'test': 'react-scripts test --env=jsdom', 'eject': 'react-scripts eject' }; diff --git a/scripts/test.js b/scripts/test.js index b173656b5db..b8d047333ad 100644 --- a/scripts/test.js +++ b/scripts/test.js @@ -22,6 +22,11 @@ if (debugTemplateIndex !== -1) { argv.splice(debugTemplateIndex, 1); } +// Watch unless on CI +if (!process.env.CI) { + argv.push('--watch'); +} + argv.push('--config', JSON.stringify(createJestConfig( relativePath => path.resolve(__dirname, '..', relativePath), path.resolve(paths.appSrc, '..') diff --git a/tasks/e2e.sh b/tasks/e2e.sh index 1e841d8699a..4fedfe63bac 100755 --- a/tasks/e2e.sh +++ b/tasks/e2e.sh @@ -67,8 +67,8 @@ test -e build/static/css/*.css test -e build/static/media/*.svg test -e build/favicon.ico -# Run tests, overriding watch option to disable it -npm test -- --watch=no +# Run tests with CI flag +CI=true npm test # Uncomment when snapshot testing is enabled by default: # test -e template/src/__snapshots__/App.test.js.snap @@ -101,8 +101,8 @@ test -e build/static/css/*.css test -e build/static/media/*.svg test -e build/favicon.ico -# Run tests, overriding watch option to disable it -npm test -- --watch=no +# Run tests with CI flag +CI=true npm test # Uncomment when snapshot testing is enabled by default: # test -e src/__snapshots__/App.test.js.snap @@ -120,7 +120,8 @@ test -e build/static/css/*.css test -e build/static/media/*.svg test -e build/favicon.ico -# Run tests, overriding watch option to disable it +# Run tests, overring the watch option to disable it +# TODO: make CI flag respected after ejecting as well npm test -- --watch=no # Uncomment when snapshot testing is enabled by default: # test -e src/__snapshots__/App.test.js.snap From 6f5594a15ba2e5d4e9ac6e4de2ae0c48349ec5bc Mon Sep 17 00:00:00 2001 From: Dan Abramov Date: Thu, 1 Sep 2016 17:51:28 +0100 Subject: [PATCH 053/105] Disable react-constant-elements because of bugs (#534) Disabled because of issues: * https://github.com/facebookincubator/create-react-app/issues/525 * https://phabricator.babeljs.io/search/query/pCNlnC2xzwzx/ TODO: Enable again when these issues are resolved. --- config/babel.prod.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/config/babel.prod.js b/config/babel.prod.js index 32f4bd66583..107872181f5 100644 --- a/config/babel.prod.js +++ b/config/babel.prod.js @@ -33,6 +33,10 @@ module.exports = { regenerator: true }], // Optimization: hoist JSX that never changes out of render() - require.resolve('babel-plugin-transform-react-constant-elements') + // Disabled because of issues: + // * https://github.com/facebookincubator/create-react-app/issues/525 + // * https://phabricator.babeljs.io/search/query/pCNlnC2xzwzx/ + // TODO: Enable again when these issues are resolved. + // require.resolve('babel-plugin-transform-react-constant-elements') ] }; From e47502b4c282b30a347d5f358dd8709b4df7dcb3 Mon Sep 17 00:00:00 2001 From: Dan Abramov Date: Thu, 1 Sep 2016 18:01:11 +0100 Subject: [PATCH 054/105] Resolve babel-runtime relative to the config (#535) This makes generators work with Jest. Fixes #255. Replaces #262. --- config/babel.dev.js | 7 ++++++- config/babel.prod.js | 7 ++++++- config/webpack.config.dev.js | 11 ++--------- config/webpack.config.prod.js | 11 ++--------- package.json | 2 +- 5 files changed, 17 insertions(+), 21 deletions(-) diff --git a/config/babel.dev.js b/config/babel.dev.js index 56533109097..ebaab1156b3 100644 --- a/config/babel.dev.js +++ b/config/babel.dev.js @@ -7,6 +7,8 @@ * of patent rights can be found in the PATENTS file in the same directory. */ +var path = require('path'); + module.exports = { // Don't try to find .babelrc because we want to force this configuration. babelrc: false, @@ -33,7 +35,10 @@ module.exports = { [require.resolve('babel-plugin-transform-runtime'), { helpers: false, polyfill: false, - regenerator: true + regenerator: true, + // Resolve the Babel runtime relative to the config. + // You can safely remove this after ejecting: + moduleName: path.dirname(require.resolve('babel-runtime/package')) }] ] }; diff --git a/config/babel.prod.js b/config/babel.prod.js index 107872181f5..d1f105f575a 100644 --- a/config/babel.prod.js +++ b/config/babel.prod.js @@ -7,6 +7,8 @@ * of patent rights can be found in the PATENTS file in the same directory. */ +var path = require('path'); + module.exports = { // Don't try to find .babelrc because we want to force this configuration. babelrc: false, @@ -30,7 +32,10 @@ module.exports = { [require.resolve('babel-plugin-transform-runtime'), { helpers: false, polyfill: false, - regenerator: true + regenerator: true, + // Resolve the Babel runtime relative to the config. + // You can safely remove this after ejecting: + moduleName: path.dirname(require.resolve('babel-runtime/package')) }], // Optimization: hoist JSX that never changes out of render() // Disabled because of issues: diff --git a/config/webpack.config.dev.js b/config/webpack.config.dev.js index 2a66d3dd816..c72435ac813 100644 --- a/config/webpack.config.dev.js +++ b/config/webpack.config.dev.js @@ -68,15 +68,8 @@ module.exports = { // These are the reasonable defaults supported by the Node ecosystem. extensions: ['.js', '.json', ''], alias: { - // This `alias` section can be safely removed after ejection. - // We do this because `babel-runtime` may be inside `react-scripts`, - // so when `babel-plugin-transform-runtime` imports it, it will not be - // available to the app directly. This is a temporary solution that lets - // us ship support for generators. However it is far from ideal, and - // if we don't have a good solution, we should just make `babel-runtime` - // a dependency in generated projects. - // See https://github.com/facebookincubator/create-react-app/issues/255 - 'babel-runtime/regenerator': require.resolve('babel-runtime/regenerator'), + // Support React Native Web + // https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/ 'react-native': 'react-native-web' } }, diff --git a/config/webpack.config.prod.js b/config/webpack.config.prod.js index 48a37d04e61..e64758b8f51 100644 --- a/config/webpack.config.prod.js +++ b/config/webpack.config.prod.js @@ -63,15 +63,8 @@ module.exports = { // These are the reasonable defaults supported by the Node ecosystem. extensions: ['.js', '.json', ''], alias: { - // This `alias` section can be safely removed after ejection. - // We do this because `babel-runtime` may be inside `react-scripts`, - // so when `babel-plugin-transform-runtime` imports it, it will not be - // available to the app directly. This is a temporary solution that lets - // us ship support for generators. However it is far from ideal, and - // if we don't have a good solution, we should just make `babel-runtime` - // a dependency in generated projects. - // See https://github.com/facebookincubator/create-react-app/issues/255 - 'babel-runtime/regenerator': require.resolve('babel-runtime/regenerator'), + // Support React Native Web + // https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/ 'react-native': 'react-native-web' } }, diff --git a/package.json b/package.json index 1899f89b5cb..5dbf4b918d0 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,7 @@ "babel-plugin-transform-object-rest-spread": "6.8.0", "babel-plugin-transform-react-constant-elements": "6.9.1", "babel-plugin-transform-regenerator": "6.14.0", - "babel-plugin-transform-runtime": "6.12.0", + "babel-plugin-transform-runtime": "6.15.0", "babel-preset-latest": "6.14.0", "babel-preset-react": "6.11.1", "babel-runtime": "6.11.6", From 70535b0e3140ca17119f0263007bdef9080bd097 Mon Sep 17 00:00:00 2001 From: Dan Abramov Date: Thu, 1 Sep 2016 18:26:07 +0100 Subject: [PATCH 055/105] Remove unnecessary describe() --- template/src/App.test.js | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/template/src/App.test.js b/template/src/App.test.js index 55dbf38ce2c..b84af98d720 100644 --- a/template/src/App.test.js +++ b/template/src/App.test.js @@ -2,9 +2,7 @@ import React from 'react'; import ReactDOM from 'react-dom'; import App from './App'; -describe('App', () => { - it('renders without crashing', () => { - const div = document.createElement('div'); - ReactDOM.render(, div); - }); +it('renders without crashing', () => { + const div = document.createElement('div'); + ReactDOM.render(, div); }); From 38d1faf3cf150b305e6196b0fd19198a0cd82972 Mon Sep 17 00:00:00 2001 From: Dan Abramov Date: Thu, 1 Sep 2016 20:40:15 +0100 Subject: [PATCH 056/105] Update deps --- config/eslint.js | 1 + package.json | 20 ++++++++++---------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/config/eslint.js b/config/eslint.js index 8eaeacbd73d..e42a2a5e2b4 100644 --- a/config/eslint.js +++ b/config/eslint.js @@ -121,6 +121,7 @@ module.exports = { 'no-sequences': 'warn', 'no-shadow-restricted-names': 'warn', 'no-sparse-arrays': 'warn', + 'no-template-curly-in-string': 'warn', 'no-this-before-super': 'warn', 'no-throw-literal': 'warn', 'no-undef': 'warn', diff --git a/package.json b/package.json index 5dbf4b918d0..3a09697203a 100644 --- a/package.json +++ b/package.json @@ -45,13 +45,13 @@ "chalk": "1.1.3", "connect-history-api-fallback": "1.3.0", "cross-spawn": "4.0.0", - "css-loader": "0.23.1", + "css-loader": "0.24.0", "detect-port": "1.0.0", - "eslint": "3.2.2", - "eslint-loader": "1.4.1", - "eslint-plugin-flowtype": "2.4.0", + "eslint": "3.4.0", + "eslint-loader": "1.5.0", + "eslint-plugin-flowtype": "2.11.4", "eslint-plugin-import": "1.12.0", - "eslint-plugin-jsx-a11y": "2.0.1", + "eslint-plugin-jsx-a11y": "2.2.1", "eslint-plugin-react": "5.2.2", "extract-text-webpack-plugin": "1.0.1", "file-loader": "0.9.0", @@ -60,21 +60,21 @@ "gzip-size": "3.0.0", "html-loader": "0.4.3", "html-webpack-plugin": "2.22.0", - "http-proxy-middleware": "0.17.0", - "jest": "15.0.1", + "http-proxy-middleware": "0.17.1", + "jest": "15.1.0", "json-loader": "0.5.4", "object-assign": "4.1.0", "opn": "4.0.2", "path-exists": "3.0.0", - "postcss-loader": "0.9.1", + "postcss-loader": "0.11.1", "promise": "7.1.1", "recursive-readdir": "2.0.0", "rimraf": "2.5.4", "strip-ansi": "3.0.1", "style-loader": "0.13.1", "url-loader": "0.5.7", - "webpack": "1.13.1", - "webpack-dev-server": "1.14.1", + "webpack": "1.13.2", + "webpack-dev-server": "1.15.1", "whatwg-fetch": "1.0.0" }, "devDependencies": { From 45038c9c4af4a349716f4a77f538f8f2511375e1 Mon Sep 17 00:00:00 2001 From: Dan Abramov Date: Fri, 2 Sep 2016 00:37:37 +0100 Subject: [PATCH 057/105] Document testing (#538) * Document testing * Update README.md * Update README.md * Clarify our recommendations on testing * Okay, that was too much. :-) * Add a few more things --- README.md | 14 ++- template/README.md | 216 ++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 225 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 2fa9f43d158..0541db4b8d5 100644 --- a/README.md +++ b/README.md @@ -58,6 +58,7 @@ my-app/ src/ App.css App.js + App.test.js index.css index.js logo.svg @@ -76,6 +77,13 @@ You will see the build errors and lint warnings in the console. Build errors +### `npm test` + +Runs the test watcher in an interactive mode. +By default, runs tests related to files changes since the last commit. + +[Read more about testing.](template/README.md#running-tests) + ### `npm run build` Builds the app for production to the `build` folder.
@@ -108,7 +116,7 @@ You can also read its latest version [here](https://github.com/facebookincubator * Autoprefixed CSS, so you don’t need `-webkit` or other prefixes. * A `build` script to bundle JS, CSS, and images for production, with sourcemaps. -**The feature set is intentionally limited**. It doesn’t support advanced features such as server rendering or CSS modules. Currently, it doesn’t support testing either. The tool is also **non-configurable** because it is hard to provide a cohesive experience and easy updates across a set of tools when the user can tweak anything. +**The feature set is intentionally limited**. It doesn’t support advanced features such as server rendering or CSS modules. The tool is also **non-configurable** because it is hard to provide a cohesive experience and easy updates across a set of tools when the user can tweak anything. **You don’t have to use this.** Historically it has been easy to [gradually adopt](https://www.youtube.com/watch?v=BF58ZJ1ZQxY) React. However many people create new single-page React apps from scratch every day. We’ve heard [loud](https://medium.com/@ericclemmons/javascript-fatigue-48d4011b6fc4) and [clear](https://twitter.com/thomasfuchs/status/708675139253174273) that this process can be error-prone and tedious, especially if this is your first JavaScript build stack. This project is an attempt to figure out a good way to start developing React apps. @@ -127,7 +135,6 @@ You don’t have to ever use `eject`. The curated feature set is suitable for sm Some features are currently **not supported**: * Server rendering. -* Testing. * Some experimental syntax extensions (e.g. decorators). * CSS Modules. * LESS or Sass. @@ -144,7 +151,8 @@ Currently it is a thin layer on top of many amazing community projects, such as: * [Babel](http://babeljs.io/) with ES6 and extensions used by Facebook (JSX, [object spread](https://github.com/sebmarkbage/ecmascript-rest-spread/commits/master), [class properties](https://github.com/jeffmo/es-class-public-fields)) * [Autoprefixer](https://github.com/postcss/autoprefixer) * [ESLint](http://eslint.org/) -* and more. +* [Jest](http://facebook.github.io/jest) +* and others. All of them are transitive dependencies of the provided npm package. diff --git a/template/README.md b/template/README.md index 31c2802d041..d4134eb23b8 100644 --- a/template/README.md +++ b/template/README.md @@ -10,6 +10,7 @@ You can find the most recent version of this guide [here](https://github.com/fac - [Folder Structure](#folder-structure) - [Available Scripts](#available-scripts) - [npm start](#npm-start) + - [npm test](#npm-test) - [npm run build](#npm-run-build) - [npm run eject](#npm-run-eject) - [Displaying Lint Output in the Editor](#displaying-lint-output-in-the-editor) @@ -24,6 +25,17 @@ You can find the most recent version of this guide [here](https://github.com/fac - [Integrating with a Node Backend](#integrating-with-a-node-backend) - [Proxying API Requests in Development](#proxying-api-requests-in-development) - [Adding `` Tags](#adding-meta-tags) +- [Running Tests](#running-tests) + - [Filename Conventions](#filename-conventions) + - [Command Line Interface](#command-line-interface) + - [Version Control Integration](#version-control-integration) + - [Writing Tests](#writing-tests) + - [Testing Components](#testing-components) + - [Using Third Party Assertion Libraries](#using-third-party-assertion-libraries) + - [Coverage Reporting](#coverage-reporting) + - [Continuous Integration](#continuous-integration) + - [Disabling jsdom](#disabling-jsdom) + - [Experimental Snapshot Testing](#experimental-snapshot-testing) - [Deployment](#deployment) - [Now](#now) - [Heroku](#heroku) @@ -97,6 +109,11 @@ Open [http://localhost:3000](http://localhost:3000) to view it in the browser. The page will reload if you make edits.
You will also see any lint errors in the console. +### `npm test` + +Launches the test runner in the interactive watch mode. +See the section about [running tests](#running-tests) for more information. + ### `npm run build` Builds the app for production to the `build` folder.
@@ -425,7 +442,7 @@ render() { The above form is looking for a variable called `REACT_APP_SECRET_CODE` from the environment. In order to consume this value, we need to have it defined in the environment: -### Windows (cmd.exe) +#### Windows (cmd.exe) ```cmd set REACT_APP_SECRET_CODE=abcdef&&npm start @@ -433,7 +450,7 @@ set REACT_APP_SECRET_CODE=abcdef&&npm start (Note: the lack of whitespace is intentional.) -### Linux, OS X (Bash) +#### Linux, OS X (Bash) ```bash REACT_APP_SECRET_CODE=abcdef npm start @@ -522,6 +539,201 @@ Then, on the server, regardless of the backend you use, you can read `index.html If you use a Node server, you can even share the route matching logic between the client and the server. However duplicating it also works fine in simple cases. +## Running Tests + +>Note: this feature is available with `react-scripts@0.3.0` and higher. +>[Read the migration guide to learn how to enable it in older projects!](https://github.com/facebookincubator/create-react-app/blob/master/CHANGELOG.md#migrating-from-023-to-030) + +Create React App uses [Jest](https://facebook.github.io/jest/) as its test runner. To prepare for this integration, we did a [major revamp](https://facebook.github.io/jest/blog/2016/09/01/jest-15.html) of Jest so if you heard bad things about it, give it another try. + +Jest is a Node-based runner. This means that the tests always run in a Node environment and not in a real browser. This lets us enable fast iteration speed and prevent flakiness. + +While Jest provides browser globals such as `window` thanks to [jsdom](https://github.com/tmpvar/jsdom), they are only approximations of the real browser behavior. Jest is intended to be used for unit tests of your logic and your components rather than the DOM quirks. + +We recommend that you use a separate tool for browser end-to-end tests if you need them. They are beyond the scope of Create React App. + +### Filename Conventions + +Jest will look for test files with any of the following popular naming conventions: + +* Files with `.js` suffix in `__tests__` folders. +* Files with `.test.js` suffix. +* Files with `.spec.js` suffix. + +The `.test.js` / `.spec.js` files (or the `__tests__` folders) can be located at any depth under the `src` top level folder. + +We recommend to put the test files (or `__tests__` folders) next to the code they are testing so that relative imports appear shorter. For example, if `App.test.js` and `App.js` are in the same folder, the test just needs to `import App from './App'` instead of a long relative path. + +### Command Line Interface + +When you run `npm test`, Jest will launch in the watch mode. Every time you save a file, it will re-run the tests, just like `npm start` recompiles the code. + +The watcher includes an interactive command-line interface with the ability to run all tests, or focus on a search pattern. It is designed this way so that you could keep it open and enjoy fast re-runs. You can learn the commands from the “Watch Usage” note that the watcher prints after every run: + +![Jest watch mode](http://facebook.github.io/jest/img/blog/15-watch.gif) + +### Version Control Integration + +By default, when you run `npm test`, Jest will only run the tests related to files changed since last commit. This is an optimization designed to make your tests runs fast regardless of how many tests you have. However it assumes that you don’t often commit the code that doesn’t pass the tests. + +Jest will always explicitly mention that it only ran tests related to the files changed since the last commit. You can also press `a` in the watch mode to force Jest to run all tests. + +Jest will always run all tests on a [continuous integration](#continuous-integration) server or if the project is not inside a Git or Mercurial repository. + +### Writing Tests + +To create tests, add `it()` blocks with the name of the test and its code. You may optionally wrap them in `describe()` blocks for logical grouping but this is neither required nor recommended. + +Jest provides a built-in `expect()` global function for making assertions. A basic test could look like this: + +```js +import sum from './sum'; + +it('sums numbers', () => { + expect(sum(1, 2)).toEqual(3); + expect(sum(2, 2)).toEqual(4); +}); +``` + +All `expect()` matchers supported by Jest are [extensively documented here](http://facebook.github.io/jest/docs/api.html#expect-value). +You can also use [`jest.fn()` and `expect(fn).toBeCalled()`](http://facebook.github.io/jest/docs/api.html#tobecalled) to create “spies” or mock functions. + +### Testing Components + +There is a broad spectrum of component testing techniques. They range from a “smoke test” verifying that a component renders without throwing, to shallow rendering and testing some of the output, to full rendering and testing component lifecycle and state changes. + +Different projects choose different testing tradeoffs based on how often components change, and how much logic they contain. If you haven’t decided on a testing strategy yet, we recommend that you start with creating simple smoke tests for your components: + +```js +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); +}); +``` + +This test mounts a component and makes sure that it didn’t throw during rendering. Tests like this provide a lot value with very little effort so they are great as a starting point, and this is the test you will find in `src/App.test.js`. + +When you encounter bugs caused by changing components, you will gain a deeper insight into which parts of them are worth testing in your application. This might be a good time to introduce more specific tests asserting specific expected output or behavior. + +If you’d like to test components in isolation from the child components they render, we recommend using [`shallow()` rendering API](http://airbnb.io/enzyme/docs/api/shallow.html) from [Enzyme](http://airbnb.io/enzyme/). You can write a smoke test with it too: + +```sh +npm install --save-dev enzyme react-addons-test-utils +``` + +```js +import React from 'react'; +import { shallow } from 'enzyme'; +import App from './App'; + +it('renders without crashing', () => { + shallow(); +}); +``` + +Unlike the previous smoke test using `ReactDOM.render()`, this test only renders `` and doesn’t go deeper. For example, even if `` itself renders a `