mirror of
https://github.com/zhigang1992/create-react-app.git
synced 2026-06-16 10:24:16 +08:00
Merge commit '84be4dd0bdf6155c075f9e9bee9f075d8982d0cd' into merge-facebook-master
This commit is contained in:
4
.gitignore
vendored
4
.gitignore
vendored
@@ -5,6 +5,8 @@ build
|
||||
my-app*
|
||||
template/src/__tests__/__snapshots__/
|
||||
lerna-debug.log
|
||||
npm-debug.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
/.changelog
|
||||
yarn.lock
|
||||
|
||||
18
.travis.yml
18
.travis.yml
@@ -1,7 +1,6 @@
|
||||
---
|
||||
language: node_js
|
||||
node_js:
|
||||
- 0.10
|
||||
- 4
|
||||
- 6
|
||||
cache:
|
||||
@@ -9,7 +8,18 @@ cache:
|
||||
- node_modules
|
||||
- packages/create-react-app/node_modules
|
||||
- packages/react-scripts/node_modules
|
||||
script: tasks/e2e.sh
|
||||
script:
|
||||
- 'if [ $TEST_SUITE = "simple" ]; then tasks/e2e-simple.sh; fi'
|
||||
- 'if [ $TEST_SUITE = "installs" ]; then tasks/e2e-installs.sh; fi'
|
||||
- 'if [ $TEST_SUITE = "kitchensink" ]; then tasks/e2e-kitchensink.sh; fi'
|
||||
env:
|
||||
- USE_YARN=no
|
||||
- USE_YARN=yes
|
||||
global:
|
||||
- USE_YARN=no
|
||||
matrix:
|
||||
- TEST_SUITE=simple
|
||||
- TEST_SUITE=installs
|
||||
- TEST_SUITE=kitchensink
|
||||
matrix:
|
||||
include:
|
||||
- node_js: 6
|
||||
env: USE_YARN=yes TEST_SUITE=simple
|
||||
|
||||
155
CHANGELOG.md
155
CHANGELOG.md
@@ -1,3 +1,156 @@
|
||||
## 0.9.0 (2017-02-11)
|
||||
|
||||
#### :rocket: New Feature
|
||||
* `react-scripts`
|
||||
* [#1489](https://github.com/facebookincubator/create-react-app/pull/1489) Support setting "homepage" to "." to generate relative asset paths. ([@tibdex](https://github.com/tibdex))
|
||||
|
||||
This addition allows any application not using the HTML5 pushState API to be built to be served from any relative URL.
|
||||
* [#937](https://github.com/facebookincubator/create-react-app/pull/1504) Add `PUBLIC_URL` env variable for advanced use. ([@EnoahNetzach](https://github.com/EnoahNetzach))
|
||||
* [#1440](https://github.com/facebookincubator/create-react-app/pull/1440) Make all react env vars accessible in index.html. ([@jihchi](https://github.com/jihchi))
|
||||
* `react-dev-utils`
|
||||
* [#1148](https://github.com/facebookincubator/create-react-app/pull/1148) Configure which browser to open in npm start (#873). ([@GAumala](https://github.com/GAumala))
|
||||
|
||||
You can now disable the automatic browser launching by setting the `BROWSER` environment variable to `none`.
|
||||
|
||||
#### :boom: Breaking Change
|
||||
* `react-scripts`
|
||||
* [#1522](https://github.com/facebookincubator/create-react-app/pull/1522) Upgrade dependencies. ([@Timer](https://github.com/Timer))
|
||||
* [#1432](https://github.com/facebookincubator/create-react-app/pull/1432) Bump Jest version. ([@gaearon](https://github.com/gaearon))
|
||||
|
||||
Jest has been updated to v18 and has introduced some [breaking changes](https://facebook.github.io/jest/blog/2016/12/15/2016-in-jest.html).
|
||||
|
||||
* `react-scripts`, `react-dev-utils`
|
||||
* [#1148](https://github.com/facebookincubator/create-react-app/pull/1148) Configure which browser to open in npm start (#873). ([@GAumala](https://github.com/GAumala))
|
||||
|
||||
Non-interactive terminals no longer automatically disable launching of the browser.
|
||||
|
||||
#### :bug: Bug Fix
|
||||
* `react-scripts`
|
||||
* [#1522](https://github.com/facebookincubator/create-react-app/pull/1522) Upgrade dependencies. ([@Timer](https://github.com/Timer))
|
||||
* [#1458](https://github.com/facebookincubator/create-react-app/pull/1458) eject: Additionally remove `react-scripts` from dependencies. ([@creynders](https://github.com/creynders))
|
||||
* [#1441](https://github.com/facebookincubator/create-react-app/pull/1441) Added babel-runtime dependency to deduplicate dependencies when using yarn. ([@jkimbo](https://github.com/jkimbo))
|
||||
* [#1309](https://github.com/facebookincubator/create-react-app/pull/1309) Bump babel-loader version (#1009). ([@frontsideair](https://github.com/frontsideair))
|
||||
* [#1267](https://github.com/facebookincubator/create-react-app/pull/1267) Only gitignore dirs in root, not deep. ([@jayphelps](https://github.com/jayphelps))
|
||||
* `react-dev-utils`
|
||||
* [#1377](https://github.com/facebookincubator/create-react-app/pull/1377) webpack-dev-server patch for 'still-ok' success status. ([@TheBlackBolt](https://github.com/TheBlackBolt))
|
||||
* [#1274](https://github.com/facebookincubator/create-react-app/pull/1274) Downgrading to compatible version of SockJS-Client. ([@holloway](https://github.com/holloway))
|
||||
* [#1247](https://github.com/facebookincubator/create-react-app/pull/1247) Only open Chrome tab if BROWSER is missing or is Chrome. ([@gaearon](https://github.com/gaearon))
|
||||
|
||||
#### :nail_care: Enhancement
|
||||
* `react-scripts`
|
||||
* [#1507](https://github.com/facebookincubator/create-react-app/pull/1507) fix: add yarn gitignores. ([@adjohnson916](https://github.com/adjohnson916))
|
||||
* [#1496](https://github.com/facebookincubator/create-react-app/pull/1496) Make build exit with error code when interrupted. ([@brandones](https://github.com/brandones))
|
||||
* [#1510](https://github.com/facebookincubator/create-react-app/pull/1510) Add missing '\n' to the end of `package.json` file. ([@pd4d10](https://github.com/pd4d10))
|
||||
* [#1352](https://github.com/facebookincubator/create-react-app/pull/1352) More descriptive error message for env.CI = true warnings causing failures. ([@jayphelps](https://github.com/jayphelps))
|
||||
* [#1432](https://github.com/facebookincubator/create-react-app/pull/1432) Bump Jest version. ([@gaearon](https://github.com/gaearon))
|
||||
* [#1324](https://github.com/facebookincubator/create-react-app/pull/1324) Use npm script hooks to avoid && in deploy script. ([@zpao](https://github.com/zpao))
|
||||
* [#1311](https://github.com/facebookincubator/create-react-app/pull/1311) Updated react-scripts babel-jest && jest packages to 18.0.0. ([@lopezator](https://github.com/lopezator))
|
||||
* [#1264](https://github.com/facebookincubator/create-react-app/pull/1264) Remove interactive shell check when opening browser on start. ([@CaryLandholt](https://github.com/CaryLandholt))
|
||||
* `create-react-app`
|
||||
* [#1270](https://github.com/facebookincubator/create-react-app/pull/1270) gh-1269: Enabling nested folder paths for project name. ([@dinukadesilva](https://github.com/dinukadesilva))
|
||||
|
||||
#### :memo: Documentation
|
||||
* `react-scripts`
|
||||
* [#1515](https://github.com/facebookincubator/create-react-app/pull/1515) readme: Advanced Configuration. ([@Timer](https://github.com/Timer))
|
||||
* [#1513](https://github.com/facebookincubator/create-react-app/pull/1513) clarifying the use of custom environment variables. ([@calweb](https://github.com/calweb))
|
||||
* [#1511](https://github.com/facebookincubator/create-react-app/pull/1511) Change "OS X" references to "macOS". ([@RodrigoHahn](https://github.com/RodrigoHahn))
|
||||
* [#1482](https://github.com/facebookincubator/create-react-app/pull/1482) Edit User Guide: Add ESLint config for VS Code users. ([@vulong23](https://github.com/vulong23))
|
||||
* [#1483](https://github.com/facebookincubator/create-react-app/pull/1483) Reflect websocket proxy support on README (#1013). ([@frontsideair](https://github.com/frontsideair))
|
||||
* [#1453](https://github.com/facebookincubator/create-react-app/pull/1453) Readme: Removes experimental from Jest snapshot. ([@frehner](https://github.com/frehner))
|
||||
* [#1437](https://github.com/facebookincubator/create-react-app/pull/1437) Added links to tutorials for integrating cra with an api backend. ([@alexdriaguine](https://github.com/alexdriaguine))
|
||||
* [#1422](https://github.com/facebookincubator/create-react-app/pull/1422) Add causes of dev server not detecting changes. ([@jetpackpony](https://github.com/jetpackpony))
|
||||
* [#1260](https://github.com/facebookincubator/create-react-app/pull/1260) Heroku Deployment: Adds a note on how to resolve "File/Module Not Found Errors" . ([@MsUzoAgu](https://github.com/MsUzoAgu))
|
||||
* [#1256](https://github.com/facebookincubator/create-react-app/pull/1256) Add "Changing the Page Title" to User Guide. ([@gaearon](https://github.com/gaearon))
|
||||
* [#1245](https://github.com/facebookincubator/create-react-app/pull/1245) Replace the Flow documentation section. ([@gaearon](https://github.com/gaearon))
|
||||
* Other
|
||||
* [#1514](https://github.com/facebookincubator/create-react-app/pull/1514) corrected minor typo. ([@crowchirp](https://github.com/crowchirp))
|
||||
* [#1393](https://github.com/facebookincubator/create-react-app/pull/1393) replace two space syntax with <br> tag. ([@carlsagan21](https://github.com/carlsagan21))
|
||||
* [#1384](https://github.com/facebookincubator/create-react-app/pull/1384) Document Flow support. ([@dschep](https://github.com/dschep))
|
||||
* `react-dev-utils`
|
||||
* [#1375](https://github.com/facebookincubator/create-react-app/pull/1375) Change console.log for errors and warnings. ([@jimmyhmiller](https://github.com/jimmyhmiller))
|
||||
* [#1369](https://github.com/facebookincubator/create-react-app/pull/1369) Add missing import in react-dev-utils README.md. ([@pedronauck](https://github.com/pedronauck))
|
||||
|
||||
#### :house: Internal
|
||||
* Other
|
||||
* [#1519](https://github.com/facebookincubator/create-react-app/pull/1519) Add test cases for PUBLIC_URL and relative path. ([@Timer](https://github.com/Timer))
|
||||
* `react-scripts`
|
||||
* [#1484](https://github.com/facebookincubator/create-react-app/pull/1484) Improve e2e-kitchensink and Jest coverage. ([@Timer](https://github.com/Timer))
|
||||
* [#1463](https://github.com/facebookincubator/create-react-app/pull/1463) Minor code style and wrong expect. ([@tuchk4](https://github.com/tuchk4))
|
||||
* [#1470](https://github.com/facebookincubator/create-react-app/pull/1470) E2e jsdom fix. ([@EnoahNetzach](https://github.com/EnoahNetzach))
|
||||
* [#1289](https://github.com/facebookincubator/create-react-app/pull/1289) Remove path-exists from dependencies and replace it with fs.existsSync. ([@halfzebra](https://github.com/halfzebra))
|
||||
* `create-react-app`, `react-scripts`
|
||||
* [#1187](https://github.com/facebookincubator/create-react-app/pull/1187) Use a more sophisticated template for end-to-end testing.. ([@EnoahNetzach](https://github.com/EnoahNetzach))
|
||||
|
||||
#### Committers: 35
|
||||
- Alex Driaguine ([alexdriaguine](https://github.com/alexdriaguine))
|
||||
- Anders D. Johnson ([adjohnson916](https://github.com/adjohnson916))
|
||||
- Anthony F. ([frehner](https://github.com/frehner))
|
||||
- Brandon Istenes ([brandones](https://github.com/brandones))
|
||||
- Calvin Webster ([calweb](https://github.com/calweb))
|
||||
- Cary Landholt ([CaryLandholt](https://github.com/CaryLandholt))
|
||||
- Chandan Rai ([crowchirp](https://github.com/crowchirp))
|
||||
- Christian Raidl ([Chris-R3](https://github.com/Chris-R3))
|
||||
- Dan Abramov ([gaearon](https://github.com/gaearon))
|
||||
- Daniel Schep ([dschep](https://github.com/dschep))
|
||||
- David ([lopezator](https://github.com/lopezator))
|
||||
- Dinuka De Silva ([dinukadesilva](https://github.com/dinukadesilva))
|
||||
- Eduard Kyvenko ([halfzebra](https://github.com/halfzebra))
|
||||
- Fabrizio Castellarin ([EnoahNetzach](https://github.com/EnoahNetzach))
|
||||
- Fatih ([frontsideair](https://github.com/frontsideair))
|
||||
- Gabriel Aumala ([GAumala](https://github.com/GAumala))
|
||||
- Jay Phelps ([jayphelps](https://github.com/jayphelps))
|
||||
- Jih-Chi Lee ([jihchi](https://github.com/jihchi))
|
||||
- Jimmy Miller ([jimmyhmiller](https://github.com/jimmyhmiller))
|
||||
- Joe Haddad ([Timer](https://github.com/Timer))
|
||||
- Johnny Magrippis ([jmagrippis](https://github.com/jmagrippis))
|
||||
- Jonathan Kim ([jkimbo](https://github.com/jkimbo))
|
||||
- MUA ([MsUzoAgu](https://github.com/MsUzoAgu))
|
||||
- Matthew Holloway ([holloway](https://github.com/holloway))
|
||||
- Nguyen Le Vu Long ([vulong23](https://github.com/vulong23))
|
||||
- Paul O’Shannessy ([zpao](https://github.com/zpao))
|
||||
- Pedro Nauck ([pedronauck](https://github.com/pedronauck))
|
||||
- Robbie H ([TheBlackBolt](https://github.com/TheBlackBolt))
|
||||
- Thibault Derousseaux ([tibdex](https://github.com/tibdex))
|
||||
- Valerii ([tuchk4](https://github.com/tuchk4))
|
||||
- Vasiliy Taranov ([jetpackpony](https://github.com/jetpackpony))
|
||||
- [RodrigoHahn](https://github.com/RodrigoHahn)
|
||||
- creynders ([creynders](https://github.com/creynders))
|
||||
- pd4d10 ([pd4d10](https://github.com/pd4d10))
|
||||
- soo ([carlsagan21](https://github.com/carlsagan21))
|
||||
|
||||
### Migrating from 0.8.5 to 0.9.0
|
||||
|
||||
Inside any created project that has not been ejected, run:
|
||||
|
||||
```
|
||||
npm install --save-dev --save-exact react-scripts@0.9.0
|
||||
```
|
||||
|
||||
## 0.8.5 (January 9, 2017)
|
||||
|
||||
#### :bug: Bug Fix
|
||||
* `create-react-app`, `react-scripts`
|
||||
* [#1365](https://github.com/facebookincubator/create-react-app/pull/1365) Use yarnpkg alias to run Yarn. ([@fson](https://github.com/fson))
|
||||
|
||||
Fixes an issue where running `create-react-app` failed on systems with Apache Hadoop installed because it falsely detected Hadoop YARN executable as Yarn package manager.
|
||||
|
||||
#### Committers: 1
|
||||
- Ville Immonen ([fson](https://github.com/fson))
|
||||
|
||||
### Migrating from 0.8.4 to 0.8.5
|
||||
|
||||
Inside any created project that has not been ejected, run:
|
||||
|
||||
```
|
||||
npm install --save-dev --save-exact react-scripts@0.8.5
|
||||
```
|
||||
|
||||
You may also optionally update the global command-line utility:
|
||||
|
||||
```
|
||||
npm install -g create-react-app@1.0.3
|
||||
```
|
||||
|
||||
## 0.8.4 (December 11, 2016)
|
||||
|
||||
#### :bug: Bug Fix
|
||||
@@ -414,7 +567,7 @@ npm install --save-dev --save-exact react-scripts@0.8.0
|
||||
|
||||
### Babel Preset (`babel-preset-react-app`)
|
||||
|
||||
* The preset now detects the Node.js version in test environment and disables unnecessary ES2015 transforms using using `babel-preset-env`. ([@shubheksha](https://github.com/shubheksha) in [#878](https://github.com/facebookincubator/create-react-app/pull/878), [@JeffreyATW](https://github.com/JeffreyATW) in [#927
|
||||
* The preset now detects the Node.js version in test environment and disables unnecessary ES2015 transforms using `babel-preset-env`. ([@shubheksha](https://github.com/shubheksha) in [#878](https://github.com/facebookincubator/create-react-app/pull/878), [@JeffreyATW](https://github.com/JeffreyATW) in [#927
|
||||
](https://github.com/facebookincubator/create-react-app/pull/927))
|
||||
* Fixes a duplicate dependency on `babel-plugin-transform-regenerator`. ([@akofman](https://github.com/akofman) in [#864](https://github.com/facebookincubator/create-react-app/pull/864))
|
||||
|
||||
|
||||
@@ -68,6 +68,7 @@ and then run `npm start` or `npm run build`.
|
||||
* You'll need an [access token for the GitHub API](https://help.github.com/articles/creating-an-access-token-for-command-line-use/). Save it to this environment variable: `export GITHUB_AUTH="..."`
|
||||
* Run `npm run changelog`. The command will find all the labeled pull requests merged since the last release and group them by the label and affected packages, and create a change log entry with all the changes and links to PRs and their authors. Copy and paste it to `CHANGELOG.md`.
|
||||
* Add a four-space indented paragraph after each non-trivial list item, explaining what changed and why. For each breaking change also write who it affects and instructions for migrating existing code.
|
||||
* Maybe add some newlines here and there. Preview the result on GitHub to get a feel for it. Changelog generator output is a bit too terse for my taste, so try to make it visually pleasing and well grouped.
|
||||
6. Make sure to include “Migrating from ...” instructions for the previous release. Often you can copy and paste them.
|
||||
7. After merging the changelog update, create a GitHub Release with the same text. See previous Releases for inspiration.
|
||||
8. **Do not run `npm publish`. Instead, run `npm run publish`.**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"lerna": "2.0.0-beta.30",
|
||||
"lerna": "2.0.0-beta.37",
|
||||
"version": "independent",
|
||||
"changelog": {
|
||||
"repo": "facebookincubator/create-react-app",
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
"build": "node packages/react-scripts/scripts/build.js",
|
||||
"changelog": "lerna-changelog",
|
||||
"create-react-app": "tasks/cra.sh",
|
||||
"e2e": "tasks/e2e.sh",
|
||||
"e2e": "tasks/e2e-simple.sh",
|
||||
"postinstall": "lerna bootstrap",
|
||||
"publish": "tasks/release.sh",
|
||||
"start": "node packages/react-scripts/scripts/start.js",
|
||||
@@ -18,7 +18,7 @@
|
||||
"eslint-plugin-import": "1.12.0",
|
||||
"eslint-plugin-jsx-a11y": "2.2.2",
|
||||
"eslint-plugin-react": "6.3.0",
|
||||
"lerna": "2.0.0-beta.30",
|
||||
"lerna": "^2.0.0-beta.37",
|
||||
"lerna-changelog": "^0.2.3"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,18 +11,18 @@
|
||||
"index.js"
|
||||
],
|
||||
"dependencies": {
|
||||
"babel-plugin-transform-class-properties": "6.16.0",
|
||||
"babel-plugin-transform-es2015-parameters": "6.18.0",
|
||||
"babel-plugin-transform-object-rest-spread": "6.19.0",
|
||||
"babel-plugin-transform-react-constant-elements": "6.9.1",
|
||||
"babel-plugin-transform-react-jsx": "6.8.0",
|
||||
"babel-plugin-transform-react-jsx-self": "6.11.0",
|
||||
"babel-plugin-transform-react-jsx-source": "6.9.0",
|
||||
"babel-plugin-transform-regenerator": "6.16.1",
|
||||
"babel-plugin-transform-runtime": "6.15.0",
|
||||
"babel-preset-env": "0.0.8",
|
||||
"babel-preset-latest": "6.16.0",
|
||||
"babel-preset-react": "6.16.0",
|
||||
"babel-runtime": "6.11.6"
|
||||
"babel-plugin-transform-class-properties": "6.22.0",
|
||||
"babel-plugin-transform-es2015-parameters": "6.22.0",
|
||||
"babel-plugin-transform-object-rest-spread": "6.22.0",
|
||||
"babel-plugin-transform-react-constant-elements": "6.22.0",
|
||||
"babel-plugin-transform-react-jsx": "6.22.0",
|
||||
"babel-plugin-transform-react-jsx-self": "6.22.0",
|
||||
"babel-plugin-transform-react-jsx-source": "6.22.0",
|
||||
"babel-plugin-transform-regenerator": "6.22.0",
|
||||
"babel-plugin-transform-runtime": "6.22.0",
|
||||
"babel-preset-env": "1.1.8",
|
||||
"babel-preset-latest": "6.22.0",
|
||||
"babel-preset-react": "6.22.0",
|
||||
"babel-runtime": "6.22.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,6 +52,7 @@ if (currentNodeVersion.split('.')[0] < 4) {
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
var commander = require('commander');
|
||||
var fs = require('fs-extra');
|
||||
var path = require('path');
|
||||
var execSync = require('child_process').execSync;
|
||||
@@ -60,7 +61,7 @@ var semver = require('semver');
|
||||
|
||||
var projectName;
|
||||
|
||||
var program = require('commander')
|
||||
var program = commander
|
||||
.version(require('./package.json').version)
|
||||
.arguments('<project-directory>')
|
||||
.usage(chalk.green('<project-directory>') + ' [options]')
|
||||
@@ -69,6 +70,7 @@ var program = require('commander')
|
||||
})
|
||||
.option('--verbose', 'print additional logs')
|
||||
.option('--scripts-version <alternative-package>', 'use a non-standard version of react-scripts')
|
||||
.allowUnknownOption()
|
||||
.on('--help', function () {
|
||||
console.log(' Only ' + chalk.green('<project-directory>') + ' is required.');
|
||||
console.log();
|
||||
@@ -82,7 +84,7 @@ var program = require('commander')
|
||||
console.log(' ' + chalk.cyan('https://github.com/facebookincubator/create-react-app/issues/new'));
|
||||
console.log();
|
||||
})
|
||||
.parse(process.argv)
|
||||
.parse(process.argv);
|
||||
|
||||
if (typeof projectName === 'undefined') {
|
||||
console.error('Please specify the project directory:');
|
||||
@@ -95,9 +97,14 @@ if (typeof projectName === 'undefined') {
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
createApp(projectName, program.verbose, program.scriptsVersion);
|
||||
var hiddenProgram = new commander.Command()
|
||||
.option('--internal-testing-template <path-to-template>', '(internal usage only, DO NOT RELY ON THIS) ' +
|
||||
'use a non-standard application template')
|
||||
.parse(process.argv)
|
||||
|
||||
function createApp(name, verbose, version) {
|
||||
createApp(projectName, program.verbose, program.scriptsVersion, hiddenProgram.internalTestingTemplate);
|
||||
|
||||
function createApp(name, verbose, version, template) {
|
||||
var root = path.resolve(name);
|
||||
var appName = path.basename(root);
|
||||
|
||||
@@ -130,12 +137,12 @@ function createApp(name, verbose, version) {
|
||||
console.log('Installing ' + chalk.cyan('react-scripts') + '...');
|
||||
console.log();
|
||||
|
||||
run(root, appName, version, verbose, originalDirectory);
|
||||
run(root, appName, version, verbose, originalDirectory, template);
|
||||
}
|
||||
|
||||
function shouldUseYarn() {
|
||||
try {
|
||||
execSync('yarn --version', {stdio: 'ignore'});
|
||||
execSync('yarnpkg --version', {stdio: 'ignore'});
|
||||
return true;
|
||||
} catch (e) {
|
||||
return false;
|
||||
@@ -146,7 +153,7 @@ function install(packageToInstall, verbose, callback) {
|
||||
var command;
|
||||
var args;
|
||||
if (shouldUseYarn()) {
|
||||
command = 'yarn';
|
||||
command = 'yarnpkg';
|
||||
args = [ 'add', '--dev', '--exact', packageToInstall];
|
||||
} else {
|
||||
command = 'npm';
|
||||
@@ -163,7 +170,7 @@ function install(packageToInstall, verbose, callback) {
|
||||
});
|
||||
}
|
||||
|
||||
function run(root, appName, version, verbose, originalDirectory) {
|
||||
function run(root, appName, version, verbose, originalDirectory, template) {
|
||||
var packageToInstall = getInstallPackage(version);
|
||||
var packageName = getPackageName(packageToInstall);
|
||||
|
||||
@@ -183,7 +190,7 @@ function run(root, appName, version, verbose, originalDirectory) {
|
||||
'init.js'
|
||||
);
|
||||
var init = require(scriptsPath);
|
||||
init(root, appName, verbose, originalDirectory);
|
||||
init(root, appName, verbose, originalDirectory, template);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "create-react-app",
|
||||
"version": "1.0.2",
|
||||
"version": "1.0.3",
|
||||
"keywords": [
|
||||
"react"
|
||||
],
|
||||
|
||||
@@ -117,6 +117,7 @@ Extracts and prettifies warning and error messages from webpack [stats](https://
|
||||
```js
|
||||
var webpack = require('webpack');
|
||||
var config = require('../config/webpack.config.dev');
|
||||
var formatWebpackMessages = require('react-dev-utils/formatWebpackMessages');
|
||||
|
||||
var compiler = webpack(config);
|
||||
|
||||
@@ -132,12 +133,12 @@ compiler.plugin('done', function(stats) {
|
||||
}
|
||||
if (messages.errors.length) {
|
||||
console.log('Failed to compile.');
|
||||
messages.errors.forEach(console.log);
|
||||
messages.errors.forEach(e => console.log(e));
|
||||
return;
|
||||
}
|
||||
if (messages.warnings.length) {
|
||||
console.log('Compiled with warnings.');
|
||||
messages.warnings.forEach(console.log);
|
||||
messages.warnings.forEach(w => console.log(w));
|
||||
}
|
||||
});
|
||||
```
|
||||
@@ -184,6 +185,7 @@ You can control the behavior on `<Enter>` with `isYesDefault`.
|
||||
|
||||
```js
|
||||
var prompt = require('react-dev-utils/prompt');
|
||||
|
||||
prompt(
|
||||
'Are you sure you want to eat all the candy?',
|
||||
/* isYesDefault */ false
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
"escape-string-regexp": "1.0.5",
|
||||
"html-entities": "1.2.0",
|
||||
"opn": "4.0.2",
|
||||
"sockjs-client": "1.0.3",
|
||||
"sockjs-client": "1.0.1",
|
||||
"strip-ansi": "3.0.1"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -248,6 +248,7 @@ connection.onmessage = function(e) {
|
||||
case 'hash':
|
||||
handleAvailableHash(message.data);
|
||||
break;
|
||||
case 'still-ok':
|
||||
case 'ok':
|
||||
handleSuccess();
|
||||
break;
|
||||
|
||||
1
packages/react-scripts/.npmignore
Normal file
1
packages/react-scripts/.npmignore
Normal file
@@ -0,0 +1 @@
|
||||
/fixtures
|
||||
16
packages/react-scripts/bin/react-scripts-ts.js
vendored
16
packages/react-scripts/bin/react-scripts-ts.js
vendored
@@ -13,6 +13,22 @@ case 'test':
|
||||
[require.resolve('../scripts/' + script)].concat(args),
|
||||
{stdio: 'inherit'}
|
||||
);
|
||||
if (result.signal) {
|
||||
if (result.signal == 'SIGKILL') {
|
||||
console.log(
|
||||
'The build failed because the process exited too early. ' +
|
||||
'This probably means the system ran out of memory or someone called ' +
|
||||
'`kill -9` on the process.'
|
||||
);
|
||||
} else if (result.signal == 'SIGTERM') {
|
||||
console.log(
|
||||
'The build failed because the process exited too early. ' +
|
||||
'Someone might have called `kill` or `killall`, or the system could ' +
|
||||
'be shutting down.'
|
||||
);
|
||||
}
|
||||
process.exit(1);
|
||||
}
|
||||
process.exit(result.status);
|
||||
break;
|
||||
default:
|
||||
|
||||
22
packages/react-scripts/config/env.js
vendored
22
packages/react-scripts/config/env.js
vendored
@@ -15,25 +15,33 @@
|
||||
var REACT_APP = /^REACT_APP_/i;
|
||||
|
||||
function getClientEnvironment(publicUrl) {
|
||||
var processEnv = Object
|
||||
var raw = Object
|
||||
.keys(process.env)
|
||||
.filter(key => REACT_APP.test(key))
|
||||
.reduce((env, key) => {
|
||||
env[key] = JSON.stringify(process.env[key]);
|
||||
env[key] = process.env[key];
|
||||
return env;
|
||||
}, {
|
||||
// Useful for determining whether we’re running in production mode.
|
||||
// Most importantly, it switches React into the correct mode.
|
||||
'NODE_ENV': JSON.stringify(
|
||||
process.env.NODE_ENV || 'development'
|
||||
),
|
||||
'NODE_ENV': process.env.NODE_ENV || 'development',
|
||||
// Useful for resolving the correct path to static assets in `public`.
|
||||
// For example, <img src={process.env.PUBLIC_URL + '/img/logo.png'} />.
|
||||
// This should only be used as an escape hatch. Normally you would put
|
||||
// images into the `src` and `import` them in code to get their paths.
|
||||
'PUBLIC_URL': JSON.stringify(publicUrl)
|
||||
'PUBLIC_URL': publicUrl
|
||||
});
|
||||
return {'process.env': processEnv};
|
||||
// Stringify all values so we can feed into Webpack DefinePlugin
|
||||
var stringified = {
|
||||
'process.env': Object
|
||||
.keys(raw)
|
||||
.reduce((env, key) => {
|
||||
env[key] = JSON.stringify(raw[key]);
|
||||
return env;
|
||||
}, {})
|
||||
};
|
||||
|
||||
return { raw, stringified };
|
||||
}
|
||||
|
||||
module.exports = getClientEnvironment;
|
||||
|
||||
44
packages/react-scripts/config/paths.js
vendored
44
packages/react-scripts/config/paths.js
vendored
@@ -11,6 +11,7 @@
|
||||
|
||||
var path = require('path');
|
||||
var fs = require('fs');
|
||||
var url = require('url');
|
||||
|
||||
// Make sure any symlinks in the project folder are resolved:
|
||||
// https://github.com/facebookincubator/create-react-app/issues/637
|
||||
@@ -40,6 +41,37 @@ var nodePaths = (process.env.NODE_PATH || '')
|
||||
.filter(folder => !path.isAbsolute(folder))
|
||||
.map(resolveApp);
|
||||
|
||||
var envPublicUrl = process.env.PUBLIC_URL;
|
||||
|
||||
function ensureSlash(path, needsSlash) {
|
||||
var hasSlash = path.endsWith('/');
|
||||
if (hasSlash && !needsSlash) {
|
||||
return path.substr(path, path.length - 1);
|
||||
} else if (!hasSlash && needsSlash) {
|
||||
return path + '/';
|
||||
} else {
|
||||
return path;
|
||||
}
|
||||
}
|
||||
|
||||
function getPublicUrl(appPackageJson) {
|
||||
return envPublicUrl || require(appPackageJson).homepage;
|
||||
}
|
||||
|
||||
// We use `PUBLIC_URL` environment variable or "homepage" field to infer
|
||||
// "public path" at which the app is served.
|
||||
// Webpack needs to know it to put the right <script> hrefs into HTML even in
|
||||
// single-page apps that may serve index.html for nested URLs like /todos/42.
|
||||
// We can't use a relative path in HTML because we don't want to load something
|
||||
// like /todos/42/static/js/bundle.7289d.js. We have to know the root.
|
||||
function getServedPath(appPackageJson) {
|
||||
var publicUrl = getPublicUrl(appPackageJson);
|
||||
var servedUrl = envPublicUrl || (
|
||||
publicUrl ? url.parse(publicUrl).pathname : '/'
|
||||
);
|
||||
return ensureSlash(servedUrl, true);
|
||||
}
|
||||
|
||||
// config after eject: we're in ./config/
|
||||
module.exports = {
|
||||
appBuild: resolveApp('build'),
|
||||
@@ -52,7 +84,9 @@ module.exports = {
|
||||
testsSetup: resolveApp('src/setupTests.ts'),
|
||||
appNodeModules: resolveApp('node_modules'),
|
||||
ownNodeModules: resolveApp('node_modules'),
|
||||
nodePaths: nodePaths
|
||||
nodePaths: nodePaths,
|
||||
publicUrl: getPublicUrl(resolveApp('package.json')),
|
||||
servedPath: getServedPath(resolveApp('package.json'))
|
||||
};
|
||||
|
||||
// @remove-on-eject-begin
|
||||
@@ -73,7 +107,9 @@ module.exports = {
|
||||
appNodeModules: resolveApp('node_modules'),
|
||||
// this is empty with npm3 but node resolution searches higher anyway:
|
||||
ownNodeModules: resolveOwn('../node_modules'),
|
||||
nodePaths: nodePaths
|
||||
nodePaths: nodePaths,
|
||||
publicUrl: getPublicUrl(resolveApp('package.json')),
|
||||
servedPath: getServedPath(resolveApp('package.json'))
|
||||
};
|
||||
|
||||
// config before publish: we're in ./packages/react-scripts/config/
|
||||
@@ -89,7 +125,9 @@ if (__dirname.indexOf(path.join('packages', 'react-scripts', 'config')) !== -1)
|
||||
testsSetup: resolveOwn('../template/src/setupTests.ts'),
|
||||
appNodeModules: resolveOwn('../node_modules'),
|
||||
ownNodeModules: resolveOwn('../node_modules'),
|
||||
nodePaths: nodePaths
|
||||
nodePaths: nodePaths,
|
||||
publicUrl: getPublicUrl(resolveOwn('../package.json')),
|
||||
servedPath: getServedPath(resolveOwn('../package.json'))
|
||||
};
|
||||
}
|
||||
// @remove-on-eject-end
|
||||
|
||||
@@ -112,20 +112,14 @@ module.exports = {
|
||||
}
|
||||
],
|
||||
loaders: [
|
||||
// Default loader: load all assets that are not handled
|
||||
// by other loaders with the url loader.
|
||||
// Note: This list needs to be updated with every change of extensions
|
||||
// the other loaders match.
|
||||
// E.g., when adding a loader for a new supported file extension,
|
||||
// we need to add the supported extension to this loader too.
|
||||
// Add one new line in `exclude` for each loader.
|
||||
//
|
||||
// "file" loader makes sure those assets get served by WebpackDevServer.
|
||||
// When you `import` an asset, you get its (virtual) filename.
|
||||
// In production, they would get copied to the `build` folder.
|
||||
// "url" loader works like "file" loader except that it embeds assets
|
||||
// smaller than specified limit in bytes as data URLs to avoid requests.
|
||||
// A missing `test` is equivalent to a match.
|
||||
// ** ADDING/UPDATING LOADERS **
|
||||
// The "url" loader handles all assets unless explicitly excluded.
|
||||
// The `exclude` list *must* be updated with every change to loader extensions.
|
||||
// When adding a new loader, you must add its `test`
|
||||
// as a new entry in the `exclude` list for "url" loader.
|
||||
|
||||
// "url" loader embeds assets smaller than specified size as data URLs to avoid requests.
|
||||
// Otherwise, it acts like the "file" loader.
|
||||
{
|
||||
exclude: [
|
||||
/\.html$/,
|
||||
@@ -170,6 +164,8 @@ module.exports = {
|
||||
name: 'static/media/[name].[hash:8].[ext]'
|
||||
}
|
||||
}
|
||||
// ** STOP ** Are you adding a new loader?
|
||||
// Remember to add the new extension(s) to the "url" loader exclusion list.
|
||||
]
|
||||
},
|
||||
// We use PostCSS for autoprefixing only.
|
||||
@@ -186,12 +182,11 @@ module.exports = {
|
||||
];
|
||||
},
|
||||
plugins: [
|
||||
// Makes the public URL available as %PUBLIC_URL% in index.html, e.g.:
|
||||
// Makes some environment variables available in index.html.
|
||||
// The public URL is available as %PUBLIC_URL% in index.html, e.g.:
|
||||
// <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
|
||||
// In development, this will be an empty string.
|
||||
new InterpolateHtmlPlugin({
|
||||
PUBLIC_URL: publicUrl
|
||||
}),
|
||||
new InterpolateHtmlPlugin(env.raw),
|
||||
// Generates an `index.html` file with the <script> injected.
|
||||
new HtmlWebpackPlugin({
|
||||
inject: true,
|
||||
@@ -199,7 +194,7 @@ module.exports = {
|
||||
}),
|
||||
// Makes some environment variables available to the JS code, for example:
|
||||
// if (process.env.NODE_ENV === 'development') { ... }. See `./env.js`.
|
||||
new webpack.DefinePlugin(env),
|
||||
new webpack.DefinePlugin(env.stringified),
|
||||
// This is necessary to emit hot updates (currently CSS only):
|
||||
new webpack.HotModuleReplacementPlugin(),
|
||||
// Watcher doesn't work well if you mistype casing in a path so we use
|
||||
|
||||
@@ -24,40 +24,37 @@ var getClientEnvironment = require('./env');
|
||||
var path = require('path');
|
||||
// @remove-on-eject-end
|
||||
|
||||
function ensureSlash(path, needsSlash) {
|
||||
var hasSlash = path.endsWith('/');
|
||||
if (hasSlash && !needsSlash) {
|
||||
return path.substr(path, path.length - 1);
|
||||
} else if (!hasSlash && needsSlash) {
|
||||
return path + '/';
|
||||
} else {
|
||||
return path;
|
||||
}
|
||||
}
|
||||
|
||||
// We use "homepage" field to infer "public path" at which the app is served.
|
||||
// Webpack needs to know it to put the right <script> hrefs into HTML even in
|
||||
// single-page apps that may serve index.html for nested URLs like /todos/42.
|
||||
// We can't use a relative path in HTML because we don't want to load something
|
||||
// like /todos/42/static/js/bundle.7289d.js. We have to know the root.
|
||||
var homepagePath = require(paths.appPackageJson).homepage;
|
||||
var homepagePathname = homepagePath ? url.parse(homepagePath).pathname : '/';
|
||||
// Webpack uses `publicPath` to determine where the app is being served from.
|
||||
// It requires a trailing slash, or the file assets will get an incorrect path.
|
||||
var publicPath = ensureSlash(homepagePathname, true);
|
||||
var publicPath = paths.servedPath;
|
||||
// Some apps do not use client-side routing with pushState.
|
||||
// For these, "homepage" can be set to "." to enable relative asset paths.
|
||||
var shouldUseRelativeAssetPaths = publicPath === './';
|
||||
// `publicUrl` is just like `publicPath`, but we will provide it to our app
|
||||
// as %PUBLIC_URL% in `index.html` and `process.env.PUBLIC_URL` in JavaScript.
|
||||
// Omit trailing slash as %PUBLIC_PATH%/xyz looks better than %PUBLIC_PATH%xyz.
|
||||
var publicUrl = ensureSlash(homepagePathname, false);
|
||||
// Omit trailing slash as %PUBLIC_URL%/xyz looks better than %PUBLIC_URL%xyz.
|
||||
var publicUrl = publicPath.slice(0, -1);
|
||||
// Get environment variables to inject into our app.
|
||||
var env = getClientEnvironment(publicUrl);
|
||||
|
||||
// Assert this just to be safe.
|
||||
// Development builds of React are slow and not intended for production.
|
||||
if (env['process.env'].NODE_ENV !== '"production"') {
|
||||
if (env.stringified['process.env'].NODE_ENV !== '"production"') {
|
||||
throw new Error('Production builds must have NODE_ENV=production.');
|
||||
}
|
||||
|
||||
// Note: defined here because it will be used more than once.
|
||||
const cssFilename = 'static/css/[name].[contenthash:8].css';
|
||||
|
||||
// ExtractTextPlugin expects the build output to be flat.
|
||||
// (See https://github.com/webpack-contrib/extract-text-webpack-plugin/issues/27)
|
||||
// However, our output is structured with css, js and media folders.
|
||||
// To have this structure working with relative paths, we have to use custom options.
|
||||
const extractTextPluginOptions = shouldUseRelativeAssetPaths
|
||||
// Making sure that the publicPath goes back to to build folder.
|
||||
? { publicPath: Array(cssFilename.split('/').length).join('../') }
|
||||
: undefined;
|
||||
|
||||
// This is the production configuration.
|
||||
// It compiles slowly and is focused on producing a fast and minimal bundle.
|
||||
// The development configuration is different and lives in a separate file.
|
||||
@@ -120,18 +117,14 @@ module.exports = {
|
||||
}
|
||||
],
|
||||
loaders: [
|
||||
// Default loader: load all assets that are not handled
|
||||
// by other loaders with the url loader.
|
||||
// Note: This list needs to be updated with every change of extensions
|
||||
// the other loaders match.
|
||||
// E.g., when adding a loader for a new supported file extension,
|
||||
// we need to add the supported extension to this loader too.
|
||||
// Add one new line in `exclude` for each loader.
|
||||
//
|
||||
// "file" loader makes sure those assets end up in the `build` folder.
|
||||
// When you `import` an asset, you get its filename.
|
||||
// "url" loader works just like "file" loader but it also embeds
|
||||
// assets smaller than specified size as data URLs to avoid requests.
|
||||
// ** ADDING/UPDATING LOADERS **
|
||||
// The "url" loader handles all assets unless explicitly excluded.
|
||||
// The `exclude` list *must* be updated with every change to loader extensions.
|
||||
// When adding a new loader, you must add its `test`
|
||||
// as a new entry in the `exclude` list in the "url" loader.
|
||||
|
||||
// "url" loader embeds assets smaller than specified size as data URLs to avoid requests.
|
||||
// Otherwise, it acts like the "file" loader.
|
||||
{
|
||||
exclude: [
|
||||
/\.html$/,
|
||||
@@ -167,7 +160,11 @@ module.exports = {
|
||||
// in the main CSS file.
|
||||
{
|
||||
test: /\.css$/,
|
||||
loader: ExtractTextPlugin.extract('style', 'css?importLoaders=1!postcss')
|
||||
loader: ExtractTextPlugin.extract(
|
||||
'style',
|
||||
'css?importLoaders=1!postcss',
|
||||
extractTextPluginOptions
|
||||
)
|
||||
// Note: this won't work without `new ExtractTextPlugin()` in `plugins`.
|
||||
},
|
||||
// JSON is not enabled by default in Webpack but both Node and Browserify
|
||||
@@ -184,6 +181,8 @@ module.exports = {
|
||||
name: 'static/media/[name].[hash:8].[ext]'
|
||||
}
|
||||
}
|
||||
// ** STOP ** Are you adding a new loader?
|
||||
// Remember to add the new extension(s) to the "url" loader exclusion list.
|
||||
]
|
||||
},
|
||||
// We use PostCSS for autoprefixing only.
|
||||
@@ -200,13 +199,12 @@ module.exports = {
|
||||
];
|
||||
},
|
||||
plugins: [
|
||||
// Makes the public URL available as %PUBLIC_URL% in index.html, e.g.:
|
||||
// Makes some environment variables available in index.html.
|
||||
// The public URL is available as %PUBLIC_URL% in index.html, e.g.:
|
||||
// <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
|
||||
// In production, it will be an empty string unless you specify "homepage"
|
||||
// in `package.json`, in which case it will be the pathname of that URL.
|
||||
new InterpolateHtmlPlugin({
|
||||
PUBLIC_URL: publicUrl
|
||||
}),
|
||||
new InterpolateHtmlPlugin(env.raw),
|
||||
// Generates an `index.html` file with the <script> injected.
|
||||
new HtmlWebpackPlugin({
|
||||
inject: true,
|
||||
@@ -228,7 +226,7 @@ module.exports = {
|
||||
// if (process.env.NODE_ENV === 'production') { ... }. See `./env.js`.
|
||||
// It is absolutely essential that NODE_ENV was set to production here.
|
||||
// Otherwise React will be compiled in the very slow development mode.
|
||||
new webpack.DefinePlugin(env),
|
||||
new webpack.DefinePlugin(env.stringified),
|
||||
// This helps ensure the builds are consistent if source hasn't changed:
|
||||
new webpack.optimize.OccurrenceOrderPlugin(),
|
||||
// Try to dedupe duplicated modules, if any:
|
||||
@@ -248,7 +246,7 @@ module.exports = {
|
||||
}
|
||||
}),
|
||||
// Note: this won't work without ExtractTextPlugin.extract(..) in `loaders`.
|
||||
new ExtractTextPlugin('static/css/[name].[contenthash:8].css'),
|
||||
new ExtractTextPlugin(cssFilename),
|
||||
// Generate a manifest file which contains a mapping of all asset filenames
|
||||
// to their corresponding output file so that tools can pick it up without
|
||||
// having to parse `index.html`.
|
||||
|
||||
3
packages/react-scripts/fixtures/kitchensink/.babelrc
Normal file
3
packages/react-scripts/fixtures/kitchensink/.babelrc
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"presets": ["react-app"]
|
||||
}
|
||||
1
packages/react-scripts/fixtures/kitchensink/.env
Normal file
1
packages/react-scripts/fixtures/kitchensink/.env
Normal file
@@ -0,0 +1 @@
|
||||
REACT_APP_FILE_ENV_MESSAGE=fromtheenvfile
|
||||
8
packages/react-scripts/fixtures/kitchensink/.flowconfig
Normal file
8
packages/react-scripts/fixtures/kitchensink/.flowconfig
Normal file
@@ -0,0 +1,8 @@
|
||||
[ignore]
|
||||
<PROJECT_ROOT>/node_modules/fbjs/.*
|
||||
|
||||
[include]
|
||||
|
||||
[libs]
|
||||
|
||||
[options]
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"babel-register": "6.22.0",
|
||||
"babel-polyfill": "6.20.0",
|
||||
"chai": "3.5.0",
|
||||
"jsdom": "9.8.3",
|
||||
"mocha": "3.2.0"
|
||||
}
|
||||
}
|
||||
15
packages/react-scripts/fixtures/kitchensink/gitignore
Normal file
15
packages/react-scripts/fixtures/kitchensink/gitignore
Normal file
@@ -0,0 +1,15 @@
|
||||
# See http://help.github.com/ignore-files/ for more about ignoring files.
|
||||
|
||||
# dependencies
|
||||
node_modules
|
||||
|
||||
# testing
|
||||
coverage
|
||||
|
||||
# production
|
||||
build
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
.env
|
||||
npm-debug.log
|
||||
@@ -0,0 +1,33 @@
|
||||
import { expect } from 'chai'
|
||||
import initDOM from './initDOM'
|
||||
|
||||
describe('Integration', () => {
|
||||
describe('Environment variables', () => {
|
||||
it('file env variables', async () => {
|
||||
const doc = await initDOM('file-env-variables')
|
||||
|
||||
expect(doc.getElementById('feature-file-env-variables').textContent).to.equal('fromtheenvfile.')
|
||||
})
|
||||
|
||||
it('NODE_PATH', async () => {
|
||||
const doc = await initDOM('node-path')
|
||||
|
||||
expect(doc.getElementById('feature-node-path').childElementCount).to.equal(4)
|
||||
})
|
||||
|
||||
it('PUBLIC_URL', async () => {
|
||||
const doc = await initDOM('public-url')
|
||||
|
||||
const prefix = process.env.NODE_ENV === 'development' ? '' : 'http://www.example.org/spa';
|
||||
expect(doc.getElementById('feature-public-url').textContent).to.equal(`${prefix}.`)
|
||||
expect(doc.querySelector('head link[rel="shortcut icon"]').getAttribute('href'))
|
||||
.to.equal(`${prefix}/favicon.ico`)
|
||||
})
|
||||
|
||||
it('shell env variables', async () => {
|
||||
const doc = await initDOM('shell-env-variables')
|
||||
|
||||
expect(doc.getElementById('feature-shell-env-variables').textContent).to.equal('fromtheshell.')
|
||||
})
|
||||
})
|
||||
})
|
||||
56
packages/react-scripts/fixtures/kitchensink/integration/initDOM.js
vendored
Normal file
56
packages/react-scripts/fixtures/kitchensink/integration/initDOM.js
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
const fs = require('fs')
|
||||
const http = require('http')
|
||||
const jsdom = require('jsdom')
|
||||
const path = require('path')
|
||||
const { expect } = require('chai')
|
||||
|
||||
let getMarkup
|
||||
let resourceLoader
|
||||
|
||||
if (process.env.E2E_FILE) {
|
||||
const file = path.isAbsolute(process.env.E2E_FILE)
|
||||
? process.env.E2E_FILE
|
||||
: path.join(process.cwd(), process.env.E2E_FILE)
|
||||
|
||||
const markup = fs.readFileSync(file, 'utf8')
|
||||
getMarkup = () => markup
|
||||
|
||||
const pathPrefix = process.env.PUBLIC_URL.replace(/^https?:\/\/[^\/]+\/?/, '')
|
||||
|
||||
resourceLoader = (resource, callback) => callback(
|
||||
null,
|
||||
fs.readFileSync(path.join(path.dirname(file), resource.url.pathname.replace(pathPrefix, '')), 'utf8')
|
||||
)
|
||||
} else if (process.env.E2E_URL) {
|
||||
getMarkup = () => new Promise(resolve => {
|
||||
http.get(process.env.E2E_URL, (res) => {
|
||||
let rawData = ''
|
||||
res.on('data', chunk => rawData += chunk)
|
||||
res.on('end', () => resolve(rawData))
|
||||
})
|
||||
})
|
||||
|
||||
resourceLoader = (resource, callback) => resource.defaultFetch(callback)
|
||||
} else {
|
||||
it.only('can run jsdom (at least one of "E2E_FILE" or "E2E_URL" environment variables must be provided)', () => {
|
||||
expect(new Error('This isn\'t the error you are looking for.')).to.be.undefined()
|
||||
})
|
||||
}
|
||||
|
||||
export default feature => new Promise(async resolve => {
|
||||
const markup = await getMarkup()
|
||||
const host = process.env.E2E_URL || 'http://www.example.org/spa:3000'
|
||||
const doc = jsdom.jsdom(markup, {
|
||||
features: {
|
||||
FetchExternalResources: ['script', 'css'],
|
||||
ProcessExternalResources: ['script'],
|
||||
},
|
||||
created: (_, win) => win.addEventListener('ReactFeatureDidMount', () => resolve(doc), true),
|
||||
deferClose: true,
|
||||
resourceLoader,
|
||||
url: `${host}#${feature}`,
|
||||
virtualConsole: jsdom.createVirtualConsole().sendTo(console),
|
||||
})
|
||||
|
||||
doc.close()
|
||||
})
|
||||
@@ -0,0 +1,96 @@
|
||||
import { expect } from 'chai'
|
||||
import initDOM from './initDOM'
|
||||
|
||||
describe('Integration', () => {
|
||||
describe('Language syntax', () => {
|
||||
it('array destructuring', async () => {
|
||||
const doc = await initDOM('array-destructuring')
|
||||
|
||||
expect(doc.getElementById('feature-array-destructuring').childElementCount).to.equal(4)
|
||||
})
|
||||
|
||||
it('array spread', async () => {
|
||||
const doc = await initDOM('array-spread')
|
||||
|
||||
expect(doc.getElementById('feature-array-spread').childElementCount).to.equal(4)
|
||||
})
|
||||
|
||||
it('async/await', async () => {
|
||||
const doc = await initDOM('async-await')
|
||||
|
||||
expect(doc.getElementById('feature-async-await').childElementCount).to.equal(4)
|
||||
})
|
||||
|
||||
it('class properties', async () => {
|
||||
const doc = await initDOM('class-properties')
|
||||
|
||||
expect(doc.getElementById('feature-class-properties').childElementCount).to.equal(4)
|
||||
})
|
||||
|
||||
it('computed properties', async () => {
|
||||
const doc = await initDOM('computed-properties')
|
||||
|
||||
expect(doc.getElementById('feature-computed-properties').childElementCount).to.equal(4)
|
||||
})
|
||||
|
||||
it('custom interpolation', async () => {
|
||||
const doc = await initDOM('custom-interpolation')
|
||||
|
||||
expect(doc.getElementById('feature-custom-interpolation').childElementCount).to.equal(4)
|
||||
})
|
||||
|
||||
it('default parameters', async () => {
|
||||
const doc = await initDOM('default-parameters')
|
||||
|
||||
expect(doc.getElementById('feature-default-parameters').childElementCount).to.equal(4)
|
||||
})
|
||||
|
||||
it('destructuring and await', async () => {
|
||||
const doc = await initDOM('destructuring-and-await')
|
||||
|
||||
expect(doc.getElementById('feature-destructuring-and-await').childElementCount).to.equal(4)
|
||||
})
|
||||
|
||||
it('generators', async () => {
|
||||
const doc = await initDOM('generators')
|
||||
|
||||
expect(doc.getElementById('feature-generators').childElementCount).to.equal(4)
|
||||
})
|
||||
|
||||
it('object destructuring', async () => {
|
||||
const doc = await initDOM('object-destructuring')
|
||||
|
||||
expect(doc.getElementById('feature-object-destructuring').childElementCount).to.equal(4)
|
||||
})
|
||||
|
||||
it('object spread', async () => {
|
||||
const doc = await initDOM('object-spread')
|
||||
|
||||
expect(doc.getElementById('feature-object-spread').childElementCount).to.equal(4)
|
||||
})
|
||||
|
||||
it('promises', async () => {
|
||||
const doc = await initDOM('promises')
|
||||
|
||||
expect(doc.getElementById('feature-promises').childElementCount).to.equal(4)
|
||||
})
|
||||
|
||||
it('rest + default', async () => {
|
||||
const doc = await initDOM('rest-and-default')
|
||||
|
||||
expect(doc.getElementById('feature-rest-and-default').childElementCount).to.equal(4)
|
||||
})
|
||||
|
||||
it('rest parameters', async () => {
|
||||
const doc = await initDOM('rest-parameters')
|
||||
|
||||
expect(doc.getElementById('feature-rest-parameters').childElementCount).to.equal(4)
|
||||
})
|
||||
|
||||
it('template interpolation', async () => {
|
||||
const doc = await initDOM('template-interpolation')
|
||||
|
||||
expect(doc.getElementById('feature-template-interpolation').childElementCount).to.equal(4)
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,44 @@
|
||||
import { expect } from 'chai'
|
||||
import initDOM from './initDOM'
|
||||
|
||||
describe('Integration', () => {
|
||||
describe('Webpack plugins', () => {
|
||||
it('css inclusion', async () => {
|
||||
const doc = await initDOM('css-inclusion')
|
||||
|
||||
expect(doc.getElementsByTagName('style')[0].textContent.replace(/\s/g, ''))
|
||||
.to.match(/#feature-css-inclusion\{background:.+;color:.+}/)
|
||||
})
|
||||
|
||||
it('image inclusion', async () => {
|
||||
const doc = await initDOM('image-inclusion')
|
||||
|
||||
expect(doc.getElementById('feature-image-inclusion').src).to.match(/^data:image\/jpeg;base64.+==$/)
|
||||
})
|
||||
|
||||
it('no ext inclusion', async () => {
|
||||
const doc = await initDOM('no-ext-inclusion')
|
||||
|
||||
expect(doc.getElementById('feature-no-ext-inclusion').textContent)
|
||||
.to.equal('This is just a file without an extension.')
|
||||
})
|
||||
|
||||
it('json inclusion', async () => {
|
||||
const doc = await initDOM('json-inclusion')
|
||||
|
||||
expect(doc.getElementById('feature-json-inclusion').textContent).to.equal('This is an abstract.')
|
||||
})
|
||||
|
||||
it('svg inclusion', async () => {
|
||||
const doc = await initDOM('svg-inclusion')
|
||||
|
||||
expect(doc.getElementById('feature-svg-inclusion').src).to.match(/\/static\/media\/logo\..+\.svg$/)
|
||||
})
|
||||
|
||||
it('unknown ext inclusion', async () => {
|
||||
const doc = await initDOM('unknown-ext-inclusion')
|
||||
|
||||
expect(doc.getElementById('feature-unknown-ext-inclusion').textContent).to.equal('Whoooo, spooky!.')
|
||||
})
|
||||
})
|
||||
})
|
||||
BIN
packages/react-scripts/fixtures/kitchensink/public/favicon.ico
Normal file
BIN
packages/react-scripts/fixtures/kitchensink/public/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 24 KiB |
@@ -0,0 +1,12 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
|
||||
<title>React App</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
</body>
|
||||
</html>
|
||||
141
packages/react-scripts/fixtures/kitchensink/src/App.js
vendored
Normal file
141
packages/react-scripts/fixtures/kitchensink/src/App.js
vendored
Normal file
@@ -0,0 +1,141 @@
|
||||
import React, { Component, PropTypes, createElement } from 'react';
|
||||
|
||||
class BuiltEmitter extends Component {
|
||||
static propTypes = {
|
||||
feature: PropTypes.func.isRequired
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
const { feature } = this.props;
|
||||
|
||||
// Class components must call this.props.onReady when they're ready for the test.
|
||||
// We will assume functional components are ready immediately after mounting.
|
||||
if (!Component.isPrototypeOf(feature)) {
|
||||
this.handleReady();
|
||||
}
|
||||
}
|
||||
|
||||
handleReady() {
|
||||
document.dispatchEvent(new Event('ReactFeatureDidMount'));
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
props: { feature },
|
||||
handleReady
|
||||
} = this;
|
||||
return (
|
||||
<div>
|
||||
{createElement(feature, {
|
||||
onReady: handleReady
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class App extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = { feature: null };
|
||||
|
||||
this.setFeature = this.setFeature.bind(this);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
const feature = location.hash.slice(1);
|
||||
switch (feature) {
|
||||
case 'array-destructuring':
|
||||
require.ensure([], () => this.setFeature(require('./features/syntax/ArrayDestructuring').default));
|
||||
break;
|
||||
case 'array-spread':
|
||||
require.ensure([], () => this.setFeature(require('./features/syntax/ArraySpread').default));
|
||||
break;
|
||||
case 'async-await':
|
||||
require.ensure([], () => this.setFeature(require('./features/syntax/AsyncAwait').default));
|
||||
break;
|
||||
case 'class-properties':
|
||||
require.ensure([], () => this.setFeature(require('./features/syntax/ClassProperties').default));
|
||||
break;
|
||||
case 'computed-properties':
|
||||
require.ensure([], () => this.setFeature(require('./features/syntax/ComputedProperties').default));
|
||||
break;
|
||||
case 'css-inclusion':
|
||||
require.ensure([], () => this.setFeature(require('./features/webpack/CssInclusion').default));
|
||||
break;
|
||||
case 'custom-interpolation':
|
||||
require.ensure([], () => this.setFeature(require('./features/syntax/CustomInterpolation').default));
|
||||
break;
|
||||
case 'default-parameters':
|
||||
require.ensure([], () => this.setFeature(require('./features/syntax/DefaultParameters').default));
|
||||
break;
|
||||
case 'destructuring-and-await':
|
||||
require.ensure([], () => this.setFeature(require('./features/syntax/DestructuringAndAwait').default));
|
||||
break;
|
||||
case 'file-env-variables':
|
||||
require.ensure([], () => this.setFeature(require('./features/env/FileEnvVariables').default));
|
||||
break;
|
||||
case 'generators':
|
||||
require.ensure([], () => this.setFeature(require('./features/syntax/Generators').default));
|
||||
break;
|
||||
case 'image-inclusion':
|
||||
require.ensure([], () => this.setFeature(require('./features/webpack/ImageInclusion').default));
|
||||
break;
|
||||
case 'json-inclusion':
|
||||
require.ensure([], () => this.setFeature(require('./features/webpack/JsonInclusion').default));
|
||||
break;
|
||||
case 'node-path':
|
||||
require.ensure([], () => this.setFeature(require('./features/env/NodePath').default));
|
||||
break;
|
||||
case 'no-ext-inclusion':
|
||||
require.ensure([], () => this.setFeature(require('./features/webpack/NoExtInclusion').default));
|
||||
break;
|
||||
case 'object-destructuring':
|
||||
require.ensure([], () => this.setFeature(require('./features/syntax/ObjectDestructuring').default));
|
||||
break;
|
||||
case 'object-spread':
|
||||
require.ensure([], () => this.setFeature(require('./features/syntax/ObjectSpread').default));
|
||||
break;
|
||||
case 'promises':
|
||||
require.ensure([], () => this.setFeature(require('./features/syntax/Promises').default));
|
||||
break;
|
||||
case 'public-url':
|
||||
require.ensure([], () => this.setFeature(require('./features/env/PublicUrl').default));
|
||||
break;
|
||||
case 'rest-and-default':
|
||||
require.ensure([], () => this.setFeature(require('./features/syntax/RestAndDefault').default));
|
||||
break;
|
||||
case 'rest-parameters':
|
||||
require.ensure([], () => this.setFeature(require('./features/syntax/RestParameters').default));
|
||||
break;
|
||||
case 'shell-env-variables':
|
||||
require.ensure([], () => this.setFeature(require('./features/env/ShellEnvVariables').default));
|
||||
break;
|
||||
case 'svg-inclusion':
|
||||
require.ensure([], () => this.setFeature(require('./features/webpack/SvgInclusion').default));
|
||||
break;
|
||||
case 'template-interpolation':
|
||||
require.ensure([], () => this.setFeature(require('./features/syntax/TemplateInterpolation').default));
|
||||
break;
|
||||
case 'unknown-ext-inclusion':
|
||||
require.ensure([], () => this.setFeature(require('./features/webpack/UnknownExtInclusion').default));
|
||||
break;
|
||||
default: throw new Error(`Missing feature "${feature}"`);
|
||||
}
|
||||
}
|
||||
|
||||
setFeature(feature) {
|
||||
this.setState({ feature });
|
||||
}
|
||||
|
||||
render() {
|
||||
const { feature } = this.state;
|
||||
if (feature !== null) {
|
||||
return <BuiltEmitter feature={feature} />;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export default App;
|
||||
6
packages/react-scripts/fixtures/kitchensink/src/absoluteLoad.js
vendored
Normal file
6
packages/react-scripts/fixtures/kitchensink/src/absoluteLoad.js
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
export default () => [
|
||||
{ id: 1, name: '1' },
|
||||
{ id: 2, name: '2' },
|
||||
{ id: 3, name: '3' },
|
||||
{ id: 4, name: '4' }
|
||||
]
|
||||
5
packages/react-scripts/fixtures/kitchensink/src/features/env/FileEnvVariables.js
vendored
Normal file
5
packages/react-scripts/fixtures/kitchensink/src/features/env/FileEnvVariables.js
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
import React from 'react'
|
||||
|
||||
export default () => (
|
||||
<span id="feature-file-env-variables">{process.env.REACT_APP_FILE_ENV_MESSAGE}.</span>
|
||||
)
|
||||
10
packages/react-scripts/fixtures/kitchensink/src/features/env/FileEnvVariables.test.js
vendored
Normal file
10
packages/react-scripts/fixtures/kitchensink/src/features/env/FileEnvVariables.test.js
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import FileEnvVariables from './FileEnvVariables';
|
||||
|
||||
describe('.env variables', () => {
|
||||
it('renders without crashing', () => {
|
||||
const div = document.createElement('div');
|
||||
ReactDOM.render(<FileEnvVariables />, div);
|
||||
});
|
||||
});
|
||||
32
packages/react-scripts/fixtures/kitchensink/src/features/env/NodePath.js
vendored
Normal file
32
packages/react-scripts/fixtures/kitchensink/src/features/env/NodePath.js
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
import React, { Component, PropTypes } from 'react'
|
||||
import load from 'absoluteLoad'
|
||||
|
||||
export default class extends Component {
|
||||
static propTypes = {
|
||||
onReady: PropTypes.func.isRequired
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = { users: [] };
|
||||
}
|
||||
|
||||
async componentDidMount() {
|
||||
const users = load();
|
||||
this.setState({ users });
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
this.props.onReady();
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div id="feature-node-path">
|
||||
{this.state.users.map(user => (
|
||||
<div key={user.id}>{user.name}</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
12
packages/react-scripts/fixtures/kitchensink/src/features/env/NodePath.test.js
vendored
Normal file
12
packages/react-scripts/fixtures/kitchensink/src/features/env/NodePath.test.js
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import NodePath from './NodePath';
|
||||
|
||||
describe('NODE_PATH', () => {
|
||||
it('renders without crashing', () => {
|
||||
const div = document.createElement('div');
|
||||
return new Promise(resolve => {
|
||||
ReactDOM.render(<NodePath onReady={resolve} />, div);
|
||||
});
|
||||
});
|
||||
});
|
||||
5
packages/react-scripts/fixtures/kitchensink/src/features/env/PublicUrl.js
vendored
Normal file
5
packages/react-scripts/fixtures/kitchensink/src/features/env/PublicUrl.js
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
import React from 'react'
|
||||
|
||||
export default () => (
|
||||
<span id="feature-public-url">{process.env.PUBLIC_URL}.</span>
|
||||
)
|
||||
10
packages/react-scripts/fixtures/kitchensink/src/features/env/PublicUrl.test.js
vendored
Normal file
10
packages/react-scripts/fixtures/kitchensink/src/features/env/PublicUrl.test.js
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import PublicUrl from './PublicUrl';
|
||||
|
||||
describe('PUBLIC_URL', () => {
|
||||
it('renders without crashing', () => {
|
||||
const div = document.createElement('div');
|
||||
ReactDOM.render(<PublicUrl />, div);
|
||||
});
|
||||
});
|
||||
5
packages/react-scripts/fixtures/kitchensink/src/features/env/ShellEnvVariables.js
vendored
Normal file
5
packages/react-scripts/fixtures/kitchensink/src/features/env/ShellEnvVariables.js
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
import React from 'react'
|
||||
|
||||
export default () => (
|
||||
<span id="feature-shell-env-variables">{process.env.REACT_APP_SHELL_ENV_MESSAGE}.</span>
|
||||
)
|
||||
10
packages/react-scripts/fixtures/kitchensink/src/features/env/ShellEnvVariables.test.js
vendored
Normal file
10
packages/react-scripts/fixtures/kitchensink/src/features/env/ShellEnvVariables.test.js
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import ShellEnvVariables from './ShellEnvVariables';
|
||||
|
||||
describe('shell env variables', () => {
|
||||
it('renders without crashing', () => {
|
||||
const div = document.createElement('div');
|
||||
ReactDOM.render(<ShellEnvVariables />, div);
|
||||
});
|
||||
});
|
||||
41
packages/react-scripts/fixtures/kitchensink/src/features/syntax/ArrayDestructuring.js
vendored
Normal file
41
packages/react-scripts/fixtures/kitchensink/src/features/syntax/ArrayDestructuring.js
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
import React, { Component, PropTypes } from 'react'
|
||||
|
||||
function load() {
|
||||
return [
|
||||
[1, '1'],
|
||||
[2, '2'],
|
||||
[3, '3'],
|
||||
[4, '4']
|
||||
];
|
||||
}
|
||||
|
||||
export default class extends Component {
|
||||
static propTypes = {
|
||||
onReady: PropTypes.func.isRequired
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = { users: [] };
|
||||
}
|
||||
|
||||
async componentDidMount() {
|
||||
const users = load();
|
||||
this.setState({ users });
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
this.props.onReady();
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div id="feature-array-destructuring">
|
||||
{this.state.users.map(user => {
|
||||
const [id, name] = user;
|
||||
return <div key={id}>{name}</div>
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import ArrayDestructuring from './ArrayDestructuring';
|
||||
|
||||
describe('array destructuring', () => {
|
||||
it('renders without crashing', () => {
|
||||
const div = document.createElement('div');
|
||||
return new Promise(resolve => {
|
||||
ReactDOM.render(<ArrayDestructuring onReady={resolve} />, div);
|
||||
});
|
||||
});
|
||||
});
|
||||
40
packages/react-scripts/fixtures/kitchensink/src/features/syntax/ArraySpread.js
vendored
Normal file
40
packages/react-scripts/fixtures/kitchensink/src/features/syntax/ArraySpread.js
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
import React, { Component, PropTypes } from 'react'
|
||||
|
||||
function load(users) {
|
||||
return [
|
||||
{ id: 1, name: '1' },
|
||||
{ id: 2, name: '2' },
|
||||
{ id: 3, name: '3' },
|
||||
...users
|
||||
];
|
||||
}
|
||||
|
||||
export default class extends Component {
|
||||
static propTypes = {
|
||||
onReady: PropTypes.func.isRequired
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = { users: [] };
|
||||
}
|
||||
|
||||
async componentDidMount() {
|
||||
const users = load([{ id: 42, name: '42' }]);
|
||||
this.setState({ users });
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
this.props.onReady();
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div id="feature-array-spread">
|
||||
{this.state.users.map(user => (
|
||||
<div key={user.id}>{user.name}</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import ArraySpread from './ArraySpread';
|
||||
|
||||
describe('array spread', () => {
|
||||
it('renders without crashing', () => {
|
||||
const div = document.createElement('div');
|
||||
return new Promise(resolve => {
|
||||
ReactDOM.render(<ArraySpread onReady={resolve} />, div);
|
||||
});
|
||||
});
|
||||
});
|
||||
40
packages/react-scripts/fixtures/kitchensink/src/features/syntax/AsyncAwait.js
vendored
Normal file
40
packages/react-scripts/fixtures/kitchensink/src/features/syntax/AsyncAwait.js
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
import React, { Component, PropTypes } from 'react'
|
||||
|
||||
async function load() {
|
||||
return [
|
||||
{ id: 1, name: '1' },
|
||||
{ id: 2, name: '2' },
|
||||
{ id: 3, name: '3' },
|
||||
{ id: 4, name: '4' }
|
||||
];
|
||||
}
|
||||
|
||||
export default class extends Component {
|
||||
static propTypes = {
|
||||
onReady: PropTypes.func.isRequired
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = { users: [] };
|
||||
}
|
||||
|
||||
async componentDidMount() {
|
||||
const users = await load();
|
||||
this.setState({ users });
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
this.props.onReady();
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div id="feature-async-await">
|
||||
{this.state.users.map(user => (
|
||||
<div key={user.id}>{user.name}</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import AsyncAwait from './AsyncAwait';
|
||||
|
||||
describe('async/await', () => {
|
||||
it('renders without crashing', () => {
|
||||
const div = document.createElement('div');
|
||||
return new Promise(resolve => {
|
||||
ReactDOM.render(<AsyncAwait onReady={resolve} />, div);
|
||||
});
|
||||
});
|
||||
});
|
||||
28
packages/react-scripts/fixtures/kitchensink/src/features/syntax/ClassProperties.js
vendored
Normal file
28
packages/react-scripts/fixtures/kitchensink/src/features/syntax/ClassProperties.js
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
import React, { Component, PropTypes } from 'react'
|
||||
|
||||
export default class extends Component {
|
||||
static propTypes = {
|
||||
onReady: PropTypes.func.isRequired
|
||||
}
|
||||
|
||||
users = [
|
||||
{ id: 1, name: '1' },
|
||||
{ id: 2, name: '2' },
|
||||
{ id: 3, name: '3' },
|
||||
{ id: 4, name: '4' }
|
||||
];
|
||||
|
||||
componentDidMount() {
|
||||
this.props.onReady()
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div id="feature-class-properties">
|
||||
{this.users.map(user => (
|
||||
<div key={user.id}>{user.name}</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import ClassProperties from './ClassProperties';
|
||||
|
||||
describe('class properties', () => {
|
||||
it('renders without crashing', () => {
|
||||
const div = document.createElement('div');
|
||||
return new Promise(resolve => {
|
||||
ReactDOM.render(<ClassProperties onReady={resolve} />, div);
|
||||
});
|
||||
});
|
||||
});
|
||||
40
packages/react-scripts/fixtures/kitchensink/src/features/syntax/ComputedProperties.js
vendored
Normal file
40
packages/react-scripts/fixtures/kitchensink/src/features/syntax/ComputedProperties.js
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
import React, { Component, PropTypes } from 'react'
|
||||
|
||||
function load(prefix) {
|
||||
return [
|
||||
{ id: 1, [prefix + 'name']: '1' },
|
||||
{ id: 2, [prefix + 'name']: '2' },
|
||||
{ id: 3, [prefix + 'name']: '3' },
|
||||
{ id: 4, [prefix + 'name']: '4' }
|
||||
];
|
||||
}
|
||||
|
||||
export default class extends Component {
|
||||
static propTypes = {
|
||||
onReady: PropTypes.func.isRequired
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = { users: [] };
|
||||
}
|
||||
|
||||
async componentDidMount() {
|
||||
const users = load('user_');
|
||||
this.setState({ users });
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
this.props.onReady();
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div id="feature-computed-properties">
|
||||
{this.state.users.map(user => (
|
||||
<div key={user.id}>{user.user_name}</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import ComputedProperties from './ComputedProperties';
|
||||
|
||||
describe('computed properties', () => {
|
||||
it('renders without crashing', () => {
|
||||
const div = document.createElement('div');
|
||||
return new Promise(resolve => {
|
||||
ReactDOM.render(<ComputedProperties onReady={resolve} />, div);
|
||||
});
|
||||
});
|
||||
});
|
||||
50
packages/react-scripts/fixtures/kitchensink/src/features/syntax/CustomInterpolation.js
vendored
Normal file
50
packages/react-scripts/fixtures/kitchensink/src/features/syntax/CustomInterpolation.js
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
import React, { Component, PropTypes } from 'react'
|
||||
|
||||
const styled = ([style]) => style.trim()
|
||||
.split(/\s*;\s*/)
|
||||
.map(rule => rule.split(/\s*:\s*/))
|
||||
.reduce((rules, rule) => ({ ...rules, [rule[0]]: rule[1] }), {});
|
||||
|
||||
function load() {
|
||||
return [
|
||||
{ id: 1, name: '1' },
|
||||
{ id: 2, name: '2' },
|
||||
{ id: 3, name: '3' },
|
||||
{ id: 4, name: '4' }
|
||||
];
|
||||
}
|
||||
|
||||
export default class extends Component {
|
||||
static propTypes = {
|
||||
onReady: PropTypes.func.isRequired
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = { users: [] };
|
||||
}
|
||||
|
||||
async componentDidMount() {
|
||||
const users = load();
|
||||
this.setState({ users });
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
this.props.onReady();
|
||||
}
|
||||
|
||||
render() {
|
||||
const veryInlineStyle = styled`
|
||||
background: palevioletred;
|
||||
color: papayawhip;
|
||||
`;
|
||||
|
||||
return (
|
||||
<div id="feature-custom-interpolation">
|
||||
{this.state.users.map(user => (
|
||||
<div key={user.id} style={veryInlineStyle}>{user.name}</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import CustomInterpolation from './CustomInterpolation';
|
||||
|
||||
describe('custom interpolation', () => {
|
||||
it('renders without crashing', () => {
|
||||
const div = document.createElement('div');
|
||||
return new Promise(resolve => {
|
||||
ReactDOM.render(<CustomInterpolation onReady={resolve} />, div);
|
||||
});
|
||||
});
|
||||
});
|
||||
40
packages/react-scripts/fixtures/kitchensink/src/features/syntax/DefaultParameters.js
vendored
Normal file
40
packages/react-scripts/fixtures/kitchensink/src/features/syntax/DefaultParameters.js
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
import React, { Component, PropTypes } from 'react'
|
||||
|
||||
function load(id = 0) {
|
||||
return [
|
||||
{ id: id + 1, name: '1' },
|
||||
{ id: id + 2, name: '2' },
|
||||
{ id: id + 3, name: '3' },
|
||||
{ id: id + 4, name: '4' }
|
||||
];
|
||||
}
|
||||
|
||||
export default class extends Component {
|
||||
static propTypes = {
|
||||
onReady: PropTypes.func.isRequired
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = { users: [] };
|
||||
}
|
||||
|
||||
async componentDidMount() {
|
||||
const users = load();
|
||||
this.setState({ users });
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
this.props.onReady();
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div id="feature-default-parameters">
|
||||
{this.state.users.map(user => (
|
||||
<div key={user.id}>{user.name}</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import DefaultParameters from './DefaultParameters';
|
||||
|
||||
describe('default parameters', () => {
|
||||
it('renders without crashing', () => {
|
||||
const div = document.createElement('div');
|
||||
return new Promise(resolve => {
|
||||
ReactDOM.render(<DefaultParameters onReady={resolve} />, div);
|
||||
});
|
||||
});
|
||||
});
|
||||
40
packages/react-scripts/fixtures/kitchensink/src/features/syntax/DestructuringAndAwait.js
vendored
Normal file
40
packages/react-scripts/fixtures/kitchensink/src/features/syntax/DestructuringAndAwait.js
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
import React, { Component, PropTypes } from 'react'
|
||||
|
||||
async function load() {
|
||||
return { users: [
|
||||
{ id: 1, name: '1' },
|
||||
{ id: 2, name: '2' },
|
||||
{ id: 3, name: '3' },
|
||||
{ id: 4, name: '4' }
|
||||
] };
|
||||
}
|
||||
|
||||
export default class extends Component {
|
||||
static propTypes = {
|
||||
onReady: PropTypes.func.isRequired
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = { users: [] };
|
||||
}
|
||||
|
||||
async componentDidMount() {
|
||||
const { users } = await load();
|
||||
this.setState({ users });
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
this.props.onReady();
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div id="feature-destructuring-and-await">
|
||||
{this.state.users.map(user => (
|
||||
<div key={user.id}>{user.name}</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import DestructuringAndAwait from './DestructuringAndAwait';
|
||||
|
||||
describe('destructuring and await', () => {
|
||||
it('renders without crashing', () => {
|
||||
const div = document.createElement('div');
|
||||
return new Promise(resolve => {
|
||||
ReactDOM.render(<DestructuringAndAwait onReady={resolve} />, div);
|
||||
});
|
||||
});
|
||||
});
|
||||
42
packages/react-scripts/fixtures/kitchensink/src/features/syntax/Generators.js
vendored
Normal file
42
packages/react-scripts/fixtures/kitchensink/src/features/syntax/Generators.js
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
import React, { Component, PropTypes } from 'react'
|
||||
|
||||
function * load(limit) {
|
||||
let i = 1;
|
||||
while (i <= limit) {
|
||||
yield { id: i, name: i };
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
export default class extends Component {
|
||||
static propTypes = {
|
||||
onReady: PropTypes.func.isRequired
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = { users: [] };
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
const users = [];
|
||||
for (let user of load(4)) {
|
||||
users.push(user);
|
||||
}
|
||||
this.setState({ users });
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
this.props.onReady();
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div id="feature-generators">
|
||||
{this.state.users.map(user => (
|
||||
<div key={user.id}>{user.name}</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import Generators from './Generators';
|
||||
|
||||
describe('generators', () => {
|
||||
it('renders without crashing', () => {
|
||||
const div = document.createElement('div');
|
||||
return new Promise(resolve => {
|
||||
ReactDOM.render(<Generators onReady={resolve} />, div);
|
||||
});
|
||||
});
|
||||
});
|
||||
41
packages/react-scripts/fixtures/kitchensink/src/features/syntax/ObjectDestructuring.js
vendored
Normal file
41
packages/react-scripts/fixtures/kitchensink/src/features/syntax/ObjectDestructuring.js
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
import React, { Component, PropTypes } from 'react'
|
||||
|
||||
function load() {
|
||||
return [
|
||||
{ id: 1, name: '1' },
|
||||
{ id: 2, name: '2' },
|
||||
{ id: 3, name: '3' },
|
||||
{ id: 4, name: '4' }
|
||||
];
|
||||
}
|
||||
|
||||
export default class extends Component {
|
||||
static propTypes = {
|
||||
onReady: PropTypes.func.isRequired
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = { users: [] };
|
||||
}
|
||||
|
||||
async componentDidMount() {
|
||||
const users = load();
|
||||
this.setState({ users });
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
this.props.onReady();
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div id="feature-object-destructuring">
|
||||
{this.state.users.map(user => {
|
||||
const { id, name } = user;
|
||||
return <div key={id}>{name}</div>
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import ObjectDestructuring from './ObjectDestructuring';
|
||||
|
||||
describe('object destructuring', () => {
|
||||
it('renders without crashing', () => {
|
||||
const div = document.createElement('div');
|
||||
return new Promise(resolve => {
|
||||
ReactDOM.render(<ObjectDestructuring onReady={resolve} />, div);
|
||||
});
|
||||
});
|
||||
});
|
||||
40
packages/react-scripts/fixtures/kitchensink/src/features/syntax/ObjectSpread.js
vendored
Normal file
40
packages/react-scripts/fixtures/kitchensink/src/features/syntax/ObjectSpread.js
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
import React, { Component, PropTypes } from 'react'
|
||||
|
||||
function load(baseUser) {
|
||||
return [
|
||||
{ id: 1, name: '1', ...baseUser },
|
||||
{ id: 2, name: '2', ...baseUser },
|
||||
{ id: 3, name: '3', ...baseUser },
|
||||
{ id: 4, name: '4', ...baseUser }
|
||||
];
|
||||
}
|
||||
|
||||
export default class extends Component {
|
||||
static propTypes = {
|
||||
onReady: PropTypes.func.isRequired
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = { users: [] };
|
||||
}
|
||||
|
||||
async componentDidMount() {
|
||||
const users = load({ age: 42 });
|
||||
this.setState({ users });
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
this.props.onReady();
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div id="feature-object-spread">
|
||||
{this.state.users.map(user => (
|
||||
<div key={user.id}>{user.name}: {user.age}</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import ObjectSpread from './ObjectSpread';
|
||||
|
||||
describe('object spread', () => {
|
||||
it('renders without crashing', () => {
|
||||
const div = document.createElement('div');
|
||||
return new Promise(resolve => {
|
||||
ReactDOM.render(<ObjectSpread onReady={resolve} />, div);
|
||||
});
|
||||
});
|
||||
});
|
||||
41
packages/react-scripts/fixtures/kitchensink/src/features/syntax/Promises.js
vendored
Normal file
41
packages/react-scripts/fixtures/kitchensink/src/features/syntax/Promises.js
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
import React, { Component, PropTypes } from 'react'
|
||||
|
||||
function load() {
|
||||
return Promise.resolve([
|
||||
{ id: 1, name: '1' },
|
||||
{ id: 2, name: '2' },
|
||||
{ id: 3, name: '3' },
|
||||
{ id: 4, name: '4' }
|
||||
]);
|
||||
}
|
||||
|
||||
export default class extends Component {
|
||||
static propTypes = {
|
||||
onReady: PropTypes.func.isRequired
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = { users: [] };
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
load().then(users => {
|
||||
this.setState({ users });
|
||||
});
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
this.props.onReady();
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div id="feature-promises">
|
||||
{this.state.users.map(user => (
|
||||
<div key={user.id}>{user.name}</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import Promises from './Promises';
|
||||
|
||||
describe('promises', () => {
|
||||
it('renders without crashing', () => {
|
||||
const div = document.createElement('div');
|
||||
return new Promise(resolve => {
|
||||
ReactDOM.render(<Promises onReady={resolve} />, div);
|
||||
});
|
||||
});
|
||||
});
|
||||
40
packages/react-scripts/fixtures/kitchensink/src/features/syntax/RestAndDefault.js
vendored
Normal file
40
packages/react-scripts/fixtures/kitchensink/src/features/syntax/RestAndDefault.js
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
import React, { Component, PropTypes } from 'react'
|
||||
|
||||
function load({ id, ...rest } = { id: 0, user: { id: 42, name: '42' } }) {
|
||||
return [
|
||||
{ id: id + 1, name: '1' },
|
||||
{ id: id + 2, name: '2' },
|
||||
{ id: id + 3, name: '3' },
|
||||
rest.user
|
||||
];
|
||||
}
|
||||
|
||||
export default class extends Component {
|
||||
static propTypes = {
|
||||
onReady: PropTypes.func.isRequired
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = { users: [] };
|
||||
}
|
||||
|
||||
async componentDidMount() {
|
||||
const users = load();
|
||||
this.setState({ users });
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
this.props.onReady();
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div id="feature-rest-and-default">
|
||||
{this.state.users.map(user => (
|
||||
<div key={user.id}>{user.name}</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import RestAndDefault from './RestAndDefault';
|
||||
|
||||
describe('rest + default', () => {
|
||||
it('renders without crashing', () => {
|
||||
const div = document.createElement('div');
|
||||
return new Promise(resolve => {
|
||||
ReactDOM.render(<RestAndDefault onReady={resolve} />, div);
|
||||
});
|
||||
});
|
||||
});
|
||||
40
packages/react-scripts/fixtures/kitchensink/src/features/syntax/RestParameters.js
vendored
Normal file
40
packages/react-scripts/fixtures/kitchensink/src/features/syntax/RestParameters.js
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
import React, { Component, PropTypes } from 'react'
|
||||
|
||||
function load({ id = 0, ...rest }) {
|
||||
return [
|
||||
{ id: id + 1, name: '1' },
|
||||
{ id: id + 2, name: '2' },
|
||||
{ id: id + 3, name: '3' },
|
||||
rest.user
|
||||
];
|
||||
}
|
||||
|
||||
export default class extends Component {
|
||||
static propTypes = {
|
||||
onReady: PropTypes.func.isRequired
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = { users: [] };
|
||||
}
|
||||
|
||||
async componentDidMount() {
|
||||
const users = load({ id: 0, user: { id: 42, name: '42' } });
|
||||
this.setState({ users });
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
this.props.onReady();
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div id="feature-rest-parameters">
|
||||
{this.state.users.map(user => (
|
||||
<div key={user.id}>{user.name}</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import RestParameters from './RestParameters';
|
||||
|
||||
describe('rest parameters', () => {
|
||||
it('renders without crashing', () => {
|
||||
const div = document.createElement('div');
|
||||
return new Promise(resolve => {
|
||||
ReactDOM.render(<RestParameters onReady={resolve} />, div);
|
||||
});
|
||||
});
|
||||
});
|
||||
40
packages/react-scripts/fixtures/kitchensink/src/features/syntax/TemplateInterpolation.js
vendored
Normal file
40
packages/react-scripts/fixtures/kitchensink/src/features/syntax/TemplateInterpolation.js
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
import React, { Component, PropTypes } from 'react'
|
||||
|
||||
function load(name) {
|
||||
return [
|
||||
{ id: 1, name: `${name}1` },
|
||||
{ id: 2, name: `${name}2` },
|
||||
{ id: 3, name: `${name}3` },
|
||||
{ id: 4, name: `${name}4` }
|
||||
];
|
||||
}
|
||||
|
||||
export default class extends Component {
|
||||
static propTypes = {
|
||||
onReady: PropTypes.func.isRequired
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = { users: [] };
|
||||
}
|
||||
|
||||
async componentDidMount() {
|
||||
const users = load('user_');
|
||||
this.setState({ users });
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
this.props.onReady();
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div id="feature-template-interpolation">
|
||||
{this.state.users.map(user => (
|
||||
<div key={user.id}>{user.name}</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import TemplateInterpolation from './TemplateInterpolation';
|
||||
|
||||
describe('template interpolation', () => {
|
||||
it('renders without crashing', () => {
|
||||
const div = document.createElement('div');
|
||||
return new Promise(resolve => {
|
||||
ReactDOM.render(<TemplateInterpolation onReady={resolve} />, div);
|
||||
});
|
||||
});
|
||||
});
|
||||
6
packages/react-scripts/fixtures/kitchensink/src/features/webpack/CssInclusion.js
vendored
Normal file
6
packages/react-scripts/fixtures/kitchensink/src/features/webpack/CssInclusion.js
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
import React from 'react'
|
||||
import './assets/style.css'
|
||||
|
||||
export default () => (
|
||||
<p id="feature-css-inclusion">We love useless text.</p>
|
||||
)
|
||||
@@ -0,0 +1,10 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import CssInclusion from './CssInclusion';
|
||||
|
||||
describe('css inclusion', () => {
|
||||
it('renders without crashing', () => {
|
||||
const div = document.createElement('div');
|
||||
ReactDOM.render(<CssInclusion />, div);
|
||||
});
|
||||
});
|
||||
6
packages/react-scripts/fixtures/kitchensink/src/features/webpack/ImageInclusion.js
vendored
Normal file
6
packages/react-scripts/fixtures/kitchensink/src/features/webpack/ImageInclusion.js
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
import React from 'react'
|
||||
import tiniestCat from './assets/tiniest-cat.jpg'
|
||||
|
||||
export default () => (
|
||||
<img id="feature-image-inclusion" src={tiniestCat} alt="tiniest cat" />
|
||||
)
|
||||
@@ -0,0 +1,10 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import ImageInclusion from './ImageInclusion';
|
||||
|
||||
describe('image inclusion', () => {
|
||||
it('renders without crashing', () => {
|
||||
const div = document.createElement('div');
|
||||
ReactDOM.render(<ImageInclusion />, div);
|
||||
});
|
||||
});
|
||||
6
packages/react-scripts/fixtures/kitchensink/src/features/webpack/JsonInclusion.js
vendored
Normal file
6
packages/react-scripts/fixtures/kitchensink/src/features/webpack/JsonInclusion.js
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
import React from 'react'
|
||||
import { abstract } from './assets/abstract.json'
|
||||
|
||||
export default () => (
|
||||
<summary id="feature-json-inclusion">{abstract}</summary>
|
||||
)
|
||||
@@ -0,0 +1,10 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import JsonInclusion from './JsonInclusion';
|
||||
|
||||
describe('JSON inclusion', () => {
|
||||
it('renders without crashing', () => {
|
||||
const div = document.createElement('div');
|
||||
ReactDOM.render(<JsonInclusion />, div);
|
||||
});
|
||||
});
|
||||
10
packages/react-scripts/fixtures/kitchensink/src/features/webpack/NoExtInclusion.js
vendored
Normal file
10
packages/react-scripts/fixtures/kitchensink/src/features/webpack/NoExtInclusion.js
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
import React from 'react'
|
||||
import aFileWithoutExt from './assets/aFileWithoutExt'
|
||||
|
||||
const text = aFileWithoutExt.includes('base64')
|
||||
? atob(aFileWithoutExt.split('base64,')[1]).trim()
|
||||
: aFileWithoutExt
|
||||
|
||||
export default () => (
|
||||
<p id="feature-no-ext-inclusion">{text}.</p>
|
||||
)
|
||||
@@ -0,0 +1,10 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import NoExtInclusion from './NoExtInclusion';
|
||||
|
||||
describe('no ext inclusion', () => {
|
||||
it('renders without crashing', () => {
|
||||
const div = document.createElement('div');
|
||||
ReactDOM.render(<NoExtInclusion />, div);
|
||||
});
|
||||
});
|
||||
6
packages/react-scripts/fixtures/kitchensink/src/features/webpack/SvgInclusion.js
vendored
Normal file
6
packages/react-scripts/fixtures/kitchensink/src/features/webpack/SvgInclusion.js
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
import React from 'react'
|
||||
import logo from './assets/logo.svg'
|
||||
|
||||
export default () => (
|
||||
<img id="feature-svg-inclusion" src={logo} alt="logo" />
|
||||
)
|
||||
@@ -0,0 +1,10 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import SvgInclusion from './SvgInclusion';
|
||||
|
||||
describe('svg inclusion', () => {
|
||||
it('renders without crashing', () => {
|
||||
const div = document.createElement('div');
|
||||
ReactDOM.render(<SvgInclusion />, div);
|
||||
});
|
||||
});
|
||||
10
packages/react-scripts/fixtures/kitchensink/src/features/webpack/UnknownExtInclusion.js
vendored
Normal file
10
packages/react-scripts/fixtures/kitchensink/src/features/webpack/UnknownExtInclusion.js
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
import React from 'react'
|
||||
import aFileWithExtUnknown from './assets/aFileWithExt.unknown'
|
||||
|
||||
const text = aFileWithExtUnknown.includes('base64')
|
||||
? atob(aFileWithExtUnknown.split('base64,')[1]).trim()
|
||||
: aFileWithExtUnknown
|
||||
|
||||
export default () => (
|
||||
<p id="feature-unknown-ext-inclusion">{text}.</p>
|
||||
)
|
||||
@@ -0,0 +1,10 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import UnknownExtInclusion from './UnknownExtInclusion';
|
||||
|
||||
describe('unknown ext inclusion', () => {
|
||||
it('renders without crashing', () => {
|
||||
const div = document.createElement('div');
|
||||
ReactDOM.render(<UnknownExtInclusion />, div);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1 @@
|
||||
Whoooo, spooky!
|
||||
@@ -0,0 +1 @@
|
||||
This is just a file without an extension
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"abstract": "This is an abstract."
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 841.9 595.3">
|
||||
<g fill="#61DAFB">
|
||||
<path d="M666.3 296.5c0-32.5-40.7-63.3-103.1-82.4 14.4-63.6 8-114.2-20.2-130.4-6.5-3.8-14.1-5.6-22.4-5.6v22.3c4.6 0 8.3.9 11.4 2.6 13.6 7.8 19.5 37.5 14.9 75.7-1.1 9.4-2.9 19.3-5.1 29.4-19.6-4.8-41-8.5-63.5-10.9-13.5-18.5-27.5-35.3-41.6-50 32.6-30.3 63.2-46.9 84-46.9V78c-27.5 0-63.5 19.6-99.9 53.6-36.4-33.8-72.4-53.2-99.9-53.2v22.3c20.7 0 51.4 16.5 84 46.6-14 14.7-28 31.4-41.3 49.9-22.6 2.4-44 6.1-63.6 11-2.3-10-4-19.7-5.2-29-4.7-38.2 1.1-67.9 14.6-75.8 3-1.8 6.9-2.6 11.5-2.6V78.5c-8.4 0-16 1.8-22.6 5.6-28.1 16.2-34.4 66.7-19.9 130.1-62.2 19.2-102.7 49.9-102.7 82.3 0 32.5 40.7 63.3 103.1 82.4-14.4 63.6-8 114.2 20.2 130.4 6.5 3.8 14.1 5.6 22.5 5.6 27.5 0 63.5-19.6 99.9-53.6 36.4 33.8 72.4 53.2 99.9 53.2 8.4 0 16-1.8 22.6-5.6 28.1-16.2 34.4-66.7 19.9-130.1 62-19.1 102.5-49.9 102.5-82.3zm-130.2-66.7c-3.7 12.9-8.3 26.2-13.5 39.5-4.1-8-8.4-16-13.1-24-4.6-8-9.5-15.8-14.4-23.4 14.2 2.1 27.9 4.7 41 7.9zm-45.8 106.5c-7.8 13.5-15.8 26.3-24.1 38.2-14.9 1.3-30 2-45.2 2-15.1 0-30.2-.7-45-1.9-8.3-11.9-16.4-24.6-24.2-38-7.6-13.1-14.5-26.4-20.8-39.8 6.2-13.4 13.2-26.8 20.7-39.9 7.8-13.5 15.8-26.3 24.1-38.2 14.9-1.3 30-2 45.2-2 15.1 0 30.2.7 45 1.9 8.3 11.9 16.4 24.6 24.2 38 7.6 13.1 14.5 26.4 20.8 39.8-6.3 13.4-13.2 26.8-20.7 39.9zm32.3-13c5.4 13.4 10 26.8 13.8 39.8-13.1 3.2-26.9 5.9-41.2 8 4.9-7.7 9.8-15.6 14.4-23.7 4.6-8 8.9-16.1 13-24.1zM421.2 430c-9.3-9.6-18.6-20.3-27.8-32 9 .4 18.2.7 27.5.7 9.4 0 18.7-.2 27.8-.7-9 11.7-18.3 22.4-27.5 32zm-74.4-58.9c-14.2-2.1-27.9-4.7-41-7.9 3.7-12.9 8.3-26.2 13.5-39.5 4.1 8 8.4 16 13.1 24 4.7 8 9.5 15.8 14.4 23.4zM420.7 163c9.3 9.6 18.6 20.3 27.8 32-9-.4-18.2-.7-27.5-.7-9.4 0-18.7.2-27.8.7 9-11.7 18.3-22.4 27.5-32zm-74 58.9c-4.9 7.7-9.8 15.6-14.4 23.7-4.6 8-8.9 16-13 24-5.4-13.4-10-26.8-13.8-39.8 13.1-3.1 26.9-5.8 41.2-7.9zm-90.5 125.2c-35.4-15.1-58.3-34.9-58.3-50.6 0-15.7 22.9-35.6 58.3-50.6 8.6-3.7 18-7 27.7-10.1 5.7 19.6 13.2 40 22.5 60.9-9.2 20.8-16.6 41.1-22.2 60.6-9.9-3.1-19.3-6.5-28-10.2zM310 490c-13.6-7.8-19.5-37.5-14.9-75.7 1.1-9.4 2.9-19.3 5.1-29.4 19.6 4.8 41 8.5 63.5 10.9 13.5 18.5 27.5 35.3 41.6 50-32.6 30.3-63.2 46.9-84 46.9-4.5-.1-8.3-1-11.3-2.7zm237.2-76.2c4.7 38.2-1.1 67.9-14.6 75.8-3 1.8-6.9 2.6-11.5 2.6-20.7 0-51.4-16.5-84-46.6 14-14.7 28-31.4 41.3-49.9 22.6-2.4 44-6.1 63.6-11 2.3 10.1 4.1 19.8 5.2 29.1zm38.5-66.7c-8.6 3.7-18 7-27.7 10.1-5.7-19.6-13.2-40-22.5-60.9 9.2-20.8 16.6-41.1 22.2-60.6 9.9 3.1 19.3 6.5 28.1 10.2 35.4 15.1 58.3 34.9 58.3 50.6-.1 15.7-23 35.6-58.4 50.6zM320.8 78.4z"/>
|
||||
<circle cx="420.9" cy="296.5" r="45.7"/>
|
||||
<path d="M520.5 78.1z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.6 KiB |
@@ -0,0 +1,4 @@
|
||||
#feature-css-inclusion {
|
||||
background: palevioletred;
|
||||
color: papayawhip;
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 691 B |
8
packages/react-scripts/fixtures/kitchensink/src/index.js
vendored
Normal file
8
packages/react-scripts/fixtures/kitchensink/src/index.js
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import App from './App';
|
||||
|
||||
ReactDOM.render(
|
||||
<App />,
|
||||
document.getElementById('root')
|
||||
);
|
||||
1
packages/react-scripts/fixtures/kitchensink/src/subfolder/lol.js
vendored
Normal file
1
packages/react-scripts/fixtures/kitchensink/src/subfolder/lol.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
module.exports = function() { return `haha` }
|
||||
@@ -22,26 +22,26 @@
|
||||
"react-scripts-ts": "./bin/react-scripts-ts.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"autoprefixer": "6.5.1",
|
||||
"autoprefixer": "6.7.2",
|
||||
"case-sensitive-paths-webpack-plugin": "1.1.4",
|
||||
"chalk": "1.1.3",
|
||||
"cli-highlight": "1.1.4",
|
||||
"connect-history-api-fallback": "1.3.0",
|
||||
"cross-spawn": "4.0.2",
|
||||
"css-loader": "0.26.0",
|
||||
"css-loader": "0.26.1",
|
||||
"detect-port": "1.0.1",
|
||||
"dotenv": "2.0.0",
|
||||
"extract-text-webpack-plugin": "1.0.1",
|
||||
"file-loader": "0.9.0",
|
||||
"file-loader": "0.10.0",
|
||||
"filesize": "3.3.0",
|
||||
"fs-extra": "0.30.0",
|
||||
"gzip-size": "3.0.0",
|
||||
"html-webpack-plugin": "2.24.0",
|
||||
"http-proxy-middleware": "0.17.2",
|
||||
"jest": "17.0.2",
|
||||
"http-proxy-middleware": "0.17.3",
|
||||
"jest": "18.1.0",
|
||||
"json-loader": "0.5.4",
|
||||
"object-assign": "4.1.0",
|
||||
"postcss-loader": "1.0.0",
|
||||
"object-assign": "4.1.1",
|
||||
"postcss-loader": "1.2.2",
|
||||
"promise": "7.1.1",
|
||||
"react-dev-utils": "^0.4.2",
|
||||
"recursive-readdir": "2.1.0",
|
||||
@@ -56,13 +56,13 @@
|
||||
"webpack": "1.14.0",
|
||||
"webpack-dev-server": "1.16.2",
|
||||
"webpack-manifest-plugin": "1.1.0",
|
||||
"whatwg-fetch": "1.0.0"
|
||||
"whatwg-fetch": "2.0.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"react": "^15.3.0",
|
||||
"react-dom": "^15.3.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"fsevents": "1.0.14"
|
||||
"fsevents": "1.0.17"
|
||||
}
|
||||
}
|
||||
|
||||
21
packages/react-scripts/scripts/build.js
vendored
21
packages/react-scripts/scripts/build.js
vendored
@@ -21,6 +21,7 @@ require('dotenv').config({silent: true});
|
||||
var chalk = require('chalk');
|
||||
var fs = require('fs-extra');
|
||||
var path = require('path');
|
||||
var url = require('url');
|
||||
var filesize = require('filesize');
|
||||
var gzipSize = require('gzip-size').sync;
|
||||
var webpack = require('webpack');
|
||||
@@ -178,7 +179,7 @@ function build(previousSizeMap) {
|
||||
}
|
||||
|
||||
if (process.env.CI && stats.compilation.warnings.length) {
|
||||
printErrors('Failed to compile.', stats.compilation.warnings);
|
||||
printErrors('Failed to compile. When process.env.CI = true, warnings are treated as failures. Most CI servers set this automatically.', stats.compilation.warnings);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
@@ -192,15 +193,16 @@ function build(previousSizeMap) {
|
||||
|
||||
var openCommand = process.platform === 'win32' ? 'start' : 'open';
|
||||
var appPackage = require(paths.appPackageJson);
|
||||
var homepagePath = appPackage.homepage;
|
||||
var publicUrl = paths.publicUrl;
|
||||
var publicPath = config.output.publicPath;
|
||||
if (homepagePath && homepagePath.indexOf('.github.io/') !== -1) {
|
||||
var publicPathname = url.parse(publicPath).pathname;
|
||||
if (publicUrl && publicUrl.indexOf('.github.io/') !== -1) {
|
||||
// "homepage": "http://user.github.io/project"
|
||||
console.log('The project was built assuming it is hosted at ' + chalk.green(publicPath) + '.');
|
||||
console.log('The project was built assuming it is hosted at ' + chalk.green(publicPathname) + '.');
|
||||
console.log('You can control this with the ' + chalk.green('homepage') + ' field in your ' + chalk.cyan('package.json') + '.');
|
||||
console.log();
|
||||
console.log('The ' + chalk.cyan('build') + ' folder is ready to be deployed.');
|
||||
console.log('To publish it at ' + chalk.green(homepagePath) + ', run:');
|
||||
console.log('To publish it at ' + chalk.green(publicUrl) + ', run:');
|
||||
// If script deploy has been added to package.json, skip the instructions
|
||||
if (typeof appPackage.scripts.deploy === 'undefined') {
|
||||
console.log();
|
||||
@@ -215,7 +217,8 @@ function build(previousSizeMap) {
|
||||
console.log(' ' + chalk.dim('// ...'));
|
||||
console.log(' ' + chalk.yellow('"scripts"') + ': {');
|
||||
console.log(' ' + chalk.dim('// ...'));
|
||||
console.log(' ' + chalk.yellow('"deploy"') + ': ' + chalk.yellow('"npm run build&&gh-pages -d build"'));
|
||||
console.log(' ' + chalk.yellow('"predeploy"') + ': ' + chalk.yellow('"npm run build",'));
|
||||
console.log(' ' + chalk.yellow('"deploy"') + ': ' + chalk.yellow('"gh-pages -d build"'));
|
||||
console.log(' }');
|
||||
console.log();
|
||||
console.log('Then run:');
|
||||
@@ -231,14 +234,14 @@ function build(previousSizeMap) {
|
||||
console.log('The ' + chalk.cyan('build') + ' folder is ready to be deployed.');
|
||||
console.log();
|
||||
} else {
|
||||
// no homepage or "homepage": "http://mywebsite.com"
|
||||
console.log('The project was built assuming it is hosted at the server root.');
|
||||
if (homepagePath) {
|
||||
if (publicUrl) {
|
||||
// "homepage": "http://mywebsite.com"
|
||||
console.log('The project was built assuming it is hosted at ' + chalk.green(publicUrl) + '.');
|
||||
console.log('You can control this with the ' + chalk.green('homepage') + ' field in your ' + chalk.cyan('package.json') + '.');
|
||||
console.log();
|
||||
} else {
|
||||
// no homepage
|
||||
console.log('The project was built assuming it is hosted at the server root.');
|
||||
console.log('To override this, specify the ' + chalk.green('homepage') + ' in your ' + chalk.cyan('package.json') + '.');
|
||||
console.log('For example, add this to build it for GitHub Pages:')
|
||||
console.log();
|
||||
|
||||
14
packages/react-scripts/scripts/eject.js
vendored
14
packages/react-scripts/scripts/eject.js
vendored
@@ -92,8 +92,14 @@ prompt(
|
||||
|
||||
console.log(cyan('Updating the dependencies'));
|
||||
var ownPackageName = ownPackage.name;
|
||||
console.log(' Removing ' + cyan(ownPackageName) + ' from devDependencies');
|
||||
delete appPackage.devDependencies[ownPackageName];
|
||||
if (appPackage.devDependencies[ownPackageName]) {
|
||||
console.log(' Removing ' + cyan(ownPackageName) + ' from devDependencies');
|
||||
delete appPackage.devDependencies[ownPackageName];
|
||||
}
|
||||
if (appPackage.dependencies[ownPackageName]) {
|
||||
console.log(' Removing ' + cyan(ownPackageName) + ' from dependencies');
|
||||
delete appPackage.dependencies[ownPackageName];
|
||||
}
|
||||
|
||||
Object.keys(ownPackage.dependencies).forEach(function (key) {
|
||||
// For some reason optionalDependencies end up in dependencies after install
|
||||
@@ -129,14 +135,14 @@ prompt(
|
||||
|
||||
fs.writeFileSync(
|
||||
path.join(appPath, 'package.json'),
|
||||
JSON.stringify(appPackage, null, 2)
|
||||
JSON.stringify(appPackage, null, 2) + '\n'
|
||||
);
|
||||
console.log();
|
||||
|
||||
if (fs.existsSync(paths.yarnLockFile)) {
|
||||
console.log(cyan('Running yarn...'));
|
||||
fs.removeSync(ownPath);
|
||||
spawnSync('yarn', [], {stdio: 'inherit'});
|
||||
spawnSync('yarnpkg', [], {stdio: 'inherit'});
|
||||
} else {
|
||||
console.log(cyan('Running npm install...'));
|
||||
fs.removeSync(ownPath);
|
||||
|
||||
22
packages/react-scripts/scripts/init.js
vendored
22
packages/react-scripts/scripts/init.js
vendored
@@ -12,7 +12,7 @@ var path = require('path');
|
||||
var spawn = require('cross-spawn');
|
||||
var chalk = require('chalk');
|
||||
|
||||
module.exports = function(appPath, appName, verbose, originalDirectory) {
|
||||
module.exports = function(appPath, appName, verbose, originalDirectory, template) {
|
||||
var ownPackageName = require(path.join(__dirname, '..', 'package.json')).name;
|
||||
var ownPath = path.join(appPath, 'node_modules', ownPackageName);
|
||||
var appPackage = require(path.join(appPath, 'package.json'));
|
||||
@@ -41,7 +41,13 @@ module.exports = function(appPath, appName, verbose, originalDirectory) {
|
||||
}
|
||||
|
||||
// Copy the files for the user
|
||||
fs.copySync(path.join(ownPath, 'template'), appPath);
|
||||
var templatePath = template ? path.resolve(originalDirectory, template) : path.join(ownPath, 'template');
|
||||
if (fs.existsSync(templatePath)) {
|
||||
fs.copySync(templatePath, appPath);
|
||||
} else {
|
||||
console.error('Could not locate supplied template: ' + chalk.green(templatePath));
|
||||
return;
|
||||
}
|
||||
|
||||
// Rename gitignore after the fact to prevent npm from renaming it to .npmignore
|
||||
// See: https://github.com/npm/npm/issues/1862
|
||||
@@ -64,7 +70,7 @@ module.exports = function(appPath, appName, verbose, originalDirectory) {
|
||||
var args;
|
||||
|
||||
if (useYarn) {
|
||||
command = 'yarn';
|
||||
command = 'yarnpkg';
|
||||
args = ['add'];
|
||||
} else {
|
||||
command = 'npm';
|
||||
@@ -76,6 +82,16 @@ module.exports = function(appPath, appName, verbose, originalDirectory) {
|
||||
}
|
||||
args.push('react', 'react-dom', '@types/node', '@types/react', '@types/react-dom', '@types/jest');
|
||||
|
||||
// Install additional template dependencies, if present
|
||||
var templateDependenciesPath = path.join(appPath, '.template.dependencies.json');
|
||||
if (fs.existsSync(templateDependenciesPath)) {
|
||||
var templateDependencies = require(templateDependenciesPath).dependencies;
|
||||
args = args.concat(Object.keys(templateDependencies).map(function (key) {
|
||||
return key + '@' + templateDependencies[key];
|
||||
}));
|
||||
fs.unlinkSync(templateDependenciesPath);
|
||||
}
|
||||
|
||||
console.log('Installing react and react-dom using ' + command + '...');
|
||||
console.log();
|
||||
|
||||
|
||||
2
packages/react-scripts/scripts/start.js
vendored
2
packages/react-scripts/scripts/start.js
vendored
@@ -243,7 +243,7 @@ function runDevServer(host, port, protocol) {
|
||||
// project directory is dangerous because we may expose sensitive files.
|
||||
// Instead, we establish a convention that only files in `public` directory
|
||||
// get served. Our build script will copy `public` into the `build` folder.
|
||||
// In `index.html`, you can get URL of `public` folder with %PUBLIC_PATH%:
|
||||
// In `index.html`, you can get URL of `public` folder with %PUBLIC_URL%:
|
||||
// <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
|
||||
// In JavaScript code, you can access it with `process.env.PUBLIC_URL`.
|
||||
// Note that we only recommend to use `public` folder as an escape hatch
|
||||
|
||||
12
packages/react-scripts/scripts/test.js
vendored
12
packages/react-scripts/scripts/test.js
vendored
@@ -26,18 +26,6 @@ if (!process.env.CI && argv.indexOf('--coverage') < 0) {
|
||||
argv.push('--watch');
|
||||
}
|
||||
|
||||
// A temporary hack to clear terminal correctly.
|
||||
// You can remove this after updating to Jest 18 when it's out.
|
||||
// https://github.com/facebook/jest/pull/2230
|
||||
var realWrite = process.stdout.write;
|
||||
var CLEAR = process.platform === 'win32' ? '\x1Bc' : '\x1B[2J\x1B[3J\x1B[H';
|
||||
process.stdout.write = function(chunk, encoding, callback) {
|
||||
if (chunk === '\x1B[2J\x1B[H') {
|
||||
chunk = CLEAR;
|
||||
}
|
||||
return realWrite.call(this, chunk, encoding, callback);
|
||||
};
|
||||
|
||||
// @remove-on-eject-begin
|
||||
// This is not necessary after eject because we embed config into package.json.
|
||||
const createJestConfig = require('../utils/createJestConfig');
|
||||
|
||||
@@ -30,7 +30,9 @@ You can find the most recent version of this guide [here](https://github.com/fac
|
||||
- [Adding Flow](#adding-flow)
|
||||
- [Adding Custom Environment Variables](#adding-custom-environment-variables)
|
||||
- [Can I Use Decorators?](#can-i-use-decorators)
|
||||
- [Integrating with a Node Backend](#integrating-with-a-node-backend)
|
||||
- [Integrating with an API Backend](#integrating-with-an-api-backend)
|
||||
- [Node](#node)
|
||||
- [Ruby on Rails](#ruby-on-rails)
|
||||
- [Proxying API Requests in Development](#proxying-api-requests-in-development)
|
||||
- [Using HTTPS in Development](#using-https-in-development)
|
||||
- [Generating Dynamic `<meta>` Tags on the Server](#generating-dynamic-meta-tags-on-the-server)
|
||||
@@ -46,7 +48,7 @@ You can find the most recent version of this guide [here](https://github.com/fac
|
||||
- [Coverage Reporting](#coverage-reporting)
|
||||
- [Continuous Integration](#continuous-integration)
|
||||
- [Disabling jsdom](#disabling-jsdom)
|
||||
- [Experimental Snapshot Testing](#experimental-snapshot-testing)
|
||||
- [Snapshot Testing](#snapshot-testing)
|
||||
- [Editor Integration](#editor-integration)
|
||||
- [Developing Components in Isolation](#developing-components-in-isolation)
|
||||
- [Making a Progressive Web App](#making-a-progressive-web-app)
|
||||
@@ -61,7 +63,9 @@ You can find the most recent version of this guide [here](https://github.com/fac
|
||||
- [Now](#now)
|
||||
- [S3 and CloudFront](#s3-and-cloudfront)
|
||||
- [Surge](#surge)
|
||||
- [Advanced Configuration](#advanced-configuration)
|
||||
- [Troubleshooting](#troubleshooting)
|
||||
- [`npm start` doesn’t detect changes](#npm-start-doesnt-detect-changes)
|
||||
- [`npm test` hangs on macOS Sierra](#npm-test-hangs-on-macos-sierra)
|
||||
- [`npm run build` silently fails](#npm-run-build-silently-fails)
|
||||
- [`npm run build` fails on Heroku](#npm-run-build-fails-on-heroku)
|
||||
@@ -174,13 +178,54 @@ Some editors, including Sublime Text, Atom, and Visual Studio Code, provide plug
|
||||
|
||||
They are not required for linting. You should see the linter output right in your terminal as well as the browser console. However, if you prefer the lint results to appear right in your editor, there are some extra steps you can do.
|
||||
|
||||
<<<<<<< HEAD
|
||||
You would need to install an TSLint plugin for your editor first.
|
||||
=======
|
||||
You would need to install an ESLint plugin for your editor first.
|
||||
|
||||
>**A note for Atom `linter-eslint` users**
|
||||
|
||||
>If you are using the Atom `linter-eslint` plugin, make sure that **Use global ESLint installation** option is checked:
|
||||
|
||||
><img src="http://i.imgur.com/yVNNHJM.png" width="300">
|
||||
|
||||
|
||||
>**For Visual Studio Code users**
|
||||
|
||||
>VS Code ESLint plugin automatically detects Create React App's configuration file. So you do not need to create `eslintrc.json` at the root directory, except when you want to add your own rules. In that case, you should include CRA's config by adding this line:
|
||||
|
||||
>```js
|
||||
{
|
||||
// ...
|
||||
"extends": "react-app"
|
||||
}
|
||||
```
|
||||
|
||||
Then add this block to the `package.json` file of your project:
|
||||
|
||||
```js
|
||||
{
|
||||
// ...
|
||||
"eslintConfig": {
|
||||
"extends": "react-app"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Finally, you will need to install some packages *globally*:
|
||||
|
||||
```sh
|
||||
npm install -g eslint-config-react-app@0.3.0 eslint@3.8.1 babel-eslint@7.0.0 eslint-plugin-react@6.4.1 eslint-plugin-import@2.0.1 eslint-plugin-jsx-a11y@2.2.3 eslint-plugin-flowtype@2.21.0
|
||||
```
|
||||
|
||||
We recognize that this is suboptimal, but it is currently required due to the way we hide the ESLint dependency. The ESLint team is already [working on a solution to this](https://github.com/eslint/eslint/issues/3458) so this may become unnecessary in a couple of months.
|
||||
>>>>>>> 84be4dd0bdf6155c075f9e9bee9f075d8982d0cd
|
||||
|
||||
## Changing the Page `<title>`
|
||||
|
||||
You can find the source HTML file in the `public` folder of the generated project. You may edit the `<title>` tag in it to change the title from “React App” to anything else.
|
||||
|
||||
Note that normally you wouldn't edit files in the `public` folder very often. For example, [adding a stylesheet](#adding-a-stylesheet) is is done without touching the HTML.
|
||||
Note that normally you wouldn't edit files in the `public` folder very often. For example, [adding a stylesheet](#adding-a-stylesheet) is done without touching the HTML.
|
||||
|
||||
If you need to dynamically update the page title based on the content, you can use the browser [`document.title`](https://developer.mozilla.org/en-US/docs/Web/API/Document/title) API. For more complex scenarios when you want to change the title from React components, you can use [React Helmet](https://github.com/nfl/react-helmet), a third party library.
|
||||
|
||||
@@ -360,7 +405,7 @@ The `<script>` tag with the compiled code will be added to it automatically duri
|
||||
|
||||
You can also add other assets to the `public` folder.
|
||||
|
||||
Note that we normally we encourage you to `import` assets in JavaScript files instead.
|
||||
Note that we normally encourage you to `import` assets in JavaScript files instead.
|
||||
For example, see the sections on [adding a stylesheet](#adding-a-stylesheet) and [adding images and fonts](#adding-images-and-fonts).
|
||||
This mechanism provides a number of benefits:
|
||||
|
||||
@@ -475,7 +520,11 @@ To learn more about Flow, check out [its documentation](https://flowtype.org/).
|
||||
|
||||
Your project can consume variables declared in your environment as if they were declared locally in your JS files. By
|
||||
default you will have `NODE_ENV` defined for you, and any other environment variables starting with
|
||||
`REACT_APP_`. These environment variables will be defined for you on `process.env`. For example, having an environment
|
||||
`REACT_APP_`.
|
||||
|
||||
>Note: You must create custom environment variables beginning with `REACT_APP_`. Any other variables except `NODE_ENV` will be ignored to avoid accidentally [exposing a private key on the machine that could have the same name](https://github.com/facebookincubator/create-react-app/issues/865#issuecomment-252199527).
|
||||
|
||||
These environment variables will be defined for you on `process.env`. For example, having an environment
|
||||
variable named `REACT_APP_SECRET_CODE` will be exposed in your JS as `process.env.REACT_APP_SECRET_CODE`, in addition
|
||||
to `process.env.NODE_ENV`.
|
||||
|
||||
@@ -538,7 +587,7 @@ set REACT_APP_SECRET_CODE=abcdef&&npm start
|
||||
|
||||
(Note: the lack of whitespace is intentional.)
|
||||
|
||||
#### Linux, OS X (Bash)
|
||||
#### Linux, macOS (Bash)
|
||||
|
||||
```bash
|
||||
REACT_APP_SECRET_CODE=abcdef npm start
|
||||
@@ -577,9 +626,19 @@ Please refer to these two threads for reference:
|
||||
|
||||
Create React App will add decorator support when the specification advances to a stable stage.
|
||||
|
||||
## Integrating with a Node Backend
|
||||
## Integrating with an API Backend
|
||||
|
||||
Check out [this tutorial](https://www.fullstackreact.com/articles/using-create-react-app-with-a-server/) for instructions on integrating an app with a Node backend running on another port, and using `fetch()` to access it. You can find the companion GitHub repository [here](https://github.com/fullstackreact/food-lookup-demo).
|
||||
These tutorials will help you to integrate your app with an API backend running on another port,
|
||||
using `fetch()` to access it.
|
||||
|
||||
### Node
|
||||
Check out [this tutorial](https://www.fullstackreact.com/articles/using-create-react-app-with-a-server/).
|
||||
You can find the companion GitHub repository [here](https://github.com/fullstackreact/food-lookup-demo).
|
||||
|
||||
### Ruby on Rails
|
||||
|
||||
Check out [this tutorial](https://www.fullstackreact.com/articles/how-to-get-create-react-app-to-work-with-your-rails-api/).
|
||||
You can find the companion GitHub repository [here](https://github.com/fullstackreact/food-lookup-demo-rails).
|
||||
|
||||
## Proxying API Requests in Development
|
||||
|
||||
@@ -612,7 +671,7 @@ Fetch API cannot load http://localhost:4000/api/todos. No 'Access-Control-Allow-
|
||||
|
||||
Keep in mind that `proxy` only has effect in development (with `npm start`), and it is up to you to ensure that URLs like `/api/todos` point to the right thing in production. You don’t have to use the `/api` prefix. Any unrecognized request without a `text/html` accept header will be redirected to the specified `proxy`.
|
||||
|
||||
Currently the `proxy` option only handles HTTP requests, and it won’t proxy WebSocket connections.<br>
|
||||
The `proxy` option supports HTTP, HTTPS and WebSocket connections.<br>
|
||||
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)).
|
||||
@@ -634,7 +693,7 @@ set HTTPS=true&&npm start
|
||||
|
||||
(Note: the lack of whitespace is intentional.)
|
||||
|
||||
#### Linux, OS X (Bash)
|
||||
#### Linux, macOS (Bash)
|
||||
|
||||
```bash
|
||||
HTTPS=true npm start
|
||||
@@ -878,7 +937,7 @@ set CI=true&&npm run build
|
||||
|
||||
(Note: the lack of whitespace is intentional.)
|
||||
|
||||
##### Linux, OS X (Bash)
|
||||
##### Linux, macOS (Bash)
|
||||
|
||||
```bash
|
||||
CI=true npm test
|
||||
@@ -919,13 +978,11 @@ In contrast, **jsdom is not needed** for the following APIs:
|
||||
* [`TestUtils.createRenderer()`](https://facebook.github.io/react/docs/test-utils.html#shallow-rendering) (shallow rendering)
|
||||
* [`shallow()`](http://airbnb.io/enzyme/docs/api/shallow.html) in [Enzyme](http://airbnb.io/enzyme/index.html)
|
||||
|
||||
Finally, jsdom is also not needed for [snapshot testing](http://facebook.github.io/jest/blog/2016/07/27/jest-14.html). Longer term, this is the direction we are interested in exploring, but snapshot testing is [not fully baked yet](https://github.com/facebookincubator/create-react-app/issues/372) so we don’t officially encourage its usage yet.
|
||||
Finally, jsdom is also not needed for [snapshot testing](http://facebook.github.io/jest/blog/2016/07/27/jest-14.html).
|
||||
|
||||
### Experimental Snapshot Testing
|
||||
### Snapshot Testing
|
||||
|
||||
Snapshot testing is a new feature of Jest that automatically generates text snapshots of your components and saves them on the disk so if the UI output changes, you get notified without manually writing any assertions on the component output.
|
||||
|
||||
This feature is experimental and still [has major usage issues](https://github.com/facebookincubator/create-react-app/issues/372) so we only encourage you to use it if you like experimental technology. We intend to gradually improve it over time and eventually offer it as the default solution for testing React components, but this will take time. [Read more about snapshot testing.](http://facebook.github.io/jest/blog/2016/07/27/jest-14.html)
|
||||
Snapshot testing is a feature of Jest that automatically generates text snapshots of your components and saves them on the disk so if the UI output changes, you get notified without manually writing any assertions on the component output. [Read more about snapshot testing.](http://facebook.github.io/jest/blog/2016/07/27/jest-14.html)
|
||||
|
||||
### Editor Integration
|
||||
|
||||
@@ -1034,6 +1091,17 @@ To override this, specify the `homepage` in your `package.json`, for example:
|
||||
|
||||
This will let Create React App correctly infer the root path to use in the generated HTML file.
|
||||
|
||||
#### Serving the Same Build from Different Paths
|
||||
|
||||
>Note: this feature is available with `react-scripts@0.9.0` and higher.
|
||||
|
||||
If you are not using the HTML5 `pushState` history API or not using client-side routing at all, it is unnecessary to specify the URL from which your app will be served. Instead, you can put this in your `package.json`:
|
||||
|
||||
```js
|
||||
"homepage": ".",
|
||||
```
|
||||
|
||||
This will make sure that all the asset paths are relative to `index.html`. You will then be able to move your app from `http://mywebsite.com` to `http://mywebsite.com/relativepath` or even `http://mywebsite.com/relative/path` without having to rebuild it.
|
||||
|
||||
### Firebase
|
||||
|
||||
@@ -1123,17 +1191,18 @@ To publish it at [https://myusername.github.io/my-app](https://myusername.github
|
||||
npm install --save-dev gh-pages
|
||||
```
|
||||
|
||||
Add the following script in your `package.json`:
|
||||
Add the following scripts in your `package.json`:
|
||||
|
||||
```js
|
||||
// ...
|
||||
"scripts": {
|
||||
// ...
|
||||
"deploy": "npm run build&&gh-pages -d build"
|
||||
"predeploy": "npm run build",
|
||||
"deploy": "gh-pages -d build"
|
||||
}
|
||||
```
|
||||
|
||||
(Note: the lack of whitespace is intentional.)
|
||||
The `predeploy` script will run automatically before `deploy` is run.
|
||||
|
||||
#### Step 3: Deploy the site by running `npm run deploy`
|
||||
|
||||
@@ -1241,8 +1310,34 @@ Install the Surge CLI if you haven't already by running `npm install -g surge`.
|
||||
|
||||
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).
|
||||
|
||||
## Advanced Configuration
|
||||
|
||||
You can adjust various development and production settings by setting environment variables in your shell or with [.env](#adding-development-environment-variables-in-env).
|
||||
|
||||
Variable | Development | Production | Usage
|
||||
:--- | :---: | :---: | :---
|
||||
BROWSER | :white_check_mark: | :x: | By default, Create React App will open the default system browser, favoring Chrome on macOS. Specify a [browser](https://github.com/sindresorhus/opn#app) to override this behavior, or set it to `none` to disable it completely.
|
||||
HOST | :white_check_mark: | :x: | By default, the development web server binds to `localhost`. You may use this variable to specify a different host.
|
||||
PORT | :white_check_mark: | :x: | By default, the development web server will attempt to listen on port 3000 or prompt you to attempt the next available port. You may use this variable to specify a different port.
|
||||
HTTPS | :white_check_mark: | :x: | When set to `true`, Create React App will run the development server in `https` mode.
|
||||
PUBLIC_URL | :x: | :white_check_mark: | Create React App assumes your application is hosted at the serving web server's root or a subpath as specified in [`package.json` (`homepage`)](#building-for-relative-paths). Normally, Create React App ignores the hostname. You may use this variable to force assets to be referenced verbatim to the url you provide (hostname included). This may be particularly useful when using a CDN to host your application.
|
||||
CI | :large_orange_diamond: | :white_check_mark: | When set to `true`, Create React App treats warnings as failures in the build. It also makes the test runner non-watching. Most CIs set this flag by default.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### `npm start` doesn’t detect changes
|
||||
|
||||
When you save a file while `npm start` is running, the browser should refresh with the updated code.<br>
|
||||
If this doesn’t happen, try one of the following workarounds:
|
||||
|
||||
* If your project is in a Dropbox folder, try moving it out.
|
||||
* If the watcher doesn’t see a file called `index.js` and you’re referencing it by the folder name, you [need to restart the watcher](https://github.com/facebookincubator/create-react-app/issues/1164) due to a Webpack bug.
|
||||
* Some editors like Vim and IntelliJ have a “safe write” feature that currently breaks the watcher. You will need to disable it. Follow the instructions in [“Working with editors supporting safe write”](https://webpack.github.io/docs/webpack-dev-server.html#working-with-editors-ides-supporting-safe-write).
|
||||
* If your project path contains parentheses, try moving the project to a path without them. This is caused by a [Webpack watcher bug](https://github.com/webpack/watchpack/issues/42).
|
||||
* On Linux and macOS, you might need to [tweak system settings](https://webpack.github.io/docs/troubleshooting.html#not-enough-watchers) to allow more watchers.
|
||||
|
||||
If none of these solutions help please leave a comment [in this thread](https://github.com/facebookincubator/create-react-app/issues/659).
|
||||
|
||||
### `npm test` hangs on macOS Sierra
|
||||
|
||||
If you run `npm test` and the console gets stuck after printing `react-scripts test --env=jsdom` to the console there might be a problem with your [Watchman](https://facebook.github.io/watchman/) installation as described in [facebookincubator/create-react-app#713](https://github.com/facebookincubator/create-react-app/issues/713).
|
||||
|
||||
@@ -12,4 +12,7 @@
|
||||
# misc
|
||||
.DS_Store
|
||||
.env
|
||||
npm-debug.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ module.exports = (resolve, rootDir, isEjecting) => {
|
||||
setupFiles: [resolve('config/polyfills.js')],
|
||||
setupTestFrameworkScriptFile: setupTestsFile,
|
||||
testPathIgnorePatterns: [
|
||||
'<rootDir>[/\\\\](build|docs|node_modules)[/\\\\]'
|
||||
'<rootDir>[/\\\\](build|docs|node_modules|scripts)[/\\\\]'
|
||||
],
|
||||
testEnvironment: 'node',
|
||||
testURL: 'http://localhost',
|
||||
|
||||
142
tasks/e2e-installs.sh
Executable file
142
tasks/e2e-installs.sh
Executable file
@@ -0,0 +1,142 @@
|
||||
#!/bin/bash
|
||||
# Copyright (c) 2015-present, Facebook, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# This source code is licensed under the BSD-style license found in the
|
||||
# LICENSE file in the root directory of this source tree. An additional grant
|
||||
# of patent rights can be found in the PATENTS file in the same directory.
|
||||
|
||||
# ******************************************************************************
|
||||
# This is an end-to-end test intended to run on CI.
|
||||
# You can also run it locally but it's slow.
|
||||
# ******************************************************************************
|
||||
|
||||
# Start in tasks/ even if run from root directory
|
||||
cd "$(dirname "$0")"
|
||||
|
||||
# CLI and app temporary locations
|
||||
# http://unix.stackexchange.com/a/84980
|
||||
temp_cli_path=`mktemp -d 2>/dev/null || mktemp -d -t 'temp_cli_path'`
|
||||
temp_app_path=`mktemp -d 2>/dev/null || mktemp -d -t 'temp_app_path'`
|
||||
|
||||
function cleanup {
|
||||
echo 'Cleaning up.'
|
||||
cd $root_path
|
||||
rm -rf $temp_cli_path $temp_app_path
|
||||
}
|
||||
|
||||
# Error messages are redirected to stderr
|
||||
function handle_error {
|
||||
echo "$(basename $0): ERROR! An error was encountered executing line $1." 1>&2;
|
||||
cleanup
|
||||
echo 'Exiting with error.' 1>&2;
|
||||
exit 1
|
||||
}
|
||||
|
||||
function handle_exit {
|
||||
cleanup
|
||||
echo 'Exiting without error.' 1>&2;
|
||||
exit
|
||||
}
|
||||
|
||||
function create_react_app {
|
||||
node "$temp_cli_path"/node_modules/create-react-app/index.js $*
|
||||
}
|
||||
|
||||
# Exit the script with a helpful error message when any error is encountered
|
||||
trap 'set +x; handle_error $LINENO $BASH_COMMAND' ERR
|
||||
|
||||
# Cleanup before exit on any termination signal
|
||||
trap 'set +x; handle_exit' SIGQUIT SIGTERM SIGINT SIGKILL SIGHUP
|
||||
|
||||
# Echo every command being executed
|
||||
set -x
|
||||
|
||||
# Go to root
|
||||
cd ..
|
||||
root_path=$PWD
|
||||
|
||||
npm install
|
||||
|
||||
if [ "$USE_YARN" = "yes" ]
|
||||
then
|
||||
# Install Yarn so that the test can use it to install packages.
|
||||
npm install -g yarn@0.17.10 # TODO: remove version when https://github.com/yarnpkg/yarn/issues/2142 is fixed.
|
||||
yarn cache clean
|
||||
fi
|
||||
|
||||
# ******************************************************************************
|
||||
# First, pack and install create-react-app.
|
||||
# ******************************************************************************
|
||||
|
||||
# Pack CLI
|
||||
cd $root_path/packages/create-react-app
|
||||
cli_path=$PWD/`npm pack`
|
||||
|
||||
# Install the CLI in a temporary location
|
||||
cd $temp_cli_path
|
||||
npm install $cli_path
|
||||
|
||||
# ******************************************************************************
|
||||
# Test --scripts-version with a version number
|
||||
# ******************************************************************************
|
||||
|
||||
cd $temp_app_path
|
||||
create_react_app --scripts-version=0.4.0 test-app-version-number
|
||||
cd test-app-version-number
|
||||
|
||||
# Check corresponding scripts version is installed.
|
||||
test -e node_modules/react-scripts
|
||||
grep '"version": "0.4.0"' node_modules/react-scripts/package.json
|
||||
|
||||
# ******************************************************************************
|
||||
# Test --scripts-version with a tarball url
|
||||
# ******************************************************************************
|
||||
|
||||
cd $temp_app_path
|
||||
create_react_app --scripts-version=https://registry.npmjs.org/react-scripts/-/react-scripts-0.4.0.tgz test-app-tarball-url
|
||||
cd test-app-tarball-url
|
||||
|
||||
# Check corresponding scripts version is installed.
|
||||
test -e node_modules/react-scripts
|
||||
grep '"version": "0.4.0"' node_modules/react-scripts/package.json
|
||||
|
||||
# ******************************************************************************
|
||||
# Test --scripts-version with a custom fork of react-scripts
|
||||
# ******************************************************************************
|
||||
|
||||
cd $temp_app_path
|
||||
create_react_app --scripts-version=react-scripts-fork test-app-fork
|
||||
cd test-app-fork
|
||||
|
||||
# Check corresponding scripts version is installed.
|
||||
test -e node_modules/react-scripts-fork
|
||||
|
||||
# ******************************************************************************
|
||||
# Test nested folder path as the project name
|
||||
# ******************************************************************************
|
||||
|
||||
#Testing a path that exists
|
||||
cd $temp_app_path
|
||||
mkdir test-app-nested-paths-t1
|
||||
cd test-app-nested-paths-t1
|
||||
mkdir -p test-app-nested-paths-t1/aa/bb/cc/dd
|
||||
create_react_app test-app-nested-paths-t1/aa/bb/cc/dd
|
||||
cd test-app-nested-paths-t1/aa/bb/cc/dd
|
||||
npm start -- --smoke-test
|
||||
|
||||
#Testing a path that does not exist
|
||||
cd $temp_app_path
|
||||
create_react_app test-app-nested-paths-t2/aa/bb/cc/dd
|
||||
cd test-app-nested-paths-t2/aa/bb/cc/dd
|
||||
npm start -- --smoke-test
|
||||
|
||||
#Testing a path that is half exists
|
||||
cd $temp_app_path
|
||||
mkdir -p test-app-nested-paths-t3/aa
|
||||
create_react_app test-app-nested-paths-t3/aa/bb/cc/dd
|
||||
cd test-app-nested-paths-t3/aa/bb/cc/dd
|
||||
npm start -- --smoke-test
|
||||
|
||||
# Cleanup
|
||||
cleanup
|
||||
212
tasks/e2e-kitchensink.sh
Executable file
212
tasks/e2e-kitchensink.sh
Executable file
@@ -0,0 +1,212 @@
|
||||
#!/bin/bash
|
||||
# Copyright (c) 2015-present, Facebook, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# This source code is licensed under the BSD-style license found in the
|
||||
# LICENSE file in the root directory of this source tree. An additional grant
|
||||
# of patent rights can be found in the PATENTS file in the same directory.
|
||||
|
||||
# ******************************************************************************
|
||||
# This is an end-to-end kitchensink test intended to run on CI.
|
||||
# You can also run it locally but it's slow.
|
||||
# ******************************************************************************
|
||||
|
||||
# Start in tasks/ even if run from root directory
|
||||
cd "$(dirname "$0")"
|
||||
|
||||
# CLI and app temporary locations
|
||||
# http://unix.stackexchange.com/a/84980
|
||||
temp_cli_path=`mktemp -d 2>/dev/null || mktemp -d -t 'temp_cli_path'`
|
||||
temp_app_path=`mktemp -d 2>/dev/null || mktemp -d -t 'temp_app_path'`
|
||||
|
||||
function cleanup {
|
||||
echo 'Cleaning up.'
|
||||
cd $root_path
|
||||
rm -rf $temp_cli_path $temp_app_path
|
||||
}
|
||||
|
||||
# Error messages are redirected to stderr
|
||||
function handle_error {
|
||||
echo "$(basename $0): ERROR! An error was encountered executing line $1." 1>&2;
|
||||
cleanup
|
||||
echo 'Exiting with error.' 1>&2;
|
||||
exit 1
|
||||
}
|
||||
|
||||
function handle_exit {
|
||||
cleanup
|
||||
echo 'Exiting without error.' 1>&2;
|
||||
exit
|
||||
}
|
||||
|
||||
function create_react_app {
|
||||
node "$temp_cli_path"/node_modules/create-react-app/index.js $*
|
||||
}
|
||||
|
||||
# Exit the script with a helpful error message when any error is encountered
|
||||
trap 'set +x; handle_error $LINENO $BASH_COMMAND' ERR
|
||||
|
||||
# Cleanup before exit on any termination signal
|
||||
trap 'set +x; handle_exit' SIGQUIT SIGTERM SIGINT SIGKILL SIGHUP
|
||||
|
||||
# Echo every command being executed
|
||||
set -x
|
||||
|
||||
# Go to root
|
||||
cd ..
|
||||
root_path=$PWD
|
||||
|
||||
npm install
|
||||
|
||||
if [ "$USE_YARN" = "yes" ]
|
||||
then
|
||||
# Install Yarn so that the test can use it to install packages.
|
||||
npm install -g yarn@0.17.10 # TODO: remove version when https://github.com/yarnpkg/yarn/issues/2142 is fixed.
|
||||
yarn cache clean
|
||||
fi
|
||||
|
||||
# ******************************************************************************
|
||||
# First, pack react-scripts and create-react-app so we can use them.
|
||||
# ******************************************************************************
|
||||
|
||||
# Pack CLI
|
||||
cd $root_path/packages/create-react-app
|
||||
cli_path=$PWD/`npm pack`
|
||||
|
||||
# Go to react-scripts
|
||||
cd $root_path/packages/react-scripts
|
||||
|
||||
# Save package.json because we're going to touch it
|
||||
cp package.json package.json.orig
|
||||
|
||||
# Replace own dependencies (those in the `packages` dir) with the local paths
|
||||
# of those packages.
|
||||
node $root_path/tasks/replace-own-deps.js
|
||||
|
||||
# Finally, pack react-scripts
|
||||
scripts_path=$root_path/packages/react-scripts/`npm pack`
|
||||
|
||||
# Restore package.json
|
||||
rm package.json
|
||||
mv package.json.orig package.json
|
||||
|
||||
# ******************************************************************************
|
||||
# Now that we have packed them, create a clean app folder and install them.
|
||||
# ******************************************************************************
|
||||
|
||||
# Install the CLI in a temporary location
|
||||
cd $temp_cli_path
|
||||
npm install $cli_path
|
||||
|
||||
# Install the app in a temporary location
|
||||
cd $temp_app_path
|
||||
create_react_app --scripts-version=$scripts_path --internal-testing-template=$root_path/packages/react-scripts/fixtures/kitchensink test-kitchensink
|
||||
|
||||
# ******************************************************************************
|
||||
# Now that we used create-react-app to create an app depending on react-scripts,
|
||||
# let's make sure all npm scripts are in the working state.
|
||||
# ******************************************************************************
|
||||
|
||||
# Enter the app directory
|
||||
cd test-kitchensink
|
||||
|
||||
# Link to our preset
|
||||
npm link $root_path/packages/babel-preset-react-app
|
||||
|
||||
# Test the build
|
||||
REACT_APP_SHELL_ENV_MESSAGE=fromtheshell \
|
||||
NODE_PATH=src \
|
||||
PUBLIC_URL=http://www.example.org/spa/ \
|
||||
npm run build
|
||||
|
||||
# Check for expected output
|
||||
test -e build/*.html
|
||||
test -e build/static/js/main.*.js
|
||||
|
||||
# Unit tests
|
||||
REACT_APP_SHELL_ENV_MESSAGE=fromtheshell \
|
||||
CI=true \
|
||||
NODE_PATH=src \
|
||||
NODE_ENV=test \
|
||||
npm test -- --no-cache --testPathPattern="/src/"
|
||||
|
||||
# Test "development" environment
|
||||
tmp_server_log=`mktemp`
|
||||
PORT=3001 \
|
||||
REACT_APP_SHELL_ENV_MESSAGE=fromtheshell \
|
||||
NODE_PATH=src \
|
||||
nohup npm start &>$tmp_server_log &
|
||||
grep -q 'The app is running at:' <(tail -f $tmp_server_log)
|
||||
E2E_URL="http://localhost:3001" \
|
||||
REACT_APP_SHELL_ENV_MESSAGE=fromtheshell \
|
||||
CI=true NODE_PATH=src \
|
||||
NODE_ENV=development \
|
||||
node node_modules/.bin/mocha --require babel-register --require babel-polyfill integration/*.test.js
|
||||
|
||||
# Test "production" environment
|
||||
E2E_FILE=./build/index.html \
|
||||
CI=true \
|
||||
NODE_PATH=src \
|
||||
NODE_ENV=production \
|
||||
PUBLIC_URL=http://www.example.org/spa/ \
|
||||
node_modules/.bin/mocha --require babel-register --require babel-polyfill integration/*.test.js
|
||||
|
||||
# ******************************************************************************
|
||||
# Finally, let's check that everything still works after ejecting.
|
||||
# ******************************************************************************
|
||||
|
||||
# Unlink our preset
|
||||
npm unlink $root_path/packages/babel-preset-react-app
|
||||
|
||||
# Eject...
|
||||
echo yes | npm run eject
|
||||
|
||||
# ...but still link to the local packages
|
||||
npm link $root_path/packages/babel-preset-react-app
|
||||
npm link $root_path/packages/eslint-config-react-app
|
||||
npm link $root_path/packages/react-dev-utils
|
||||
npm link $root_path/packages/react-scripts
|
||||
|
||||
# ...and we need to remove template's .babelrc
|
||||
rm .babelrc
|
||||
|
||||
# Test the build
|
||||
REACT_APP_SHELL_ENV_MESSAGE=fromtheshell \
|
||||
NODE_PATH=src \
|
||||
PUBLIC_URL=http://www.example.org/spa/ \
|
||||
npm run build
|
||||
|
||||
# Check for expected output
|
||||
test -e build/*.html
|
||||
test -e build/static/js/main.*.js
|
||||
|
||||
# Unit tests
|
||||
REACT_APP_SHELL_ENV_MESSAGE=fromtheshell \
|
||||
CI=true \
|
||||
NODE_PATH=src \
|
||||
NODE_ENV=test \
|
||||
npm test -- --no-cache --testPathPattern="/src/"
|
||||
|
||||
# Test "development" environment
|
||||
tmp_server_log=`mktemp`
|
||||
PORT=3002 \
|
||||
REACT_APP_SHELL_ENV_MESSAGE=fromtheshell \
|
||||
NODE_PATH=src \
|
||||
nohup npm start &>$tmp_server_log &
|
||||
grep -q 'The app is running at:' <(tail -f $tmp_server_log)
|
||||
E2E_URL="http://localhost:3002" \
|
||||
REACT_APP_SHELL_ENV_MESSAGE=fromtheshell \
|
||||
CI=true NODE_PATH=src \
|
||||
NODE_ENV=development \
|
||||
node_modules/.bin/mocha --require babel-register --require babel-polyfill integration/*.test.js
|
||||
|
||||
# Test "production" environment
|
||||
E2E_FILE=./build/index.html \
|
||||
CI=true \
|
||||
NODE_ENV=production \
|
||||
NODE_PATH=src \
|
||||
PUBLIC_URL=http://www.example.org/spa/ \
|
||||
node_modules/.bin/mocha --require babel-register --require babel-polyfill integration/*.test.js
|
||||
|
||||
# Cleanup
|
||||
cleanup
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user