diff --git a/.travis.yml b/.travis.yml index 0ca362c23c3..860000b5c9b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,13 +1,9 @@ --- -# Use Ubuntu Precise instead of new default Trusty which cause build fail -# with pre installed yarn v0.17.8 -# https://github.com/facebookincubator/create-react-app/issues/3054 -# TODO: remove after Trusty environment is updated with a lastet version of yarn -dist: precise +dist: trusty language: node_js node_js: - - 6 - 8 + - 9 cache: directories: - node_modules @@ -18,9 +14,8 @@ 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' + - 'if [ $TEST_SUITE = "old-node" ]; then tasks/e2e-old-node.sh; fi' env: - global: - - USE_YARN=no matrix: - TEST_SUITE=simple - TEST_SUITE=installs @@ -28,8 +23,6 @@ env: matrix: include: - node_js: 0.10 - env: TEST_SUITE=simple -# There's a weird Yarn/Lerna bug related to prerelease versions. -# TODO: reenable after we ship 1.0. -# - node_js: 6 -# env: USE_YARN=yes TEST_SUITE=simple + env: TEST_SUITE=old-node + - node_js: 6 + env: TEST_SUITE=kitchensink diff --git a/.yarnrc b/.yarnrc new file mode 100644 index 00000000000..07e44a9a5b2 --- /dev/null +++ b/.yarnrc @@ -0,0 +1,3 @@ +--install.no-lockfile true +--install.check-files true +--add.no-lockfile true diff --git a/CHANGELOG.md b/CHANGELOG.md index 21f50c8e5f6..d5431b5bd3e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,522 @@ +## 1.1.5 (August 24, 2018) + +* `react-scripts` + + * Update the `webpack-dev-server` dependency + +* `react-dev-utils` + + * [#4866](https://github.com/facebook/create-react-app/pull/4866) Fix a Windows-only vulnerability (`CVE-2018-6342`) in the development server ([@acdlite](https://github.com/acdlite)) + * Update the `sockjs-client` dependency + +#### Committers: 1 +- Andrew Clark ([acdlite](https://github.com/acdlite)) + +### Migrating from 1.1.4 to 1.1.5 + +Inside any created project that has not been ejected, run: + +``` +npm install --save --save-exact react-scripts@1.1.5 +``` + +or + +``` +yarn add --exact react-scripts@1.1.5 +``` + +## 1.1.4 (April 3, 2018) + +#### :bug: Bug Fix + +* `react-dev-utils` + + * [#4250](https://github.com/facebook/create-react-app/pull/4250) Upgrade `detect-port-alt` to fix [#4189](https://github.com/facebook/create-react-app/issues/4189). ([@Timer](https://github.com/Timer)) + +#### Committers: 1 +- Joe Haddad ([Timer](https://github.com/Timer)) + +### Migrating from 1.1.3 to 1.1.4 + +Inside any created project that has not been ejected, run: + +``` +npm install --save --save-exact react-scripts@1.1.4 +``` + +or + +``` +yarn add --exact react-scripts@1.1.4 +``` + +## 1.1.3 (April 3, 2018) + +#### :bug: Bug Fix + +* `react-scripts` + + * [#4247](https://github.com/facebook/create-react-app/pull/4247) Fix `environment.dispose is not a function` error caused by a Jest bug. ([@gaearon](https://github.com/gaearon)) + +#### Committers: 1 +- Dan Abramov ([gaearon](https://github.com/gaearon)) + +### Migrating from 1.1.2 to 1.1.3 + +Inside any created project that has not been ejected, run: + +``` +npm install --save --save-exact react-scripts@1.1.3 +``` + +or + +``` +yarn add --exact react-scripts@1.1.3 +``` + +## 1.1.2 (April 3, 2018) + +#### :bug: Bug Fix + +* `react-scripts` + + * [#4085](https://github.com/facebook/create-react-app/pull/4085) Resolve `.js` before `.mjs` files to unbreak dependencies with native ESM support. ([@leebyron](https://github.com/leebyron)) + +#### :memo: Documentation + +* `react-scripts` + + * [#4197](https://github.com/facebook/create-react-app/pull/4197) Add troubleshooting for Github Pages. ([@xnt](https://github.com/xnt)) + +#### Committers: 2 +- Lee Byron ([leebyron](https://github.com/leebyron)) +- Vicente Plata ([xnt](https://github.com/xnt)) + +### Migrating from 1.1.1 to 1.1.2 + +Inside any created project that has not been ejected, run: + +``` +npm install --save --save-exact react-scripts@1.1.2 +``` + +or + +``` +yarn add --exact react-scripts@1.1.2 +``` + +## 1.1.1 (February 2, 2018) + +#### :bug: Bug Fix +* `react-scripts` + * [#4000](https://github.com/facebook/create-react-app/pull/4000) Fix escaping `$` in environment variables. ([@iansu](https://github.com/iansu)) + +#### :nail_care: Enhancement +* `react-scripts` + * [#4006](https://github.com/facebook/create-react-app/pull/4006) Add Node 9 compatibility for `fsevents`. ([@gaearon](https://github.com/gaearon)) + +#### :memo: Documentation +* `react-scripts` + * [#3971](https://github.com/facebook/create-react-app/pull/3971) Update instructions for continuous delivery with Netlify. ([@hubgit](https://github.com/hubgit)) + * [#3894](https://github.com/facebook/create-react-app/pull/3894) Include `{json,css}` files in prettier command. ([@reyronald](https://github.com/reyronald)) + +#### :house: Internal +* `create-react-app` + * [#3853](https://github.com/facebook/create-react-app/pull/3853) pin envinfo version to 3.4.2. ([@bondz](https://github.com/bondz)) + +#### Committers: 6 +- Alf Eaton ([hubgit](https://github.com/hubgit)) +- Bond ([bondz](https://github.com/bondz)) +- Dan Abramov ([gaearon](https://github.com/gaearon)) +- Ian Sutherland ([iansu](https://github.com/iansu)) +- Ronald Rey ([reyronald](https://github.com/reyronald)) + +### Migrating from 1.1.0 to 1.1.1 + +Inside any created project that has not been ejected, run: + +``` +npm install --save --save-exact react-scripts@1.1.1 +``` + +or + +``` +yarn add --exact react-scripts@1.1.1 +``` + +## 1.1.0 (January 15, 2018) + +#### :rocket: New Feature + +* `react-scripts` + + * [#3387](https://github.com/facebookincubator/create-react-app/pull/3387) Add support for variable expansion in `.env` files. ([@moos](https://github.com/moos)) + +* `react-error-overlay` + + * [#3474](https://github.com/facebookincubator/create-react-app/pull/3474) Allow the error overlay to be unregistered. ([@Timer](https://github.com/Timer)) + +* `create-react-app` + + * [#3408](https://github.com/facebookincubator/create-react-app/pull/3408) Add `--info` flag to help gather bug reports. ([@tabrindle](https://github.com/tabrindle)) + * [#3409](https://github.com/facebookincubator/create-react-app/pull/3409) Add `--use-npm` flag to bypass Yarn even on systems that have it. ([@tabrindle](https://github.com/tabrindle)) + * [#3725](https://github.com/facebookincubator/create-react-app/pull/3725) Extend `--scripts-version` to include `.tar.gz` format. ([@SaschaDens](https://github.com/SaschaDens)) + * [#3629](https://github.com/facebookincubator/create-react-app/pull/3629) Allowing `"file:"` `--scripts-version` values. ([@GreenGremlin](https://github.com/GreenGremlin)) + + +#### :bug: Bug Fix + +* `babel-preset-react-app`, `react-scripts` + + * [#3788](https://github.com/facebookincubator/create-react-app/pull/3788) Fix object destructuring inside an array on Node 6. ([@gaearon](https://github.com/gaearon)) + +* `react-dev-utils` + + * [#3784](https://github.com/facebookincubator/create-react-app/pull/3784) Detach browser process from the shell on Linux. ([@gaearon](https://github.com/gaearon)) + * [#3726](https://github.com/facebookincubator/create-react-app/pull/3726) Use proxy for all request methods other than `GET`. ([@doshisid](https://github.com/doshisid)) + * [#3440](https://github.com/facebookincubator/create-react-app/pull/3440) Print full directory name from `lsof`. ([@rmccue](https://github.com/rmccue)) + * [#2071](https://github.com/facebookincubator/create-react-app/pull/2071) Fix broken console clearing on Windows. ([@danielverejan](https://github.com/danielverejan)) + * [#3686](https://github.com/facebookincubator/create-react-app/pull/3686) Fix starting a project in directory with `++` in the name. ([@Norris1z](https://github.com/Norris1z)) + +* `create-react-app` + + * [#3320](https://github.com/facebookincubator/create-react-app/pull/3320) Fix offline installation to respect proxy from `.npmrc`. ([@mdogadailo](https://github.com/mdogadailo)) + +* `react-scripts` + + * [#3537](https://github.com/facebookincubator/create-react-app/pull/3537) Add `mjs` and `jsx` filename extensions to `file-loader` exclude pattern. ([@iansu](https://github.com/iansu)) + * [#3511](https://github.com/facebookincubator/create-react-app/pull/3511) Unmount the component in the default generated test. ([@gaearon](https://github.com/gaearon)) + +#### :nail_care: Enhancement + +* `react-scripts` + + * [#3730](https://github.com/facebookincubator/create-react-app/pull/3730) Print when `HOST` environment variable is set. ([@iansu](https://github.com/iansu)) + * [#3455](https://github.com/facebookincubator/create-react-app/pull/3455) Add a localhost-only log message pointing folks to the PWA docs. ([@jeffposnick](https://github.com/jeffposnick)) + * [#3416](https://github.com/facebookincubator/create-react-app/pull/3416) Improve eject message. ([@xjlim](https://github.com/xjlim)) + +* `create-react-app` + + * [#3740](https://github.com/facebookincubator/create-react-app/pull/3740) Allow more non-conflicting files in initial project directory. ([@GreenGremlin](https://github.com/GreenGremlin)) + +* `react-dev-utils` + + * [#3104](https://github.com/facebookincubator/create-react-app/pull/3104) Add link to deployment docs after build. ([@viankakrisna](https://github.com/viankakrisna)) + * [#3652](https://github.com/facebookincubator/create-react-app/pull/3652) Add `code-insiders` to the editor list. ([@shrynx](https://github.com/shrynx)) + * [#3700](https://github.com/facebookincubator/create-react-app/pull/3700) Add editor support for Sublime Dev & VSCode Insiders. ([@yyx990803](https://github.com/yyx990803)) + * [#3545](https://github.com/facebookincubator/create-react-app/pull/3545) Autodetect MacVim editor. ([@gnapse](https://github.com/gnapse)) + +* `react-dev-utils`, `react-error-overlay` + + * [#3465](https://github.com/facebookincubator/create-react-app/pull/3465) Open editor to exact column from build error overlay. ([@tharakawj](https://github.com/tharakawj)) + +* `react-dev-utils`, `react-scripts` + + * [#3721](https://github.com/facebookincubator/create-react-app/pull/3721) Support setting `none` in `REACT_EDITOR` environment variable. ([@raerpo](https://github.com/raerpo)) + +* `eslint-config-react-app` + + * [#3716](https://github.com/facebookincubator/create-react-app/pull/3716) Relax `no-cond-assign` rule. ([@gaearon](https://github.com/gaearon)) + +#### :memo: Documentation + +* User Guide + + * [#3659](https://github.com/facebookincubator/create-react-app/pull/3659) Add info about service-worker and HTTP caching headers into Firebase section. ([@bobrosoft](https://github.com/bobrosoft)) + * [#3515](https://github.com/facebookincubator/create-react-app/pull/3515) Add Powershell commands to README.md. ([@Gua-naiko-che](https://github.com/Gua-naiko-che)) + * [#3656](https://github.com/facebookincubator/create-react-app/pull/3656) Better documentation for setupTests.js when ejecting. ([@dannycalleri](https://github.com/dannycalleri)) + * [#1791](https://github.com/facebookincubator/create-react-app/pull/1791) Add link for automatic deployment to azure. ([@ulrikstrid](https://github.com/ulrikstrid)) + * [#3717](https://github.com/facebookincubator/create-react-app/pull/3717) Update README.md. ([@maecapozzi](https://github.com/maecapozzi)) + * [#3710](https://github.com/facebookincubator/create-react-app/pull/3710) Link to an explanation for forking react-scripts. ([@gaearon](https://github.com/gaearon)) + * [#3709](https://github.com/facebookincubator/create-react-app/pull/3709) Document adding a router. ([@gaearon](https://github.com/gaearon)) + * [#3670](https://github.com/facebookincubator/create-react-app/pull/3670) Fix typo in the User Guide. ([@qbahers](https://github.com/qbahers)) + * [#3645](https://github.com/facebookincubator/create-react-app/pull/3645) Update README.md. ([@elie222](https://github.com/elie222)) + * [#3533](https://github.com/facebookincubator/create-react-app/pull/3533) Use safer/more aesthetic syntax for setting environment variables on Windows. ([@cdanielsen](https://github.com/cdanielsen)) + * [#3605](https://github.com/facebookincubator/create-react-app/pull/3605) Updated Debugging Tests for VSCode. ([@amadeogallardo](https://github.com/amadeogallardo)) + * [#3601](https://github.com/facebookincubator/create-react-app/pull/3601) Fixed typo in webpack.config.dev.js. ([@nmenglund](https://github.com/nmenglund)) + * [#3576](https://github.com/facebookincubator/create-react-app/pull/3576) Updates comment to reflect codebase. ([@rahulcs](https://github.com/rahulcs)) + * [#3510](https://github.com/facebookincubator/create-react-app/pull/3510) Update User Guide with deploying to GitHub User pages. ([@aaronlna](https://github.com/aaronlna)) + * [#3503](https://github.com/facebookincubator/create-react-app/pull/3503) Update Prettier editor integration link. ([@gaving](https://github.com/gaving)) + * [#3453](https://github.com/facebookincubator/create-react-app/pull/3453) Fix dead links. ([@vannio](https://github.com/vannio)) + * [#2992](https://github.com/facebookincubator/create-react-app/pull/2992) Docs: How to Debug Unit Tests. ([@MattMorgis](https://github.com/MattMorgis)) + +* Other + + * [#3729](https://github.com/facebookincubator/create-react-app/pull/3729) Update README.md to note Neutrino's support of react components. ([@eliperelman](https://github.com/eliperelman)) + * [#2841](https://github.com/facebookincubator/create-react-app/pull/2841) Documentation to help windows contributors. ([@Dubes](https://github.com/Dubes)) + * [#3489](https://github.com/facebookincubator/create-react-app/pull/3489) Add link to nvm-windows. ([@davidgilbertson](https://github.com/davidgilbertson)) + +* `eslint-config-react-app` + + * [#3460](https://github.com/facebookincubator/create-react-app/pull/3460) Fix broken link to `href-no-hash` eslint rule. ([@hazolsky](https://github.com/hazolsky)) + +#### :house: Internal + +* Other + + * [#3769](https://github.com/facebookincubator/create-react-app/pull/3769) Enable Yarn check files. ([@Timer](https://github.com/Timer)) + * [#3756](https://github.com/facebookincubator/create-react-app/pull/3756) Clean up changes to npm and yarn registry in E2E tests. ([@viankakrisna](https://github.com/viankakrisna)) + * [#3744](https://github.com/facebookincubator/create-react-app/pull/3744) Use private registry in E2E tests. ([@Timer](https://github.com/Timer)) + * [#3738](https://github.com/facebookincubator/create-react-app/pull/3738) Always use Yarn on CI. ([@gaearon](https://github.com/gaearon)) + * [#2309](https://github.com/facebookincubator/create-react-app/pull/2309) Port `cra.sh` development task to javascript. ([@ianschmitz](https://github.com/ianschmitz)) + * [#3411](https://github.com/facebookincubator/create-react-app/pull/3411) Simplify waiting for app start in E2E tests. ([@xjlim](https://github.com/xjlim)) + * [#3755](https://github.com/facebookincubator/create-react-app/pull/3755) Switch to Yarn Workspaces. ([@gaearon](https://github.com/gaearon)) + * [#3757](https://github.com/facebookincubator/create-react-app/pull/3757) Try updating Flow. ([@gaearon](https://github.com/gaearon)) + * [#3414](https://github.com/facebookincubator/create-react-app/pull/3414) Export `dismissRuntimeErrors` function. ([@skidding](https://github.com/skidding)) + * [#3036](https://github.com/facebookincubator/create-react-app/pull/3036) Cleaning up `printHostingInstructions` a bit. ([@GreenGremlin](https://github.com/GreenGremlin)) + * [#3514](https://github.com/facebookincubator/create-react-app/pull/3514) Fix `FileSizeReporter` for multi build Webpack setups. ([@iiska](https://github.com/iiska)) + * [#3362](https://github.com/facebookincubator/create-react-app/pull/3362) Refactor extra watch options regex to `react-dev-utils`. ([@xjlim](https://github.com/xjlim)) + +#### Committers: 47 + +- Aaron Lamb ([aaronlna](https://github.com/aaronlna)) +- Ade Viankakrisna Fadlil ([viankakrisna](https://github.com/viankakrisna)) +- Amadeo Gallardo ([amadeogallardo](https://github.com/amadeogallardo)) +- Andy Kenward ([andykenward](https://github.com/andykenward)) +- Christian Danielsen ([cdanielsen](https://github.com/cdanielsen)) +- Clayton Ray ([iamclaytonray](https://github.com/iamclaytonray)) +- Dan Abramov ([gaearon](https://github.com/gaearon)) +- Daniel Verejan ([danielverejan](https://github.com/danielverejan)) +- Danny Calleri ([dannycalleri](https://github.com/dannycalleri)) +- David Boyne ([boyney123](https://github.com/boyney123)) +- David Gilbertson ([davidgilbertson](https://github.com/davidgilbertson)) +- Eli Perelman ([eliperelman](https://github.com/eliperelman)) +- Elie ([elie222](https://github.com/elie222)) +- Ernesto García ([gnapse](https://github.com/gnapse)) +- Evan You ([yyx990803](https://github.com/yyx990803)) +- Gavin Gilmour ([gaving](https://github.com/gaving)) +- Ian Schmitz ([ianschmitz](https://github.com/ianschmitz)) +- Ian Sutherland ([iansu](https://github.com/iansu)) +- JANG SUN HYUK ([wkdtjsgur100](https://github.com/wkdtjsgur100)) +- Jeffrey Posnick ([jeffposnick](https://github.com/jeffposnick)) +- Joe Haddad ([Timer](https://github.com/Timer)) +- Joe Lim ([xjlim](https://github.com/xjlim)) +- Jonathan ([GreenGremlin](https://github.com/GreenGremlin)) +- Juhamatti Niemelä ([iiska](https://github.com/iiska)) +- Mae Capozzi ([maecapozzi](https://github.com/maecapozzi)) +- Maksym Dogadailo ([mdogadailo](https://github.com/mdogadailo)) +- Mario Nebl ([marionebl](https://github.com/marionebl)) +- Matt Morgis ([MattMorgis](https://github.com/MattMorgis)) +- Misha Khokhlov ([hazolsky](https://github.com/hazolsky)) +- Moos ([moos](https://github.com/moos)) +- Nils Magnus Englund ([nmenglund](https://github.com/nmenglund)) +- Norris Oduro ([Norris1z](https://github.com/Norris1z)) +- Ovidiu Cherecheș ([skidding](https://github.com/skidding)) +- Quentin Bahers ([qbahers](https://github.com/qbahers)) +- Rafael E. Poveda ([raerpo](https://github.com/raerpo)) +- Rahul Chanila ([rahulcs](https://github.com/rahulcs)) +- Ryan McCue ([rmccue](https://github.com/rmccue)) +- Sascha Dens ([SaschaDens](https://github.com/SaschaDens)) +- Siddharth Doshi ([doshisid](https://github.com/doshisid)) +- Tao Gómez Gil ([Gua-naiko-che](https://github.com/Gua-naiko-che)) +- Tharaka Wijebandara ([tharakawj](https://github.com/tharakawj)) +- Trevor Brindle ([tabrindle](https://github.com/tabrindle)) +- Ulrik Strid ([ulrikstrid](https://github.com/ulrikstrid)) +- Vladimir Tolstikov ([bobrosoft](https://github.com/bobrosoft)) +- [Dubes](https://github.com/Dubes) +- [vannio](https://github.com/vannio) +- shrynx ([shrynx](https://github.com/shrynx)) + +### Migrating from 1.0.17 to 1.1.0 + +Inside any created project that has not been ejected, run: + +``` +npm install --save --save-exact react-scripts@1.1.0 +``` + +or + +``` +yarn add --exact react-scripts@1.1.0 +``` + +## 1.0.17 (November 3, 2017) + +#### :nail_care: Enhancement + +* `react-scripts` + + * [#3401](https://github.com/facebookincubator/create-react-app/pull/3401) Stop using a deprecated option. ([@gaearon](https://github.com/gaearon)) + +#### :memo: Documentation + +* `react-scripts` + + * [#3399](https://github.com/facebookincubator/create-react-app/pull/3399) Add link to VS Code troubleshooting guide. ([@auchenberg](https://github.com/auchenberg)) + * [#3400](https://github.com/facebookincubator/create-react-app/pull/3400) Update VS Code debug configuration. ([@auchenberg](https://github.com/auchenberg)) + +#### Committers: 3 + +- Dan Abramov ([gaearon](https://github.com/gaearon)) +- Kenneth Auchenberg ([auchenberg](https://github.com/auchenberg)) +- Loren Sands-Ramshaw ([lorensr](https://github.com/lorensr)) + +### Migrating from 1.0.16 to 1.0.17 + +Inside any created project that has not been ejected, run: + +``` +npm install --save --save-exact react-scripts@1.0.17 +``` + +or + +``` +yarn add --exact react-scripts@1.0.17 +``` + +## 1.0.16 (October 31, 2017) 🎃 + +#### :bug: Bug Fix + +* `react-scripts` + + * [#3374](https://github.com/facebookincubator/create-react-app/pull/3374) Set correct image type and sizes in `manifest.json`. ([@piotr-cz](https://github.com/piotr-cz)) + +* `react-dev-utils` + + * [#3368](https://github.com/facebookincubator/create-react-app/pull/3368) Fix a crash in development mode in older browsers. ([@felthy](https://github.com/felthy)) + +#### Committers: 2 + +- Dan Abramov ([gaearon](https://github.com/gaearon)) +- Piotr ([piotr-cz](https://github.com/piotr-cz)) + +### Migrating from 1.0.15 to 1.0.16 + +Inside any created project that has not been ejected, run: + +``` +npm install --save --save-exact react-scripts@1.0.16 +``` + +or + +``` +yarn add --exact react-scripts@1.0.16 +``` + +## 1.0.15 (October 30, 2017) + +#### :bug: Bug Fix + +* `react-scripts` + + * [#3287](https://github.com/facebookincubator/create-react-app/pull/3287) Fix favicon sizes value in the project manifest. ([@ryansully](https://github.com/ryansully)) + +* `react-dev-utils`, `react-scripts` + + * [#3230](https://github.com/facebookincubator/create-react-app/pull/3230) Fix watching for changes in `src/node_modules`. ([@xjlim](https://github.com/xjlim)) + +#### :nail_care: Enhancement + +* `react-scripts` + + * [#3239](https://github.com/facebookincubator/create-react-app/pull/3239) Allow importing `.mjs` files. ([@Timer](https://github.com/Timer)) + * [#3340](https://github.com/facebookincubator/create-react-app/pull/3340) Polyfill `requestAnimationFrame` in test environment. ([@gaearon](https://github.com/gaearon)) + +* `babel-preset-react-app`, `react-dev-utils`, `react-error-overlay`, `react-scripts` + + * [#3342](https://github.com/facebookincubator/create-react-app/pull/3342) Bump dependencies. ([@gaearon](https://github.com/gaearon)) + +* `react-dev-utils`, `react-error-overlay` + + * [#3100](https://github.com/facebookincubator/create-react-app/pull/3100) Add click-to-open support for build errors. ([@tharakawj](https://github.com/tharakawj)) + +* `create-react-app` + + * [#3355](https://github.com/facebookincubator/create-react-app/pull/3355) Add preflight CWD check for npm to detect bad Windows setups. ([@gaearon](https://github.com/gaearon)) + +#### :memo: Documentation + +* User Guide + + * [#2957](https://github.com/facebookincubator/create-react-app/pull/2957) Use `npm-run-all` to build Sass and JS. ([@shime](https://github.com/shime)) + * [#3108](https://github.com/facebookincubator/create-react-app/pull/3108) Update the Service Worker opt-out documentation. ([@captDaylight](https://github.com/captDaylight)) + * [#3286](https://github.com/facebookincubator/create-react-app/pull/3286) Add documentation for Enzyme 3 integration. ([@ryansully](https://github.com/ryansully)) + * [#3328](https://github.com/facebookincubator/create-react-app/pull/3328) Recommend react-snap as an alternative to react-snapshot. ([@aaronshaf](https://github.com/aaronshaf)) + * [#3279](https://github.com/facebookincubator/create-react-app/pull/3279) Add jest coverage configuration docs. ([@mattphillips](https://github.com/mattphillips)) + * [#3303](https://github.com/facebookincubator/create-react-app/pull/3303) Update link to Jest Expect docs. ([@jbranchaud](https://github.com/jbranchaud)) + * [#3289](https://github.com/facebookincubator/create-react-app/pull/3289) Fix dead link to Jest "expect" docs. ([@alexkrolick](https://github.com/alexkrolick)) + * [#3265](https://github.com/facebookincubator/create-react-app/pull/3265) Add external links to deployment services. ([@aericson](https://github.com/aericson)) + * [#3075](https://github.com/facebookincubator/create-react-app/pull/3075) Minor docs change to highlight dev proxy behaviour. ([@davidjb](https://github.com/davidjb)) + * [#3185](https://github.com/facebookincubator/create-react-app/pull/3185) Correct manual proxy documentation. ([@robertpanzer](https://github.com/robertpanzer)) + +* README + + * [#3227](https://github.com/facebookincubator/create-react-app/pull/3227) Fix package management link in README for issue #3218. ([@nishina555](https://github.com/nishina555)) + * [#3211](https://github.com/facebookincubator/create-react-app/pull/3211) Improve grammar in README. ([@Mohamed3on](https://github.com/Mohamed3on)) + +#### :house: Internal + +* Other + + * [#3345](https://github.com/facebookincubator/create-react-app/pull/3345) Stop using `npm link` in tests. ([@Timer](https://github.com/Timer)) + +* `react-error-overlay` + + * [#3122](https://github.com/facebookincubator/create-react-app/pull/3122) Fix for add .gitattributes file #3080. ([@ijajmulani](https://github.com/ijajmulani)) + * [#3267](https://github.com/facebookincubator/create-react-app/pull/3267) Use production React version for bundled overlay. ([@Timer](https://github.com/Timer)) + * [#3264](https://github.com/facebookincubator/create-react-app/pull/3264) Add warning when using `react-error-overlay` in production. ([@Timer](https://github.com/Timer)) + * [#3263](https://github.com/facebookincubator/create-react-app/pull/3263) `react-error-overlay` has no dependencies now (it's bundled). ([@Timer](https://github.com/Timer)) + * [#3142](https://github.com/facebookincubator/create-react-app/pull/3142) Make error overlay run in the context of the iframe. ([@tharakawj](https://github.com/tharakawj)) + +* `react-scripts` + + * [#3150](https://github.com/facebookincubator/create-react-app/pull/3150) Remove an useless negation in `registerServiceWorker.js`. ([@dunglas](https://github.com/dunglas)) + * [#3158](https://github.com/facebookincubator/create-react-app/pull/3158) Remove `output.path` from dev webpack config. ([@nikolas](https://github.com/nikolas)) + * [#3281](https://github.com/facebookincubator/create-react-app/pull/3281) Add a workaround for Uglify incompatiblity with Safari 10.0 in the future. ([@satyavh](https://github.com/satyavh)) + * [#3146](https://github.com/facebookincubator/create-react-app/pull/3146) Fix `reason-react` support. ([@lpalmes](https://github.com/lpalmes)) + * [#3236](https://github.com/facebookincubator/create-react-app/pull/3236) Update `style-loader` and disable inclusion of its HMR code in builds. ([@insin](https://github.com/insin)) + * [#3246](https://github.com/facebookincubator/create-react-app/pull/3246) Update `url-loader` to 0.6.2 for mime ReDoS vulnerability. ([@d3viant0ne](https://github.com/d3viant0ne)) + * [#2914](https://github.com/facebookincubator/create-react-app/pull/2914) `` -> ``. ([@Hurtak](https://github.com/Hurtak)) + +#### Committers: 24 + +- Aaron Shafovaloff ([aaronshaf](https://github.com/aaronshaf)) +- Alex ([alexkrolick](https://github.com/alexkrolick)) +- André Ericson ([aericson](https://github.com/aericson)) +- Dan Abramov ([gaearon](https://github.com/gaearon)) +- David Beitey ([davidjb](https://github.com/davidjb)) +- Hrvoje Šimić ([shime](https://github.com/shime)) +- IJAJ MULANI ([ijajmulani](https://github.com/ijajmulani)) +- Joe Haddad ([Timer](https://github.com/Timer)) +- Joe Lim ([xjlim](https://github.com/xjlim)) +- Jonny Buchanan ([insin](https://github.com/insin)) +- Josh Branchaud ([jbranchaud](https://github.com/jbranchaud)) +- Joshua Wiens ([d3viant0ne](https://github.com/d3viant0ne)) +- Kévin Dunglas ([dunglas](https://github.com/dunglas)) +- Lorenzo Palmes ([lpalmes](https://github.com/lpalmes)) +- Matt Phillips ([mattphillips](https://github.com/mattphillips)) +- Mohamed Oun ([Mohamed3on](https://github.com/Mohamed3on)) +- Nik Nyby ([nikolas](https://github.com/nikolas)) +- Petr Huřťák ([Hurtak](https://github.com/Hurtak)) +- Robert Panzer ([robertpanzer](https://github.com/robertpanzer)) +- Ryan Sullivan ([ryansully](https://github.com/ryansully)) +- Satya van Heummen ([satyavh](https://github.com/satyavh)) +- Tharaka Wijebandara ([tharakawj](https://github.com/tharakawj)) +- Toshiharu Nishina ([nishina555](https://github.com/nishina555)) +- [captDaylight](https://github.com/captDaylight) + +### Migrating from 1.0.14 to 1.0.15 + +Inside any created project that has not been ejected, run: + +``` +npm install --save --save-exact react-scripts@1.0.15 +``` + +or + +``` +yarn add --exact react-scripts@1.0.15 +``` + ## 1.0.14 (September 26, 2017) #### :bug: Bug Fix diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 00000000000..55203be746a --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,3 @@ +# Code of Conduct + +Facebook has adopted a Code of Conduct that we expect project participants to adhere to. Please [read the full text](https://code.facebook.com/pages/876921332402685/open-source-code-of-conduct) so that you can understand what actions will and will not be tolerated. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 68a9c4e09cc..72994ebbf68 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -75,20 +75,18 @@ All functionality must be retained (and configuration given to the user) if they 1. Clone the repo with `git clone https://github.com/facebookincubator/create-react-app` -2. Run `npm install` in the root `create-react-app` folder. +2. Run `yarn` in the root `create-react-app` folder. -Once it is done, you can modify any file locally and run `npm start`, `npm test` or `npm run build` just like in a generated project. +Once it is done, you can modify any file locally and run `yarn start`, `yarn test` or `yarn build` just like in a generated project. If you want to try out the end-to-end flow with the global CLI, you can do this too: ``` -npm run create-react-app my-app +yarn create-react-app my-app cd my-app ``` -and then run `npm start` or `npm run build`. - -*Note: if you are using yarn, we suggest that you use `yarn install --no-lockfile` instead of the bare `yarn` or `yarn install` because we [intentionally](https://github.com/facebookincubator/create-react-app/pull/2014#issuecomment-300811661) do not ignore or add yarn.lock to our repo.* +and then run `yarn start` or `yarn build`. ## Contributing to E2E (end to end) tests @@ -96,6 +94,21 @@ and then run `npm start` or `npm run build`. More detailed information are in the dedicated [README](/packages/react-scripts/fixtures/kitchensink/README.md). +## Tips for contributors using Windows + +The scripts in tasks folder and other scripts in `package.json` will not work in Windows out of the box. However, using [Bash on windows](https://msdn.microsoft.com/en-us/commandline/wsl/about) makes it easier to use those scripts without any workarounds. The steps to do so are detailed below: + +### Install Bash on Ubuntu on Windows + +A good step by step guide can be found [here](https://www.howtogeek.com/249966/how-to-install-and-use-the-linux-bash-shell-on-windows-10/) + +### Install Node.js and yarn +Even if you have node and yarn installed on your windows, it would not be accessible from the bash shell. You would have to install it again. Installing via [`nvm`](https://github.com/creationix/nvm#install-script) is recommended. + +### Line endings + +By default git would use `CRLF` line endings which would cause the scripts to fail. You can change it for this repo only by setting `autocrlf` to false by running `git config core.autocrlf false`. You can also enable it for all your repos by using the `--global` flag if you wish to do so. + ## Cutting a Release 1. Tag all merged pull requests that go into the release with the relevant milestone. Each merged PR should also be labeled with one of the [labels](https://github.com/facebookincubator/create-react-app/labels) named `tag: ...` to indicate what kind of change it is. @@ -104,13 +117,13 @@ More detailed information are in the dedicated [README](/packages/react-scripts/ 4. Note that files in `packages/create-react-app` should be modified with extreme caution. Since it’s a global CLI, any version of `create-react-app` (global CLI) including very old ones should work with the latest version of `react-scripts`. 5. Create a change log entry for the release: * 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`. + * Run `yarn 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`.** -9. Wait for a long time, and it will get published. Don’t worry that it’s stuck. In the end the publish script will prompt for versions before publishing the packages. +7. Run `npm run publish`. (It has to be `npm run publish` exactly, not just `npm publish` or `yarn publish`.) +8. Wait for a long time, and it will get published. Don’t worry that it’s stuck. In the end the publish script will prompt for versions before publishing the packages. +9. After publishing, create a GitHub Release with the same text as the changelog entry. See previous Releases for inspiration. Make sure to test the released version! If you want to be extra careful, you can publish a prerelease by running `npm run publish -- --tag next` instead of `npm run publish`. diff --git a/README.md b/README.md index 6009e8a6d88..b09630e90ba 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ Create React apps with no build configuration. -* [Getting Started](#getting-started) – How to create a new app. +* [Creating an App](#creating-an-app) – How to create a new app. * [User Guide](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md) – How to develop apps bootstrapped with Create React App. Create React App works on macOS, Windows, and Linux.
@@ -11,17 +11,19 @@ If something doesn’t work, please [file an issue](https://github.com/facebooki ## Quick Overview ```sh -npm install -g create-react-app - -create-react-app my-app -cd my-app/ +npx create-react-app my-app +cd my-app npm start ``` +*([npx](https://medium.com/@maybekatz/introducing-npx-an-npm-package-runner-55f7d4bd282b) comes with npm 5.2+ and higher, see [instructions for older npm versions](https://gist.github.com/gaearon/4064d3c23a77c74a3614c498a8bb1c5f))* + Then open [http://localhost:3000/](http://localhost:3000/) to see your app.
When you’re ready to deploy to production, create a minified bundle with `npm run build`. -npm start +

+ +

### Get Started Immediately @@ -30,28 +32,17 @@ They are preconfigured and hidden so that you can focus on the code. Just create a project, and you’re good to go. -## Getting Started +## Creating an App -### Installation +**You’ll need to have Node >= 6 on your local development machine** (but it’s not required on the server). You can use [nvm](https://github.com/creationix/nvm#installation) (macOS/Linux) or [nvm-windows](https://github.com/coreybutler/nvm-windows#node-version-manager-nvm-for-windows) to easily switch Node versions between different projects. -Install it once globally: +To create a new app, run a single command: ```sh -npm install -g create-react-app +npx create-react-app my-app ``` -**You’ll need to have Node >= 6 on your machine**. You can use [nvm](https://github.com/creationix/nvm#installation) to easily switch Node versions between different projects. - -**This tool doesn’t assume a Node backend**. The Node installation is only required for Create React App itself. - -### Creating an App - -To create a new app, run: - -```sh -create-react-app my-app -cd my-app -``` +*([npx](https://medium.com/@maybekatz/introducing-npx-an-npm-package-runner-55f7d4bd282b) comes with npm 5.2+ and higher, see [instructions for older npm versions](https://gist.github.com/gaearon/4064d3c23a77c74a3614c498a8bb1c5f))* It will create a directory called `my-app` inside the current folder.
Inside that directory, it will generate the initial project structure and install the transitive dependencies: @@ -77,7 +68,13 @@ my-app ``` No configuration or complicated folder structures, just the files you need to build your app.
-Once the installation is done, you can run some commands inside the project folder: +Once the installation is done, you can open your project folder: + +```sh +cd my-app +``` + +Inside the newly created project, you can run some built-in commands: ### `npm start` or `yarn start` @@ -113,6 +110,7 @@ The [User Guide](https://github.com/facebookincubator/create-react-app/blob/mast - [Updating to New Releases](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#updating-to-new-releases) - [Folder Structure](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#folder-structure) - [Available Scripts](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#available-scripts) +- [Supported Browsers](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#supported-browsers) - [Supported Language Features and Polyfills](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#supported-language-features-and-polyfills) - [Syntax Highlighting in the Editor](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#syntax-highlighting-in-the-editor) - [Displaying Lint Output in the Editor](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#displaying-lint-output-in-the-editor) @@ -130,15 +128,19 @@ The [User Guide](https://github.com/facebookincubator/create-react-app/blob/mast - [Using Global Variables](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#using-global-variables) - [Adding Bootstrap](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#adding-bootstrap) - [Adding Flow](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#adding-flow) +- [Adding a Router](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#adding-a-router) - [Adding Custom Environment Variables](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#adding-custom-environment-variables) - [Can I Use Decorators?](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#can-i-use-decorators) +- [Fetching Data with AJAX Requests](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#fetching-data-with-ajax-requests) - [Integrating with an API Backend](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#integrating-with-an-api-backend) - [Proxying API Requests in Development](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#proxying-api-requests-in-development) - [Using HTTPS in Development](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#using-https-in-development) - [Generating Dynamic `` Tags on the Server](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#generating-dynamic-meta-tags-on-the-server) - [Pre-Rendering into Static HTML Files](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#pre-rendering-into-static-html-files) - [Running Tests](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#running-tests) +- [Debugging Tests](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#debugging-tests) - [Developing Components in Isolation](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#developing-components-in-isolation) +- [Publishing Components to npm](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#publishing-components-to-npm) - [Making a Progressive Web App](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#making-a-progressive-web-app) - [Analyzing the Bundle Size](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#analyzing-the-bundle-size) - [Deployment](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#deployment) @@ -159,57 +161,50 @@ Please refer to the [User Guide](https://github.com/facebookincubator/create-rea * **No Lock-In:** You can “eject” to a custom setup at any time. Run a single command, and all the configuration and build dependencies will be moved directly into your project, so you can pick up right where you left off. -## Why Use This? +## What’s Included? -**If you’re getting started** with React, use `create-react-app` to automate the build of your app. There is no configuration file, and `react-scripts` is the only extra build dependency in your `package.json`. Your environment will have everything you need to build a modern React app: +Your environment will have everything you need to build a modern single-page React app: * React, JSX, ES6, and Flow syntax support. * Language extras beyond ES6 like the object spread operator. -* A dev server that lints for common errors. -* Import CSS and image files directly from JavaScript. * Autoprefixed CSS, so you don’t need `-webkit` or other prefixes. -* A `build` script to bundle JS, CSS, and images for production, with sourcemaps. +* A fast interactive unit test runner with built-in support for coverage reporting. +* A live development server that warns about common mistakes. +* A build script to bundle JS, CSS, and images for production, with hashes and sourcemaps. * An offline-first [service worker](https://developers.google.com/web/fundamentals/getting-started/primers/service-workers) and a [web app manifest](https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/), meeting all the [Progressive Web App](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#making-a-progressive-web-app) criteria. +* Hassle-free updates for the above tools with a single dependency. -**The feature set is intentionally limited**. It doesn’t support advanced features such as server rendering or CSS modules. The tool is also **non-configurable** because it is hard to provide a cohesive experience and easy updates across a set of tools when the user can tweak anything. +Check out [this guide](https://github.com/nitishdayal/cra_closer_look) for an overview of how these tools fit together. -**You don’t have to use this.** Historically it has been easy to [gradually adopt](https://www.youtube.com/watch?v=BF58ZJ1ZQxY) React. However many people create new single-page React apps from scratch every day. We’ve heard [loud](https://medium.com/@ericclemmons/javascript-fatigue-48d4011b6fc4) and [clear](https://twitter.com/thomasfuchs/status/708675139253174273) that this process can be error-prone and tedious, especially if this is your first JavaScript build stack. This project is an attempt to figure out a good way to start developing React apps. +The tradeoff is that **these tools are preconfigured to work in a specific way**. If your project needs more customization, you can ["eject"](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#npm-run-eject) and customize it, but then you will need to maintain this configuration. -### Converting to a Custom Setup +## Popular Alternatives -**If you’re a power user** and you aren’t happy with the default configuration, you can “eject” from the tool and use it as a boilerplate generator. +Create React App is a great fit for: -Running `npm run eject` copies all the configuration files and the transitive dependencies (Webpack, Babel, ESLint, etc) right into your project so you have full control over them. Commands like `npm start` and `npm run build` will still work, but they will point to the copied scripts so you can tweak them. At this point, you’re on your own. +* **Learning React** in a comfortable and feature-rich development environment. +* **Starting new single-page React applications.** +* **Creating examples** with React for your libraries and components. -**Note: this is a one-way operation. Once you `eject`, you can’t go back!** +Here’s a few common cases where you might want to try something else: -You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it. +* If you want to **try React** without hundreds of transitive build tool dependencies, consider [using a single HTML file or an online sandbox instead](https://reactjs.org/docs/try-react.html). -## Limitations +* If you need to **integrate React code with a server-side template framework** like Rails or Django, or if you’re **not building a single-page app**, consider using [nwb](https://github.com/insin/nwb) or [Neutrino](https://neutrino.js.org/) which are more flexible. -Some features are currently **not supported**: +* If you need to **publish a React component**, [nwb](https://github.com/insin/nwb) can [also do this](https://github.com/insin/nwb#react-components-and-libraries), as well as [Neutrino's react-components preset](https://neutrino.js.org/packages/react-components/). -* Server rendering. -* Some experimental syntax extensions (e.g. decorators). -* CSS Modules (see [#2285](https://github.com/facebookincubator/create-react-app/pull/2285)). -* Importing LESS or Sass directly ([but you still can use them](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#adding-a-css-preprocessor-sass-less-etc)). -* Hot reloading of components. +* If you want to do **server rendering** with React and Node.js, check out [Next.js](https://github.com/zeit/next.js/) or [Razzle](https://github.com/jaredpalmer/razzle). Create React App is agnostic of the backend, and just produces static HTML/JS/CSS bundles. -Some of them might get added in the future if they are stable, are useful to majority of React apps, don’t conflict with existing tools, and don’t introduce additional configuration. +* If your website is **mostly static** (for example, a portfolio or a blog), consider using [Gatsby](https://www.gatsbyjs.org/) instead. Unlike Create React App, it pre-renders the website into HTML at the build time. -## What’s Inside? +* If you want to use **TypeScript**, consider using [create-react-app-typescript](https://github.com/wmonk/create-react-app-typescript). -The tools used by Create React App are subject to change. -Currently it is a thin layer on top of many amazing community projects, such as: +* Finally, if you need **more customization**, check out [Neutrino](https://neutrino.js.org/) and its [React preset](https://neutrino.js.org/packages/react/). -* [webpack](https://webpack.js.org/) with [webpack-dev-server](https://github.com/webpack/webpack-dev-server), [html-webpack-plugin](https://github.com/ampedandwired/html-webpack-plugin) and [style-loader](https://github.com/webpack/style-loader) -* [Babel](http://babeljs.io/) with ES6 and extensions used by Facebook (JSX, [object spread](https://github.com/sebmarkbage/ecmascript-rest-spread/commits/master), [class properties](https://github.com/jeffmo/es-class-public-fields)) -* [Autoprefixer](https://github.com/postcss/autoprefixer) -* [ESLint](http://eslint.org/) -* [Jest](http://facebook.github.io/jest) -* and others. +All of the above tools can work with little to no configuration. -All of them are transitive dependencies of the provided npm package. +If you prefer configuring the build yourself, [follow this guide](https://reactjs.org/docs/add-react-to-an-existing-app.html). ## Contributing @@ -227,32 +222,3 @@ We are grateful to the authors of existing related projects for their ideas and * [@eanplatter](https://github.com/eanplatter) * [@insin](https://github.com/insin) * [@mxstbr](https://github.com/mxstbr) - -## Alternatives - -If you don’t agree with the choices made in this project, you might want to explore alternatives with different tradeoffs.
-Some of the more popular and actively maintained ones are: - -* [insin/nwb](https://github.com/insin/nwb) -* [mozilla-neutrino/neutrino-dev](https://github.com/mozilla-neutrino/neutrino-dev) -* [jaredpalmer/razzle](https://github.com/jaredpalmer/razzle) -* [NYTimes/kyt](https://github.com/NYTimes/kyt) -* [zeit/next.js](https://github.com/zeit/next.js) -* [gatsbyjs/gatsby](https://github.com/gatsbyjs/gatsby) -* [electrode-io/electrode](https://github.com/electrode-io/electrode) - -Notable alternatives also include: - -* [enclave](https://github.com/eanplatter/enclave) -* [motion](https://github.com/steelbrain/pundle/tree/master/packages/motion) -* [quik](https://github.com/satya164/quik) -* [sagui](https://github.com/saguijs/sagui) -* [roc](https://github.com/rocjs/roc) -* [aik](https://github.com/d4rkr00t/aik) -* [react-app](https://github.com/kriasoft/react-app) -* [dev-toolkit](https://github.com/stoikerty/dev-toolkit) -* [sku](https://github.com/seek-oss/sku) -* [gluestick](https://github.com/TrueCar/gluestick) - -You can also use module bundlers like [webpack](http://webpack.js.org) and [Browserify](http://browserify.org/) directly.
-React documentation includes [a walkthrough](https://reactjs.org/docs/installation.html#development-and-production-versions) on this topic. diff --git a/appveyor.cleanup-cache.txt b/appveyor.cleanup-cache.txt index 19d0b989b62..ea6d1b9c010 100644 --- a/appveyor.cleanup-cache.txt +++ b/appveyor.cleanup-cache.txt @@ -3,3 +3,4 @@ http://help.appveyor.com/discussions/questions/1310-delete-cache ---- Just testing if this works. +lalala. diff --git a/appveyor.yml b/appveyor.yml index e00da39436c..5d957aa7eea 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -2,11 +2,11 @@ image: Visual Studio 2017 environment: matrix: - - nodejs_version: 7 + - nodejs_version: 8 test_suite: "simple" - - nodejs_version: 7 + - nodejs_version: 8 test_suite: "installs" - - nodejs_version: 7 + - nodejs_version: 8 test_suite: "kitchensink" - nodejs_version: 6 test_suite: "simple" @@ -28,8 +28,6 @@ platform: - x64 install: - # TODO: Remove after https://github.com/appveyor/ci/issues/1426 is fixed - - set PATH=C:\Program Files\Git\mingw64\bin;%PATH% - ps: Install-Product node $env:nodejs_version $env:platform build: off @@ -41,4 +39,4 @@ skip_commits: test_script: - node --version - npm --version - - sh tasks/e2e-%test_suite%.sh + - bash tasks/e2e-%test_suite%.sh diff --git a/bootstrap.js b/bootstrap.js deleted file mode 100644 index b54a1ed9f36..00000000000 --- a/bootstrap.js +++ /dev/null @@ -1,67 +0,0 @@ -'use strict'; - -const { execSync, spawn } = require('child_process'); -const { resolve } = require('path'); -const { existsSync } = require('fs'); -const { platform } = require('os'); - -function shouldUseYarn() { - try { - execSync('yarnpkg --version', { stdio: 'ignore' }); - return true; - } catch (e) { - return false; - } -} - -function shouldUseNpmConcurrently() { - try { - const versionString = execSync('npm --version'); - const m = /^(\d+)[.]/.exec(versionString); - // NPM >= 5 support concurrent installs - return Number(m[1]) >= 5; - } catch (e) { - return false; - } -} - -const yarn = shouldUseYarn(); -const windows = platform() === 'win32'; -const lerna = resolve( - __dirname, - 'node_modules', - '.bin', - windows ? 'lerna.cmd' : 'lerna' -); - -if (!existsSync(lerna)) { - if (yarn) { - console.log('Cannot find lerna. Please run `yarn --check-files`.'); - } else { - console.log( - 'Cannot find lerna. Please remove `node_modules` and run `npm install`.' - ); - } - process.exit(1); -} - -let child; -if (yarn) { - // Yarn does not support concurrency - child = spawn(lerna, ['bootstrap', '--npm-client=yarn', '--concurrency=1'], { - stdio: 'inherit', - }); -} else { - let args = ['bootstrap']; - if ( - // The Windows filesystem does not handle concurrency well - windows || - // Only newer npm versions support concurrency - !shouldUseNpmConcurrently() - ) { - args.push('--concurrency=1'); - } - child = spawn(lerna, args, { stdio: 'inherit' }); -} - -child.on('close', code => process.exit(code)); diff --git a/lerna.json b/lerna.json index 1673f8a3187..f1d78d84bae 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,7 @@ { - "lerna": "2.0.0", + "lerna": "2.6.0", + "npmClient": "yarn", + "useWorkspaces": true, "version": "independent", "changelog": { "repo": "facebookincubator/create-react-app", @@ -12,8 +14,5 @@ "tag: internal": ":house: Internal" }, "cacheDir": ".changelog" - }, - "packages": [ - "packages/*" - ] + } } diff --git a/package.json b/package.json index 2bede9a9469..08bab46bc9d 100644 --- a/package.json +++ b/package.json @@ -2,26 +2,31 @@ "name": "create-react-app", "version": "0.1.1", "private": true, + "workspaces": [ + "packages/*" + ], "scripts": { - "build": "node packages/react-scripts/scripts/build.js", + "build": "cd packages/react-scripts && node scripts/build.js", "changelog": "lerna-changelog", - "create-react-app": "tasks/cra.sh", + "create-react-app": "node tasks/cra.js", "e2e": "tasks/e2e-simple.sh", "e2e:docker": "tasks/local-test.sh", - "postinstall": "node bootstrap.js && cd packages/react-error-overlay/ && npm run build:prod", - "publish": "tasks/release.sh", - "start": "node packages/react-scripts/scripts/start.js", - "test": "node packages/react-scripts/scripts/test.js --env=jsdom", + "postinstall": "cd packages/react-error-overlay/ && yarn build:prod", + "publish": "tasks/publish.sh", + "start": "cd packages/react-scripts && node scripts/start.js", + "screencast": "svg-term --cast hItN7sl5yfCPTHxvFg5glhhfp --out screencast.svg --window", + "test": "cd packages/react-scripts && node scripts/test.js --env=jsdom", "format": "prettier --trailing-comma es5 --single-quote --write 'packages/*/*.js' 'packages/*/!(node_modules)/**/*.js'", "precommit": "lint-staged" }, "devDependencies": { "eslint": "^4.4.1", "husky": "^0.13.2", - "lerna": "^2.0.0", + "lerna": "2.6.0", "lerna-changelog": "^0.6.0", "lint-staged": "^3.3.1", - "prettier": "1.6.1" + "prettier": "1.6.1", + "svg-term-cli": "^2.0.3" }, "lint-staged": { "*.js": [ diff --git a/packages/babel-preset-react-app/README.md b/packages/babel-preset-react-app/README.md index 4dc9fb9b168..5653831ac7e 100644 --- a/packages/babel-preset-react-app/README.md +++ b/packages/babel-preset-react-app/README.md @@ -16,6 +16,12 @@ If you want to use this Babel preset in a project not built with Create React Ap First, [install Babel](https://babeljs.io/docs/setup/). +Then install babel-preset-react-app. + +```sh +npm install babel-preset-react-app --save-dev +``` + Then create a file named `.babelrc` with following contents in the root folder of your project: ```js diff --git a/packages/babel-preset-react-app/create.js b/packages/babel-preset-react-app/create.js new file mode 100644 index 00000000000..7156ff4ee8b --- /dev/null +++ b/packages/babel-preset-react-app/create.js @@ -0,0 +1,135 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +'use strict'; + +module.exports = function create(env) { + if (env !== 'development' && env !== 'test' && env !== 'production') { + throw new Error( + 'Using `babel-preset-react-app` requires that you specify `NODE_ENV` or ' + + '`BABEL_ENV` environment variables. Valid values are "development", ' + + '"test", and "production". Instead, received: ' + + JSON.stringify(env) + + '.' + ); + } + + const plugins = [ + // Necessary to include regardless of the environment because + // in practice some other transforms (such as object-rest-spread) + // don't work without it: https://github.com/babel/babel/issues/7215 + require.resolve('babel-plugin-transform-es2015-destructuring'), + // class { handleClick = () => { } } + require.resolve('babel-plugin-transform-class-properties'), + // The following two plugins use Object.assign directly, instead of Babel's + // extends helper. Note that this assumes `Object.assign` is available. + // { ...todo, completed: true } + [ + require.resolve('babel-plugin-transform-object-rest-spread'), + { + useBuiltIns: true, + }, + ], + // Transforms JSX + [ + require.resolve('babel-plugin-transform-react-jsx'), + { + useBuiltIns: true, + }, + ], + // Polyfills the runtime needed for async/await and generators + [ + require.resolve('babel-plugin-transform-runtime'), + { + helpers: false, + polyfill: false, + regenerator: true, + }, + ], + ]; + + if (env === 'development' || env === 'test') { + // The following two plugins are currently necessary to make React warnings + // include more valuable information. They are included here because they are + // currently not enabled in babel-preset-react. See the below threads for more info: + // https://github.com/babel/babel/issues/4702 + // https://github.com/babel/babel/pull/3540#issuecomment-228673661 + // https://github.com/facebookincubator/create-react-app/issues/989 + plugins.push.apply(plugins, [ + // Adds component stack to warning messages + require.resolve('babel-plugin-transform-react-jsx-source'), + // Adds __self attribute to JSX which React will use for some warnings + require.resolve('babel-plugin-transform-react-jsx-self'), + ]); + } + + if (env === 'test') { + return { + presets: [ + // ES features necessary for user's Node version + [ + require('babel-preset-env').default, + { + targets: { + node: 'current', + }, + }, + ], + // JSX, Flow + require.resolve('babel-preset-react'), + ], + plugins: plugins.concat([ + // Compiles import() to a deferred require() + require.resolve('babel-plugin-dynamic-import-node'), + ]), + }; + } else { + return { + presets: [ + // Latest stable ECMAScript features + [ + require.resolve('babel-preset-env'), + { + targets: { + // React parses on ie 9, so we should too + ie: 9, + // We currently minify with uglify + // Remove after https://github.com/mishoo/UglifyJS2/issues/448 + uglify: true, + }, + // Disable polyfill transforms + useBuiltIns: false, + // Do not transform modules to CJS + modules: false, + }, + ], + // JSX, Flow + require.resolve('babel-preset-react'), + ], + plugins: plugins.concat([ + // function* () { yield 42; yield 43; } + [ + require.resolve('babel-plugin-transform-regenerator'), + { + // Async functions are converted to generators by babel-preset-env + async: false, + }, + ], + // Adds syntax support for import() + require.resolve('babel-plugin-syntax-dynamic-import'), + ]), + }; + + if (env === 'production') { + // Optimization: hoist JSX that never changes out of render() + // Disabled because of issues: https://github.com/facebookincubator/create-react-app/issues/553 + // TODO: Enable again when these issues are resolved. + // plugins.push.apply(plugins, [ + // require.resolve('babel-plugin-transform-react-constant-elements') + // ]); + } + } +}; diff --git a/packages/babel-preset-react-app/dev.js b/packages/babel-preset-react-app/dev.js new file mode 100644 index 00000000000..399cfb708c3 --- /dev/null +++ b/packages/babel-preset-react-app/dev.js @@ -0,0 +1,11 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +'use strict'; + +const create = require('./create'); + +module.exports = create('development'); diff --git a/packages/babel-preset-react-app/index.js b/packages/babel-preset-react-app/index.js index 2b08ea07e14..68a90d7b2a6 100644 --- a/packages/babel-preset-react-app/index.js +++ b/packages/babel-preset-react-app/index.js @@ -13,35 +13,7 @@ */ 'use strict'; -const plugins = [ - // class { handleClick = () => { } } - require.resolve('babel-plugin-transform-class-properties'), - // The following two plugins use Object.assign directly, instead of Babel's - // extends helper. Note that this assumes `Object.assign` is available. - // { ...todo, completed: true } - [ - require.resolve('babel-plugin-transform-object-rest-spread'), - { - useBuiltIns: true, - }, - ], - // Transforms JSX - [ - require.resolve('babel-plugin-transform-react-jsx'), - { - useBuiltIns: true, - }, - ], - // Polyfills the runtime needed for async/await and generators - [ - require.resolve('babel-plugin-transform-runtime'), - { - helpers: false, - polyfill: false, - regenerator: true, - }, - ], -]; +const create = require('./create'); // This is similar to how `env` works in Babel: // https://babeljs.io/docs/usage/babelrc/#env-option @@ -50,94 +22,5 @@ const plugins = [ // https://github.com/facebookincubator/create-react-app/issues/720 // It’s also nice that we can enforce `NODE_ENV` being specified. var env = process.env.BABEL_ENV || process.env.NODE_ENV; -if (env !== 'development' && env !== 'test' && env !== 'production') { - throw new Error( - 'Using `babel-preset-react-app` requires that you specify `NODE_ENV` or ' + - '`BABEL_ENV` environment variables. Valid values are "development", ' + - '"test", and "production". Instead, received: ' + - JSON.stringify(env) + - '.' - ); -} -if (env === 'development' || env === 'test') { - // The following two plugins are currently necessary to make React warnings - // include more valuable information. They are included here because they are - // currently not enabled in babel-preset-react. See the below threads for more info: - // https://github.com/babel/babel/issues/4702 - // https://github.com/babel/babel/pull/3540#issuecomment-228673661 - // https://github.com/facebookincubator/create-react-app/issues/989 - plugins.push.apply(plugins, [ - // Adds component stack to warning messages - require.resolve('babel-plugin-transform-react-jsx-source'), - // Adds __self attribute to JSX which React will use for some warnings - require.resolve('babel-plugin-transform-react-jsx-self'), - ]); -} - -if (env === 'test') { - module.exports = { - presets: [ - // ES features necessary for user's Node version - [ - require('babel-preset-env').default, - { - targets: { - node: 'current', - }, - }, - ], - // JSX, Flow - require.resolve('babel-preset-react'), - ], - plugins: plugins.concat([ - // Compiles import() to a deferred require() - require.resolve('babel-plugin-dynamic-import-node'), - ]), - }; -} else { - module.exports = { - presets: [ - // Latest stable ECMAScript features - [ - require.resolve('babel-preset-env'), - { - targets: { - // React parses on ie 9, so we should too - ie: 9, - // We currently minify with uglify - // Remove after https://github.com/mishoo/UglifyJS2/issues/448 - uglify: true, - }, - // Disable polyfill transforms - useBuiltIns: false, - // Do not transform modules to CJS - modules: false, - }, - ], - // JSX, Flow - require.resolve('babel-preset-react'), - ], - plugins: plugins.concat([ - // function* () { yield 42; yield 43; } - [ - require.resolve('babel-plugin-transform-regenerator'), - { - // Async functions are converted to generators by babel-preset-env - async: false, - }, - ], - // Adds syntax support for import() - require.resolve('babel-plugin-syntax-dynamic-import'), - ]), - }; - - if (env === 'production') { - // Optimization: hoist JSX that never changes out of render() - // Disabled because of issues: https://github.com/facebookincubator/create-react-app/issues/553 - // TODO: Enable again when these issues are resolved. - // plugins.push.apply(plugins, [ - // require.resolve('babel-plugin-transform-react-constant-elements') - // ]); - } -} +module.exports = create(env); diff --git a/packages/babel-preset-react-app/package.json b/packages/babel-preset-react-app/package.json index 058d1a4af9c..81dd0fa1fe9 100644 --- a/packages/babel-preset-react-app/package.json +++ b/packages/babel-preset-react-app/package.json @@ -1,6 +1,6 @@ { "name": "babel-preset-react-app", - "version": "3.0.3", + "version": "3.1.2", "description": "Babel preset used by Create React App", "repository": "facebookincubator/create-react-app", "license": "MIT", @@ -8,20 +8,25 @@ "url": "https://github.com/facebookincubator/create-react-app/issues" }, "files": [ - "index.js" + "index.js", + "create.js", + "dev.js", + "prod.js", + "test.js" ], "dependencies": { - "babel-plugin-dynamic-import-node": "1.0.2", + "babel-plugin-dynamic-import-node": "1.1.0", "babel-plugin-syntax-dynamic-import": "6.18.0", "babel-plugin-transform-class-properties": "6.24.1", - "babel-plugin-transform-object-rest-spread": "6.23.0", + "babel-plugin-transform-es2015-destructuring": "6.23.0", + "babel-plugin-transform-object-rest-spread": "6.26.0", "babel-plugin-transform-react-constant-elements": "6.23.0", "babel-plugin-transform-react-jsx": "6.24.1", "babel-plugin-transform-react-jsx-self": "6.22.0", "babel-plugin-transform-react-jsx-source": "6.22.0", - "babel-plugin-transform-regenerator": "6.24.1", + "babel-plugin-transform-regenerator": "6.26.0", "babel-plugin-transform-runtime": "6.23.0", - "babel-preset-env": "1.5.2", + "babel-preset-env": "1.6.1", "babel-preset-react": "6.24.1" }, "peerDependencies": { diff --git a/packages/babel-preset-react-app/prod.js b/packages/babel-preset-react-app/prod.js new file mode 100644 index 00000000000..bf7520c45b5 --- /dev/null +++ b/packages/babel-preset-react-app/prod.js @@ -0,0 +1,11 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +'use strict'; + +const create = require('./create'); + +module.exports = create('production'); diff --git a/packages/babel-preset-react-app/test.js b/packages/babel-preset-react-app/test.js new file mode 100644 index 00000000000..3202d288810 --- /dev/null +++ b/packages/babel-preset-react-app/test.js @@ -0,0 +1,11 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +'use strict'; + +const create = require('./create'); + +module.exports = create('test'); diff --git a/packages/create-react-app/createReactApp.js b/packages/create-react-app/createReactApp.js index 161beab50e8..a2d9fdbd86b 100755 --- a/packages/create-react-app/createReactApp.js +++ b/packages/create-react-app/createReactApp.js @@ -47,6 +47,7 @@ const tmp = require('tmp'); const unpack = require('tar-pack').unpack; const url = require('url'); const hyperquest = require('hyperquest'); +const envinfo = require('envinfo'); const packageJson = require('./package.json'); @@ -60,10 +61,12 @@ const program = new commander.Command(packageJson.name) projectName = name; }) .option('--verbose', 'print additional logs') + .option('--info', 'print environment debug info') .option( '--scripts-version ', 'use a non-standard version of react-scripts' ) + .option('--use-npm') .allowUnknownOption() .on('--help', () => { console.log(` Only ${chalk.green('')} is required.`); @@ -82,6 +85,11 @@ const program = new commander.Command(packageJson.name) 'https://mysite.com/my-react-scripts-0.8.2.tgz' )}` ); + console.log( + ` - a .tar.gz archive: ${chalk.green( + 'https://mysite.com/my-react-scripts-0.8.2.tar.gz' + )}` + ); console.log( ` It is not needed unless you specifically want to use a fork.` ); @@ -99,6 +107,14 @@ const program = new commander.Command(packageJson.name) .parse(process.argv); if (typeof projectName === 'undefined') { + if (program.info) { + envinfo.print({ + packages: ['react', 'react-dom', 'react-scripts'], + noNativeIDE: true, + duplicates: true, + }); + process.exit(0); + } console.error('Please specify the project directory:'); console.log( ` ${chalk.cyan(program.name())} ${chalk.green('')}` @@ -133,10 +149,11 @@ createApp( projectName, program.verbose, program.scriptsVersion, + program.useNpm, hiddenProgram.internalTestingTemplate ); -function createApp(name, verbose, version, template) { +function createApp(name, verbose, version, useNpm, template) { const root = path.resolve(name); const appName = path.basename(root); @@ -158,8 +175,13 @@ function createApp(name, verbose, version, template) { path.join(root, 'package.json'), JSON.stringify(packageJson, null, 2) ); + + const useYarn = useNpm ? false : shouldUseYarn(); const originalDirectory = process.cwd(); process.chdir(root); + if (!useYarn && !checkThatNpmCanReadCwd()) { + process.exit(1); + } if (!semver.satisfies(process.version, '>=6.0.0')) { console.log( @@ -172,7 +194,6 @@ function createApp(name, verbose, version, template) { version = 'react-scripts@0.9.x'; } - const useYarn = shouldUseYarn(); if (!useYarn) { const npmInfo = checkNpmVersion(); if (!npmInfo.hasMinNpm) { @@ -200,7 +221,7 @@ function shouldUseYarn() { } } -function install(useYarn, dependencies, verbose, isOnline) { +function install(root, useYarn, dependencies, verbose, isOnline) { return new Promise((resolve, reject) => { let command; let args; @@ -212,6 +233,14 @@ function install(useYarn, dependencies, verbose, isOnline) { } [].push.apply(args, dependencies); + // Explicitly set cwd() to work around issues like + // https://github.com/facebookincubator/create-react-app/issues/3326. + // Unfortunately we can only do this for Yarn because npm support for + // equivalent --prefix flag doesn't help with this issue. + // This is why for npm, we run checkThatNpmCanReadCwd() early instead. + args.push('--cwd'); + args.push(root); + if (!isOnline) { console.log(chalk.yellow('You appear to be offline.')); console.log(chalk.yellow('Falling back to the local Yarn cache.')); @@ -254,7 +283,7 @@ function run( template, useYarn ) { - const packageToInstall = getInstallPackage(version); + const packageToInstall = getInstallPackage(version, originalDirectory); const allDependencies = ['react', 'react-dom', packageToInstall]; console.log('Installing packages. This might take a couple of minutes.'); @@ -275,7 +304,7 @@ function run( ); console.log(); - return install(useYarn, allDependencies, verbose, isOnline).then( + return install(root, useYarn, allDependencies, verbose, isOnline).then( () => packageName ); }) @@ -351,11 +380,16 @@ function run( }); } -function getInstallPackage(version) { +function getInstallPackage(version, originalDirectory) { let packageToInstall = 'react-scripts'; const validSemver = semver.valid(version); if (validSemver) { packageToInstall += `@${validSemver}`; + } else if (version && version.match(/^file:/)) { + packageToInstall = `file:${path.resolve( + originalDirectory, + version.match(/^file:(.*)?$/)[1] + )}`; } else if (version) { // for tar.gz or alternative paths packageToInstall = version; @@ -403,7 +437,7 @@ function extractStream(stream, dest) { // Extract package name from tarball url or path. function getPackageName(installPackage) { - if (installPackage.indexOf('.tgz') > -1) { + if (installPackage.match(/^.+\.(tgz|tar\.gz)$/)) { return getTemporaryDirectory() .then(obj => { let stream; @@ -426,7 +460,7 @@ function getPackageName(installPackage) { `Could not extract the package name from the archive: ${err.message}` ); const assumedProjectName = installPackage.match( - /^.+\/(.+?)(?:-\d+.+)?\.tgz$/ + /^.+\/(.+?)(?:-\d+.+)?\.(tgz|tar\.gz)$/ )[1]; console.log( `Based on the filename, assuming it is "${chalk.cyan( @@ -445,6 +479,10 @@ function getPackageName(installPackage) { return Promise.resolve( installPackage.charAt(0) + installPackage.substr(1).split('@')[0] ); + } else if (installPackage.match(/^file:/)) { + const installPackagePath = installPackage.match(/^file:(.*)?$/)[1]; + const installPackageJson = require(path.join(installPackagePath, 'package.json')); + return Promise.resolve(installPackageJson.name); } return Promise.resolve(installPackage); } @@ -581,6 +619,12 @@ function isSafeToCreateProjectIn(root, name) { '.hg', '.hgignore', '.hgcheck', + '.npmignore', + 'mkdocs.yml', + 'docs', + '.travis.yml', + '.gitlab-ci.yml', + '.gitattributes', ]; console.log(); @@ -606,6 +650,82 @@ function isSafeToCreateProjectIn(root, name) { return false; } +function getProxy() { + if (process.env.https_proxy) { + return process.env.https_proxy; + } else { + try { + // Trying to read https-proxy from .npmrc + let httpsProxy = execSync('npm config get https-proxy') + .toString() + .trim(); + return httpsProxy !== 'null' ? httpsProxy : undefined; + } catch (e) { + return; + } + } +} +function checkThatNpmCanReadCwd() { + const cwd = process.cwd(); + let childOutput = null; + try { + // Note: intentionally using spawn over exec since + // the problem doesn't reproduce otherwise. + // `npm config list` is the only reliable way I could find + // to reproduce the wrong path. Just printing process.cwd() + // in a Node process was not enough. + childOutput = spawn.sync('npm', ['config', 'list']).output.join(''); + } catch (err) { + // Something went wrong spawning node. + // Not great, but it means we can't do this check. + // We might fail later on, but let's continue. + return true; + } + if (typeof childOutput !== 'string') { + return true; + } + const lines = childOutput.split('\n'); + // `npm config list` output includes the following line: + // "; cwd = C:\path\to\current\dir" (unquoted) + // I couldn't find an easier way to get it. + const prefix = '; cwd = '; + const line = lines.find(line => line.indexOf(prefix) === 0); + if (typeof line !== 'string') { + // Fail gracefully. They could remove it. + return true; + } + const npmCWD = line.substring(prefix.length); + if (npmCWD === cwd) { + return true; + } + console.error( + chalk.red( + `Could not start an npm process in the right directory.\n\n` + + `The current directory is: ${chalk.bold(cwd)}\n` + + `However, a newly started npm process runs in: ${chalk.bold( + npmCWD + )}\n\n` + + `This is probably caused by a misconfigured system terminal shell.` + ) + ); + if (process.platform === 'win32') { + console.error( + chalk.red(`On Windows, this can usually be fixed by running:\n\n`) + + ` ${chalk.cyan( + 'reg' + )} delete "HKCU\\Software\\Microsoft\\Command Processor" /v AutoRun /f\n` + + ` ${chalk.cyan( + 'reg' + )} delete "HKLM\\Software\\Microsoft\\Command Processor" /v AutoRun /f\n\n` + + chalk.red(`Try to run the above two lines in the terminal.\n`) + + chalk.red( + `To learn more about this problem, read: https://blogs.msdn.microsoft.com/oldnewthing/20071121-00/?p=24433/` + ) + ); + } + return false; +} + function checkIfOnline(useYarn) { if (!useYarn) { // Don't ping the Yarn registry. @@ -615,10 +735,11 @@ function checkIfOnline(useYarn) { return new Promise(resolve => { dns.lookup('registry.yarnpkg.com', err => { - if (err != null && process.env.https_proxy) { + let proxy; + if (err != null && (proxy = getProxy())) { // If a proxy is defined, we likely can't resolve external hostnames. // Try to resolve the proxy name as an indication of a connection. - dns.lookup(url.parse(process.env.https_proxy).hostname, proxyErr => { + dns.lookup(url.parse(proxy).hostname, proxyErr => { resolve(proxyErr == null); }); } else { diff --git a/packages/create-react-app/package.json b/packages/create-react-app/package.json index 73400bb0339..4d8f4112ead 100644 --- a/packages/create-react-app/package.json +++ b/packages/create-react-app/package.json @@ -1,6 +1,6 @@ { "name": "create-react-app", - "version": "1.4.1", + "version": "1.5.2", "keywords": [ "react" ], @@ -24,6 +24,7 @@ "chalk": "^1.1.1", "commander": "^2.9.0", "cross-spawn": "^4.0.0", + "envinfo": "3.4.2", "fs-extra": "^1.0.0", "hyperquest": "^2.1.2", "semver": "^5.0.3", diff --git a/packages/eslint-config-react-app/README.md b/packages/eslint-config-react-app/README.md index 6918cda52e0..777b8f46e79 100644 --- a/packages/eslint-config-react-app/README.md +++ b/packages/eslint-config-react-app/README.md @@ -45,7 +45,7 @@ The following rules from the [eslint-plugin-jsx-a11y](https://github.com/evcohen - [aria-role](https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/aria-role.md) - [aria-unsupported-elements](https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/aria-unsupported-elements.md) - [heading-has-content](https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/heading-has-content.md) -- [href-no-hash](https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/href-no-hash.md) +- [href-no-hash](https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/v5.1.1/docs/rules/href-no-hash.md) - [iframe-has-title](https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/iframe-has-title.md) - [img-redundant-alt](https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/img-redundant-alt.md) - [no-access-key](https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/no-access-key.md) diff --git a/packages/eslint-config-react-app/index.js b/packages/eslint-config-react-app/index.js index adcdb86bc16..c7a619abd62 100644 --- a/packages/eslint-config-react-app/index.js +++ b/packages/eslint-config-react-app/index.js @@ -116,7 +116,7 @@ module.exports = { 'new-parens': 'warn', 'no-array-constructor': 'warn', 'no-caller': 'warn', - 'no-cond-assign': ['warn', 'always'], + 'no-cond-assign': ['warn', 'except-parens'], 'no-const-assign': 'warn', 'no-control-regex': 'warn', 'no-delete-var': 'warn', diff --git a/packages/eslint-config-react-app/package.json b/packages/eslint-config-react-app/package.json index a10ef679952..c13b0417c46 100644 --- a/packages/eslint-config-react-app/package.json +++ b/packages/eslint-config-react-app/package.json @@ -1,6 +1,6 @@ { "name": "eslint-config-react-app", - "version": "2.0.1", + "version": "2.1.0", "description": "ESLint configuration used by Create React App", "repository": "facebookincubator/create-react-app", "license": "MIT", diff --git a/packages/react-dev-utils/FileSizeReporter.js b/packages/react-dev-utils/FileSizeReporter.js index 01ce52c6b55..68aae411f12 100644 --- a/packages/react-dev-utils/FileSizeReporter.js +++ b/packages/react-dev-utils/FileSizeReporter.js @@ -25,21 +25,29 @@ function printFileSizesAfterBuild( ) { var root = previousSizeMap.root; var sizes = previousSizeMap.sizes; - var assets = webpackStats - .toJson() - .assets.filter(asset => /\.(js|css)$/.test(asset.name)) - .map(asset => { - var fileContents = fs.readFileSync(path.join(root, asset.name)); - var size = gzipSize(fileContents); - var previousSize = sizes[removeFileNameHash(root, asset.name)]; - var difference = getDifferenceLabel(size, previousSize); - return { - folder: path.join(path.basename(buildFolder), path.dirname(asset.name)), - name: path.basename(asset.name), - size: size, - sizeLabel: filesize(size) + (difference ? ' (' + difference + ')' : ''), - }; - }); + var assets = (webpackStats.stats || [webpackStats]) + .map(stats => + stats + .toJson() + .assets.filter(asset => /\.(js|css)$/.test(asset.name)) + .map(asset => { + var fileContents = fs.readFileSync(path.join(root, asset.name)); + var size = gzipSize(fileContents); + var previousSize = sizes[removeFileNameHash(root, asset.name)]; + var difference = getDifferenceLabel(size, previousSize); + return { + folder: path.join( + path.basename(buildFolder), + path.dirname(asset.name) + ), + name: path.basename(asset.name), + size: size, + sizeLabel: + filesize(size) + (difference ? ' (' + difference + ')' : '') + }; + }) + ) + .reduce((single, all) => all.concat(single), []); assets.sort((a, b) => b.size - a.size); var longestSizeLabelLength = Math.max.apply( null, diff --git a/packages/react-dev-utils/WebpackDevServerUtils.js b/packages/react-dev-utils/WebpackDevServerUtils.js index f19582e1227..4add9f9c1bc 100644 --- a/packages/react-dev-utils/WebpackDevServerUtils.js +++ b/packages/react-dev-utils/WebpackDevServerUtils.js @@ -317,15 +317,19 @@ function prepareProxy(proxy, appPublicFolder) { // For single page apps, we generally want to fallback to /index.html. // However we also want to respect `proxy` for API calls. // So if `proxy` is specified as a string, we need to decide which fallback to use. - // We use a heuristic: if request `accept`s text/html, we pick /index.html. + // We use a heuristic: We want to proxy all the requests that are not meant + // for static assets and as all the requests for static assets will be using + // `GET` method, we can proxy all non-`GET` requests. + // For `GET` requests, if request `accept`s text/html, we pick /index.html. // Modern browsers include text/html into `accept` header when navigating. // However API calls like `fetch()` won’t generally accept text/html. // If this heuristic doesn’t work well for you, use a custom `proxy` object. context: function(pathname, req) { return ( - mayProxy(pathname) && - req.headers.accept && - req.headers.accept.indexOf('text/html') === -1 + req.method !== 'GET' || + (mayProxy(pathname) && + req.headers.accept && + req.headers.accept.indexOf('text/html') === -1) ); }, onProxyReq: proxyReq => { diff --git a/packages/react-dev-utils/__tests__/.eslintrc b/packages/react-dev-utils/__tests__/.eslintrc new file mode 100644 index 00000000000..55f121d152d --- /dev/null +++ b/packages/react-dev-utils/__tests__/.eslintrc @@ -0,0 +1,5 @@ +{ + "env": { + "jest": true + } +} diff --git a/packages/react-dev-utils/__tests__/ignoredFiles.test.js b/packages/react-dev-utils/__tests__/ignoredFiles.test.js new file mode 100644 index 00000000000..6feed979797 --- /dev/null +++ b/packages/react-dev-utils/__tests__/ignoredFiles.test.js @@ -0,0 +1,55 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +'use strict'; + +const ignoredFiles = require('../ignoredFiles'); + +describe('ignore watch files regex', () => { + it('normal file', () => { + const appSrc = '/root/src/'; + const isIgnored = ignoredFiles(appSrc).test('/foo'); + const isIgnoredInSrc = ignoredFiles(appSrc).test('/root/src/foo'); + + expect(isIgnored).toBe(false); + expect(isIgnoredInSrc).toBe(false); + }); + + it('node modules', () => { + const appSrc = '/root/src/'; + const isIgnored = ignoredFiles(appSrc).test('/root/node_modules/foo'); + + expect(isIgnored).toBe(true); + }); + + it('node modules inside source directory', () => { + const appSrc = '/root/src/'; + const isIgnored = ignoredFiles(appSrc).test('/root/src/node_modules/foo'); + const isIgnoredMoreThanOneLevel = ignoredFiles(appSrc).test( + '/root/src/bar/node_modules/foo' + ); + + expect(isIgnored).toBe(false); + expect(isIgnoredMoreThanOneLevel).toBe(false); + }); + + it('path contains source directory', () => { + const appSrc = '/root/src/'; + const isIgnored = ignoredFiles(appSrc).test( + '/bar/root/src/node_modules/foo' + ); + + expect(isIgnored).toBe(true); + }); + + it('path starts with source directory', () => { + const appSrc = '/root/src/'; + const isIgnored = ignoredFiles(appSrc).test('/root/src2/node_modules/foo'); + + expect(isIgnored).toBe(true); + }); +}); diff --git a/packages/react-dev-utils/clearConsole.js b/packages/react-dev-utils/clearConsole.js index 6e3b3c9cefe..cb02af89237 100644 --- a/packages/react-dev-utils/clearConsole.js +++ b/packages/react-dev-utils/clearConsole.js @@ -8,9 +8,7 @@ 'use strict'; function clearConsole() { - process.stdout.write( - process.platform === 'win32' ? '\x1Bc' : '\x1B[2J\x1B[3J\x1B[H' - ); + process.stdout.write(process.platform === 'win32' ? '\x1B[2J\x1B[0f' : '\x1B[2J\x1B[3J\x1B[H'); } module.exports = clearConsole; diff --git a/packages/react-dev-utils/errorOverlayMiddleware.js b/packages/react-dev-utils/errorOverlayMiddleware.js index b756b0ef647..873b1994732 100644 --- a/packages/react-dev-utils/errorOverlayMiddleware.js +++ b/packages/react-dev-utils/errorOverlayMiddleware.js @@ -12,7 +12,9 @@ const launchEditorEndpoint = require('./launchEditorEndpoint'); module.exports = function createLaunchEditorMiddleware() { return function launchEditorMiddleware(req, res, next) { if (req.url.startsWith(launchEditorEndpoint)) { - launchEditor(req.query.fileName, req.query.lineNumber); + const lineNumber = parseInt(req.query.lineNumber, 10) || 1; + const colNumber = parseInt(req.query.colNumber, 10) || 1; + launchEditor(req.query.fileName, lineNumber, colNumber); res.end(); } else { next(); diff --git a/packages/react-dev-utils/getProcessForPort.js b/packages/react-dev-utils/getProcessForPort.js index 932f3e5bf4d..f9eda7752b4 100644 --- a/packages/react-dev-utils/getProcessForPort.js +++ b/packages/react-dev-utils/getProcessForPort.js @@ -58,7 +58,7 @@ function getProcessCommand(processId, processDirectory) { function getDirectoryOfProcessById(processId) { return execSync( - 'lsof -p ' + processId + ' | awk \'$4=="cwd" {print $9}\'', + 'lsof -p ' + processId + ' | awk \'$4=="cwd" {for (i=9; i<=NF; i++) printf "%s ", $i}\'', execOptions ).trim(); } diff --git a/packages/react-dev-utils/ignoredFiles.js b/packages/react-dev-utils/ignoredFiles.js new file mode 100644 index 00000000000..73a6e8bc5cf --- /dev/null +++ b/packages/react-dev-utils/ignoredFiles.js @@ -0,0 +1,20 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +'use strict'; + +const path = require('path'); +const escape = require('escape-string-regexp'); + +module.exports = function ignoredFiles(appSrc) { + return new RegExp( + `^(?!${escape( + path.normalize(appSrc + '/').replace(/[\\]+/g, '/') + )}).+/node_modules/`, + 'g' + ); +}; diff --git a/packages/react-dev-utils/launchEditor.js b/packages/react-dev-utils/launchEditor.js index ba16827e644..7ae94247b05 100644 --- a/packages/react-dev-utils/launchEditor.js +++ b/packages/react-dev-utils/launchEditor.js @@ -33,9 +33,13 @@ const COMMON_EDITORS_OSX = { '/Applications/Brackets.app/Contents/MacOS/Brackets': 'brackets', '/Applications/Sublime Text.app/Contents/MacOS/Sublime Text': '/Applications/Sublime Text.app/Contents/SharedSupport/bin/subl', + '/Applications/Sublime Text Dev.app/Contents/MacOS/Sublime Text': + '/Applications/Sublime Text Dev.app/Contents/SharedSupport/bin/subl', '/Applications/Sublime Text 2.app/Contents/MacOS/Sublime Text 2': '/Applications/Sublime Text 2.app/Contents/SharedSupport/bin/subl', '/Applications/Visual Studio Code.app/Contents/MacOS/Electron': 'code', + '/Applications/Visual Studio Code - Insiders.app/Contents/MacOS/Electron': + 'code-insiders', '/Applications/AppCode.app/Contents/MacOS/appcode': '/Applications/AppCode.app/Contents/MacOS/appcode', '/Applications/CLion.app/Contents/MacOS/clion': @@ -52,12 +56,15 @@ const COMMON_EDITORS_OSX = { '/Applications/RubyMine.app/Contents/MacOS/rubymine', '/Applications/WebStorm.app/Contents/MacOS/webstorm': '/Applications/WebStorm.app/Contents/MacOS/webstorm', + '/Applications/MacVim.app/Contents/MacOS/MacVim': + 'mvim', }; const COMMON_EDITORS_LINUX = { atom: 'atom', Brackets: 'brackets', code: 'code', + 'code-insiders': 'code-insiders', emacs: 'emacs', 'idea.sh': 'idea', 'phpstorm.sh': 'phpstorm', @@ -71,6 +78,7 @@ const COMMON_EDITORS_LINUX = { const COMMON_EDITORS_WIN = [ 'Brackets.exe', 'Code.exe', + 'Code - Insiders.exe', 'atom.exe', 'sublime_text.exe', 'notepad++.exe', @@ -88,6 +96,11 @@ const COMMON_EDITORS_WIN = [ 'webstorm64.exe', ]; +// Transpiled version of: /^[\p{L}0-9/.\-_\\]+$/u +// Non-transpiled version requires support for Unicode property regex. Allows +// alphanumeric characters, periods, dashes, slashes, and underscores. +const WINDOWS_FILE_NAME_WHITELIST = /^(?:[\x2D-9A-Z\\_a-z\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0560-\u0588\u05D0-\u05EA\u05EF-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u0860-\u086A\u08A0-\u08B4\u08B6-\u08BD\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u09FC\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C60\u0C61\u0C80\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D54-\u0D56\u0D5F-\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16F1-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1878\u1880-\u1884\u1887-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1C80-\u1C88\u1C90-\u1CBA\u1CBD-\u1CBF\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312F\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FEF\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788\uA78B-\uA7B9\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\uA8FE\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF2D-\uDF40\uDF42-\uDF49\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF]|\uD801[\uDC00-\uDC9D\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE35\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE4\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2\uDD00-\uDD23\uDF00-\uDF1C\uDF27\uDF30-\uDF45]|\uD804[\uDC03-\uDC37\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD44\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE2B\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61]|\uD805[\uDC00-\uDC34\uDC47-\uDC4A\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE80-\uDEAA\uDF00-\uDF1A]|\uD806[\uDC00-\uDC2B\uDCA0-\uDCDF\uDCFF\uDE00\uDE0B-\uDE32\uDE3A\uDE50\uDE5C-\uDE83\uDE86-\uDE89\uDE9D\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC2E\uDC40\uDC72-\uDC8F\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD30\uDD46\uDD60-\uDD65\uDD67\uDD68\uDD6A-\uDD89\uDD98\uDEE0-\uDEF2]|\uD808[\uDC00-\uDF99]|\uD809[\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDE40-\uDE7F\uDF00-\uDF44\uDF50\uDF93-\uDF9F\uDFE0\uDFE1]|\uD821[\uDC00-\uDFF1]|\uD822[\uDC00-\uDEF2]|\uD82C[\uDC00-\uDD1E\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB]|\uD83A[\uDC00-\uDCC4\uDD00-\uDD43]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D])+$/ + function addWorkspaceToArgumentsIfExists(args, workspace) { if (workspace) { args.unshift(workspace); @@ -95,7 +108,13 @@ function addWorkspaceToArgumentsIfExists(args, workspace) { return args; } -function getArgumentsForLineNumber(editor, fileName, lineNumber, workspace) { +function getArgumentsForLineNumber( + editor, + fileName, + lineNumber, + colNumber, + workspace +) { const editorBasename = path.basename(editor).replace(/\.(exe|cmd|bat)$/i, ''); switch (editorBasename) { case 'atom': @@ -104,25 +123,29 @@ function getArgumentsForLineNumber(editor, fileName, lineNumber, workspace) { case 'subl': case 'sublime': case 'sublime_text': + return [fileName + ':' + lineNumber + ':' + colNumber]; case 'wstorm': case 'charm': return [fileName + ':' + lineNumber]; case 'notepad++': - return ['-n' + lineNumber, fileName]; + return ['-n' + lineNumber, '-c' + colNumber, fileName]; case 'vim': case 'mvim': case 'joe': + return ['+' + lineNumber, fileName]; case 'emacs': case 'emacsclient': - return ['+' + lineNumber, fileName]; + return ['+' + lineNumber + ':' + colNumber, fileName]; case 'rmate': case 'mate': case 'mine': return ['--line', lineNumber, fileName]; case 'code': case 'Code': + case 'code-insiders': + case 'Code - Insiders': return addWorkspaceToArgumentsIfExists( - ['-g', fileName + ':' + lineNumber], + ['-g', fileName + ':' + lineNumber + ':' + colNumber], workspace ); case 'appcode': @@ -245,23 +268,35 @@ function printInstructions(fileName, errorMessage) { } let _childProcess = null; -function launchEditor(fileName, lineNumber) { +function launchEditor(fileName, lineNumber, colNumber) { if (!fs.existsSync(fileName)) { return; } // Sanitize lineNumber to prevent malicious use on win32 // via: https://github.com/nodejs/node/blob/c3bb4b1aa5e907d489619fb43d233c3336bfc03d/lib/child_process.js#L333 - if (lineNumber && isNaN(lineNumber)) { + // and it should be a positive integer + if (!(Number.isInteger(lineNumber) && lineNumber > 0)) { return; } + // colNumber is optional, but should be a positive integer too + // default is 1 + if (!(Number.isInteger(colNumber) && colNumber > 0)) { + colNumber = 1; + } + let [editor, ...args] = guessEditor(); + if (!editor) { printInstructions(fileName, null); return; } + if (editor.toLowerCase() === 'none') { + return; + } + if ( process.platform === 'linux' && fileName.startsWith('/mnt/') && @@ -276,10 +311,39 @@ function launchEditor(fileName, lineNumber) { fileName = path.relative('', fileName); } + // cmd.exe on Windows is vulnerable to RCE attacks given a file name of the + // form "C:\Users\myusername\Downloads\& curl 172.21.93.52". Use a whitelist + // to validate user-provided file names. This doesn't cover the entire range + // of valid file names but should cover almost all of them in practice. + if ( + process.platform === 'win32' && + !WINDOWS_FILE_NAME_WHITELIST.test(fileName.trim()) + ) { + console.log(); + console.log( + chalk.red('Could not open ' + path.basename(fileName) + ' in the editor.') + ); + console.log(); + console.log( + 'When running on Windows, file names are checked against a whitelist ' + + 'to protect against remote code execution attacks. File names may ' + + 'consist only of alphanumeric characters (all languages), periods, ' + + 'dashes, slashes, and underscores.' + ); + console.log(); + return; + } + let workspace = null; if (lineNumber) { args = args.concat( - getArgumentsForLineNumber(editor, fileName, lineNumber, workspace) + getArgumentsForLineNumber( + editor, + fileName, + lineNumber, + colNumber, + workspace + ) ); } else { args.push(fileName); diff --git a/packages/react-dev-utils/package.json b/packages/react-dev-utils/package.json index 04daa59d5ac..a0cd7503ae5 100644 --- a/packages/react-dev-utils/package.json +++ b/packages/react-dev-utils/package.json @@ -1,6 +1,6 @@ { "name": "react-dev-utils", - "version": "4.1.0", + "version": "5.0.2", "description": "Webpack utilities used by Create React App", "repository": "facebookincubator/create-react-app", "license": "MIT", @@ -20,6 +20,7 @@ "printBuildError.js", "formatWebpackMessages.js", "getProcessForPort.js", + "ignoredFiles.js", "inquirer.js", "InterpolateHtmlPlugin.js", "launchEditor.js", @@ -34,23 +35,29 @@ "webpackHotDevClient.js" ], "dependencies": { - "address": "1.0.2", - "babel-code-frame": "6.22.0", + "address": "1.0.3", + "babel-code-frame": "6.26.0", "chalk": "1.1.3", "cross-spawn": "5.1.0", - "detect-port-alt": "1.1.3", + "detect-port-alt": "1.1.6", "escape-string-regexp": "1.0.5", - "filesize": "3.5.10", + "filesize": "3.5.11", "global-modules": "1.0.0", "gzip-size": "3.0.0", - "inquirer": "3.2.1", + "inquirer": "3.3.0", "is-root": "1.0.0", - "opn": "5.1.0", - "react-error-overlay": "^2.0.2", + "opn": "5.2.0", + "react-error-overlay": "^4.0.1", "recursive-readdir": "2.2.1", "shell-quote": "1.6.1", - "sockjs-client": "1.1.4", + "sockjs-client": "1.1.5", "strip-ansi": "3.0.1", "text-table": "0.2.0" + }, + "devDependencies": { + "jest": "20.0.4" + }, + "scripts": { + "test": "jest" } } diff --git a/packages/react-dev-utils/printHostingInstructions.js b/packages/react-dev-utils/printHostingInstructions.js index 4a080dba2c9..4f761dfb0d0 100644 --- a/packages/react-dev-utils/printHostingInstructions.js +++ b/packages/react-dev-utils/printHostingInstructions.js @@ -19,118 +19,108 @@ function printHostingInstructions( buildFolder, useYarn ) { - const publicPathname = url.parse(publicPath).pathname; - if (publicUrl && publicUrl.indexOf('.github.io/') !== -1) { + if (publicUrl && publicUrl.includes('.github.io/')) { // "homepage": "http://user.github.io/project" + const publicPathname = url.parse(publicPath).pathname; + const hasDeployScript = typeof appPackage.scripts.deploy !== 'undefined'; + printBaseMessage(buildFolder, publicPathname); + + printDeployInstructions(publicUrl, hasDeployScript, useYarn); + } else if (publicPath !== '/') { + // "homepage": "http://mywebsite.com/project" + printBaseMessage(buildFolder, publicPath); + } else { + // "homepage": "http://mywebsite.com" + // or no homepage + printBaseMessage(buildFolder, publicUrl); + + printStaticServerInstructions(buildFolder, useYarn); + } + console.log(); + console.log('Find out more about deployment here:'); + console.log(); + console.log(` ${chalk.yellow('http://bit.ly/2vY88Kr')}`); + console.log(); +} + +function printBaseMessage(buildFolder, hostingLocation) { + console.log( + `The project was built assuming it is hosted at ${chalk.green( + hostingLocation || 'the server root' + )}.` + ); + console.log( + `You can control this with the ${chalk.green( + 'homepage' + )} field in your ${chalk.cyan('package.json')}.` + ); + + if (!hostingLocation) { + console.log('For example, add this to build it for GitHub Pages:'); + console.log(); + 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')}.` + ` ${chalk.green('"homepage"')} ${chalk.cyan(':')} ${chalk.green( + '"http://myname.github.io/myapp"' + )}${chalk.cyan(',')}` ); - console.log(); - console.log(`The ${chalk.cyan('build')} folder is ready to be deployed.`); - 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(); - if (useYarn) { - console.log(` ${chalk.cyan('yarn')} add --dev gh-pages`); - } else { - console.log(` ${chalk.cyan('npm')} install --save-dev gh-pages`); - } - console.log(); - console.log( - `Add the following script in your ${chalk.cyan('package.json')}.` - ); - console.log(); - console.log(` ${chalk.dim('// ...')}`); - console.log(` ${chalk.yellow('"scripts"')}: {`); - console.log(` ${chalk.dim('// ...')}`); - 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:'); + } + console.log(); + console.log(`The ${chalk.cyan(buildFolder)} folder is ready to be deployed.`); +} + +function printDeployInstructions(publicUrl, hasDeployScript, useYarn) { + console.log(`To publish it at ${chalk.green(publicUrl)}, run:`); + console.log(); + + // If script deploy has been added to package.json, skip the instructions + if (!hasDeployScript) { + if (useYarn) { + console.log(` ${chalk.cyan('yarn')} add --dev gh-pages`); + } else { + console.log(` ${chalk.cyan('npm')} install --save-dev gh-pages`); } console.log(); - console.log(` ${chalk.cyan(useYarn ? 'yarn' : 'npm')} run deploy`); + + console.log( + `Add the following script in your ${chalk.cyan('package.json')}.` + ); console.log(); - } else if (publicPath !== '/') { - // "homepage": "http://mywebsite.com/project" + + console.log(` ${chalk.dim('// ...')}`); + console.log(` ${chalk.yellow('"scripts"')}: {`); + console.log(` ${chalk.dim('// ...')}`); console.log( - `The project was built assuming it is hosted at ${chalk.green( - publicPath - )}.` + ` ${chalk.yellow('"predeploy"')}: ${chalk.yellow( + '"npm run build",' + )}` ); console.log( - `You can control this with the ${chalk.green( - 'homepage' - )} field in your ${chalk.cyan('package.json')}.` + ` ${chalk.yellow('"deploy"')}: ${chalk.yellow( + '"gh-pages -d build"' + )}` ); + console.log(' }'); console.log(); - console.log(`The ${chalk.cyan('build')} folder is ready to be deployed.`); + + console.log('Then run:'); console.log(); - } else { - 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(); + } + console.log(` ${chalk.cyan(useYarn ? 'yarn' : 'npm')} run deploy`); +} + +function printStaticServerInstructions(buildFolder, useYarn) { + console.log('You may serve it with a static server:'); + console.log(); + + if (!fs.existsSync(`${globalModules}/serve`)) { + if (useYarn) { + console.log(` ${chalk.cyan('yarn')} global add serve`); } 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(); - console.log( - ` ${chalk.green('"homepage"')} ${chalk.cyan(':')} ${chalk.green( - '"http://myname.github.io/myapp"' - )}${chalk.cyan(',')}` - ); - console.log(); + console.log(` ${chalk.cyan('npm')} install -g serve`); } - console.log( - `The ${chalk.cyan(buildFolder)} folder is ready to be deployed.` - ); - console.log('You may serve it with a static server:'); - console.log(); - if (!fs.existsSync(`${globalModules}/serve`)) { - if (useYarn) { - console.log(` ${chalk.cyan('yarn')} global add serve`); - } else { - console.log(` ${chalk.cyan('npm')} install -g serve`); - } - } - console.log(` ${chalk.cyan('serve')} -s ${buildFolder}`); - console.log(); } + console.log(` ${chalk.cyan('serve')} -s ${buildFolder}`); } module.exports = printHostingInstructions; diff --git a/packages/react-dev-utils/webpackHotDevClient.js b/packages/react-dev-utils/webpackHotDevClient.js index 611fc6ba042..cbbc80029ae 100644 --- a/packages/react-dev-utils/webpackHotDevClient.js +++ b/packages/react-dev-utils/webpackHotDevClient.js @@ -23,6 +23,19 @@ var launchEditorEndpoint = require('./launchEditorEndpoint'); var formatWebpackMessages = require('./formatWebpackMessages'); var ErrorOverlay = require('react-error-overlay'); +ErrorOverlay.setEditorHandler(function editorHandler(errorLocation) { + // Keep this sync with errorOverlayMiddleware.js + fetch( + launchEditorEndpoint + + '?fileName=' + + window.encodeURIComponent(errorLocation.fileName) + + '&lineNumber=' + + window.encodeURIComponent(errorLocation.lineNumber || 1) + + '&colNumber=' + + window.encodeURIComponent(errorLocation.colNumber || 1) + ); +}); + // We need to keep track of if there has been a runtime error. // Essentially, we cannot guarantee application state was not corrupted by the // runtime error. To prevent confusing behavior, we forcibly reload the entire @@ -31,7 +44,6 @@ var ErrorOverlay = require('react-error-overlay'); // See https://github.com/facebookincubator/create-react-app/issues/3096 var hadRuntimeError = false; ErrorOverlay.startReportingRuntimeErrors({ - launchEditorEndpoint: launchEditorEndpoint, onError: function() { hadRuntimeError = true; }, diff --git a/packages/react-error-overlay/.flowconfig b/packages/react-error-overlay/.flowconfig index 8d7de784e29..c976167c2a9 100644 --- a/packages/react-error-overlay/.flowconfig +++ b/packages/react-error-overlay/.flowconfig @@ -1,9 +1,15 @@ -[ignore] -.*/node_modules/eslint-plugin-jsx-a11y/.* - [include] -src/**/*.js +/src/**/*.js + +[ignore] +.*/node_modules/.* +.*/.git/.* +.*/__test__/.* +.*/fixtures/.* [libs] +flow/ [options] +module.file_ext=.js +sharedmemory.hash_table_pow=19 diff --git a/packages/react-error-overlay/.gitattributes b/packages/react-error-overlay/.gitattributes new file mode 100644 index 00000000000..cbdcbbc258e --- /dev/null +++ b/packages/react-error-overlay/.gitattributes @@ -0,0 +1 @@ +*.js text eol=lf diff --git a/packages/react-error-overlay/build.js b/packages/react-error-overlay/build.js new file mode 100644 index 00000000000..592da141ffe --- /dev/null +++ b/packages/react-error-overlay/build.js @@ -0,0 +1,95 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +const webpack = require('webpack'); +const chalk = require('chalk'); +const webpackConfig = require('./webpack.config.js'); +const iframeWebpackConfig = require('./webpack.config.iframe.js'); +const rimraf = require('rimraf'); +const chokidar = require('chokidar'); + +const args = process.argv.slice(2); +const watchMode = args[0] === '--watch' || args[0] === '-w'; + +const isCI = + process.env.CI && + (typeof process.env.CI !== 'string' || + process.env.CI.toLowerCase() !== 'false'); + +function build(config, name, callback) { + console.log(chalk.cyan('Compiling ' + name)); + webpack(config).run((error, stats) => { + if (error) { + console.log(chalk.red('Failed to compile.')); + console.log(error.message || error); + console.log(); + } + + if (stats.compilation.errors.length) { + console.log(chalk.red('Failed to compile.')); + console.log(stats.toString({ all: false, errors: true })); + } + + if (stats.compilation.warnings.length) { + console.log(chalk.yellow('Compiled with warnings.')); + console.log(stats.toString({ all: false, warnings: true })); + } + + // Fail the build if running in a CI server + if ( + error || + stats.compilation.errors.length || + stats.compilation.warnings.length + ) { + isCI && process.exit(1); + return; + } + + console.log( + stats.toString({ colors: true, modules: false, version: false }) + ); + console.log(); + + callback(stats); + }); +} + +function runBuildSteps() { + build(iframeWebpackConfig, 'iframeScript.js', () => { + build(webpackConfig, 'index.js', () => { + console.log(chalk.bold.green('Compiled successfully!\n\n')); + }); + }); +} + +function setupWatch() { + const watcher = chokidar.watch('./src', { + ignoreInitial: true, + }); + + watcher.on('change', runBuildSteps); + watcher.on('add', runBuildSteps); + + watcher.on('ready', () => { + runBuildSteps(); + }); + + process.on('SIGINT', function() { + watcher.close(); + process.exit(0); + }); + + watcher.on('error', error => { + console.error('Watcher failure', error); + process.exit(1); + }); +} + +// Clean up lib folder +rimraf('lib/', () => { + console.log('Cleaned up the lib folder.\n'); + watchMode ? setupWatch() : runBuildSteps(); +}); diff --git a/packages/react-error-overlay/flow/env.js b/packages/react-error-overlay/flow/env.js new file mode 100644 index 00000000000..12b151f5e4b --- /dev/null +++ b/packages/react-error-overlay/flow/env.js @@ -0,0 +1,19 @@ +declare module 'anser' { + declare module.exports: any; +} + +declare module 'babel-code-frame' { + declare module.exports: any; +} + +declare module 'html-entities' { + declare module.exports: any; +} + +declare module 'settle-promise' { + declare module.exports: any; +} + +declare module 'source-map' { + declare module.exports: any; +} diff --git a/packages/react-error-overlay/package.json b/packages/react-error-overlay/package.json index 7640d1c5d92..06354daf1b6 100644 --- a/packages/react-error-overlay/package.json +++ b/packages/react-error-overlay/package.json @@ -1,14 +1,14 @@ { "name": "react-error-overlay", - "version": "2.0.2", + "version": "4.0.1", "description": "An overlay for displaying stack frames.", "main": "lib/index.js", "scripts": { "prepublishOnly": "npm run build:prod && npm test", - "start": "rimraf lib/ && cross-env NODE_ENV=development npm run build -- --watch", - "test": "flow && jest", - "build": "rimraf lib/ && babel src/ -d lib/", - "build:prod": "rimraf lib/ && cross-env NODE_ENV=production babel src/ -d lib/" + "start": "cross-env NODE_ENV=development node build.js --watch", + "test": "cross-env NODE_ENV=test jest", + "build": "cross-env NODE_ENV=development node build.js", + "build:prod": "cross-env NODE_ENV=production node build.js" }, "repository": "facebookincubator/create-react-app", "license": "MIT", @@ -27,34 +27,38 @@ ], "author": "Joe Haddad ", "files": [ - "lib/", - "middleware.js" + "lib/index.js" ], - "dependencies": { - "anser": "1.4.1", - "babel-code-frame": "6.22.0", - "babel-runtime": "6.26.0", - "html-entities": "1.2.1", - "react": "^15 || ^16", - "react-dom": "^15 || ^16", - "settle-promise": "1.0.0", - "source-map": "0.5.6" - }, "devDependencies": { - "babel-cli": "6.24.1", + "anser": "1.4.4", + "babel-code-frame": "6.26.0", + "babel-core": "^6.26.0", "babel-eslint": "7.2.3", - "babel-preset-react-app": "^3.0.3", + "babel-loader": "^7.1.2", + "babel-preset-react-app": "^3.1.1", + "babel-runtime": "6.26.0", + "chalk": "^2.1.0", + "chokidar": "^1.7.0", "cross-env": "5.0.5", "eslint": "4.4.1", - "eslint-config-react-app": "^2.0.1", + "eslint-config-react-app": "^2.1.0", "eslint-plugin-flowtype": "2.35.0", "eslint-plugin-import": "2.7.0", "eslint-plugin-jsx-a11y": "5.1.1", "eslint-plugin-react": "7.1.0", - "flow-bin": "^0.54.0", + "flow-bin": "^0.63.1", + "html-entities": "1.2.1", "jest": "20.0.4", "jest-fetch-mock": "1.2.1", - "rimraf": "^2.6.1" + "object-assign": "4.1.1", + "promise": "8.0.1", + "raw-loader": "^0.5.1", + "react": "^16.0.0", + "react-dom": "^16.0.0", + "rimraf": "^2.6.1", + "settle-promise": "1.0.0", + "source-map": "0.5.6", + "webpack": "^3.6.0" }, "jest": { "setupFiles": [ diff --git a/packages/react-error-overlay/src/containers/CompileErrorContainer.js b/packages/react-error-overlay/src/containers/CompileErrorContainer.js index 5d491a9d47f..9d1e399fd10 100644 --- a/packages/react-error-overlay/src/containers/CompileErrorContainer.js +++ b/packages/react-error-overlay/src/containers/CompileErrorContainer.js @@ -12,18 +12,34 @@ import Footer from '../components/Footer'; import Header from '../components/Header'; import CodeBlock from '../components/CodeBlock'; import generateAnsiHTML from '../utils/generateAnsiHTML'; +import parseCompileError from '../utils/parseCompileError'; +import type { ErrorLocation } from '../utils/parseCompileError'; + +const codeAnchorStyle = { + cursor: 'pointer', +}; type Props = {| error: string, + editorHandler: (errorLoc: ErrorLocation) => void, |}; class CompileErrorContainer extends PureComponent { render() { - const { error } = this.props; + const { error, editorHandler } = this.props; + const errLoc: ?ErrorLocation = parseCompileError(error); + const canOpenInEditor = errLoc !== null && editorHandler !== null; return (
- + editorHandler(errLoc) : null + } + style={canOpenInEditor ? codeAnchorStyle : null} + > + +