diff --git a/.eslintignore b/.eslintignore
new file mode 100644
index 00000000000..4eaf46c6d7d
--- /dev/null
+++ b/.eslintignore
@@ -0,0 +1,5 @@
+node_modules/
+build
+my-app*
+packages/react-scripts/template
+packages/react-scripts/fixtures
diff --git a/.eslintrc b/.eslintrc
index 5e603ecd193..d4e6d47749e 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -1,3 +1,16 @@
{
- "extends": "react-app"
+ "extends": "eslint:recommended",
+ "env": {
+ "browser": true,
+ "commonjs": true,
+ "node": true,
+ "es6": true
+ },
+ "parserOptions": {
+ "ecmaVersion": 6
+ },
+ "rules": {
+ "no-console": "off",
+ "strict": ["error", "global"]
+ }
}
diff --git a/.gitignore b/.gitignore
index 0aa0ed568ba..79ce88915d7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,5 @@
+.idea/
+.vscode/
node_modules/
build
.DS_Store
diff --git a/.travis.yml b/.travis.yml
index aa61d9eb976..fa2c7d8b364 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -3,11 +3,13 @@ language: node_js
node_js:
- 4
- 6
+ - 7
cache:
directories:
- node_modules
- packages/create-react-app/node_modules
- packages/react-scripts/node_modules
+install: true
script:
- 'if [ $TEST_SUITE = "simple" ]; then tasks/e2e-simple.sh; fi'
- 'if [ $TEST_SUITE = "installs" ]; then tasks/e2e-installs.sh; fi'
@@ -21,5 +23,7 @@ env:
- TEST_SUITE=kitchensink
matrix:
include:
+ - node_js: 0.10
+ env: TEST_SUITE=simple
- node_js: 6
env: USE_YARN=yes TEST_SUITE=simple
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5d4225d0755..b96fd76db7d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,337 @@
+## 0.9.5 (March 9, 2017)
+
+#### :bug: Bug Fix
+
+* `react-scripts`
+
+ * [#1783](https://github.com/facebookincubator/create-react-app/pull/1783) **Work around Node 7.7.2 bug that crashes `npm start`.** ([@ryanwalters](https://github.com/ryanwalters))
+
+#### :nail_care: Enhancement
+
+* `eslint-config-react-app`
+
+ * [#1773](https://github.com/facebookincubator/create-react-app/pull/1773) Remove `guard-for-in` lint rule. ([@spicyj](https://github.com/spicyj))
+
+* `react-scripts`
+ * [#1760](https://github.com/facebookincubator/create-react-app/pull/1760) Suggest `serve` for running in production. ([@leo](https://github.com/leo))
+ * [#1747](https://github.com/facebookincubator/create-react-app/pull/1747) Display `yarn` instead of `yarnpkg` when creating a new app. ([@lpalmes](https://github.com/lpalmes))
+
+#### :memo: Documentation
+
+* `react-scripts`
+
+ * [#1756](https://github.com/facebookincubator/create-react-app/pull/1756) Add Yarn steps for adding Flow. ([@zertosh](https://github.com/zertosh))
+
+#### :house: Internal
+
+* `babel-preset-react-app`
+
+ * [#1742](https://github.com/facebookincubator/create-react-app/pull/1742) Switch to `babel-preset-env` to remove the deprecation warning. ([@Timer](https://github.com/Timer))
+
+#### Committers: 6
+- Andres Suarez ([zertosh](https://github.com/zertosh))
+- Ben Alpert ([spicyj](https://github.com/spicyj))
+- Joe Haddad ([Timer](https://github.com/Timer))
+- Leo Lamprecht ([leo](https://github.com/leo))
+- Lorenzo Palmes ([lpalmes](https://github.com/lpalmes))
+- Ryan Walters ([ryanwalters](https://github.com/ryanwalters))
+
+### Migrating from 0.9.4 to 0.9.5
+
+Inside any created project that has not been ejected, run:
+
+```
+npm install --save-dev --save-exact react-scripts@0.9.5
+```
+
+## 0.9.4 (March 6, 2017)
+
+#### :bug: Bug Fix
+* `create-react-app`
+
+ * [#1706](https://github.com/facebookincubator/create-react-app/pull/1706) Extract compressed package for package name. ([@Timer](https://github.com/Timer))
+
+ You may now specify a scoped package for `--scripts-version` and obtain a working installation.
+
+ * [#1695](https://github.com/facebookincubator/create-react-app/pull/1695) Print why installation was aborted. ([@tgig](https://github.com/tgig))
+
+* `react-scripts`
+
+ * [#1727](https://github.com/facebookincubator/create-react-app/pull/1727) Fix ejecting from a scoped fork. ([@gaearon](https://github.com/gaearon))
+
+ Ejecting now works within a scoped fork.
+
+ * [#1721](https://github.com/facebookincubator/create-react-app/pull/1721) Fix hot reloading for WebpackDevServer after eject. ([@gaearon](https://github.com/gaearon))
+
+* `react-dev-utils`
+
+ * [#1690](https://github.com/facebookincubator/create-react-app/pull/1690) Fix `openBrowser()` when `BROWSER=open` on macOS. ([@bpierre](https://github.com/bpierre))
+
+ * [#1696](https://github.com/facebookincubator/create-react-app/pull/1696) Improve reliability of port detection. ([@chrisdrackett](https://github.com/chrisdrackett))
+
+#### :nail_care: Enhancement
+* `eslint-config-react-app`, `react-scripts`
+
+ * [#1705](https://github.com/facebookincubator/create-react-app/pull/1705) Add support for `ignoreRestSiblings` in `no-unused-vars`. ([@chrisdrackett](https://github.com/chrisdrackett))
+
+ Linter no longer warns when using rest properties to remove variables from an object.
+
+ * [#1542](https://github.com/facebookincubator/create-react-app/pull/1542) Bump `jsx-a11y` version. ([@bondz](https://github.com/bondz))
+
+* `react-dev-utils`, `react-scripts`
+
+ * [#1726](https://github.com/facebookincubator/create-react-app/pull/1726) Extract generic build functions into `react-dev-utils`. ([@viankakrisna](https://github.com/viankakrisna))
+
+* Other
+
+ * [#1402](https://github.com/facebookincubator/create-react-app/pull/1402) Stub `package.json` for e2e test. ([@matoilic](https://github.com/matoilic))
+
+#### :memo: Documentation
+* `react-scripts`
+ * [#1710](https://github.com/facebookincubator/create-react-app/pull/1710) Update now.sh deployment instructions. ([@replaid](https://github.com/replaid))
+ * [#1717](https://github.com/facebookincubator/create-react-app/pull/1717) Add docs for Apache client side routing. ([@viankakrisna](https://github.com/viankakrisna))
+ * [#1698](https://github.com/facebookincubator/create-react-app/pull/1698) Suggest to use `.env` for enabling polling mode. ([@gaearon](https://github.com/gaearon))
+ * [#1687](https://github.com/facebookincubator/create-react-app/pull/1687) Fixed missing `--recursive` flag in first `npm run watch-css` command. ([@mklemme](https://github.com/mklemme))
+
+#### :house: Internal
+* `react-scripts`
+ * [#1736](https://github.com/facebookincubator/create-react-app/pull/1736) Fix eject for linked react-scripts. ([@tuchk4](https://github.com/tuchk4))
+ * [#1741](https://github.com/facebookincubator/create-react-app/pull/1741) Fix internal linting setup. ([@gaearon](https://github.com/gaearon))
+ * [#1730](https://github.com/facebookincubator/create-react-app/pull/1730) Fix Node 4 e2e tests. ([@Timer](https://github.com/Timer))
+* `eslint-config-react-app`
+ * [#1740](https://github.com/facebookincubator/create-react-app/pull/1740) Relax ESLint config peerDependency. ([@gaearon](https://github.com/gaearon))
+* `eslint-config-react-app`, `react-dev-utils`, `react-scripts`
+ * [#1729](https://github.com/facebookincubator/create-react-app/pull/1729) Lint internal scripts with `eslint:recommended`. ([@gaearon](https://github.com/gaearon))
+* `react-dev-utils`
+ * [#1724](https://github.com/facebookincubator/create-react-app/pull/1724) Don't use ES6 in a file that should run on Node 4. ([@gaearon](https://github.com/gaearon))
+* Other
+ * [#1723](https://github.com/facebookincubator/create-react-app/pull/1723) Skip AppVeyor CI builds for Markdown changes. ([@gaearon](https://github.com/gaearon))
+ * [#1707](https://github.com/facebookincubator/create-react-app/pull/1707) Add double quotes to escape spaces in paths in e2e. ([@viankakrisna](https://github.com/viankakrisna))
+ * [#1688](https://github.com/facebookincubator/create-react-app/pull/1688) Upgrade `lerna` version. ([@viankakrisna](https://github.com/viankakrisna))
+
+#### Committers: 11
+- Ade Viankakrisna Fadlil ([viankakrisna](https://github.com/viankakrisna))
+- Bond ([bondz](https://github.com/bondz))
+- Chris Drackett ([chrisdrackett](https://github.com/chrisdrackett))
+- Dan Abramov ([gaearon](https://github.com/gaearon))
+- Joe Haddad ([Timer](https://github.com/Timer))
+- Mato Ilic ([matoilic](https://github.com/matoilic))
+- Myk Klemme ([mklemme](https://github.com/mklemme))
+- Pierre Bertet ([bpierre](https://github.com/bpierre))
+- Ryan Platte ([replaid](https://github.com/replaid))
+- Travis Giggy ([tgig](https://github.com/tgig))
+- Valerii Sorokobatko ([tuchk4](https://github.com/tuchk4))
+
+### Migrating from 0.9.3 to 0.9.4
+
+Inside any created project that has not been ejected, run:
+
+```
+npm install --save-dev --save-exact react-scripts@0.9.4
+```
+
+You may also optionally update the global command-line utility for scoped package support:
+
+```
+npm install -g create-react-app@1.3.0
+```
+
+## 0.9.3 (February 28, 2017)
+
+#### :rocket: New Feature
+* `create-react-app`
+ * [#1423](https://github.com/facebookincubator/create-react-app/pull/1423) **Fall back to Yarn offline cache when creating a new project.** ([@voxsim](https://github.com/voxsim))
+
+ If you are using Yarn, and you have created at least one app previously, Create React App now works offline.
+
+
+
+#### :bug: Bug Fix
+
+* `react-scripts`
+
+ * [#1665](https://github.com/facebookincubator/create-react-app/pull/1665) Temporarily disable ESLint caching because of a bug. ([@gaearon](https://github.com/gaearon))
+
+* `create-react-app`
+ * [#1675](https://github.com/facebookincubator/create-react-app/pull/1675) Delete project folder on failed installation on Windows. ([@johann-sonntagbauer](https://github.com/johann-sonntagbauer))
+ * [#1662](https://github.com/facebookincubator/create-react-app/pull/1662) Validate project name before creating a project. ([@johann-sonntagbauer](https://github.com/johann-sonntagbauer))
+ * [#1669](https://github.com/facebookincubator/create-react-app/pull/1669) Make sure React dependencies aren’t pinned in new projects. ([@johann-sonntagbauer](https://github.com/johann-sonntagbauer))
+
+#### :nail_care: Enhancement
+* `react-scripts`
+
+ * [#1677](https://github.com/facebookincubator/create-react-app/pull/1677) Add `X-FORWARDED` headers for proxy requests. ([@johann-sonntagbauer](https://github.com/johann-sonntagbauer))
+
+#### :memo: Documentation
+* `react-scripts`
+
+ * [#1657](https://github.com/facebookincubator/create-react-app/pull/1657) Tweak the Visual Studio Code debugging guide. ([@ryansully](https://github.com/ryansully))
+
+#### :house: Internal
+* End-to-end Tests
+
+ * [#1648](https://github.com/facebookincubator/create-react-app/pull/1648) Add Windows CI tests for better stability. ([@Timer](https://github.com/Timer))
+
+#### Committers: 5
+- Dan Abramov ([gaearon](https://github.com/gaearon))
+- Joe Haddad ([Timer](https://github.com/Timer))
+- Johann Hubert Sonntagbauer ([johann-sonntagbauer](https://github.com/johann-sonntagbauer))
+- Ryan Sullivan ([ryansully](https://github.com/ryansully))
+- Simon Vocella ([voxsim](https://github.com/voxsim))
+
+### Migrating from 0.9.2 to 0.9.3
+
+Inside any created project that has not been ejected, run:
+
+```
+npm install --save-dev --save-exact react-scripts@0.9.3
+```
+
+You may also optionally update the global command-line utility for offline Yarn cache support:
+
+```
+npm install -g create-react-app@1.2.1
+```
+
+## 0.9.2 (February 26, 2017)
+
+#### :nail_care: Enhancement
+
+* `create-react-app`
+ * [#1253](https://github.com/facebookincubator/create-react-app/pull/1253) **Install time optimization.** ([@n3tr](https://github.com/n3tr))
+
+ React, ReactDOM, and `react-scripts` are now installed in the same install instead of two different installs. This reduces app creation time by a noticeable amount.
+
+ * [#1512](https://github.com/facebookincubator/create-react-app/pull/1512) **Graceful error handling.** ([@chitchu](https://github.com/chitchu))
+
+ If an error occurs while `create-react-app` is running, it will now clean up and not leave a broken project to reduce confusion.
+
+ * [#1193](https://github.com/facebookincubator/create-react-app/pull/1193) Suggest upgrading to NPM >= 3 for faster install times. ([@mobinni](https://github.com/mobinni))
+
+ * [#1603](https://github.com/facebookincubator/create-react-app/pull/1603) Allow app creation in a WebStorm project. ([@driquelme](https://github.com/driquelme))
+
+ * [#1570](https://github.com/facebookincubator/create-react-app/pull/1570) Allow git urls in `--scripts-version`. ([@tomconroy](https://github.com/tomconroy))
+
+* `react-scripts`
+ * [#1578](https://github.com/facebookincubator/create-react-app/pull/1578) Enable lint caching in development. ([@viankakrisna](https://github.com/viankakrisna))
+
+ * [#1478](https://github.com/facebookincubator/create-react-app/pull/1478) Update the build script message to show the correct port. ([@chyipin](https://github.com/chyipin))
+
+ * [#1567](https://github.com/facebookincubator/create-react-app/pull/1567) Remove .bin files after eject. ([@tuchk4](https://github.com/tuchk4))
+
+ * [#1560](https://github.com/facebookincubator/create-react-app/pull/1560) Bump `recursive-readdir`. ([@wtgtybhertgeghgtwtg](https://github.com/wtgtybhertgeghgtwtg))
+
+#### :bug: Bug Fix
+* `react-scripts`
+
+ * [#1635](https://github.com/facebookincubator/create-react-app/pull/1635) **Fix Jest configuration.** ([@Timer](https://github.com/Timer))
+
+ Fixes ejecting on Windows for macOS and Linux machines.
+
+ * [#1356](https://github.com/facebookincubator/create-react-app/pull/1356) Fix workflow if react-scripts package is linked via npm-link. ([@tuchk4](https://github.com/tuchk4))
+
+ Advanced users may opt to fork `react-scripts` instead of ejecting so they still receive upstream updates.
+ `react-scripts` will now function as expected when linking to a development version.
+ Previously, you could not test changes with an existing application via linking.
+
+ * [#1585](https://github.com/facebookincubator/create-react-app/pull/1585) Ensure PORT environment variable is an integer. ([@matoilic](https://github.com/matoilic))
+
+ * [#1628](https://github.com/facebookincubator/create-react-app/pull/1628) Show correct port for pushstate-server URL text. ([@mattccrampton](https://github.com/mattccrampton))
+
+ * [#1647](https://github.com/facebookincubator/create-react-app/pull/1647) Fix `npm test` on Windows ([@gaearon](https://github.com/gaearon))
+
+
+#### :memo: Documentation
+* User Guides
+ * [#1391](https://github.com/facebookincubator/create-react-app/pull/1391) Add note how to resolve missing required files for Heroku. ([@sbritoig](https://github.com/sbritoig))
+ * [#1577](https://github.com/facebookincubator/create-react-app/pull/1577) Add a how-to on `react-snapshot`. ([@superhighfives](https://github.com/superhighfives))
+ * [#1121](https://github.com/facebookincubator/create-react-app/pull/1121) Add documentation for customizing Bootstrap theme. ([@myappincome](https://github.com/myappincome))
+ * [#1540](https://github.com/facebookincubator/create-react-app/pull/1540) Document debugging in Visual Studio Code. ([@bondz](https://github.com/bondz))
+ * [#1618](https://github.com/facebookincubator/create-react-app/pull/1618) Add note about when to import Bootstrap CSS. ([@joewoodhouse](https://github.com/joewoodhouse))
+ * [#1518](https://github.com/facebookincubator/create-react-app/pull/1518) Update flow configuration documentation. ([@SBrown52](https://github.com/SBrown52))
+ * [#1625](https://github.com/facebookincubator/create-react-app/pull/1625) Specify that NODE_ENV is set to 'production' during the build step. ([@mderazon](https://github.com/mderazon))
+ * [#1573](https://github.com/facebookincubator/create-react-app/pull/1573) Update Jest documentation links. ([@mkermani144](https://github.com/mkermani144))
+ * [#1564](https://github.com/facebookincubator/create-react-app/pull/1564) Add --recursive to Sass watch script. ([@aleburato](https://github.com/aleburato))
+ * [#1561](https://github.com/facebookincubator/create-react-app/pull/1561) Use https in link in documentation. ([@dariocravero](https://github.com/dariocravero))
+ * [#1562](https://github.com/facebookincubator/create-react-app/pull/1562) Update `jest-enzyme` documentation. ([@kiranps](https://github.com/kiranps))
+ * [#1543](https://github.com/facebookincubator/create-react-app/pull/1543) Update CSS preprocessor instructions. ([@aleburato](https://github.com/aleburato))
+ * [#1338](https://github.com/facebookincubator/create-react-app/pull/1338) Add link to Azure deployment tutorial. ([@tpetrina](https://github.com/tpetrina))
+ * [#1320](https://github.com/facebookincubator/create-react-app/pull/1320) Document how to disable autoprefix feature. ([@rrubas](https://github.com/rrubas))
+ * [#1313](https://github.com/facebookincubator/create-react-app/pull/1313) List features beyond ES6 supported by create-react-app. ([@jonathanconway](https://github.com/jonathanconway))
+ * [#1008](https://github.com/facebookincubator/create-react-app/pull/1008) Add Saas support documentation. ([@tsironis](https://github.com/tsironis))
+ * [#994](https://github.com/facebookincubator/create-react-app/pull/994) Suggest `jest-enzyme` for simplifying test matchers. ([@blainekasten](https://github.com/blainekasten))
+ * [#1608](https://github.com/facebookincubator/create-react-app/pull/1608) Add note for using CHOKIDAR_USEPOLLING in virtual machines to enable HMR. ([@AJamesPhillips](https://github.com/AJamesPhillips))
+ * [#1495](https://github.com/facebookincubator/create-react-app/pull/1495) Add useful link to react-scripts. ([@pd4d10](https://github.com/pd4d10))
+* READMEs
+ * [#1576](https://github.com/facebookincubator/create-react-app/pull/1576) Switch from Neo to Neutrino. ([@eliperelman](https://github.com/eliperelman))
+ * [#1275](https://github.com/facebookincubator/create-react-app/pull/1275) Suggest yarn commands in addition to npm. ([@lifez](https://github.com/lifez))
+
+#### :house: Internal
+* `babel-preset-react-app`
+ * [#1598](https://github.com/facebookincubator/create-react-app/pull/1598) Remove redundant babel-plugin-transform-es2015-parameters. ([@christophehurpeau](https://github.com/christophehurpeau))
+* Other
+ * [#1534](https://github.com/facebookincubator/create-react-app/pull/1534) Use yarn@latest in e2e. ([@gaearon](https://github.com/gaearon))
+ * [#1295](https://github.com/facebookincubator/create-react-app/pull/1295) Make node version check more robust in e2e. ([@pugnascotia](https://github.com/pugnascotia))
+ * [#1503](https://github.com/facebookincubator/create-react-app/pull/1503) Fix `test -e` in e2e. ([@igetgames](https://github.com/igetgames))
+
+#### Committers: 36
+- Ade Viankakrisna Fadlil ([viankakrisna](https://github.com/viankakrisna))
+- Alessandro Burato ([aleburato](https://github.com/aleburato))
+- Alexander James Phillips ([AJamesPhillips](https://github.com/AJamesPhillips))
+- Blaine Kasten ([blainekasten](https://github.com/blainekasten))
+- Bond ([bondz](https://github.com/bondz))
+- Charlie Gleason ([superhighfives](https://github.com/superhighfives))
+- Christophe Hurpeau ([christophehurpeau](https://github.com/christophehurpeau))
+- Dan Abramov ([gaearon](https://github.com/gaearon))
+- Daniel Riquelme ([driquelme](https://github.com/driquelme))
+- Darío Javier Cravero ([dariocravero](https://github.com/dariocravero))
+- Dimitris Tsironis ([tsironis](https://github.com/tsironis))
+- Eli Perelman ([eliperelman](https://github.com/eliperelman))
+- Jirat Ki. ([n3tr](https://github.com/n3tr))
+- Joe Haddad ([Timer](https://github.com/Timer))
+- Joe Woodhouse ([joewoodhouse](https://github.com/joewoodhouse))
+- Jonathan Conway ([jonathanconway](https://github.com/jonathanconway))
+- Marcus R. Brown ([igetgames](https://github.com/igetgames))
+- Mato Ilic ([matoilic](https://github.com/matoilic))
+- Matt Crampton ([mattccrampton](https://github.com/mattccrampton))
+- Michael DeRazon ([mderazon](https://github.com/mderazon))
+- Mo Binni ([mobinni](https://github.com/mobinni))
+- Mohammad Kermani ([mkermani144](https://github.com/mkermani144))
+- Phawin Khongkhasawan ([lifez](https://github.com/lifez))
+- Roman Rubas ([rrubas](https://github.com/rrubas))
+- Rory Hunter ([pugnascotia](https://github.com/pugnascotia))
+- Tom Conroy ([tomconroy](https://github.com/tomconroy))
+- Toni Petrina ([tpetrina](https://github.com/tpetrina))
+- Valerii Sorokobatko ([tuchk4](https://github.com/tuchk4))
+- Vicente Jr Yuchitcho ([chitchu](https://github.com/chitchu))
+- [SBrown52](https://github.com/SBrown52)
+- [chyipin](https://github.com/chyipin)
+- [myappincome](https://github.com/myappincome)
+- [sbritoig](https://github.com/sbritoig)
+- [wtgtybhertgeghgtwtg](https://github.com/wtgtybhertgeghgtwtg)
+- kiran ps ([kiranps](https://github.com/kiranps))
+- pd4d10 ([pd4d10](https://github.com/pd4d10))
+
+### Migrating from 0.9.0 to 0.9.2
+
+**Note:** 0.9.1 had known issues so you should skip it.
+
+Inside any created project that has not been ejected, run:
+
+```
+npm install --save-dev --save-exact react-scripts@0.9.2
+```
+
+You may also optionally update the global command-line utility for more efficient installs (thanks [@n3tr](https://github.com/n3tr)):
+
+```
+npm install -g create-react-app@1.1.0
+```
+
+## 0.9.1 (February 25, 2017)
+
+This release has known issues and you should skip it. Update directly to 0.9.2 instead.
+
## 0.9.0 (February 11, 2017)
Thanks to [@Timer](https://github.com/timer) for cutting this release.
@@ -7,23 +341,23 @@ Thanks to [@Timer](https://github.com/timer) for cutting this release.
* `react-scripts`
* [#1489](https://github.com/facebookincubator/create-react-app/pull/1489) Support setting `"homepage"` to `"."` to generate relative asset paths. ([@tibdex](https://github.com/tibdex))
-
+
Applications that don’t use the HTML5 `pushState` API can now be built to be served from any relative URL. To enable this, specify `"."` as your `homepage` setting in `package.json`. It used to be possible before with a few known bugs, but they should be fixed now. See [Serving the Same Build from Different Paths](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#serving-the-same-build-from-different-paths).
* [#937](https://github.com/facebookincubator/create-react-app/pull/1504) Add `PUBLIC_URL` environment variable for advanced use. ([@EnoahNetzach](https://github.com/EnoahNetzach))
-
+
If you use a CDN to serve the app, you can now specify `PUBLIC_URL` environment variable to override the base URL (including the hostname) for resources referenced from the built code. This new variable is mentioned in the new [Advanced Configuration](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#advanced-configuration) section.
* [#1440](https://github.com/facebookincubator/create-react-app/pull/1440) Make all `REACT_APP_*` environment variables accessible in `index.html`. ([@jihchi](https://github.com/jihchi))
-
+
This makes all environment variables previously available in JS, also available in the HTML file, for example `%REACT_APP_MY_VARIABLE%`. See [Referencing Environment Variables in HTML](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#referencing-environment-variables-in-the-html).
* `react-dev-utils`
* [#1148](https://github.com/facebookincubator/create-react-app/pull/1148) Configure which browser to open with `npm start`. ([@GAumala](https://github.com/GAumala))
-
+
You can now disable the automatic browser launching by setting the `BROWSER` environment variable to `none`. You can also specify a different browser (or an arbitrary script) to open by default, [as supported by `opn` command](https://github.com/sindresorhus/opn#app) that we use under the hood. See [Advanced Configuration](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#advanced-configuration).
-
+
#### :boom: Breaking Change
* `react-scripts`
@@ -31,7 +365,7 @@ Thanks to [@Timer](https://github.com/timer) for cutting this release.
* [#1522](https://github.com/facebookincubator/create-react-app/pull/1522) Upgrade dependencies. ([@Timer](https://github.com/Timer))
* [#1432](https://github.com/facebookincubator/create-react-app/pull/1432) Bump Jest version. ([@gaearon](https://github.com/gaearon))
* [#1311](https://github.com/facebookincubator/create-react-app/pull/1311) Updated `babel-jest` and `jest` packages to 18.0.0. ([@lopezator](https://github.com/lopezator))
-
+
Jest has been updated to 18 and has introduced some [breaking changes and new features](https://facebook.github.io/jest/blog/2016/12/15/2016-in-jest.html).
* `react-scripts`, `react-dev-utils`
@@ -45,7 +379,7 @@ Thanks to [@Timer](https://github.com/timer) for cutting this release.
* `react-scripts`
* [#1441](https://github.com/facebookincubator/create-react-app/pull/1441) Added `babel-runtime` dependency to deduplicate dependencies when using Yarn. ([@jkimbo](https://github.com/jkimbo))
-
+
This works around a bug in Yarn that caused newly created projects to be over 400MB. Now they are down to 126MB, just like with npm 3.
* [#1522](https://github.com/facebookincubator/create-react-app/pull/1522) Upgrade dependencies. ([@Timer](https://github.com/Timer))
@@ -110,7 +444,7 @@ Thanks to [@Timer](https://github.com/timer) for cutting this release.
* [#1463](https://github.com/facebookincubator/create-react-app/pull/1463) Minor code style and wrong expect. ([@tuchk4](https://github.com/tuchk4))
* [#1470](https://github.com/facebookincubator/create-react-app/pull/1470) E2e jsdom fix. ([@EnoahNetzach](https://github.com/EnoahNetzach))
* [#1187](https://github.com/facebookincubator/create-react-app/pull/1187) Use a more sophisticated template for end-to-end testing.. ([@EnoahNetzach](https://github.com/EnoahNetzach))
-
+
* Other
* [#1289](https://github.com/facebookincubator/create-react-app/pull/1289) Remove path-exists from dependencies and replace it with fs.existsSync. ([@halfzebra](https://github.com/halfzebra))
@@ -197,60 +531,60 @@ npm install -g create-react-app@1.0.3
* `react-scripts`
* [#1233](https://github.com/facebookincubator/create-react-app/pull/1233) Disable subresource integrity temporarily. ([@Timer](https://github.com/Timer))
-
+
We added [Subresource Integrity](https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity) checks to the build output in 0.8.2 but it turns out that they may fail in browsers using special compression proxies, such as Chrome on Android, when served over HTTP. We disabled the checks until we can find a safe way to add them.
-
+
* `react-dev-utils`
* [#1226](https://github.com/facebookincubator/create-react-app/pull/1226) Fix weird lint output. ([@n3tr](https://github.com/n3tr))
-
+
Fixes strange lint message formatting in some edge cases.
-
+
* [#1215](https://github.com/facebookincubator/create-react-app/pull/1215) Fix - openChrome won't open default browser (using Canary). ([@n3tr](https://github.com/n3tr))
-
+
Fixes a regression that caused stable Google Chrome to be opened even if you are using Canary as the default browser.
-
+
* `create-react-app`
* [#1223](https://github.com/facebookincubator/create-react-app/pull/1223) Clean up Yarn detection and install code. ([@fson](https://github.com/fson))
-
+
Fixes noisy output on Windows when Yarn is not installed.
* [#1224](https://github.com/facebookincubator/create-react-app/pull/1224) Exit with an error code when npm/yarn install fails. ([@fson](https://github.com/fson))
-
+
#### :nail_care: Enhancement
* `react-scripts`
* [#1237](https://github.com/facebookincubator/create-react-app/pull/1237) Clear scrollback in test mode. ([@gaearon](https://github.com/gaearon))
-
+
Ensures test watcher clears the console before running.
-
+
* [#1229](https://github.com/facebookincubator/create-react-app/pull/1229) Disable jest watch mode when --coverage flag is present [#1207]. ([@BenoitAverty](https://github.com/BenoitAverty))
-
+
Since coverage doesn't work well with watch mode, we don’t run the watcher on `npm test -- --coverage` anymore.
-
+
* [#1212](https://github.com/facebookincubator/create-react-app/pull/1212) Proxy rewrites Origin header to match the target server URL. ([@koles](https://github.com/koles))
-
+
Makes sure more API endpoints can work with the `proxy` setting.
-
+
* [#1222](https://github.com/facebookincubator/create-react-app/pull/1222) Disable gh-page setup instruction if scripts.deploy has been added. ([@n3tr](https://github.com/n3tr))
-
+
Suppresses the instructions printed at the end of `npm run build` if `npm run deploy` already exists.
* `create-react-app`
* [#1236](https://github.com/facebookincubator/create-react-app/pull/1236) Tweak console messages. ([@gaearon](https://github.com/gaearon))
-
+
Makes error messages more friendly.
-
+
* [#1195](https://github.com/facebookincubator/create-react-app/pull/1195) Use "commander" for cli argv handling. ([@EnoahNetzach](https://github.com/EnoahNetzach))
-
+
Adds `create-react-app --help` with a list of options.
* `react-dev-utils`
* [#1211](https://github.com/facebookincubator/create-react-app/pull/1211) Use a better clear console sequence. ([@gaearon](https://github.com/gaearon))
-
+
Ensures the development server clears the terminal when files are changed.
#### :memo: Documentation
@@ -300,14 +634,14 @@ npm install -g create-react-app@1.0.2
* [#1204](https://github.com/facebookincubator/create-react-app/pull/1204) Catch synchronous errors from spawning yarn. ([@gaearon](https://github.com/gaearon))
Fixes a crash when running `create-react-app` in some cases.
-
+
* `react-scripts`
* [#1203](https://github.com/facebookincubator/create-react-app/pull/1203) Update webpack-subresource-integrity to fix Windows builds. ([@gaearon](https://github.com/gaearon))
-
+
Fixes a crash when running `npm run build` on Windows.
-
+
* [#1201](https://github.com/facebookincubator/create-react-app/pull/1201) Instruct Jest to load native components from RNW instead of RN. ([@remon-georgy](https://github.com/remon-georgy))
-
+
Fixes tests for users of React Native Web.
#### :memo: Documentation
@@ -771,7 +1105,7 @@ This ensures it become a part of the build output, and resolves correctly both w
## 0.4.3 (September 18, 2016)
-This is a hotfix release for a broken package.
+This is a hotfix release for a broken package.
It contained no changes to the code.
### Build Dependency (`react-scripts`)
@@ -913,7 +1247,7 @@ npm install --save-dev --save-exact react-scripts@0.3.0
#### Breaking Change
-Now `favicon.ico` is not treated specially anymore.
+Now `favicon.ico` is not treated specially anymore.
If you use it, move it to `src` and add the following line to `
` in your HTML:
```html
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index b6c4e69bbfd..8ec3111ab94 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -10,7 +10,7 @@ Following these guidelines helps to communicate that you respect the time of the
As much as possible, we try to avoid adding configuration and flags. The purpose of this tool is to provide the best experience for people getting started with React, and this will always be our first priority. This means that sometimes we [sacrifice additional functionality](https://gettingreal.37signals.com/ch05_Half_Not_Half_Assed.php) (such as server rendering) because it is too hard to solve it in a way that wouldn’t require any configuration.
-We prefer **convention, heuristics, or interactivity** over configuration.
+We prefer **convention, heuristics, or interactivity** over configuration.
Here’s a few examples of them in action.
### Convention
@@ -47,6 +47,8 @@ Please also provide a **test plan**, i.e. specify how you verified that your add
2. Run `npm install` in the root `create-react-app` folder.
+3. *(Only for MacOS Sierra)*: install [Watchman](https://facebook.github.io/watchman/docs/install.html), for example `brew install watchman`
+
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.
If you want to try out the end-to-end flow with the global CLI, you can do this too:
diff --git a/PULL_REQUEST_TEMPLATE.md b/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index 00000000000..87acf9c2f90
--- /dev/null
+++ b/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,8 @@
+
diff --git a/README.md b/README.md
index 52843b572ed..ec24d939774 100644
--- a/README.md
+++ b/README.md
@@ -5,7 +5,10 @@ Create React apps with no build configuration.
* [Getting Started](#getting-started) – How to create a new app.
* [User Guide](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md) – How to develop apps bootstrapped with Create React App.
-## tl;dr
+Create React App works on macOS, Windows, and Linux.
+If something doesn’t work please [file an issue](https://github.com/facebookincubator/create-react-app/issues/new).
+
+## Quick Overview
```sh
npm install -g create-react-app
@@ -13,7 +16,6 @@ npm install -g create-react-app
create-react-app my-app
cd my-app/
npm start
-
```
Then open [http://localhost:3000/](http://localhost:3000/) to see your app.
@@ -21,6 +23,13 @@ When you’re ready to deploy to production, create a minified bundle with `npm
+### Get Started Immediately
+
+You **don’t** need to install or configure tools like Webpack or Babel.
+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
### Installation
@@ -35,7 +44,7 @@ npm install -g create-react-app
**We strongly recommend to use Node >= 6 and npm >= 3 for faster installation speed and better disk usage.** You can use [nvm](https://github.com/creationix/nvm#usage) to easily switch Node versions between different projects.
-**This tool doesn’t assume a Node backend**. The Node installation is only required for the build tools that rely on it locally, such as Webpack and Babel.
+**This tool doesn’t assume a Node backend**. The Node installation is only required for Create React App itself.
### Creating an App
@@ -70,7 +79,7 @@ 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:
-### `npm start`
+### `npm start` or `yarn start`
Runs the app in development mode.
Open [http://localhost:3000](http://localhost:3000) to view it in the browser.
@@ -80,14 +89,14 @@ You will see the build errors and lint warnings in the console.
-### `npm test`
+### `npm test` or `yarn test`
Runs the test watcher in an interactive mode.
By default, runs tests related to files changes since the last commit.
[Read more about testing.](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#running-tests)
-### `npm run build`
+### `npm run build` or `yarn build`
Builds the app for production to the `build` folder.
It correctly bundles React in production mode and optimizes the build for the best performance.
@@ -102,14 +111,17 @@ 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 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)
+- [Debugging in the Editor](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#debugging-in-the-editor)
- [Changing the Page ``](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#changing-the-page-title)
- [Installing a Dependency](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#installing-a-dependency)
- [Importing a Component](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#importing-a-component)
- [Adding a Stylesheet](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#adding-a-stylesheet)
- [Post-Processing CSS](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#post-processing-css)
-- [Adding Images and Fonts](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#adding-images-and-fonts)
+- [Adding a CSS Preprocessor (Sass, Less etc.)](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#adding-a-css-preprocessor-sass-less-etc)
+- [Adding Images, Fonts, and Files](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#adding-images-fonts-and-files)
- [Using the `public` Folder](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#using-the-public-folder)
- [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)
@@ -120,6 +132,7 @@ The [User Guide](https://github.com/facebookincubator/create-react-app/blob/mast
- [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)
- [Developing Components in Isolation](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#developing-components-in-isolation)
- [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)
@@ -137,7 +150,7 @@ Please refer to the [User Guide](https://github.com/facebookincubator/create-rea
* **One Dependency:** There is just one build dependency. It uses Webpack, Babel, ESLint, and other amazing projects, but provides a cohesive curated experience on top of them.
-* **Convention over Configuration:** You don't need to configure anything by default. Reasonably good configuration of both development and production builds is handled for you so you can focus on writing code.
+* **No Configuration Required:** You don't need to configure anything. Reasonably good configuration of both development and production builds is handled for you so you can focus on writing code.
* **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.
@@ -173,7 +186,7 @@ Some features are currently **not supported**:
* Server rendering.
* Some experimental syntax extensions (e.g. decorators).
* CSS Modules.
-* LESS or Sass.
+* 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.
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.
@@ -196,6 +209,11 @@ All of them are transitive dependencies of the provided npm package.
We'd love to have your helping hand on `create-react-app`! See [CONTRIBUTING.md](CONTRIBUTING.md) for more information on what we're looking for and how to get started.
+## React Native
+
+Looking for something similar, but for React Native?
+Check out [Create React Native App](https://github.com/react-community/create-react-native-app/).
+
## Acknowledgements
We are grateful to the authors of existing related projects for their ideas and collaboration:
@@ -210,7 +228,7 @@ If you don’t agree with the choices made in this project, you might want to ex
Some of the more popular and actively maintained ones are:
* [insin/nwb](https://github.com/insin/nwb)
-* [mozilla/neo](https://github.com/mozilla/neo)
+* [mozilla-neutrino/neutrino-dev](https://github.com/mozilla-neutrino/neutrino-dev)
* [NYTimes/kyt](https://github.com/NYTimes/kyt)
* [zeit/next.js](https://github.com/zeit/next.js)
* [gatsbyjs/gatsby](https://github.com/gatsbyjs/gatsby)
diff --git a/appveyor.cleanup-cache.txt b/appveyor.cleanup-cache.txt
new file mode 100644
index 00000000000..19d0b989b62
--- /dev/null
+++ b/appveyor.cleanup-cache.txt
@@ -0,0 +1,5 @@
+Edit this file to trigger a cache rebuild.
+http://help.appveyor.com/discussions/questions/1310-delete-cache
+
+----
+Just testing if this works.
diff --git a/appveyor.yml b/appveyor.yml
new file mode 100644
index 00000000000..8b2b688fc66
--- /dev/null
+++ b/appveyor.yml
@@ -0,0 +1,50 @@
+image: Visual Studio 2017
+
+environment:
+ matrix:
+ - nodejs_version: 7
+ test_suite: "simple"
+ - nodejs_version: 7
+ test_suite: "installs"
+ - nodejs_version: 7
+ test_suite: "kitchensink"
+ - nodejs_version: 6
+ test_suite: "simple"
+ - nodejs_version: 6
+ test_suite: "installs"
+ - nodejs_version: 6
+ test_suite: "kitchensink"
+ - nodejs_version: 4
+ test_suite: "simple"
+ - nodejs_version: 4
+ test_suite: "installs"
+ - nodejs_version: 4
+ test_suite: "kitchensink"
+
+cache:
+ - node_modules -> appveyor.cleanup-cache.txt
+ - packages\react-scripts\node_modules -> appveyor.cleanup-cache.txt
+
+clone_depth: 50
+
+matrix:
+ fast_finish: true
+
+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
+
+skip_commits:
+ files:
+ - '**/*.md'
+
+test_script:
+ - node --version
+ - npm --version
+ - sh tasks/e2e-%test_suite%.sh
diff --git a/lerna.json b/lerna.json
index f648aac48a1..e2429777df4 100644
--- a/lerna.json
+++ b/lerna.json
@@ -1,5 +1,5 @@
{
- "lerna": "2.0.0-beta.37",
+ "lerna": "2.0.0-beta.38",
"version": "independent",
"changelog": {
"repo": "facebookincubator/create-react-app",
@@ -12,5 +12,8 @@
"tag: internal": ":house: Internal"
},
"cacheDir": ".changelog"
- }
+ },
+ "packages": [
+ "packages/*"
+ ]
}
diff --git a/package.json b/package.json
index a9262568d25..9ca7cfc03d9 100644
--- a/package.json
+++ b/package.json
@@ -8,17 +8,22 @@
"postinstall": "lerna bootstrap",
"publish": "tasks/release.sh",
"start": "node packages/react-scripts/scripts/start.js",
- "test": "node packages/react-scripts/scripts/test.js --env=jsdom"
+ "test": "node packages/react-scripts/scripts/test.js --env=jsdom",
+ "format": "prettier --trailing-comma es5 --single-quote --write 'packages/*/*.js' 'packages/*/!(node_modules)/**/*.js'",
+ "precommit": "lint-staged"
},
"devDependencies": {
- "babel-eslint": "6.1.2",
- "eslint": "3.5.0",
- "eslint-config-react-app": "0.2.1",
- "eslint-plugin-flowtype": "2.18.1",
- "eslint-plugin-import": "1.12.0",
- "eslint-plugin-jsx-a11y": "2.2.2",
- "eslint-plugin-react": "6.3.0",
- "lerna": "^2.0.0-beta.37",
- "lerna-changelog": "^0.2.3"
+ "eslint": "3.16.1",
+ "husky": "^0.13.2",
+ "lerna": "2.0.0-beta.38",
+ "lerna-changelog": "^0.2.3",
+ "lint-staged": "^3.3.1",
+ "prettier": "^0.21.0"
+ },
+ "lint-staged": {
+ "*.js": [
+ "prettier --trailing-comma es5 --single-quote --write",
+ "git add"
+ ]
}
}
diff --git a/packages/babel-preset-react-app/README.md b/packages/babel-preset-react-app/README.md
index 5221c41af59..4dc9fb9b168 100644
--- a/packages/babel-preset-react-app/README.md
+++ b/packages/babel-preset-react-app/README.md
@@ -1,6 +1,6 @@
# babel-preset-react-app
-This package includes the Babel preset used by [Create React App](https://github.com/facebookincubator/create-react-app).
+This package includes the Babel preset used by [Create React App](https://github.com/facebookincubator/create-react-app).
Please refer to its documentation:
* [Getting Started](https://github.com/facebookincubator/create-react-app/blob/master/README.md#getting-started) – How to create a new app.
diff --git a/packages/babel-preset-react-app/index.js b/packages/babel-preset-react-app/index.js
index a028babc06c..089c81dbbe0 100644
--- a/packages/babel-preset-react-app/index.js
+++ b/packages/babel-preset-react-app/index.js
@@ -16,21 +16,30 @@ const plugins = [
// 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
- }],
+ [
+ require.resolve('babel-plugin-transform-object-rest-spread'),
+ {
+ useBuiltIns: true,
+ },
+ ],
// Transforms JSX
- [require.resolve('babel-plugin-transform-react-jsx'), {
- useBuiltIns: true
- }],
+ [
+ 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,
- // Resolve the Babel runtime relative to the config.
- moduleName: path.dirname(require.resolve('babel-runtime/package'))
- }]
+ [
+ require.resolve('babel-plugin-transform-runtime'),
+ {
+ helpers: false,
+ polyfill: false,
+ regenerator: true,
+ // Resolve the Babel runtime relative to the config.
+ moduleName: path.dirname(require.resolve('babel-runtime/package')),
+ },
+ ],
];
// This is similar to how `env` works in Babel:
@@ -42,9 +51,11 @@ const plugins = [
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) + '.'
+ '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) +
+ '.'
);
}
@@ -59,46 +70,65 @@ if (env === 'development' || env === 'test') {
// 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')
+ require.resolve('babel-plugin-transform-react-jsx-self'),
]);
}
if (env === 'test') {
- plugins.push.apply(plugins, [
- // We always include this plugin regardless of environment
- // because of a Babel bug that breaks object rest/spread without it:
- // https://github.com/babel/babel/issues/4851
- require.resolve('babel-plugin-transform-es2015-parameters')
- ]);
-
module.exports = {
presets: [
// ES features necessary for user's Node version
- [require('babel-preset-env').default, {
- targets: {
- node: 'current',
+ [
+ require('babel-preset-env').default,
+ {
+ targets: {
+ node: 'current',
+ },
},
- }],
+ ],
// JSX, Flow
- require.resolve('babel-preset-react')
+ require.resolve('babel-preset-react'),
],
- plugins: plugins
+ 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-latest'),
+ [
+ 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')
+ 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-latest
- async: false
- }],
- ])
+ [
+ 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') {
diff --git a/packages/babel-preset-react-app/package.json b/packages/babel-preset-react-app/package.json
index ae5ab93be65..aa955e43762 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": "2.1.0",
+ "version": "2.1.1",
"description": "Babel preset used by Create React App",
"repository": "facebookincubator/create-react-app",
"license": "BSD-3-Clause",
@@ -11,18 +11,18 @@
"index.js"
],
"dependencies": {
- "babel-plugin-transform-class-properties": "6.22.0",
- "babel-plugin-transform-es2015-parameters": "6.22.0",
- "babel-plugin-transform-object-rest-spread": "6.22.0",
- "babel-plugin-transform-react-constant-elements": "6.22.0",
- "babel-plugin-transform-react-jsx": "6.22.0",
+ "babel-plugin-dynamic-import-node": "1.0.0",
+ "babel-plugin-syntax-dynamic-import": "6.18.0",
+ "babel-plugin-transform-class-properties": "6.23.0",
+ "babel-plugin-transform-object-rest-spread": "6.23.0",
+ "babel-plugin-transform-react-constant-elements": "6.23.0",
+ "babel-plugin-transform-react-jsx": "6.23.0",
"babel-plugin-transform-react-jsx-self": "6.22.0",
"babel-plugin-transform-react-jsx-source": "6.22.0",
"babel-plugin-transform-regenerator": "6.22.0",
- "babel-plugin-transform-runtime": "6.22.0",
- "babel-preset-env": "1.1.8",
- "babel-preset-latest": "6.22.0",
- "babel-preset-react": "6.22.0",
- "babel-runtime": "6.22.0"
+ "babel-plugin-transform-runtime": "6.23.0",
+ "babel-preset-env": "1.2.1",
+ "babel-preset-react": "6.23.0",
+ "babel-runtime": "6.23.0"
}
}
diff --git a/packages/create-react-app/README.md b/packages/create-react-app/README.md
index 062a320250d..c8fed06489f 100644
--- a/packages/create-react-app/README.md
+++ b/packages/create-react-app/README.md
@@ -1,6 +1,6 @@
# create-react-app
-This package includes the global command for [Create React App](https://github.com/facebookincubator/create-react-app).
+This package includes the global command for [Create React App](https://github.com/facebookincubator/create-react-app).
Please refer to its documentation:
* [Getting Started](https://github.com/facebookincubator/create-react-app/blob/master/README.md#getting-started) – How to create a new app.
diff --git a/packages/create-react-app/createReactApp.js b/packages/create-react-app/createReactApp.js
new file mode 100755
index 00000000000..72a82317245
--- /dev/null
+++ b/packages/create-react-app/createReactApp.js
@@ -0,0 +1,553 @@
+/**
+ * Copyright (c) 2015-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// /!\ DO NOT MODIFY THIS FILE /!\
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// create-react-app is installed globally on people's computers. This means
+// that it is extremely difficult to have them upgrade the version and
+// because there's only one global version installed, it is very prone to
+// breaking changes.
+//
+// The only job of create-react-app is to init the repository and then
+// forward all the commands to the local version of create-react-app.
+//
+// If you need to add a new command, please add it to the scripts/ folder.
+//
+// The only reason to modify this file is to add more warnings and
+// troubleshooting information for the `create-react-app` command.
+//
+// Do not make breaking changes! We absolutely don't want to have to
+// tell people to update their global version of create-react-app.
+//
+// Also be careful with new language features.
+// This file must work on Node 4+.
+//
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// /!\ DO NOT MODIFY THIS FILE /!\
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+'use strict';
+
+const validateProjectName = require('validate-npm-package-name');
+const chalk = require('chalk');
+const commander = require('commander');
+const fs = require('fs-extra');
+const path = require('path');
+const execSync = require('child_process').execSync;
+const spawn = require('cross-spawn');
+const semver = require('semver');
+const dns = require('dns');
+const tmp = require('tmp');
+const unpack = require('tar-pack').unpack;
+const hyperquest = require('hyperquest');
+
+const packageJson = require('./package.json');
+
+let projectName;
+
+const program = new commander.Command(packageJson.name)
+ .version(packageJson.version)
+ .arguments('')
+ .usage(`${chalk.green('')} [options]`)
+ .action(name => {
+ projectName = name;
+ })
+ .option('--verbose', 'print additional logs')
+ .option(
+ '--scripts-version ',
+ 'use a non-standard version of react-scripts'
+ )
+ .allowUnknownOption()
+ .on('--help', () => {
+ console.log(` Only ${chalk.green('')} is required.`);
+ console.log();
+ console.log(
+ ` A custom ${chalk.cyan('--scripts-version')} can be one of:`
+ );
+ console.log(` - a specific npm version: ${chalk.green('0.8.2')}`);
+ console.log(
+ ` - a custom fork published on npm: ${chalk.green('my-react-scripts')}`
+ );
+ console.log(
+ ` - a .tgz archive: ${chalk.green('https://mysite.com/my-react-scripts-0.8.2.tgz')}`
+ );
+ console.log(
+ ` It is not needed unless you specifically want to use a fork.`
+ );
+ console.log();
+ console.log(
+ ` If you have any problems, do not hesitate to file an issue:`
+ );
+ console.log(
+ ` ${chalk.cyan('https://github.com/facebookincubator/create-react-app/issues/new')}`
+ );
+ console.log();
+ })
+ .parse(process.argv);
+
+if (typeof projectName === 'undefined') {
+ console.error('Please specify the project directory:');
+ console.log(
+ ` ${chalk.cyan(program.name())} ${chalk.green('')}`
+ );
+ console.log();
+ console.log('For example:');
+ console.log(` ${chalk.cyan(program.name())} ${chalk.green('my-react-app')}`);
+ console.log();
+ console.log(
+ `Run ${chalk.cyan(`${program.name()} --help`)} to see all options.`
+ );
+ process.exit(1);
+}
+
+function printValidationResults(results) {
+ if (typeof results !== 'undefined') {
+ results.forEach(error => {
+ console.error(chalk.red(` * ${error}`));
+ });
+ }
+}
+
+const hiddenProgram = new commander.Command()
+ .option(
+ '--internal-testing-template ',
+ '(internal usage only, DO NOT RELY ON THIS) ' +
+ 'use a non-standard application template'
+ )
+ .parse(process.argv);
+
+createApp(
+ projectName,
+ program.verbose,
+ program.scriptsVersion,
+ hiddenProgram.internalTestingTemplate
+);
+
+function createApp(name, verbose, version, template) {
+ const root = path.resolve(name);
+ const appName = path.basename(root);
+
+ checkAppName(appName);
+ fs.ensureDirSync(name);
+ if (!isSafeToCreateProjectIn(root)) {
+ console.log(
+ `The directory ${chalk.green(name)} contains files that could conflict.`
+ );
+ console.log('Try using a new directory name.');
+ process.exit(1);
+ }
+
+ console.log(`Creating a new React app in ${chalk.green(root)}.`);
+ console.log();
+
+ const packageJson = {
+ name: appName,
+ version: '0.1.0',
+ private: true,
+ };
+ fs.writeFileSync(
+ path.join(root, 'package.json'),
+ JSON.stringify(packageJson, null, 2)
+ );
+ const originalDirectory = process.cwd();
+ process.chdir(root);
+
+ run(root, appName, version, verbose, originalDirectory, template);
+}
+
+function shouldUseYarn() {
+ try {
+ execSync('yarnpkg --version', { stdio: 'ignore' });
+ return true;
+ } catch (e) {
+ return false;
+ }
+}
+
+function install(useYarn, dependencies, verbose, isOnline) {
+ return new Promise((resolve, reject) => {
+ let command;
+ let args;
+ if (useYarn) {
+ command = 'yarnpkg';
+ args = ['add', '--exact'];
+ if (!isOnline) {
+ args.push('--offline');
+ }
+ [].push.apply(args, dependencies);
+
+ if (!isOnline) {
+ console.log(chalk.yellow('You appear to be offline.'));
+ console.log(chalk.yellow('Falling back to the local Yarn cache.'));
+ console.log();
+ }
+ } else {
+ checkNpmVersion();
+ command = 'npm';
+ args = ['install', '--save', '--save-exact'].concat(dependencies);
+ }
+
+ if (verbose) {
+ args.push('--verbose');
+ }
+
+ const child = spawn(command, args, { stdio: 'inherit' });
+ child.on('close', code => {
+ if (code !== 0) {
+ reject({
+ command: `${command} ${args.join(' ')}`,
+ });
+ return;
+ }
+ resolve();
+ });
+ });
+}
+
+function run(root, appName, version, verbose, originalDirectory, template) {
+ const packageToInstall = getInstallPackage(version);
+ const allDependencies = ['react', 'react-dom', packageToInstall];
+
+ console.log('Installing packages. This might take a couple minutes.');
+
+ const useYarn = shouldUseYarn();
+ getPackageName(packageToInstall)
+ .then(packageName => checkIfOnline(useYarn).then(isOnline => ({
+ isOnline: isOnline,
+ packageName: packageName,
+ })))
+ .then(info => {
+ const isOnline = info.isOnline;
+ const packageName = info.packageName;
+ console.log(
+ `Installing ${chalk.cyan('react')}, ${chalk.cyan('react-dom')}, and ${chalk.cyan(packageName)}...`
+ );
+ console.log();
+
+ return install(useYarn, allDependencies, verbose, isOnline).then(
+ () => packageName
+ );
+ })
+ .then(packageName => {
+ checkNodeVersion(packageName);
+
+ // Since react-scripts has been installed with --save
+ // we need to move it into devDependencies and rewrite package.json
+ // also ensure react dependencies have caret version range
+ fixDependencies(packageName);
+
+ const scriptsPath = path.resolve(
+ process.cwd(),
+ 'node_modules',
+ packageName,
+ 'scripts',
+ 'init.js'
+ );
+ const init = require(scriptsPath);
+ init(root, appName, verbose, originalDirectory, template);
+ })
+ .catch(reason => {
+ console.log();
+ console.log('Aborting installation.');
+ if (reason.command) {
+ console.log(` ${chalk.cyan(reason.command)} has failed.`);
+ } else {
+ console.log(chalk.red('Unexpected error. Please report it as a bug:'));
+ console.log(reason);
+ }
+ console.log();
+
+ // On 'exit' we will delete these files from target directory.
+ const knownGeneratedFiles = [
+ 'package.json',
+ 'npm-debug.log',
+ 'yarn-error.log',
+ 'yarn-debug.log',
+ 'node_modules',
+ ];
+ const currentFiles = fs.readdirSync(path.join(root));
+ currentFiles.forEach(file => {
+ knownGeneratedFiles.forEach(fileToMatch => {
+ // This will catch `(npm-debug|yarn-error|yarn-debug).log*` files
+ // and the rest of knownGeneratedFiles.
+ if (
+ (fileToMatch.match(/.log/g) && file.indexOf(fileToMatch) === 0) ||
+ file === fileToMatch
+ ) {
+ console.log(`Deleting generated file... ${chalk.cyan(file)}`);
+ fs.removeSync(path.join(root, file));
+ }
+ });
+ });
+ const remainingFiles = fs.readdirSync(path.join(root));
+ if (!remainingFiles.length) {
+ // Delete target folder if empty
+ console.log(
+ `Deleting ${chalk.cyan(`${appName} /`)} from ${chalk.cyan(path.resolve(root, '..'))}`
+ );
+ process.chdir(path.resolve(root, '..'));
+ fs.removeSync(path.join(root));
+ }
+ console.log('Done.');
+ process.exit(1);
+ });
+}
+
+function getInstallPackage(version) {
+ let packageToInstall = 'react-scripts';
+ const validSemver = semver.valid(version);
+ if (validSemver) {
+ packageToInstall += `@${validSemver}`;
+ } else if (version) {
+ // for tar.gz or alternative paths
+ packageToInstall = version;
+ }
+ return packageToInstall;
+}
+
+function getTemporaryDirectory() {
+ return new Promise((resolve, reject) => {
+ // Unsafe cleanup lets us recursively delete the directory if it contains
+ // contents; by default it only allows removal if it's empty
+ tmp.dir({ unsafeCleanup: true }, (err, tmpdir, callback) => {
+ if (err) {
+ reject(err);
+ } else {
+ resolve({
+ tmpdir: tmpdir,
+ cleanup: () => {
+ try {
+ callback();
+ } catch (ignored) {
+ // Callback might throw and fail, since it's a temp directory the
+ // OS will clean it up eventually...
+ }
+ },
+ });
+ }
+ });
+ });
+}
+
+function extractStream(stream, dest) {
+ return new Promise((resolve, reject) => {
+ stream.pipe(
+ unpack(dest, err => {
+ if (err) {
+ reject(err);
+ } else {
+ resolve(dest);
+ }
+ })
+ );
+ });
+}
+
+// Extract package name from tarball url or path.
+function getPackageName(installPackage) {
+ if (installPackage.indexOf('.tgz') > -1) {
+ return getTemporaryDirectory()
+ .then(obj => {
+ let stream;
+ if (/^http/.test(installPackage)) {
+ stream = hyperquest(installPackage);
+ } else {
+ stream = fs.createReadStream(installPackage);
+ }
+ return extractStream(stream, obj.tmpdir).then(() => obj);
+ })
+ .then(obj => {
+ const packageName = require(path.join(obj.tmpdir, 'package.json')).name;
+ obj.cleanup();
+ return packageName;
+ })
+ .catch(err => {
+ // The package name could be with or without semver version, e.g. react-scripts-0.2.0-alpha.1.tgz
+ // However, this function returns package name only without semver version.
+ console.log(
+ `Could not extract the package name from the archive: ${err.message}`
+ );
+ const assumedProjectName = installPackage.match(
+ /^.+\/(.+?)(?:-\d+.+)?\.tgz$/
+ )[1];
+ console.log(
+ `Based on the filename, assuming it is "${chalk.cyan(assumedProjectName)}"`
+ );
+ return Promise.resolve(assumedProjectName);
+ });
+ } else if (installPackage.indexOf('git+') === 0) {
+ // Pull package name out of git urls e.g:
+ // git+https://github.com/mycompany/react-scripts.git
+ // git+ssh://github.com/mycompany/react-scripts.git#v1.2.3
+ return Promise.resolve(installPackage.match(/([^\/]+)\.git(#.*)?$/)[1]);
+ } else if (installPackage.indexOf('@') > 0) {
+ // Do not match @scope/ when stripping off @version or @tag
+ return Promise.resolve(
+ installPackage.charAt(0) + installPackage.substr(1).split('@')[0]
+ );
+ }
+ return Promise.resolve(installPackage);
+}
+
+function checkNpmVersion() {
+ let isNpm2 = false;
+ try {
+ const npmVersion = execSync('npm --version').toString();
+ isNpm2 = semver.lt(npmVersion, '3.0.0');
+ } catch (err) {
+ return;
+ }
+ if (!isNpm2) {
+ return;
+ }
+ console.log(chalk.yellow('It looks like you are using npm 2.'));
+ console.log(
+ chalk.yellow(
+ 'We suggest using npm 3 or Yarn for faster install times ' +
+ 'and less disk space usage.'
+ )
+ );
+ console.log();
+}
+
+function checkNodeVersion(packageName) {
+ const packageJsonPath = path.resolve(
+ process.cwd(),
+ 'node_modules',
+ packageName,
+ 'package.json'
+ );
+ const packageJson = require(packageJsonPath);
+ if (!packageJson.engines || !packageJson.engines.node) {
+ return;
+ }
+
+ if (!semver.satisfies(process.version, packageJson.engines.node)) {
+ console.error(
+ chalk.red(
+ 'You are running Node %s.\n' +
+ 'Create React App requires Node %s or higher. \n' +
+ 'Please update your version of Node.'
+ ),
+ process.version,
+ packageJson.engines.node
+ );
+ process.exit(1);
+ }
+}
+
+function checkAppName(appName) {
+ const validationResult = validateProjectName(appName);
+ if (!validationResult.validForNewPackages) {
+ console.error(
+ `Could not create a project called ${chalk.red(`"${appName}"`)} because of npm naming restrictions:`
+ );
+ printValidationResults(validationResult.errors);
+ printValidationResults(validationResult.warnings);
+ process.exit(1);
+ }
+
+ // TODO: there should be a single place that holds the dependencies
+ const dependencies = ['react', 'react-dom'];
+ const devDependencies = ['react-scripts'];
+ const allDependencies = dependencies.concat(devDependencies).sort();
+ if (allDependencies.indexOf(appName) >= 0) {
+ console.error(
+ chalk.red(
+ `We cannot create a project called ${chalk.green(appName)} because a dependency with the same name exists.\n` +
+ `Due to the way npm works, the following names are not allowed:\n\n`
+ ) +
+ chalk.cyan(allDependencies.map(depName => ` ${depName}`).join('\n')) +
+ chalk.red('\n\nPlease choose a different project name.')
+ );
+ process.exit(1);
+ }
+}
+
+function makeCaretRange(dependencies, name) {
+ const version = dependencies[name];
+
+ if (typeof version === 'undefined') {
+ console.error(chalk.red(`Missing ${name} dependency in package.json`));
+ process.exit(1);
+ }
+
+ let patchedVersion = `^${version}`;
+
+ if (!semver.validRange(patchedVersion)) {
+ console.error(
+ `Unable to patch ${name} dependency version because version ${chalk.red(version)} will become invalid ${chalk.red(patchedVersion)}`
+ );
+ patchedVersion = version;
+ }
+
+ dependencies[name] = patchedVersion;
+}
+
+function fixDependencies(packageName) {
+ const packagePath = path.join(process.cwd(), 'package.json');
+ const packageJson = require(packagePath);
+
+ if (typeof packageJson.dependencies === 'undefined') {
+ console.error(chalk.red('Missing dependencies in package.json'));
+ process.exit(1);
+ }
+
+ const packageVersion = packageJson.dependencies[packageName];
+
+ if (typeof packageVersion === 'undefined') {
+ console.error(chalk.red(`Unable to find ${packageName} in package.json`));
+ process.exit(1);
+ }
+
+ packageJson.devDependencies = packageJson.devDependencies || {};
+ packageJson.devDependencies[packageName] = packageVersion;
+ delete packageJson.dependencies[packageName];
+
+ makeCaretRange(packageJson.dependencies, 'react');
+ makeCaretRange(packageJson.dependencies, 'react-dom');
+
+ fs.writeFileSync(packagePath, JSON.stringify(packageJson, null, 2));
+}
+
+// If project only contains files generated by GH, it’s safe.
+// We also special case IJ-based products .idea because it integrates with CRA:
+// https://github.com/facebookincubator/create-react-app/pull/368#issuecomment-243446094
+function isSafeToCreateProjectIn(root) {
+ const validFiles = [
+ '.DS_Store',
+ 'Thumbs.db',
+ '.git',
+ '.gitignore',
+ '.idea',
+ 'README.md',
+ 'LICENSE',
+ 'web.iml',
+ '.hg',
+ '.hgignore',
+ '.hgcheck',
+ ];
+ return fs.readdirSync(root).every(file => validFiles.indexOf(file) >= 0);
+}
+
+function checkIfOnline(useYarn) {
+ if (!useYarn) {
+ // Don't ping the Yarn registry.
+ // We'll just assume the best case.
+ return Promise.resolve(true);
+ }
+
+ return new Promise(resolve => {
+ dns.lookup('registry.yarnpkg.com', err => {
+ resolve(err === null);
+ });
+ });
+}
diff --git a/packages/create-react-app/index.js b/packages/create-react-app/index.js
old mode 100644
new mode 100755
index 4dbb37f4969..19a3ff09fd4
--- a/packages/create-react-app/index.js
+++ b/packages/create-react-app/index.js
@@ -40,243 +40,18 @@
var chalk = require('chalk');
-var currentNodeVersion = process.versions.node
+var currentNodeVersion = process.versions.node;
if (currentNodeVersion.split('.')[0] < 4) {
console.error(
chalk.red(
- 'You are running Node ' + currentNodeVersion + '.\n' +
- 'Create React App requires Node 4 or higher. \n' +
- 'Please update your version of Node.'
+ 'You are running Node ' +
+ currentNodeVersion +
+ '.\n' +
+ 'Create React App requires Node 4 or higher. \n' +
+ 'Please update your version of Node.'
)
);
process.exit(1);
}
-var commander = require('commander');
-var fs = require('fs-extra');
-var path = require('path');
-var execSync = require('child_process').execSync;
-var spawn = require('cross-spawn');
-var semver = require('semver');
-
-var projectName;
-
-var program = commander
- .version(require('./package.json').version)
- .arguments('')
- .usage(chalk.green('') + ' [options]')
- .action(function (name) {
- projectName = name;
- })
- .option('--verbose', 'print additional logs')
- .option('--scripts-version ', 'use a non-standard version of react-scripts')
- .allowUnknownOption()
- .on('--help', function () {
- console.log(' Only ' + chalk.green('') + ' is required.');
- console.log();
- console.log(' A custom ' + chalk.cyan('--scripts-version') + ' can be one of:');
- console.log(' - a specific npm version: ' + chalk.green('0.8.2'));
- console.log(' - a custom fork published on npm: ' + chalk.green('my-react-scripts'));
- console.log(' - a .tgz archive: ' + chalk.green('https://mysite.com/my-react-scripts-0.8.2.tgz'));
- console.log(' It is not needed unless you specifically want to use a fork.');
- console.log();
- console.log(' If you have any problems, do not hesitate to file an issue:');
- console.log(' ' + chalk.cyan('https://github.com/facebookincubator/create-react-app/issues/new'));
- console.log();
- })
- .parse(process.argv);
-
-if (typeof projectName === 'undefined') {
- console.error('Please specify the project directory:');
- console.log(' ' + chalk.cyan(program.name()) + chalk.green(' '));
- console.log();
- console.log('For example:');
- console.log(' ' + chalk.cyan(program.name()) + chalk.green(' my-react-app'));
- console.log();
- console.log('Run ' + chalk.cyan(program.name() + ' --help') + ' to see all options.');
- process.exit(1);
-}
-
-var hiddenProgram = new commander.Command()
- .option('--internal-testing-template ', '(internal usage only, DO NOT RELY ON THIS) ' +
- 'use a non-standard application template')
- .parse(process.argv)
-
-createApp(projectName, program.verbose, program.scriptsVersion, hiddenProgram.internalTestingTemplate);
-
-function createApp(name, verbose, version, template) {
- var root = path.resolve(name);
- var appName = path.basename(root);
-
- checkAppName(appName);
- fs.ensureDirSync(name);
- if (!isSafeToCreateProjectIn(root)) {
- console.log('The directory ' + chalk.green(name) + ' contains files that could conflict.');
- console.log('Try using a new directory name.');
- process.exit(1);
- }
-
- console.log(
- 'Creating a new React app in ' + chalk.green(root) + '.'
- );
- console.log();
-
- var packageJson = {
- name: appName,
- version: '0.1.0',
- private: true,
- };
- fs.writeFileSync(
- path.join(root, 'package.json'),
- JSON.stringify(packageJson, null, 2)
- );
- var originalDirectory = process.cwd();
- process.chdir(root);
-
- console.log('Installing packages. This might take a couple minutes.');
- console.log('Installing ' + chalk.cyan('react-scripts') + '...');
- console.log();
-
- run(root, appName, version, verbose, originalDirectory, template);
-}
-
-function shouldUseYarn() {
- try {
- execSync('yarnpkg --version', {stdio: 'ignore'});
- return true;
- } catch (e) {
- return false;
- }
-}
-
-function install(packageToInstall, verbose, callback) {
- var command;
- var args;
- if (shouldUseYarn()) {
- command = 'yarnpkg';
- args = [ 'add', '--dev', '--exact', packageToInstall];
- } else {
- command = 'npm';
- args = ['install', '--save-dev', '--save-exact', packageToInstall];
- }
-
- if (verbose) {
- args.push('--verbose');
- }
-
- var child = spawn(command, args, {stdio: 'inherit'});
- child.on('close', function(code) {
- callback(code, command, args);
- });
-}
-
-function run(root, appName, version, verbose, originalDirectory, template) {
- var packageToInstall = getInstallPackage(version);
- var packageName = getPackageName(packageToInstall);
-
- install(packageToInstall, verbose, function(code, command, args) {
- if (code !== 0) {
- console.error(chalk.cyan(command + ' ' + args.join(' ')) + ' failed');
- process.exit(1);
- }
-
- checkNodeVersion(packageName);
-
- var scriptsPath = path.resolve(
- process.cwd(),
- 'node_modules',
- packageName,
- 'scripts',
- 'init.js'
- );
- var init = require(scriptsPath);
- init(root, appName, verbose, originalDirectory, template);
- });
-}
-
-function getInstallPackage(version) {
- var packageToInstall = 'react-scripts';
- var validSemver = semver.valid(version);
- if (validSemver) {
- packageToInstall += '@' + validSemver;
- } else if (version) {
- // for tar.gz or alternative paths
- packageToInstall = version;
- }
- return packageToInstall;
-}
-
-// Extract package name from tarball url or path.
-function getPackageName(installPackage) {
- if (installPackage.indexOf('.tgz') > -1) {
- // The package name could be with or without semver version, e.g. react-scripts-0.2.0-alpha.1.tgz
- // However, this function returns package name only without semver version.
- return installPackage.match(/^.+\/(.+?)(?:-\d+.+)?\.tgz$/)[1];
- } else if (installPackage.indexOf('@') > 0) {
- // Do not match @scope/ when stripping off @version or @tag
- return installPackage.charAt(0) + installPackage.substr(1).split('@')[0];
- }
- return installPackage;
-}
-
-function checkNodeVersion(packageName) {
- var packageJsonPath = path.resolve(
- process.cwd(),
- 'node_modules',
- packageName,
- 'package.json'
- );
- var packageJson = require(packageJsonPath);
- if (!packageJson.engines || !packageJson.engines.node) {
- return;
- }
-
- if (!semver.satisfies(process.version, packageJson.engines.node)) {
- console.error(
- chalk.red(
- 'You are running Node %s.\n' +
- 'Create React App requires Node %s or higher. \n' +
- 'Please update your version of Node.'
- ),
- process.version,
- packageJson.engines.node
- );
- process.exit(1);
- }
-}
-
-function checkAppName(appName) {
- // TODO: there should be a single place that holds the dependencies
- var dependencies = ['react', 'react-dom'];
- var devDependencies = ['react-scripts'];
- var allDependencies = dependencies.concat(devDependencies).sort();
-
- if (allDependencies.indexOf(appName) >= 0) {
- console.error(
- chalk.red(
- 'We cannot create a project called ' + chalk.green(appName) + ' because a dependency with the same name exists.\n' +
- 'Due to the way npm works, the following names are not allowed:\n\n'
- ) +
- chalk.cyan(
- allDependencies.map(function(depName) {
- return ' ' + depName;
- }).join('\n')
- ) +
- chalk.red('\n\nPlease choose a different project name.')
- );
- process.exit(1);
- }
-}
-
-// If project only contains files generated by GH, it’s safe.
-// We also special case IJ-based products .idea because it integrates with CRA:
-// https://github.com/facebookincubator/create-react-app/pull/368#issuecomment-243446094
-function isSafeToCreateProjectIn(root) {
- var validFiles = [
- '.DS_Store', 'Thumbs.db', '.git', '.gitignore', '.idea', 'README.md', 'LICENSE'
- ];
- return fs.readdirSync(root)
- .every(function(file) {
- return validFiles.indexOf(file) >= 0;
- });
-}
+require('./createReactApp');
diff --git a/packages/create-react-app/package.json b/packages/create-react-app/package.json
index 93df8da55b8..918fcbefa56 100644
--- a/packages/create-react-app/package.json
+++ b/packages/create-react-app/package.json
@@ -1,6 +1,6 @@
{
"name": "create-react-app",
- "version": "1.0.4",
+ "version": "1.3.0",
"keywords": [
"react"
],
@@ -14,7 +14,8 @@
"url": "https://github.com/facebookincubator/create-react-app/issues"
},
"files": [
- "index.js"
+ "index.js",
+ "createReactApp.js"
],
"bin": {
"create-react-app": "./index.js"
@@ -24,6 +25,10 @@
"commander": "^2.9.0",
"cross-spawn": "^4.0.0",
"fs-extra": "^1.0.0",
- "semver": "^5.0.3"
+ "hyperquest": "^2.1.2",
+ "semver": "^5.0.3",
+ "tar-pack": "^3.4.0",
+ "tmp": "0.0.31",
+ "validate-npm-package-name": "^3.0.0"
}
}
diff --git a/packages/eslint-config-react-app/README.md b/packages/eslint-config-react-app/README.md
index 5c20f50ca2e..8eace6efffc 100644
--- a/packages/eslint-config-react-app/README.md
+++ b/packages/eslint-config-react-app/README.md
@@ -1,6 +1,6 @@
# eslint-config-react-app
-This package includes the shareable ESLint configuration used by [Create React App](https://github.com/facebookincubator/create-react-app).
+This package includes the shareable ESLint configuration used by [Create React App](https://github.com/facebookincubator/create-react-app).
Please refer to its documentation:
* [Getting Started](https://github.com/facebookincubator/create-react-app/blob/master/README.md#getting-started) – How to create a new app.
@@ -17,7 +17,7 @@ If you want to use this ESLint configuration in a project not built with Create
First, install this package, ESLint and the necessary plugins.
```sh
- npm install --save-dev eslint-config-react-app babel-eslint@7.0.0 eslint@3.8.1 eslint-plugin-flowtype@2.21.0 eslint-plugin-import@2.0.1 eslint-plugin-jsx-a11y@2.2.3 eslint-plugin-react@6.4.1
+ npm install --save-dev eslint-config-react-app babel-eslint@7.1.1 eslint@3.16.1 eslint-plugin-flowtype@2.21.0 eslint-plugin-import@2.0.1 eslint-plugin-jsx-a11y@4.0.0 eslint-plugin-react@6.4.1
```
Then create a file named `.eslintrc` with following contents in the root folder of your project:
diff --git a/packages/eslint-config-react-app/index.js b/packages/eslint-config-react-app/index.js
index d93478bc8c9..b909db3e21b 100644
--- a/packages/eslint-config-react-app/index.js
+++ b/packages/eslint-config-react-app/index.js
@@ -7,6 +7,8 @@
* of patent rights can be found in the PATENTS file in the same directory.
*/
+'use strict';
+
// Inspired by https://github.com/airbnb/javascript but less opinionated.
// We use eslint-loader so even warnings are very visible.
@@ -28,7 +30,7 @@ module.exports = {
commonjs: true,
es6: true,
jest: true,
- node: true
+ node: true,
},
parserOptions: {
@@ -37,20 +39,18 @@ module.exports = {
ecmaFeatures: {
jsx: true,
generators: true,
- experimentalObjectRestSpread: true
- }
+ experimentalObjectRestSpread: true,
+ },
},
settings: {
- 'import/ignore': [
- 'node_modules'
- ],
+ 'import/ignore': ['node_modules'],
'import/extensions': ['.js'],
'import/resolver': {
node: {
- extensions: ['.js', '.json']
- }
- }
+ extensions: ['.js', '.json'],
+ },
+ },
},
rules: {
@@ -59,7 +59,6 @@ module.exports = {
'default-case': ['warn', { commentPattern: '^no default$' }],
'dot-location': ['warn', 'property'],
eqeqeq: ['warn', 'allow-null'],
- 'guard-for-in': 'warn',
'new-parens': 'warn',
'no-array-constructor': 'warn',
'no-caller': 'warn',
@@ -87,15 +86,18 @@ module.exports = {
'no-labels': ['warn', { allowLoop: false, allowSwitch: false }],
'no-lone-blocks': 'warn',
'no-loop-func': 'warn',
- 'no-mixed-operators': ['warn', {
- groups: [
- ['&', '|', '^', '~', '<<', '>>', '>>>'],
- ['==', '!=', '===', '!==', '>', '>=', '<', '<='],
- ['&&', '||'],
- ['in', 'instanceof']
- ],
- allowSamePrecedence: false
- }],
+ 'no-mixed-operators': [
+ 'warn',
+ {
+ groups: [
+ ['&', '|', '^', '~', '<<', '>>', '>>>'],
+ ['==', '!=', '===', '!==', '>', '>=', '<', '<='],
+ ['&&', '||'],
+ ['in', 'instanceof'],
+ ],
+ allowSamePrecedence: false,
+ },
+ ],
'no-multi-str': 'warn',
'no-native-reassign': 'warn',
'no-negated-in-lhs': 'warn',
@@ -108,11 +110,7 @@ module.exports = {
'no-octal-escape': 'warn',
'no-redeclare': 'warn',
'no-regex-spaces': 'warn',
- 'no-restricted-syntax': [
- 'warn',
- 'LabeledStatement',
- 'WithStatement',
- ],
+ 'no-restricted-syntax': ['warn', 'LabeledStatement', 'WithStatement'],
'no-script-url': 'warn',
'no-self-assign': 'warn',
'no-self-compare': 'warn',
@@ -123,28 +121,39 @@ module.exports = {
'no-this-before-super': 'warn',
'no-throw-literal': 'warn',
'no-undef': 'error',
+ 'no-restricted-globals': ['error', 'event'],
'no-unexpected-multiline': 'warn',
'no-unreachable': 'warn',
- 'no-unused-expressions': ['warn', {
- 'allowShortCircuit': true,
- 'allowTernary': true
- }],
+ 'no-unused-expressions': [
+ 'warn',
+ {
+ allowShortCircuit: true,
+ allowTernary: true,
+ },
+ ],
'no-unused-labels': 'warn',
- 'no-unused-vars': ['warn', {
- vars: 'local',
- varsIgnorePattern: '^_',
- args: 'none'
- }],
+ 'no-unused-vars': [
+ 'warn',
+ {
+ vars: 'local',
+ varsIgnorePattern: '^_',
+ args: 'none',
+ ignoreRestSiblings: true,
+ },
+ ],
'no-use-before-define': ['warn', 'nofunc'],
'no-useless-computed-key': 'warn',
'no-useless-concat': 'warn',
'no-useless-constructor': 'warn',
'no-useless-escape': 'warn',
- 'no-useless-rename': ['warn', {
- ignoreDestructuring: false,
- ignoreImport: false,
- ignoreExport: false,
- }],
+ 'no-useless-rename': [
+ 'warn',
+ {
+ ignoreDestructuring: false,
+ ignoreImport: false,
+ ignoreExport: false,
+ },
+ ],
'no-with': 'warn',
'no-whitespace-before-property': 'warn',
'operator-assignment': ['warn', 'always'],
@@ -155,6 +164,19 @@ module.exports = {
'unicode-bom': ['warn', 'never'],
'use-isnan': 'warn',
'valid-typeof': 'warn',
+ 'no-restricted-properties': [
+ 'error',
+ {
+ object: 'require',
+ property: 'ensure',
+ message: 'Please use import() instead. More info: https://webpack.js.org/guides/code-splitting-import/#dynamic-import',
+ },
+ {
+ object: 'System',
+ property: 'import',
+ message: 'Please use import() instead. More info: https://webpack.js.org/guides/code-splitting-import/#dynamic-import',
+ },
+ ],
// https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/
@@ -190,10 +212,13 @@ module.exports = {
'react/jsx-equals-spacing': ['warn', 'never'],
'react/jsx-no-duplicate-props': ['warn', { ignoreCase: true }],
'react/jsx-no-undef': 'error',
- 'react/jsx-pascal-case': ['warn', {
- allowAllCaps: true,
- ignore: [],
- }],
+ 'react/jsx-pascal-case': [
+ 'warn',
+ {
+ allowAllCaps: true,
+ ignore: [],
+ },
+ ],
'react/jsx-uses-react': 'warn',
'react/jsx-uses-vars': 'warn',
'react/no-danger-with-children': 'warn',
@@ -213,6 +238,6 @@ module.exports = {
// https://github.com/gajus/eslint-plugin-flowtype
'flowtype/define-flow-type': 'warn',
'flowtype/require-valid-file-annotation': 'warn',
- 'flowtype/use-flow-type': 'warn'
- }
+ 'flowtype/use-flow-type': 'warn',
+ },
};
diff --git a/packages/eslint-config-react-app/package.json b/packages/eslint-config-react-app/package.json
index 87c7e8742f7..855713e4f46 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": "0.5.1",
+ "version": "0.6.1",
"description": "ESLint configuration used by Create React App",
"repository": "facebookincubator/create-react-app",
"license": "BSD-3-Clause",
@@ -12,10 +12,10 @@
],
"peerDependencies": {
"babel-eslint": "^7.0.0",
- "eslint": "^3.8.1",
+ "eslint": "^3.16.1",
"eslint-plugin-flowtype": "^2.21.0",
"eslint-plugin-import": "^2.0.1",
- "eslint-plugin-jsx-a11y": "^2.2.3",
+ "eslint-plugin-jsx-a11y": "^2.0.0 || ^3.0.0 || ^4.0.0",
"eslint-plugin-react": "^6.4.1"
}
}
diff --git a/packages/react-dev-utils/FileSizeReporter.js b/packages/react-dev-utils/FileSizeReporter.js
new file mode 100644
index 00000000000..a0db0684f4a
--- /dev/null
+++ b/packages/react-dev-utils/FileSizeReporter.js
@@ -0,0 +1,112 @@
+/**
+ * Copyright (c) 2015-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
+'use strict';
+
+var fs = require('fs');
+var path = require('path');
+var chalk = require('chalk');
+var filesize = require('filesize');
+var recursive = require('recursive-readdir');
+var stripAnsi = require('strip-ansi');
+var gzipSize = require('gzip-size').sync;
+
+// Prints a detailed summary of build files.
+function printFileSizesAfterBuild(webpackStats, previousSizeMap) {
+ 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('build', path.dirname(asset.name)),
+ name: path.basename(asset.name),
+ size: size,
+ sizeLabel: filesize(size) + (difference ? ' (' + difference + ')' : ''),
+ };
+ });
+ assets.sort((a, b) => b.size - a.size);
+ var longestSizeLabelLength = Math.max.apply(
+ null,
+ assets.map(a => stripAnsi(a.sizeLabel).length)
+ );
+ assets.forEach(asset => {
+ var sizeLabel = asset.sizeLabel;
+ var sizeLength = stripAnsi(sizeLabel).length;
+ if (sizeLength < longestSizeLabelLength) {
+ var rightPadding = ' '.repeat(longestSizeLabelLength - sizeLength);
+ sizeLabel += rightPadding;
+ }
+ console.log(
+ ' ' +
+ sizeLabel +
+ ' ' +
+ chalk.dim(asset.folder + path.sep) +
+ chalk.cyan(asset.name)
+ );
+ });
+}
+
+function removeFileNameHash(buildFolder, fileName) {
+ return fileName
+ .replace(buildFolder, '')
+ .replace(/\/?(.*)(\.\w+)(\.js|\.css)/, (match, p1, p2, p3) => p1 + p3);
+}
+
+// Input: 1024, 2048
+// Output: "(+1 KB)"
+function getDifferenceLabel(currentSize, previousSize) {
+ var FIFTY_KILOBYTES = 1024 * 50;
+ var difference = currentSize - previousSize;
+ var fileSize = !Number.isNaN(difference) ? filesize(difference) : 0;
+ if (difference >= FIFTY_KILOBYTES) {
+ return chalk.red('+' + fileSize);
+ } else if (difference < FIFTY_KILOBYTES && difference > 0) {
+ return chalk.yellow('+' + fileSize);
+ } else if (difference < 0) {
+ return chalk.green(fileSize);
+ } else {
+ return '';
+ }
+}
+
+function measureFileSizesBeforeBuild(buildFolder) {
+ return new Promise(resolve => {
+ recursive(buildFolder, (err, fileNames) => {
+ var sizes;
+ if (!err && fileNames) {
+ sizes = fileNames
+ .filter(fileName => /\.(js|css)$/.test(fileName))
+ .reduce(
+ (memo, fileName) => {
+ var contents = fs.readFileSync(fileName);
+ var key = removeFileNameHash(buildFolder, fileName);
+ memo[key] = gzipSize(contents);
+ return memo;
+ },
+ {}
+ );
+ }
+ resolve({
+ root: buildFolder,
+ sizes: sizes || {},
+ });
+ });
+ });
+}
+
+module.exports = {
+ measureFileSizesBeforeBuild: measureFileSizesBeforeBuild,
+ printFileSizesAfterBuild: printFileSizesAfterBuild,
+};
diff --git a/packages/react-dev-utils/InterpolateHtmlPlugin.js b/packages/react-dev-utils/InterpolateHtmlPlugin.js
index 07558f47830..ac1d3e9967d 100644
--- a/packages/react-dev-utils/InterpolateHtmlPlugin.js
+++ b/packages/react-dev-utils/InterpolateHtmlPlugin.js
@@ -25,7 +25,8 @@ class InterpolateHtmlPlugin {
apply(compiler) {
compiler.plugin('compilation', compilation => {
- compilation.plugin('html-webpack-plugin-before-html-processing',
+ compilation.plugin(
+ 'html-webpack-plugin-before-html-processing',
(data, callback) => {
// Run HTML through a series of user-specified string replacements.
Object.keys(this.replacements).forEach(key => {
diff --git a/packages/react-dev-utils/README.md b/packages/react-dev-utils/README.md
index 455996fcc59..26d762c3597 100644
--- a/packages/react-dev-utils/README.md
+++ b/packages/react-dev-utils/README.md
@@ -1,6 +1,6 @@
# react-dev-utils
-This package includes some utilities used by [Create React App](https://github.com/facebookincubator/create-react-app).
+This package includes some utilities used by [Create React App](https://github.com/facebookincubator/create-react-app).
Please refer to its documentation:
* [Getting Started](https://github.com/facebookincubator/create-react-app/blob/master/README.md#getting-started) – How to create a new app.
@@ -20,7 +20,7 @@ There is no single entry point. You can only import individual top-level modules
#### `new InterpolateHtmlPlugin(replacements: {[key:string]: string})`
-This Webpack plugin lets us interpolate custom variables into `index.html`.
+This Webpack plugin lets us interpolate custom variables into `index.html`.
It works in tandem with [HtmlWebpackPlugin](https://github.com/ampedandwired/html-webpack-plugin) 2.x via its [events](https://github.com/ampedandwired/html-webpack-plugin#events).
```js
@@ -58,8 +58,8 @@ module.exports = {
#### `new WatchMissingNodeModulesPlugin(nodeModulesPath: string)`
-This Webpack plugin ensures `npm install ` forces a project rebuild.
-We’re not sure why this isn't Webpack's default behavior.
+This Webpack plugin ensures `npm install ` forces a project rebuild.
+We’re not sure why this isn't Webpack's default behavior.
See [#186](https://github.com/facebookincubator/create-react-app/issues/186) for details.
```js
@@ -83,8 +83,8 @@ module.exports = {
#### `checkRequiredFiles(files: Array): boolean`
-Makes sure that all passed files exist.
-Filenames are expected to be absolute.
+Makes sure that all passed files exist.
+Filenames are expected to be absolute.
If a file is not found, prints a warning message and returns `false`.
```js
@@ -110,6 +110,29 @@ clearConsole();
console.log('Just cleared the screen!');
```
+#### `FileSizeReporter`
+
+##### `measureFileSizesBeforeBuild(buildFolder: string): Promise`
+
+Captures JS and CSS asset sizes inside the passed `buildFolder`. Save the result value to compare it after the build.
+
+##### `printFileSizesAfterBuild(webpackStats: WebpackStats, previousFileSizes: OpaqueFileSizes)`
+
+Prints the JS and CSS asset sizes after the build, and includes a size comparison with `previousFileSizes` that were captured earlier using `measureFileSizesBeforeBuild()`.
+
+```js
+var {
+ measureFileSizesBeforeBuild,
+ printFileSizesAfterBuild,
+} = require('react-dev-utils/FileSizeReporter');
+
+measureFileSizesBeforeBuild(buildFolder).then(previousFileSizes => {
+ return cleanAndRebuild().then(webpackStats => {
+ printFileSizesAfterBuild(webpackStats, previousFileSizes);
+ });
+});
+```
+
#### `formatWebpackMessages({errors: Array, warnings: Array}): {errors: Array, warnings: Array}`
Extracts and prettifies warning and error messages from webpack [stats](https://github.com/webpack/docs/wiki/node.js-api#stats) object.
@@ -161,8 +184,8 @@ getProcessForPort(3000);
#### `openBrowser(url: string): boolean`
-Attempts to open the browser with a given URL.
-On Mac OS X, attempts to reuse an existing Chrome tab via AppleScript.
+Attempts to open the browser with a given URL.
+On Mac OS X, attempts to reuse an existing Chrome tab via AppleScript.
Otherwise, falls back to [opn](https://github.com/sindresorhus/opn) behavior.
@@ -179,8 +202,8 @@ if (openBrowser('http://localhost:3000')) {
This function displays a console prompt to the user.
-By convention, "no" should be the conservative choice.
-If you mistype the answer, we'll always take it as a "no".
+By convention, "no" should be the conservative choice.
+If you mistype the answer, we'll always take it as a "no".
You can control the behavior on `` with `isYesDefault`.
```js
diff --git a/packages/react-dev-utils/ansiHTML.js b/packages/react-dev-utils/ansiHTML.js
new file mode 100644
index 00000000000..1144fec5e65
--- /dev/null
+++ b/packages/react-dev-utils/ansiHTML.js
@@ -0,0 +1,101 @@
+/**
+ * Copyright (c) 2015-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
+'use strict';
+
+var Anser = require('anser');
+
+// Color scheme inspired by https://chriskempson.github.io/base16/css/base16-github.css
+// var base00 = 'ffffff'; // Default Background
+var base01 = 'f5f5f5'; // Lighter Background (Used for status bars)
+// var base02 = 'c8c8fa'; // Selection Background
+var base03 = '969896'; // Comments, Invisibles, Line Highlighting
+// var base04 = 'e8e8e8'; // Dark Foreground (Used for status bars)
+var base05 = '333333'; // Default Foreground, Caret, Delimiters, Operators
+// var base06 = 'ffffff'; // Light Foreground (Not often used)
+// var base07 = 'ffffff'; // Light Background (Not often used)
+var base08 = 'ed6a43'; // Variables, XML Tags, Markup Link Text, Markup Lists, Diff Deleted
+// var base09 = '0086b3'; // Integers, Boolean, Constants, XML Attributes, Markup Link Url
+// var base0A = '795da3'; // Classes, Markup Bold, Search Text Background
+var base0B = '183691'; // Strings, Inherited Class, Markup Code, Diff Inserted
+var base0C = '183691'; // Support, Regular Expressions, Escape Characters, Markup Quotes
+// var base0D = '795da3'; // Functions, Methods, Attribute IDs, Headings
+var base0E = 'a71d5d'; // Keywords, Storage, Selector, Markup Italic, Diff Changed
+// var base0F = '333333'; // Deprecated, Opening/Closing Embedded Language Tags e.g.
+
+// Map ANSI colors from what babel-code-frame uses to base16-github
+// See: https://github.com/babel/babel/blob/e86f62b304d280d0bab52c38d61842b853848ba6/packages/babel-code-frame/src/index.js#L9-L22
+var colors = {
+ reset: [base05, 'transparent'],
+ black: base05,
+ red: base08 /* marker, bg-invalid */,
+ green: base0B /* string */,
+ yellow: base08 /* capitalized, jsx_tag, punctuator */,
+ blue: base0C,
+ magenta: base0C /* regex */,
+ cyan: base0E /* keyword */,
+ gray: base03 /* comment, gutter */,
+ lightgrey: base01,
+ darkgrey: base03,
+};
+
+var anserMap = {
+ 'ansi-bright-black': 'black',
+ 'ansi-bright-yellow': 'yellow',
+ 'ansi-yellow': 'yellow',
+ 'ansi-bright-green': 'green',
+ 'ansi-green': 'green',
+ 'ansi-bright-cyan': 'cyan',
+ 'ansi-cyan': 'cyan',
+ 'ansi-bright-red': 'red',
+ 'ansi-red': 'red',
+ 'ansi-bright-magenta': 'magenta',
+ 'ansi-magenta': 'magenta',
+};
+
+function ansiHTML(txt) {
+ var arr = new Anser().ansiToJson(txt, {
+ use_classes: true,
+ });
+
+ var result = '';
+ var open = false;
+ for (var index = 0; index < arr.length; ++index) {
+ var c = arr[index];
+ var content = c.content, fg = c.fg;
+
+ var contentParts = content.split('\n');
+ for (var _index = 0; _index < contentParts.length; ++_index) {
+ if (!open) {
+ result += '';
+ open = true;
+ }
+ var part = contentParts[_index].replace('\r', '');
+ var color = colors[anserMap[fg]];
+ if (color != null) {
+ result += '' + part + '';
+ } else {
+ if (fg != null) console.log('Missing color mapping: ', fg);
+ result += '' + part + '';
+ }
+ if (_index < contentParts.length - 1) {
+ result += '';
+ open = false;
+ result += ' ';
+ }
+ }
+ }
+ if (open) {
+ result += '';
+ open = false;
+ }
+ return result;
+}
+
+module.exports = ansiHTML;
diff --git a/packages/react-dev-utils/checkRequiredFiles.js b/packages/react-dev-utils/checkRequiredFiles.js
index 69233db4837..55139b0b870 100644
--- a/packages/react-dev-utils/checkRequiredFiles.js
+++ b/packages/react-dev-utils/checkRequiredFiles.js
@@ -7,6 +7,8 @@
* of patent rights can be found in the PATENTS file in the same directory.
*/
+'use strict';
+
var fs = require('fs');
var path = require('path');
var chalk = require('chalk');
diff --git a/packages/react-dev-utils/clearConsole.js b/packages/react-dev-utils/clearConsole.js
index cfd10155167..05ab28c44d2 100644
--- a/packages/react-dev-utils/clearConsole.js
+++ b/packages/react-dev-utils/clearConsole.js
@@ -7,8 +7,12 @@
* of patent rights can be found in the PATENTS file in the same directory.
*/
+'use strict';
+
function clearConsole() {
- process.stdout.write(process.platform === 'win32' ? '\x1Bc' : '\x1B[2J\x1B[3J\x1B[H');
+ process.stdout.write(
+ process.platform === 'win32' ? '\x1Bc' : '\x1B[2J\x1B[3J\x1B[H'
+ );
}
module.exports = clearConsole;
diff --git a/packages/react-dev-utils/crashOverlay.js b/packages/react-dev-utils/crashOverlay.js
new file mode 100644
index 00000000000..4f58e927f3c
--- /dev/null
+++ b/packages/react-dev-utils/crashOverlay.js
@@ -0,0 +1,935 @@
+/**
+ * Copyright (c) 2015-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
+'use strict';
+
+var codeFrame = require('babel-code-frame');
+var ansiHTML = require('./ansiHTML');
+var StackTraceResolve = require('stack-frame-resolver').default;
+
+var CONTEXT_SIZE = 3;
+
+var black = '#293238';
+var darkGray = '#878e91';
+var lightGray = '#fafafa';
+var red = '#ce1126';
+var lightRed = '#fccfcf';
+var yellow = '#fbf5b4';
+
+function getHead() {
+ return document.head || document.getElementsByTagName('head')[0];
+}
+
+var injectedCss = [];
+
+// From: http://stackoverflow.com/a/524721/127629
+function injectCss(css) {
+ var head = getHead();
+ var style = document.createElement('style');
+
+ style.type = 'text/css';
+ if (style.styleSheet) {
+ style.styleSheet.cssText = css;
+ } else {
+ style.appendChild(document.createTextNode(css));
+ }
+
+ head.appendChild(style);
+ injectedCss.push(style);
+}
+
+var css = [
+ '.cra-container {',
+ ' padding-right: 15px;',
+ ' padding-left: 15px;',
+ ' margin-right: auto;',
+ ' margin-left: auto;',
+ '}',
+ '',
+ '@media (min-width: 768px) {',
+ ' .cra-container {',
+ ' width: calc(750px - 6em);',
+ ' }',
+ '}',
+ '',
+ '@media (min-width: 992px) {',
+ ' .cra-container {',
+ ' width: calc(970px - 6em);',
+ ' }',
+ '}',
+ '',
+ '@media (min-width: 1200px) {',
+ ' .cra-container {',
+ ' width: calc(1170px - 6em);',
+ ' }',
+ '}',
+].join('\n');
+
+var overlayStyle = {
+ position: 'fixed',
+ 'box-sizing': 'border-box',
+ top: '1em',
+ left: '1em',
+ bottom: '1em',
+ right: '1em',
+ width: 'calc(100% - 2em)',
+ height: 'calc(100% - 2em)',
+ 'border-radius': '3px',
+ 'background-color': lightGray,
+ padding: '4rem',
+ 'z-index': 1337,
+ 'font-family': 'Consolas, Menlo, monospace',
+ color: black,
+ 'white-space': 'pre-wrap',
+ overflow: 'auto',
+ 'overflow-x': 'hidden',
+ 'word-break': 'break-all',
+ 'box-shadow': '0 0 6px 0 rgba(0, 0, 0, 0.5)',
+ 'line-height': 1.5,
+};
+
+var hintsStyle = {
+ 'font-size': '0.8em',
+ 'margin-top': '-3em',
+ 'margin-bottom': '3em',
+ 'text-align': 'right',
+ color: darkGray,
+};
+
+var hintStyle = {
+ padding: '0.5em 1em',
+ cursor: 'pointer',
+};
+
+var closeButtonStyle = {
+ 'font-size': '26px',
+ color: black,
+ padding: '0.5em 1em',
+ cursor: 'pointer',
+ position: 'absolute',
+ right: 0,
+ top: 0,
+};
+
+var additionalStyle = {
+ 'margin-bottom': '1.5em',
+ 'margin-top': '-4em',
+};
+
+var headerStyle = {
+ 'font-size': '1.7em',
+ 'font-weight': 'bold',
+ color: red,
+};
+
+var functionNameStyle = {
+ 'margin-top': '1em',
+ 'font-size': '1.2em',
+};
+
+var linkStyle = {
+ 'font-size': '0.9em',
+};
+
+var anchorStyle = {
+ 'text-decoration': 'none',
+ color: darkGray,
+};
+
+var traceStyle = {
+ 'font-size': '1em',
+};
+
+var depStyle = {
+ 'font-size': '1.2em',
+};
+
+var primaryErrorStyle = {
+ 'background-color': lightRed,
+};
+
+var secondaryErrorStyle = {
+ 'background-color': yellow,
+};
+
+var omittedFramesStyle = {
+ color: black,
+ 'font-size': '0.9em',
+ margin: '1.5em 0',
+ cursor: 'pointer',
+};
+
+var preStyle = {
+ display: 'block',
+ padding: '0.5em',
+ 'margin-top': '1.5em',
+ 'margin-bottom': '0px',
+ 'overflow-x': 'auto',
+ 'font-size': '1.1em',
+ 'white-space': 'pre',
+};
+
+var toggleStyle = {
+ 'margin-bottom': '1.5em',
+ color: darkGray,
+ cursor: 'pointer',
+};
+
+var codeStyle = {
+ 'font-family': 'Consolas, Menlo, monospace',
+};
+
+var hiddenStyle = {
+ display: 'none',
+};
+
+var groupStyle = {
+ 'margin-left': '1em',
+};
+
+var _groupElemStyle = {
+ 'background-color': 'inherit',
+ 'border-color': '#ddd',
+ 'border-width': '1px',
+ 'border-radius': '4px',
+ 'border-style': 'solid',
+ padding: '3px 6px',
+ cursor: 'pointer',
+};
+
+var groupElemLeft = Object.assign({}, _groupElemStyle, {
+ 'border-top-right-radius': '0px',
+ 'border-bottom-right-radius': '0px',
+ 'margin-right': '0px',
+});
+
+var groupElemRight = Object.assign({}, _groupElemStyle, {
+ 'border-top-left-radius': '0px',
+ 'border-bottom-left-radius': '0px',
+ 'margin-left': '-1px',
+});
+
+var footerStyle = {
+ 'text-align': 'center',
+ color: darkGray,
+};
+
+function applyStyles(element, styles) {
+ element.setAttribute('style', '');
+ // Firefox can't handle const due to non-compliant implementation
+ // Revisit Jan 2016
+ // https://developer.mozilla.org/en-US/Firefox/Releases/51#JavaScript
+ // https://bugzilla.mozilla.org/show_bug.cgi?id=1101653
+ for (var key in styles) {
+ if (!styles.hasOwnProperty(key)) continue;
+ var val = styles[key];
+ if (typeof val === 'function') val = val();
+ element.style[key] = val.toString();
+ }
+}
+
+var overlayReference = null;
+var additionalReference = null;
+var capturedErrors = [];
+var viewIndex = -1;
+var frameSettings = [];
+
+function consumeEvent(e) {
+ e.preventDefault();
+ e.target.blur();
+}
+
+function accessify(node) {
+ node.setAttribute('tabindex', 0);
+ node.addEventListener('keydown', function(e) {
+ var key = e.key, which = e.which, keyCode = e.keyCode;
+ if (key === 'Enter' || which === 13 || keyCode === 13) {
+ e.preventDefault();
+ e.target.click();
+ }
+ });
+}
+
+function renderAdditional() {
+ if (additionalReference.lastChild) {
+ additionalReference.removeChild(additionalReference.lastChild);
+ }
+
+ var text = ' ';
+ if (capturedErrors.length <= 1) {
+ additionalReference.appendChild(document.createTextNode(text));
+ return;
+ }
+ text = 'Errors ' + (viewIndex + 1) + ' of ' + capturedErrors.length;
+ var span = document.createElement('span');
+ span.appendChild(document.createTextNode(text));
+ var group = document.createElement('span');
+ applyStyles(group, groupStyle);
+ var left = document.createElement('button');
+ applyStyles(left, groupElemLeft);
+ left.addEventListener('click', function(e) {
+ consumeEvent(e);
+ switchError(-1);
+ });
+ left.appendChild(document.createTextNode('←'));
+ accessify(left);
+ var right = document.createElement('button');
+ applyStyles(right, groupElemRight);
+ right.addEventListener('click', function(e) {
+ consumeEvent(e);
+ switchError(1);
+ });
+ right.appendChild(document.createTextNode('→'));
+ accessify(right);
+ group.appendChild(left);
+ group.appendChild(right);
+ span.appendChild(group);
+ additionalReference.appendChild(span);
+}
+
+function removeNextBr(parent, component) {
+ while (component != null && component.tagName.toLowerCase() !== 'br') {
+ component = component.nextSibling;
+ }
+ if (component != null) {
+ parent.removeChild(component);
+ }
+}
+
+function absolutifyCode(component) {
+ var ccn = component.childNodes;
+ for (var index = 0; index < ccn.length; ++index) {
+ var c = ccn[index];
+ if (c.tagName.toLowerCase() !== 'span') continue;
+ var text = c.innerText.replace(/\s/g, '');
+ if (text !== '|^') continue;
+ c.style.position = 'absolute';
+ removeNextBr(component, c);
+ }
+}
+
+function sourceCodePre(sourceLines, lineNum, columnNum) {
+ var main = arguments.length > 3 && arguments[3] !== undefined
+ ? arguments[3]
+ : false;
+
+ var sourceCode = [];
+ var whiteSpace = Infinity;
+ sourceLines.forEach(function(_ref2) {
+ var text = _ref2.text;
+
+ var m = text.match(/^\s*/);
+ if (text === '') return;
+ if (m && m[0]) {
+ whiteSpace = Math.min(whiteSpace, m[0].length);
+ } else {
+ whiteSpace = 0;
+ }
+ });
+ sourceLines.forEach(function(_ref3) {
+ var text = _ref3.text, line = _ref3.line;
+
+ if (isFinite(whiteSpace)) text = text.substring(whiteSpace);
+ sourceCode[line - 1] = text;
+ });
+ sourceCode = sourceCode.join('\n');
+ var ansiHighlight = codeFrame(
+ sourceCode,
+ lineNum,
+ columnNum - (isFinite(whiteSpace) ? whiteSpace : 0),
+ {
+ forceColor: true,
+ linesAbove: CONTEXT_SIZE,
+ linesBelow: CONTEXT_SIZE,
+ }
+ );
+ var htmlHighlight = ansiHTML(ansiHighlight);
+ var code = document.createElement('code');
+ code.innerHTML = htmlHighlight;
+ absolutifyCode(code);
+ applyStyles(code, codeStyle);
+
+ var ccn = code.childNodes;
+ for (var index = 0; index < ccn.length; ++index) {
+ var node = ccn[index];
+ var breakOut = false;
+ var ccn2 = node.childNodes;
+ for (var index2 = 0; index2 < ccn2.length; ++index2) {
+ var lineNode = ccn2[index2];
+ if (lineNode.innerText.indexOf(' ' + lineNum + ' |') === -1) continue;
+ applyStyles(node, main ? primaryErrorStyle : secondaryErrorStyle);
+ breakOut = true;
+ }
+ if (breakOut) break;
+ }
+ var pre = document.createElement('pre');
+ applyStyles(pre, preStyle);
+ pre.appendChild(code);
+ return pre;
+}
+
+function createHint(hint) {
+ var span = document.createElement('span');
+ span.appendChild(document.createTextNode(hint));
+ applyStyles(span, hintStyle);
+ return span;
+}
+
+function hintsDiv() {
+ var hints = document.createElement('div');
+ applyStyles(hints, hintsStyle);
+
+ var close = createHint('×');
+ close.addEventListener('click', function() {
+ unmount();
+ });
+ applyStyles(close, closeButtonStyle);
+ hints.appendChild(close);
+ return hints;
+}
+
+function frameDiv(functionName, url, internalUrl) {
+ var frame = document.createElement('div');
+ var frameFunctionName = document.createElement('div');
+
+ var cleanedFunctionName = void 0;
+ if (!functionName || functionName === 'Object.') {
+ cleanedFunctionName = '(anonymous function)';
+ } else {
+ cleanedFunctionName = functionName;
+ }
+
+ var cleanedUrl = url.replace('webpack://', '.');
+
+ if (internalUrl) {
+ applyStyles(
+ frameFunctionName,
+ Object.assign({}, functionNameStyle, depStyle)
+ );
+ } else {
+ applyStyles(frameFunctionName, functionNameStyle);
+ }
+
+ frameFunctionName.appendChild(document.createTextNode(cleanedFunctionName));
+ frame.appendChild(frameFunctionName);
+
+ var frameLink = document.createElement('div');
+ applyStyles(frameLink, linkStyle);
+ var frameAnchor = document.createElement('a');
+ applyStyles(frameAnchor, anchorStyle);
+ //frameAnchor.href = url
+ frameAnchor.appendChild(document.createTextNode(cleanedUrl));
+ frameLink.appendChild(frameAnchor);
+ frame.appendChild(frameLink);
+
+ return frame;
+}
+
+function getGroupToggle(omitsCount, omitBundle) {
+ var omittedFrames = document.createElement('div');
+ accessify(omittedFrames);
+ var text1 = document.createTextNode(
+ '\u25B6 ' + omitsCount + ' stack frames were collapsed.'
+ );
+ omittedFrames.appendChild(text1);
+ omittedFrames.addEventListener('click', function() {
+ var hide = text1.textContent.match(/▲/);
+ var list = document.getElementsByName('bundle-' + omitBundle);
+ for (var index = 0; index < list.length; ++index) {
+ var n = list[index];
+ if (hide) {
+ n.style.display = 'none';
+ } else {
+ n.style.display = '';
+ }
+ }
+ if (hide) {
+ text1.textContent = text1.textContent.replace(/▲/, '▶');
+ text1.textContent = text1.textContent.replace(/expanded/, 'collapsed');
+ } else {
+ text1.textContent = text1.textContent.replace(/▶/, '▲');
+ text1.textContent = text1.textContent.replace(/collapsed/, 'expanded');
+ }
+ });
+ applyStyles(omittedFrames, omittedFramesStyle);
+ return omittedFrames;
+}
+
+function insertBeforeBundle(parent, omitsCount, omitBundle, actionElement) {
+ var children = document.getElementsByName('bundle-' + omitBundle);
+ if (children.length < 1) return;
+ var first = children[0];
+ while (first.parentNode !== parent) {
+ first = first.parentNode;
+ }
+ var div = document.createElement('div');
+ accessify(div);
+ div.setAttribute('name', 'bundle-' + omitBundle);
+ var text = document.createTextNode(
+ '\u25BC ' + omitsCount + ' stack frames were expanded.'
+ );
+ div.appendChild(text);
+ div.addEventListener('click', function() {
+ return actionElement.click();
+ });
+ applyStyles(div, omittedFramesStyle);
+ div.style.display = 'none';
+
+ parent.insertBefore(div, first);
+}
+
+function traceFrame(
+ frameSetting,
+ frame,
+ critical,
+ omits,
+ omitBundle,
+ parentContainer,
+ lastElement
+) {
+ var compiled = frameSetting.compiled;
+ var functionName = frame.functionName,
+ fileName = frame.fileName,
+ lineNumber = frame.lineNumber,
+ columnNumber = frame.columnNumber,
+ scriptLines = frame.scriptLines,
+ sourceFileName = frame.sourceFileName,
+ sourceLineNumber = frame.sourceLineNumber,
+ sourceColumnNumber = frame.sourceColumnNumber,
+ sourceLines = frame.sourceLines;
+
+ var url = void 0;
+ if (!compiled && sourceFileName) {
+ url = sourceFileName + ':' + sourceLineNumber;
+ if (sourceColumnNumber) url += ':' + sourceColumnNumber;
+ } else {
+ url = fileName + ':' + lineNumber;
+ if (columnNumber) url += ':' + columnNumber;
+ }
+
+ var needsHidden = false;
+ var internalUrl = isInternalFile(url, sourceFileName);
+ if (internalUrl) {
+ ++omits.value;
+ needsHidden = true;
+ }
+ var collapseElement = null;
+ if (!internalUrl || lastElement) {
+ if (omits.value > 0) {
+ var omittedFrames = getGroupToggle(omits.value, omitBundle);
+ setTimeout(
+ (function() {
+ insertBeforeBundle.apply(undefined, arguments);
+ }).bind(
+ undefined,
+ parentContainer,
+ omits.value,
+ omitBundle,
+ omittedFrames
+ ),
+ 1
+ );
+ if (lastElement && internalUrl) {
+ collapseElement = omittedFrames;
+ } else {
+ parentContainer.appendChild(omittedFrames);
+ }
+ ++omits.bundle;
+ }
+ omits.value = 0;
+ }
+
+ var elem = frameDiv(functionName, url, internalUrl);
+ if (needsHidden) {
+ applyStyles(elem, hiddenStyle);
+ elem.setAttribute('name', 'bundle-' + omitBundle);
+ }
+
+ var hasSource = false;
+ if (!internalUrl) {
+ if (compiled && scriptLines.length !== 0) {
+ elem.appendChild(
+ sourceCodePre(scriptLines, lineNumber, columnNumber, critical)
+ );
+ hasSource = true;
+ } else if (!compiled && sourceLines.length !== 0) {
+ elem.appendChild(
+ sourceCodePre(
+ sourceLines,
+ sourceLineNumber,
+ sourceColumnNumber,
+ critical
+ )
+ );
+ hasSource = true;
+ }
+ }
+
+ return { elem: elem, hasSource: hasSource, collapseElement: collapseElement };
+}
+
+function lazyFrame(parent, factory, lIndex) {
+ var fac = factory();
+ if (fac == null) return;
+ var hasSource = fac.hasSource,
+ elem = fac.elem,
+ collapseElement = fac.collapseElement;
+
+ var elemWrapper = document.createElement('div');
+ elemWrapper.appendChild(elem);
+
+ if (hasSource) {
+ (function() {
+ var compiledDiv = document.createElement('div');
+ accessify(compiledDiv);
+ applyStyles(compiledDiv, toggleStyle);
+
+ var o = frameSettings[lIndex];
+ var compiledText = document.createTextNode(
+ 'View ' + (o && o.compiled ? 'source' : 'compiled')
+ );
+ compiledDiv.addEventListener('click', function() {
+ if (o) o.compiled = !o.compiled;
+
+ var next = lazyFrame(parent, factory, lIndex);
+ if (next != null) {
+ parent.insertBefore(next, elemWrapper);
+ parent.removeChild(elemWrapper);
+ }
+ });
+ compiledDiv.appendChild(compiledText);
+ elemWrapper.appendChild(compiledDiv);
+ })();
+ }
+
+ if (collapseElement != null) {
+ elemWrapper.appendChild(collapseElement);
+ }
+
+ return elemWrapper;
+}
+
+function traceDiv(resolvedFrames) {
+ var trace = document.createElement('div');
+ applyStyles(trace, traceStyle);
+
+ var index = 0;
+ var critical = true;
+ var omits = { value: 0, bundle: 1 };
+ resolvedFrames.forEach(function(frame) {
+ var lIndex = index++;
+ var elem = lazyFrame(
+ trace,
+ traceFrame.bind(
+ undefined,
+ frameSettings[lIndex],
+ frame,
+ critical,
+ omits,
+ omits.bundle,
+ trace,
+ index === resolvedFrames.length
+ ),
+ lIndex
+ );
+ if (elem == null) return;
+ critical = false;
+ trace.appendChild(elem);
+ });
+ //TODO: fix this
+ omits.value = 0;
+
+ return trace;
+}
+
+function footer() {
+ var div = document.createElement('div');
+ applyStyles(div, footerStyle);
+ div.appendChild(
+ document.createTextNode(
+ 'This screen is visible only in development. It will not appear when the app crashes in production.'
+ )
+ );
+ div.appendChild(document.createElement('br'));
+ div.appendChild(
+ document.createTextNode(
+ 'Open your browser’s developer console to further inspect this error.'
+ )
+ );
+ return div;
+}
+
+function render(error, name, message, resolvedFrames) {
+ dispose();
+
+ frameSettings = resolvedFrames.map(function() {
+ return { compiled: false };
+ });
+
+ injectCss(css);
+
+ // Create overlay
+ var overlay = document.createElement('div');
+ applyStyles(overlay, overlayStyle);
+ overlay.appendChild(hintsDiv());
+
+ // Create container
+ var container = document.createElement('div');
+ container.className = 'cra-container';
+ overlay.appendChild(container);
+
+ // Create additional
+ additionalReference = document.createElement('div');
+ applyStyles(additionalReference, additionalStyle);
+ container.appendChild(additionalReference);
+ renderAdditional();
+
+ // Create header
+ var header = document.createElement('div');
+ applyStyles(header, headerStyle);
+ if (message.match(/^\w*:/)) {
+ header.appendChild(document.createTextNode(message));
+ } else {
+ header.appendChild(document.createTextNode(name + ': ' + message));
+ }
+ container.appendChild(header);
+
+ // Create trace
+ container.appendChild(traceDiv(resolvedFrames));
+
+ // Show message
+ container.appendChild(footer());
+
+ // Mount
+ document.body.appendChild((overlayReference = overlay));
+}
+
+function dispose() {
+ if (overlayReference === null) return;
+ document.body.removeChild(overlayReference);
+ overlayReference = null;
+ var head = getHead();
+ injectedCss.forEach(function(node) {
+ head.removeChild(node);
+ });
+ injectedCss = [];
+}
+
+function unmount() {
+ dispose();
+ capturedErrors = [];
+ viewIndex = -1;
+}
+
+function isInternalFile(url, sourceFileName) {
+ return url.indexOf('/~/') !== -1 ||
+ url.trim().indexOf(' ') !== -1 ||
+ !sourceFileName;
+}
+
+function renderError(index) {
+ viewIndex = index;
+ var _capturedErrors$index = capturedErrors[index],
+ error = _capturedErrors$index.error,
+ unhandledRejection = _capturedErrors$index.unhandledRejection,
+ resolvedFrames = _capturedErrors$index.resolvedFrames;
+
+ if (unhandledRejection) {
+ render(
+ error,
+ 'Unhandled Rejection (' + error.name + ')',
+ error.message,
+ resolvedFrames
+ );
+ } else {
+ render(error, error.name, error.message, resolvedFrames);
+ }
+}
+
+function crash(error) {
+ var unhandledRejection = arguments.length > 1 && arguments[1] !== undefined
+ ? arguments[1]
+ : false;
+ var sourceOverrides = arguments.length > 2 && arguments[2] !== undefined
+ ? arguments[2]
+ : [];
+
+ if (module.hot) module.hot.decline();
+
+ StackTraceResolve(error, CONTEXT_SIZE)
+ .then(function(resolvedFrames) {
+ resolvedFrames = resolvedFrames.filter(function(_ref) {
+ var functionName = _ref.functionName;
+ return functionName.indexOf('__cra_proxy_console__') === -1;
+ });
+ var overrideCount = sourceOverrides.length,
+ frameCount = resolvedFrames.length;
+ var frameIndex = 0;
+ for (
+ var overrideIndex = 0;
+ overrideIndex < overrideCount;
+ ++overrideIndex
+ ) {
+ var tag = sourceOverrides[overrideIndex];
+ var shouldContinue = false;
+ for (; frameIndex < frameCount; ++frameIndex) {
+ var sourceFileName = resolvedFrames[frameIndex].sourceFileName;
+
+ if (sourceFileName == null) continue;
+ if (sourceFileName.indexOf('/' + tag.file) !== -1) {
+ var prevLineNumber = resolvedFrames[frameIndex].sourceLineNumber;
+ if (Math.abs(prevLineNumber - tag.lineNum) < CONTEXT_SIZE) {
+ resolvedFrames[frameIndex].sourceLineNumber = tag.lineNum;
+ }
+ shouldContinue = true;
+ break;
+ }
+ }
+ if (shouldContinue) continue;
+ break;
+ }
+ capturedErrors.push({
+ error: error,
+ unhandledRejection: unhandledRejection,
+ resolvedFrames: resolvedFrames,
+ });
+ if (overlayReference !== null)
+ renderAdditional();
+ else {
+ renderError((viewIndex = 0));
+ }
+ })
+ .catch(function(e) {
+ // This is another fail case (unlikely to happen)
+ // e.g. render(...) throws an error with provided arguments
+ console.log('Red box renderer error:', e);
+ unmount();
+ render(
+ null,
+ 'Error',
+ 'There is an error with red box. *Please* report this (see console).',
+ []
+ );
+ });
+}
+
+function switchError(offset) {
+ try {
+ var nextView = viewIndex + offset;
+ if (nextView < 0 || nextView >= capturedErrors.length) return;
+ renderError(nextView);
+ } catch (e) {
+ console.log('Red box renderer error:', e);
+ unmount();
+ render(
+ null,
+ 'Error',
+ 'There is an error with red box. *Please* report this (see console).',
+ []
+ );
+ }
+}
+
+window.onerror = function(messageOrEvent, source, lineno, colno, error) {
+ if (
+ error == null ||
+ !(error instanceof Error) ||
+ messageOrEvent.indexOf('Script error') !== -1
+ ) {
+ crash(new Error(error || messageOrEvent)); // TODO: more helpful message
+ } else {
+ crash(error);
+ }
+};
+
+var promiseHandler = function promiseHandler(event) {
+ if (event != null && event.reason != null) {
+ var reason = event.reason;
+
+ if (reason == null || !(reason instanceof Error)) {
+ crash(new Error(reason), true);
+ } else {
+ crash(reason, true);
+ }
+ } else {
+ crash(new Error('Unknown event'), true);
+ }
+};
+
+window.addEventListener('unhandledrejection', promiseHandler);
+
+var escapeHandler = function escapeHandler(event) {
+ var key = event.key, keyCode = event.keyCode, which = event.which;
+
+ if (key === 'Escape' || keyCode === 27 || which === 27) unmount();
+ else if (key === 'ArrowLeft' || keyCode === 37 || which === 37)
+ switchError(-1);
+ else if (key === 'ArrowRight' || keyCode === 39 || which === 39)
+ switchError(1);
+};
+
+window.addEventListener('keydown', escapeHandler);
+
+try {
+ Error.stackTraceLimit = 50;
+} catch (e) {
+ // Browser may not support this, we don't care.
+}
+
+// eslint-disable-next-line
+var proxyConsole = function proxyConsole(type) {
+ var orig = console[type];
+ console[type] = function __cra_proxy_console__() {
+ var warning = [].slice.call(arguments).join(' ');
+ var nIndex = warning.indexOf('\n');
+ var message = warning;
+ if (nIndex !== -1) message = message.substring(0, nIndex);
+ var stack = warning
+ .substring(nIndex + 1)
+ .split('\n')
+ .filter(function(line) {
+ return line.indexOf('(at ') !== -1;
+ })
+ .map(function(line) {
+ var prefix = '(at ';
+ var suffix = ')';
+ line = line.substring(line.indexOf(prefix) + prefix.length);
+ line = line.substring(0, line.indexOf(suffix));
+ var parts = line.split(/[:]/g);
+ if (parts.length !== 2) return null;
+ var file = parts[0];
+ var lineNum = Number(parts[1]);
+ if (isNaN(lineNum)) return null;
+ return { file: file, lineNum: lineNum };
+ })
+ .filter(function(obj) {
+ return obj !== null;
+ });
+ var error = void 0;
+ try {
+ throw new Error(message);
+ } catch (e) {
+ error = e;
+ }
+ setTimeout(function() {
+ return crash(error, false, stack);
+ });
+ return orig.apply(this, arguments);
+ };
+};
+
+// proxyConsole('error');
+
+if (module.hot) {
+ module.hot.dispose(function() {
+ unmount();
+ window.removeEventListener('unhandledrejection', promiseHandler);
+ window.removeEventListener('keydown', escapeHandler);
+ });
+}
diff --git a/packages/react-dev-utils/formatWebpackMessages.js b/packages/react-dev-utils/formatWebpackMessages.js
index 88834a9fc62..098c48657e2 100644
--- a/packages/react-dev-utils/formatWebpackMessages.js
+++ b/packages/react-dev-utils/formatWebpackMessages.js
@@ -7,6 +7,8 @@
* of patent rights can be found in the PATENTS file in the same directory.
*/
+'use strict';
+
// WARNING: this code is untranspiled and is used in browser too.
// Please make sure any changes are in ES5 or contribute a Babel compile step.
@@ -44,18 +46,15 @@ function formatMessage(message) {
lines = [
lines[0],
// Clean up message because "Module not found: " is descriptive enough.
- lines[1].replace(
- 'Cannot resolve \'file\' or \'directory\' ', ''
- ).replace(
- 'Cannot resolve module ', ''
- ).replace(
- 'Error: ', ''
- ),
+ lines[1]
+ .replace("Cannot resolve 'file' or 'directory' ", '')
+ .replace('Cannot resolve module ', '')
+ .replace('Error: ', ''),
// Skip all irrelevant lines.
// (For some reason they only appear on the client in browser.)
'',
- lines[lines.length - 1] // error location is the last line
- ]
+ lines[lines.length - 1], // error location is the last line
+ ];
}
// Cleans up syntax error messages.
@@ -106,7 +105,8 @@ function formatMessage(message) {
// from user code generated by WebPack. For more information see
// https://github.com/facebookincubator/create-react-app/pull/1050
message = message.replace(
- /^\s*at\s((?!webpack:).)*:\d+:\d+[\s\)]*(\n|$)/gm, ''
+ /^\s*at\s((?!webpack:).)*:\d+:\d+[\s\)]*(\n|$)/gm,
+ ''
); // at ... ...:x:y
return message;
@@ -114,14 +114,14 @@ function formatMessage(message) {
function formatWebpackMessages(json) {
var formattedErrors = json.errors.map(function(message) {
- return 'Error in ' + formatMessage(message)
+ return 'Error in ' + formatMessage(message);
});
var formattedWarnings = json.warnings.map(function(message) {
- return 'Warning in ' + formatMessage(message)
+ return 'Warning in ' + formatMessage(message);
});
var result = {
errors: formattedErrors,
- warnings: formattedWarnings
+ warnings: formattedWarnings,
};
if (result.errors.some(isLikelyASyntaxError)) {
// If there are any syntax errors, show just them.
diff --git a/packages/react-dev-utils/getProcessForPort.js b/packages/react-dev-utils/getProcessForPort.js
index 5540fbad47a..2d9e531c381 100644
--- a/packages/react-dev-utils/getProcessForPort.js
+++ b/packages/react-dev-utils/getProcessForPort.js
@@ -1,3 +1,14 @@
+/**
+ * Copyright (c) 2015-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
+'use strict';
+
var chalk = require('chalk');
var execSync = require('child_process').execSync;
var path = require('path');
@@ -7,8 +18,8 @@ var execOptions = {
stdio: [
'pipe', // stdin (default)
'pipe', // stdout (default)
- 'ignore' //stderr
- ]
+ 'ignore', //stderr
+ ],
};
function isProcessAReactApp(processCommand) {
@@ -16,7 +27,10 @@ function isProcessAReactApp(processCommand) {
}
function getProcessIdOnPort(port) {
- return execSync('lsof -i:' + port + ' -P -t -sTCP:LISTEN', execOptions).trim();
+ return execSync(
+ 'lsof -i:' + port + ' -P -t -sTCP:LISTEN',
+ execOptions
+ ).trim();
}
function getPackageNameInDirectory(directory) {
@@ -24,26 +38,30 @@ function getPackageNameInDirectory(directory) {
try {
return require(packagePath).name;
- } catch(e) {
+ } catch (e) {
return null;
}
-
}
function getProcessCommand(processId, processDirectory) {
- var command = execSync('ps -o command -p ' + processId + ' | sed -n 2p', execOptions);
+ var command = execSync(
+ 'ps -o command -p ' + processId + ' | sed -n 2p',
+ execOptions
+ );
if (isProcessAReactApp(command)) {
const packageName = getPackageNameInDirectory(processDirectory);
- return (packageName) ? packageName + '\n' : command;
+ return packageName ? packageName + '\n' : command;
} else {
return command;
}
-
}
function getDirectoryOfProcessById(processId) {
- return execSync('lsof -p '+ processId + ' | grep cwd | awk \'{print $9}\'', execOptions).trim();
+ return execSync(
+ 'lsof -p ' + processId + ' | awk \'$4=="cwd" {print $9}\'',
+ execOptions
+ ).trim();
}
function getProcessForPort(port) {
@@ -52,10 +70,9 @@ function getProcessForPort(port) {
var directory = getDirectoryOfProcessById(processId);
var command = getProcessCommand(processId, directory);
return chalk.cyan(command) + chalk.blue(' in ') + chalk.cyan(directory);
- } catch(e) {
+ } catch (e) {
return null;
}
}
module.exports = getProcessForPort;
-
diff --git a/packages/react-dev-utils/openBrowser.js b/packages/react-dev-utils/openBrowser.js
index a3623515e0a..8c97f723c4f 100644
--- a/packages/react-dev-utils/openBrowser.js
+++ b/packages/react-dev-utils/openBrowser.js
@@ -7,6 +7,8 @@
* of patent rights can be found in the PATENTS file in the same directory.
*/
+'use strict';
+
var execSync = require('child_process').execSync;
var opn = require('opn');
@@ -17,7 +19,7 @@ function openBrowser(url) {
// Attempt to honor this environment variable.
// It is specific to the operating system.
// See https://github.com/sindresorhus/opn#app for documentation.
- const browser = process.env.BROWSER;
+ var browser = process.env.BROWSER;
// Special case: BROWSER="none" will prevent opening completely.
if (browser === 'none') {
@@ -28,32 +30,36 @@ function openBrowser(url) {
// requested a different browser, we can try opening
// Chrome with AppleScript. This lets us reuse an
// existing tab when possible instead of creating a new one.
- const shouldTryOpenChromeWithAppleScript = (
- process.platform === 'darwin' && (
- typeof browser !== 'string' ||
- browser === OSX_CHROME
- )
- );
+ const shouldTryOpenChromeWithAppleScript = process.platform === 'darwin' &&
+ (typeof browser !== 'string' || browser === OSX_CHROME);
if (shouldTryOpenChromeWithAppleScript) {
try {
// Try our best to reuse existing tab
// on OS X Google Chrome with AppleScript
execSync('ps cax | grep "Google Chrome"');
- execSync(
- 'osascript openChrome.applescript ' + url,
- {cwd: __dirname, stdio: 'ignore'}
- );
+ execSync('osascript openChrome.applescript ' + url, {
+ cwd: __dirname,
+ stdio: 'ignore',
+ });
return true;
} catch (err) {
// Ignore errors.
}
}
+ // Another special case: on OS X, check if BROWSER has been set to "open".
+ // In this case, instead of passing `open` to `opn` (which won't work),
+ // just ignore it (thus ensuring the intended behavior, i.e. opening the system browser):
+ // https://github.com/facebookincubator/create-react-app/pull/1690#issuecomment-283518768
+ if (process.platform === 'darwin' && browser === 'open') {
+ browser = undefined;
+ }
+
// Fallback to opn
// (It will always open new tab)
try {
- var options = {app: browser};
+ var options = { app: browser };
opn(url, options).catch(() => {}); // Prevent `unhandledRejection` error.
return true;
} catch (err) {
diff --git a/packages/react-dev-utils/package.json b/packages/react-dev-utils/package.json
index 9870e1ecc34..64037886a0e 100644
--- a/packages/react-dev-utils/package.json
+++ b/packages/react-dev-utils/package.json
@@ -1,6 +1,6 @@
{
"name": "react-dev-utils",
- "version": "0.5.0",
+ "version": "0.5.2",
"description": "Webpack utilities used by Create React App",
"repository": "facebookincubator/create-react-app",
"license": "BSD-3-Clause",
@@ -11,24 +11,32 @@
"node": ">=4"
},
"files": [
- "clearConsole.js",
+ "ansiHTML.js",
"checkRequiredFiles.js",
+ "clearConsole.js",
+ "crashOverlay.js",
+ "FileSizeReporter.js",
"formatWebpackMessages.js",
"getProcessForPort.js",
"InterpolateHtmlPlugin.js",
- "openChrome.applescript",
"openBrowser.js",
+ "openChrome.applescript",
"prompt.js",
"WatchMissingNodeModulesPlugin.js",
"webpackHotDevClient.js"
],
"dependencies": {
- "ansi-html": "0.0.5",
+ "anser": "1.1.0",
+ "babel-code-frame": "6.20.0",
"chalk": "1.1.3",
"escape-string-regexp": "1.0.5",
+ "filesize": "3.3.0",
+ "gzip-size": "3.0.0",
"html-entities": "1.2.0",
"opn": "4.0.2",
- "sockjs-client": "1.0.1",
+ "recursive-readdir": "2.1.1",
+ "sockjs-client": "1.1.2",
+ "stack-frame-resolver": "0.1.3",
"strip-ansi": "3.0.1"
}
}
diff --git a/packages/react-dev-utils/prompt.js b/packages/react-dev-utils/prompt.js
index 4b1faf9bac8..4257924576d 100644
--- a/packages/react-dev-utils/prompt.js
+++ b/packages/react-dev-utils/prompt.js
@@ -7,6 +7,8 @@
* of patent rights can be found in the PATENTS file in the same directory.
*/
+'use strict';
+
var rl = require('readline');
// Convention: "no" should be the conservative choice.
@@ -14,7 +16,9 @@ var rl = require('readline');
// You can control the behavior on with `isYesDefault`.
function prompt(question, isYesDefault) {
if (typeof isYesDefault !== 'boolean') {
- throw new Error('Provide explicit boolean isYesDefault as second argument.');
+ throw new Error(
+ 'Provide explicit boolean isYesDefault as second argument.'
+ );
}
return new Promise(resolve => {
var rlInterface = rl.createInterface({
@@ -37,6 +41,6 @@ function prompt(question, isYesDefault) {
return resolve(isYes);
});
});
-};
+}
module.exports = prompt;
diff --git a/packages/react-dev-utils/webpackHotDevClient.js b/packages/react-dev-utils/webpackHotDevClient.js
index 7b1768d8fa0..77cc62be2b7 100644
--- a/packages/react-dev-utils/webpackHotDevClient.js
+++ b/packages/react-dev-utils/webpackHotDevClient.js
@@ -7,6 +7,8 @@
* of patent rights can be found in the PATENTS file in the same directory.
*/
+'use strict';
+
// This alternative WebpackDevServer combines the functionality of:
// https://github.com/webpack/webpack-dev-server/blob/webpack-1/client/index.js
// https://github.com/webpack/webpack/blob/webpack-1/hot/dev-server.js
@@ -16,28 +18,15 @@
// that looks similar to our console output. The error overlay is inspired by:
// https://github.com/glenjamin/webpack-hot-middleware
-var ansiHTML = require('ansi-html');
var SockJS = require('sockjs-client');
var stripAnsi = require('strip-ansi');
var url = require('url');
var formatWebpackMessages = require('./formatWebpackMessages');
var Entities = require('html-entities').AllHtmlEntities;
+var ansiHTML = require('./ansiHTML');
var entities = new Entities();
-// Color scheme inspired by https://github.com/glenjamin/webpack-hot-middleware
-var colors = {
- reset: ['transparent', 'transparent'],
- black: '181818',
- red: 'E36049',
- green: 'B3CB74',
- yellow: 'FFD080',
- blue: '7CAFC2',
- magenta: '7FACCA',
- cyan: 'C3C2EF',
- lightgrey: 'EBE7E3',
- darkgrey: '6D7891'
-};
-ansiHTML.setColors(colors);
+var red = '#E36049';
function createOverlayIframe(onIframeLoad) {
var iframe = document.createElement('iframe');
@@ -57,7 +46,7 @@ function createOverlayIframe(onIframeLoad) {
}
function addOverlayDivTo(iframe) {
- var div = iframe.contentDocument.createElement('div');
+ var div = iframe.contentDocument.createElement('div');
div.id = 'react-dev-utils-webpack-hot-dev-client-overlay-div';
div.style.position = 'fixed';
div.style.boxSizing = 'border-box';
@@ -67,8 +56,8 @@ function addOverlayDivTo(iframe) {
div.style.bottom = 0;
div.style.width = '100vw';
div.style.height = '100vh';
- div.style.backgroundColor = 'black';
- div.style.color = '#E8E8E8';
+ div.style.backgroundColor = '#fafafa';
+ div.style.color = '#333';
div.style.fontFamily = 'Menlo, Consolas, monospace';
div.style.fontSize = 'large';
div.style.padding = '2rem';
@@ -115,15 +104,14 @@ function ensureOverlayDivExists(onOverlayDivReady) {
function showErrorOverlay(message) {
ensureOverlayDivExists(function onOverlayDivReady(overlayDiv) {
// Make it look similar to our terminal.
- overlayDiv.innerHTML =
- 'Failed to compile.
' +
ansiHTML(entities.encode(message));
});
}
-function destroyErrorOverlay() {
+function destroyErrorOverlay() {
if (!overlayDiv) {
// It is not there in the first place.
return;
@@ -137,13 +125,15 @@ function destroyErrorOverlay() {
}
// Connect to WebpackDevServer via a socket.
-var connection = new SockJS(url.format({
- protocol: window.location.protocol,
- hostname: window.location.hostname,
- port: window.location.port,
- // Hardcoded in WebpackDevServer
- pathname: '/sockjs-node'
-}));
+var connection = new SockJS(
+ url.format({
+ protocol: window.location.protocol,
+ hostname: window.location.hostname,
+ port: window.location.port,
+ // Hardcoded in WebpackDevServer
+ pathname: '/sockjs-node',
+ })
+);
// Unlike WebpackDevServer client, we won't try to reconnect
// to avoid spamming the console. Disconnect usually happens
@@ -220,7 +210,7 @@ function handleErrors(errors) {
// "Massage" webpack messages.
var formatted = formatWebpackMessages({
errors: errors,
- warnings: []
+ warnings: [],
});
// Only show the first error.
@@ -245,23 +235,27 @@ function handleAvailableHash(hash) {
connection.onmessage = function(e) {
var message = JSON.parse(e.data);
switch (message.type) {
- case 'hash':
- handleAvailableHash(message.data);
- break;
- case 'still-ok':
- case 'ok':
- handleSuccess();
- break;
- case 'warnings':
- handleWarnings(message.data);
- break;
- case 'errors':
- handleErrors(message.data);
- break;
- default:
+ case 'hash':
+ handleAvailableHash(message.data);
+ break;
+ case 'still-ok':
+ case 'ok':
+ handleSuccess();
+ break;
+ case 'content-changed':
+ // Triggered when a file from `contentBase` changed.
+ window.location.reload();
+ break;
+ case 'warnings':
+ handleWarnings(message.data);
+ break;
+ case 'errors':
+ handleErrors(message.data);
+ break;
+ default:
// Do nothing.
}
-}
+};
// Is there a newer version of this code available?
function isUpdateAvailable() {
@@ -306,7 +300,7 @@ function tryApplyUpdates(onHotUpdateSuccess) {
}
// https://webpack.github.io/docs/hot-module-replacement.html#check
- var result = module.hot.check(/* autoApply */true, handleApplyUpdates);
+ var result = module.hot.check(/* autoApply */ true, handleApplyUpdates);
// // Webpack 2 returns a Promise instead of invoking a callback
if (result && result.then) {
@@ -319,4 +313,4 @@ function tryApplyUpdates(onHotUpdateSuccess) {
}
);
}
-};
+}
diff --git a/packages/react-scripts/.babelrc b/packages/react-scripts/.babelrc
deleted file mode 100644
index ad8e03a8248..00000000000
--- a/packages/react-scripts/.babelrc
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "presets": ["react-app"]
-}
\ No newline at end of file
diff --git a/packages/react-scripts/.eslintrc b/packages/react-scripts/.eslintrc
deleted file mode 100644
index 5e603ecd193..00000000000
--- a/packages/react-scripts/.eslintrc
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "extends": "react-app"
-}
diff --git a/packages/react-scripts/README.md b/packages/react-scripts/README.md
index 845e546c67c..8004b887004 100644
--- a/packages/react-scripts/README.md
+++ b/packages/react-scripts/README.md
@@ -1,6 +1,6 @@
# react-scripts
-This package includes scripts and configuration used by [Create React App](https://github.com/facebookincubator/create-react-app).
+This package includes scripts and configuration used by [Create React App](https://github.com/facebookincubator/create-react-app).
Please refer to its documentation:
* [Getting Started](https://github.com/facebookincubator/create-react-app/blob/master/README.md#getting-started) – How to create a new app.
diff --git a/packages/react-scripts/bin/react-scripts.js b/packages/react-scripts/bin/react-scripts.js
index a3ae830f45b..8a1175c99ea 100755
--- a/packages/react-scripts/bin/react-scripts.js
+++ b/packages/react-scripts/bin/react-scripts.js
@@ -1,38 +1,52 @@
#!/usr/bin/env node
+/**
+ * Copyright (c) 2015-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
+'use strict';
+
var spawn = require('cross-spawn');
var script = process.argv[2];
var args = process.argv.slice(3);
switch (script) {
-case 'build':
-case 'eject':
-case 'start':
-case 'test':
- var result = spawn.sync(
- 'node',
- [require.resolve('../scripts/' + script)].concat(args),
- {stdio: 'inherit'}
- );
- if (result.signal) {
- if (result.signal == 'SIGKILL') {
- console.log(
- 'The build failed because the process exited too early. ' +
- 'This probably means the system ran out of memory or someone called ' +
- '`kill -9` on the process.'
- );
- } else if (result.signal == 'SIGTERM') {
- console.log(
- 'The build failed because the process exited too early. ' +
- 'Someone might have called `kill` or `killall`, or the system could ' +
- 'be shutting down.'
- );
+ case 'build':
+ case 'eject':
+ case 'start':
+ case 'test':
+ var result = spawn.sync(
+ 'node',
+ [require.resolve('../scripts/' + script)].concat(args),
+ { stdio: 'inherit' }
+ );
+ if (result.signal) {
+ if (result.signal === 'SIGKILL') {
+ console.log(
+ 'The build failed because the process exited too early. ' +
+ 'This probably means the system ran out of memory or someone called ' +
+ '`kill -9` on the process.'
+ );
+ } else if (result.signal === 'SIGTERM') {
+ console.log(
+ 'The build failed because the process exited too early. ' +
+ 'Someone might have called `kill` or `killall`, or the system could ' +
+ 'be shutting down.'
+ );
+ }
+ process.exit(1);
}
- process.exit(1);
- }
- process.exit(result.status);
- break;
-default:
- console.log('Unknown script "' + script + '".');
- console.log('Perhaps you need to update react-scripts?');
- break;
+ process.exit(result.status);
+ break;
+ default:
+ console.log('Unknown script "' + script + '".');
+ console.log('Perhaps you need to update react-scripts?');
+ console.log(
+ 'See: https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#updating-to-new-releases'
+ );
+ break;
}
diff --git a/packages/react-scripts/config/env.js b/packages/react-scripts/config/env.js
index 168e1e644f1..c018467a95b 100644
--- a/packages/react-scripts/config/env.js
+++ b/packages/react-scripts/config/env.js
@@ -8,37 +8,40 @@
* of patent rights can be found in the PATENTS file in the same directory.
*/
// @remove-on-eject-end
+'use strict';
// Grab NODE_ENV and REACT_APP_* environment variables and prepare them to be
// injected into the application via DefinePlugin in Webpack configuration.
-
-var REACT_APP = /^REACT_APP_/i;
+const REACT_APP = /^REACT_APP_/i;
function getClientEnvironment(publicUrl) {
- var raw = Object
- .keys(process.env)
+ const raw = Object.keys(process.env)
.filter(key => REACT_APP.test(key))
- .reduce((env, key) => {
- env[key] = process.env[key];
- return env;
- }, {
- // Useful for determining whether we’re running in production mode.
- // Most importantly, it switches React into the correct mode.
- 'NODE_ENV': process.env.NODE_ENV || 'development',
- // Useful for resolving the correct path to static assets in `public`.
- // For example, .
- // This should only be used as an escape hatch. Normally you would put
- // images into the `src` and `import` them in code to get their paths.
- 'PUBLIC_URL': publicUrl
- });
+ .reduce(
+ (env, key) => {
+ env[key] = process.env[key];
+ return env;
+ },
+ {
+ // Useful for determining whether we’re running in production mode.
+ // Most importantly, it switches React into the correct mode.
+ NODE_ENV: process.env.NODE_ENV || 'development',
+ // Useful for resolving the correct path to static assets in `public`.
+ // For example, .
+ // This should only be used as an escape hatch. Normally you would put
+ // images into the `src` and `import` them in code to get their paths.
+ PUBLIC_URL: publicUrl,
+ }
+ );
// Stringify all values so we can feed into Webpack DefinePlugin
- var stringified = {
- 'process.env': Object
- .keys(raw)
- .reduce((env, key) => {
+ const stringified = {
+ 'process.env': Object.keys(raw).reduce(
+ (env, key) => {
env[key] = JSON.stringify(raw[key]);
return env;
- }, {})
+ },
+ {}
+ ),
};
return { raw, stringified };
diff --git a/packages/react-scripts/config/jest/babelTransform.js b/packages/react-scripts/config/jest/babelTransform.js
index 145bd86cc9a..bee55b1b156 100644
--- a/packages/react-scripts/config/jest/babelTransform.js
+++ b/packages/react-scripts/config/jest/babelTransform.js
@@ -1,3 +1,4 @@
+// @remove-file-on-eject
/**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
@@ -5,10 +6,11 @@
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
+'use strict';
const babelJest = require('babel-jest');
module.exports = babelJest.createTransformer({
presets: [require.resolve('babel-preset-react-app')],
- babelrc: false
+ babelrc: false,
});
diff --git a/packages/react-scripts/config/jest/cssTransform.js b/packages/react-scripts/config/jest/cssTransform.js
index eead954406b..0a9849f1f54 100644
--- a/packages/react-scripts/config/jest/cssTransform.js
+++ b/packages/react-scripts/config/jest/cssTransform.js
@@ -7,6 +7,7 @@
* of patent rights can be found in the PATENTS file in the same directory.
*/
// @remove-on-eject-end
+'use strict';
// This is a custom Jest transformer turning style imports into empty objects.
// http://facebook.github.io/jest/docs/tutorial-webpack.html
@@ -15,7 +16,7 @@ module.exports = {
process() {
return 'module.exports = {};';
},
- getCacheKey(fileData, filename) {
+ getCacheKey() {
// The output is always the same.
return 'cssTransform';
},
diff --git a/packages/react-scripts/config/jest/fileTransform.js b/packages/react-scripts/config/jest/fileTransform.js
index 82c672bebd3..89027bdc702 100644
--- a/packages/react-scripts/config/jest/fileTransform.js
+++ b/packages/react-scripts/config/jest/fileTransform.js
@@ -7,6 +7,7 @@
* of patent rights can be found in the PATENTS file in the same directory.
*/
// @remove-on-eject-end
+'use strict';
const path = require('path');
@@ -15,6 +16,6 @@ const path = require('path');
module.exports = {
process(src, filename) {
- return 'module.exports = ' + JSON.stringify(path.basename(filename)) + ';';
+ return `module.exports = ${JSON.stringify(path.basename(filename))};`;
},
};
diff --git a/packages/react-scripts/config/paths.js b/packages/react-scripts/config/paths.js
index 7d114080f7c..76397756040 100644
--- a/packages/react-scripts/config/paths.js
+++ b/packages/react-scripts/config/paths.js
@@ -8,14 +8,15 @@
* of patent rights can be found in the PATENTS file in the same directory.
*/
// @remove-on-eject-end
+'use strict';
-var path = require('path');
-var fs = require('fs');
-var url = require('url');
+const path = require('path');
+const fs = require('fs');
+const url = require('url');
// Make sure any symlinks in the project folder are resolved:
// https://github.com/facebookincubator/create-react-app/issues/637
-var appDirectory = fs.realpathSync(process.cwd());
+const appDirectory = fs.realpathSync(process.cwd());
function resolveApp(relativePath) {
return path.resolve(appDirectory, relativePath);
}
@@ -35,20 +36,20 @@ function resolveApp(relativePath) {
// Otherwise, we risk importing Node.js core modules into an app instead of Webpack shims.
// https://github.com/facebookincubator/create-react-app/issues/1023#issuecomment-265344421
-var nodePaths = (process.env.NODE_PATH || '')
+const nodePaths = (process.env.NODE_PATH || '')
.split(process.platform === 'win32' ? ';' : ':')
.filter(Boolean)
.filter(folder => !path.isAbsolute(folder))
.map(resolveApp);
-var envPublicUrl = process.env.PUBLIC_URL;
+const envPublicUrl = process.env.PUBLIC_URL;
function ensureSlash(path, needsSlash) {
- var hasSlash = path.endsWith('/');
+ const hasSlash = path.endsWith('/');
if (hasSlash && !needsSlash) {
return path.substr(path, path.length - 1);
} else if (!hasSlash && needsSlash) {
- return path + '/';
+ return `${path}/`;
} else {
return path;
}
@@ -65,10 +66,9 @@ function getPublicUrl(appPackageJson) {
// We can't use a relative path in HTML because we don't want to load something
// like /todos/42/static/js/bundle.7289d.js. We have to know the root.
function getServedPath(appPackageJson) {
- var publicUrl = getPublicUrl(appPackageJson);
- var servedUrl = envPublicUrl || (
- publicUrl ? url.parse(publicUrl).pathname : '/'
- );
+ const publicUrl = getPublicUrl(appPackageJson);
+ const servedUrl = envPublicUrl ||
+ (publicUrl ? url.parse(publicUrl).pathname : '/');
return ensureSlash(servedUrl, true);
}
@@ -83,19 +83,19 @@ module.exports = {
yarnLockFile: resolveApp('yarn.lock'),
testsSetup: resolveApp('src/setupTests.js'),
appNodeModules: resolveApp('node_modules'),
- ownNodeModules: resolveApp('node_modules'),
nodePaths: nodePaths,
publicUrl: getPublicUrl(resolveApp('package.json')),
- servedPath: getServedPath(resolveApp('package.json'))
+ servedPath: getServedPath(resolveApp('package.json')),
};
// @remove-on-eject-begin
function resolveOwn(relativePath) {
- return path.resolve(__dirname, relativePath);
+ return path.resolve(__dirname, '..', relativePath);
}
// config before eject: we're in ./node_modules/react-scripts/config/
module.exports = {
+ appPath: resolveApp('.'),
appBuild: resolveApp('build'),
appPublic: resolveApp('public'),
appHtml: resolveApp('public/index.html'),
@@ -105,29 +105,41 @@ module.exports = {
yarnLockFile: resolveApp('yarn.lock'),
testsSetup: resolveApp('src/setupTests.js'),
appNodeModules: resolveApp('node_modules'),
- // this is empty with npm3 but node resolution searches higher anyway:
- ownNodeModules: resolveOwn('../node_modules'),
nodePaths: nodePaths,
publicUrl: getPublicUrl(resolveApp('package.json')),
- servedPath: getServedPath(resolveApp('package.json'))
+ servedPath: getServedPath(resolveApp('package.json')),
+ // These properties only exist before ejecting:
+ ownPath: resolveOwn('.'),
+ ownNodeModules: resolveOwn('node_modules'), // This is empty on npm 3
};
+const ownPackageJson = require('../package.json');
+const reactScriptsPath = resolveApp(`node_modules/${ownPackageJson.name}`);
+const reactScriptsLinked = fs.existsSync(reactScriptsPath) &&
+ fs.lstatSync(reactScriptsPath).isSymbolicLink();
+
// config before publish: we're in ./packages/react-scripts/config/
-if (__dirname.indexOf(path.join('packages', 'react-scripts', 'config')) !== -1) {
+if (
+ !reactScriptsLinked &&
+ __dirname.indexOf(path.join('packages', 'react-scripts', 'config')) !== -1
+) {
module.exports = {
- appBuild: resolveOwn('../../../build'),
- appPublic: resolveOwn('../template/public'),
- appHtml: resolveOwn('../template/public/index.html'),
- appIndexJs: resolveOwn('../template/src/index.js'),
- appPackageJson: resolveOwn('../package.json'),
- appSrc: resolveOwn('../template/src'),
- yarnLockFile: resolveOwn('../template/yarn.lock'),
- testsSetup: resolveOwn('../template/src/setupTests.js'),
- appNodeModules: resolveOwn('../node_modules'),
- ownNodeModules: resolveOwn('../node_modules'),
+ appPath: resolveApp('.'),
+ appBuild: resolveOwn('../../build'),
+ appPublic: resolveOwn('template/public'),
+ appHtml: resolveOwn('template/public/index.html'),
+ appIndexJs: resolveOwn('template/src/index.js'),
+ appPackageJson: resolveOwn('package.json'),
+ appSrc: resolveOwn('template/src'),
+ yarnLockFile: resolveOwn('template/yarn.lock'),
+ testsSetup: resolveOwn('template/src/setupTests.js'),
+ appNodeModules: resolveOwn('node_modules'),
nodePaths: nodePaths,
- publicUrl: getPublicUrl(resolveOwn('../package.json')),
- servedPath: getServedPath(resolveOwn('../package.json'))
+ publicUrl: getPublicUrl(resolveOwn('package.json')),
+ servedPath: getServedPath(resolveOwn('package.json')),
+ // These properties only exist before ejecting:
+ ownPath: resolveOwn('.'),
+ ownNodeModules: resolveOwn('node_modules'),
};
}
// @remove-on-eject-end
diff --git a/packages/react-scripts/config/polyfills.js b/packages/react-scripts/config/polyfills.js
index a1353ca3d2d..14031a1688d 100644
--- a/packages/react-scripts/config/polyfills.js
+++ b/packages/react-scripts/config/polyfills.js
@@ -8,6 +8,7 @@
* of patent rights can be found in the PATENTS file in the same directory.
*/
// @remove-on-eject-end
+'use strict';
if (typeof Promise === 'undefined') {
// Rejection tracking prevents a common issue where React gets into an
diff --git a/packages/react-scripts/config/webpack.config.dev.js b/packages/react-scripts/config/webpack.config.dev.js
index 0109eb6e4ac..7244ff79671 100644
--- a/packages/react-scripts/config/webpack.config.dev.js
+++ b/packages/react-scripts/config/webpack.config.dev.js
@@ -8,30 +8,26 @@
* of patent rights can be found in the PATENTS file in the same directory.
*/
// @remove-on-eject-end
+'use strict';
-var autoprefixer = require('autoprefixer');
-var webpack = require('webpack');
-var HtmlWebpackPlugin = require('html-webpack-plugin');
-var CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin');
-var InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin');
-var WatchMissingNodeModulesPlugin = require('react-dev-utils/WatchMissingNodeModulesPlugin');
-var getClientEnvironment = require('./env');
-var paths = require('./paths');
-
-// @remove-on-eject-begin
-// `path` is not used after eject - see https://github.com/facebookincubator/create-react-app/issues/1174
-var path = require('path');
-// @remove-on-eject-end
+const autoprefixer = require('autoprefixer');
+const webpack = require('webpack');
+const HtmlWebpackPlugin = require('html-webpack-plugin');
+const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin');
+const InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin');
+const WatchMissingNodeModulesPlugin = require('react-dev-utils/WatchMissingNodeModulesPlugin');
+const getClientEnvironment = require('./env');
+const paths = require('./paths');
// Webpack uses `publicPath` to determine where the app is being served from.
// In development, we always serve from the root. This makes config easier.
-var publicPath = '/';
+const publicPath = '/';
// `publicUrl` is just like `publicPath`, but we will provide it to our app
// as %PUBLIC_URL% in `index.html` and `process.env.PUBLIC_URL` in JavaScript.
// Omit trailing slash as %PUBLIC_PATH%/xyz looks better than %PUBLIC_PATH%xyz.
-var publicUrl = '';
+const publicUrl = '';
// Get environment variables to inject into our app.
-var env = getClientEnvironment(publicUrl);
+const env = getClientEnvironment(publicUrl);
// This is the development configuration.
// It is focused on developer experience and fast rebuilds.
@@ -57,8 +53,10 @@ module.exports = {
require.resolve('react-dev-utils/webpackHotDevClient'),
// We ship a few polyfills by default:
require.resolve('./polyfills'),
+ // Errors should be considered fatal in development
+ require.resolve('react-dev-utils/crashOverlay'),
// Finally, this is your app's code:
- paths.appIndexJs
+ paths.appIndexJs,
// We include the app code last so that if there is a runtime error during
// initialization, it doesn't blow up the WebpackDevServer client, and
// changing JS code would still trigger a refresh.
@@ -73,73 +71,104 @@ module.exports = {
// containing code from all our entry points, and the Webpack runtime.
filename: 'static/js/bundle.js',
// This is the URL that app is served from. We use "/" in development.
- publicPath: publicPath
+ publicPath: publicPath,
},
resolve: {
// This allows you to set a fallback for where Webpack should look for modules.
// We read `NODE_PATH` environment variable in `paths.js` and pass paths here.
- // We use `fallback` instead of `root` because we want `node_modules` to "win"
- // if there any conflicts. This matches Node resolution mechanism.
+ // We placed these paths second because we want `node_modules` to "win"
+ // if there are any conflicts. This matches Node resolution mechanism.
// https://github.com/facebookincubator/create-react-app/issues/253
- fallback: paths.nodePaths,
+ modules: ['node_modules', paths.appNodeModules].concat(paths.nodePaths),
// These are the reasonable defaults supported by the Node ecosystem.
// We also include JSX as a common component filename extension to support
// some tools, although we do not recommend using it, see:
// https://github.com/facebookincubator/create-react-app/issues/290
- extensions: ['.js', '.json', '.jsx', ''],
+ extensions: ['.js', '.json', '.jsx'],
alias: {
// Support React Native Web
// https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/
- 'react-native': 'react-native-web'
- }
+ 'react-native': 'react-native-web',
+ },
},
// @remove-on-eject-begin
// Resolve loaders (webpack plugins for CSS, images, transpilation) from the
// directory of `react-scripts` itself rather than the project directory.
resolveLoader: {
- root: paths.ownNodeModules,
- moduleTemplates: ['*-loader']
+ modules: [
+ paths.ownNodeModules,
+ // Lerna hoists everything, so we need to look in our app directory
+ paths.appNodeModules,
+ ],
},
// @remove-on-eject-end
module: {
- // First, run the linter.
- // It's important to do this before Babel processes the JS.
- preLoaders: [
+ rules: [
+ // Disable require.ensure as it's not a standard language feature.
+ { parser: { requireEnsure: false } },
+ // First, run the linter.
+ // It's important to do this before Babel processes the JS.
{
test: /\.(js|jsx)$/,
- loader: 'eslint',
+ enforce: 'pre',
+ use: [
+ {
+ // @remove-on-eject-begin
+ // Point ESLint to our predefined config.
+ options: {
+ baseConfig: {
+ extends: ['react-app'],
+ },
+ useEslintrc: false,
+ },
+ // @remove-on-eject-end
+ loader: 'eslint-loader',
+ },
+ ],
include: paths.appSrc,
- }
- ],
- loaders: [
+ },
// ** ADDING/UPDATING LOADERS **
// The "url" loader handles all assets unless explicitly excluded.
// The `exclude` list *must* be updated with every change to loader extensions.
// When adding a new loader, you must add its `test`
// as a new entry in the `exclude` list for "url" loader.
- // "url" loader embeds assets smaller than specified size as data URLs to avoid requests.
- // Otherwise, it acts like the "file" loader.
+ // "file" loader makes sure those assets get served by WebpackDevServer.
+ // When you `import` an asset, you get its (virtual) filename.
+ // In production, they would get copied to the `build` folder.
{
exclude: [
/\.html$/,
/\.(js|jsx)$/,
/\.css$/,
/\.json$/,
- /\.svg$/
+ /\.bmp$/,
+ /\.gif$/,
+ /\.jpe?g$/,
+ /\.png$/,
],
- loader: 'url',
- query: {
+ loader: 'file-loader',
+ options: {
+ name: 'static/media/[name].[hash:8].[ext]',
+ },
+ },
+ // "url" loader works like "file" loader except that it embeds assets
+ // smaller than specified limit in bytes as data URLs to avoid requests.
+ // A missing `test` is equivalent to a match.
+ {
+ test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/],
+ loader: 'url-loader',
+ options: {
limit: 10000,
- name: 'static/media/[name].[hash:8].[ext]'
- }
+ name: 'static/media/[name].[hash:8].[ext]',
+ },
},
// Process JS with Babel.
{
test: /\.(js|jsx)$/,
include: paths.appSrc,
- loader: 'babel',
- query: {
+ loader: 'babel-loader',
+ options: {
// @remove-on-eject-begin
babelrc: false,
presets: [require.resolve('babel-preset-react-app')],
@@ -147,8 +176,8 @@ module.exports = {
// This is a feature of `babel-loader` for webpack (not Babel itself).
// It enables caching results in ./node_modules/.cache/babel-loader/
// directory for faster rebuilds.
- cacheDirectory: true
- }
+ cacheDirectory: true,
+ },
},
// "postcss" loader applies autoprefixer to our CSS.
// "css" loader resolves paths in CSS and adds assets as dependencies.
@@ -157,45 +186,35 @@ module.exports = {
// in development "style" loader enables hot editing of CSS.
{
test: /\.css$/,
- loader: 'style!css?importLoaders=1!postcss'
- },
- // JSON is not enabled by default in Webpack but both Node and Browserify
- // allow it implicitly so we also enable it.
- {
- test: /\.json$/,
- loader: 'json'
+ use: [
+ 'style-loader',
+ {
+ loader: 'css-loader',
+ options: {
+ importLoaders: 1,
+ },
+ },
+ {
+ loader: 'postcss-loader',
+ options: {
+ ident: 'postcss', // https://webpack.js.org/guides/migrating/#complex-options
+ plugins: () => [
+ autoprefixer({
+ browsers: [
+ '>1%',
+ 'last 4 versions',
+ 'Firefox ESR',
+ 'not ie < 9', // React doesn't support IE8 anyway
+ ],
+ }),
+ ],
+ },
+ },
+ ],
},
- // "file" loader for svg
- {
- test: /\.svg$/,
- loader: 'file',
- query: {
- name: 'static/media/[name].[hash:8].[ext]'
- }
- }
// ** STOP ** Are you adding a new loader?
// Remember to add the new extension(s) to the "url" loader exclusion list.
- ]
- },
- // @remove-on-eject-begin
- // Point ESLint to our predefined config.
- eslint: {
- configFile: path.join(__dirname, '../.eslintrc'),
- useEslintrc: false
- },
- // @remove-on-eject-end
- // We use PostCSS for autoprefixing only.
- postcss: function() {
- return [
- autoprefixer({
- browsers: [
- '>1%',
- 'last 4 versions',
- 'Firefox ESR',
- 'not ie < 9', // React doesn't support IE8 anyway
- ]
- }),
- ];
+ ],
},
plugins: [
// Makes some environment variables available in index.html.
@@ -221,13 +240,19 @@ module.exports = {
// to restart the development server for Webpack to discover it. This plugin
// makes the discovery automatic so you don't have to restart.
// See https://github.com/facebookincubator/create-react-app/issues/186
- new WatchMissingNodeModulesPlugin(paths.appNodeModules)
+ new WatchMissingNodeModulesPlugin(paths.appNodeModules),
],
// Some libraries import Node modules but don't use them in the browser.
// Tell Webpack to provide empty mocks for them so importing them works.
node: {
fs: 'empty',
net: 'empty',
- tls: 'empty'
- }
+ tls: 'empty',
+ },
+ // Turn off performance hints during development because we don't do any
+ // splitting or minification in interest of speed. These warnings become
+ // cumbersome.
+ performance: {
+ hints: false,
+ },
};
diff --git a/packages/react-scripts/config/webpack.config.prod.js b/packages/react-scripts/config/webpack.config.prod.js
index 4e75be521bb..01e9d6fe796 100644
--- a/packages/react-scripts/config/webpack.config.prod.js
+++ b/packages/react-scripts/config/webpack.config.prod.js
@@ -8,34 +8,29 @@
* of patent rights can be found in the PATENTS file in the same directory.
*/
// @remove-on-eject-end
+'use strict';
-var autoprefixer = require('autoprefixer');
-var webpack = require('webpack');
-var HtmlWebpackPlugin = require('html-webpack-plugin');
-var ExtractTextPlugin = require('extract-text-webpack-plugin');
-var ManifestPlugin = require('webpack-manifest-plugin');
-var InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin');
-var url = require('url');
-var paths = require('./paths');
-var getClientEnvironment = require('./env');
-
-// @remove-on-eject-begin
-// `path` is not used after eject - see https://github.com/facebookincubator/create-react-app/issues/1174
-var path = require('path');
-// @remove-on-eject-end
+const autoprefixer = require('autoprefixer');
+const webpack = require('webpack');
+const HtmlWebpackPlugin = require('html-webpack-plugin');
+const ExtractTextPlugin = require('extract-text-webpack-plugin');
+const ManifestPlugin = require('webpack-manifest-plugin');
+const InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin');
+const paths = require('./paths');
+const getClientEnvironment = require('./env');
// Webpack uses `publicPath` to determine where the app is being served from.
// It requires a trailing slash, or the file assets will get an incorrect path.
-var publicPath = paths.servedPath;
+const publicPath = paths.servedPath;
// Some apps do not use client-side routing with pushState.
// For these, "homepage" can be set to "." to enable relative asset paths.
-var shouldUseRelativeAssetPaths = publicPath === './';
+const shouldUseRelativeAssetPaths = publicPath === './';
// `publicUrl` is just like `publicPath`, but we will provide it to our app
// as %PUBLIC_URL% in `index.html` and `process.env.PUBLIC_URL` in JavaScript.
// Omit trailing slash as %PUBLIC_URL%/xyz looks better than %PUBLIC_URL%xyz.
-var publicUrl = publicPath.slice(0, -1);
+const publicUrl = publicPath.slice(0, -1);
// Get environment variables to inject into our app.
-var env = getClientEnvironment(publicUrl);
+const env = getClientEnvironment(publicUrl);
// Assert this just to be safe.
// Development builds of React are slow and not intended for production.
@@ -51,9 +46,9 @@ const cssFilename = 'static/css/[name].[contenthash:8].css';
// However, our output is structured with css, js and media folders.
// To have this structure working with relative paths, we have to use custom options.
const extractTextPluginOptions = shouldUseRelativeAssetPaths
- // Making sure that the publicPath goes back to to build folder.
- ? { publicPath: Array(cssFilename.split('/').length).join('../') }
- : undefined;
+ ? // Making sure that the publicPath goes back to to build folder.
+ { publicPath: Array(cssFilename.split('/').length).join('../') }
+ : {};
// This is the production configuration.
// It compiles slowly and is focused on producing a fast and minimal bundle.
@@ -65,10 +60,7 @@ module.exports = {
// You can exclude the *.map files from the build during deployment.
devtool: 'source-map',
// In production, we only want to load the polyfills and the app code.
- entry: [
- require.resolve('./polyfills'),
- paths.appIndexJs
- ],
+ entry: [require.resolve('./polyfills'), paths.appIndexJs],
output: {
// The build folder.
path: paths.appBuild,
@@ -78,74 +70,105 @@ module.exports = {
filename: 'static/js/[name].[chunkhash:8].js',
chunkFilename: 'static/js/[name].[chunkhash:8].chunk.js',
// We inferred the "public path" (such as / or /my-project) from homepage.
- publicPath: publicPath
+ publicPath: publicPath,
},
resolve: {
// This allows you to set a fallback for where Webpack should look for modules.
// We read `NODE_PATH` environment variable in `paths.js` and pass paths here.
- // We use `fallback` instead of `root` because we want `node_modules` to "win"
- // if there any conflicts. This matches Node resolution mechanism.
+ // We placed these paths second because we want `node_modules` to "win"
+ // if there are any conflicts. This matches Node resolution mechanism.
// https://github.com/facebookincubator/create-react-app/issues/253
- fallback: paths.nodePaths,
+ modules: ['node_modules', paths.appNodeModules].concat(paths.nodePaths),
// These are the reasonable defaults supported by the Node ecosystem.
// We also include JSX as a common component filename extension to support
// some tools, although we do not recommend using it, see:
// https://github.com/facebookincubator/create-react-app/issues/290
- extensions: ['.js', '.json', '.jsx', ''],
+ extensions: ['.js', '.json', '.jsx'],
alias: {
// Support React Native Web
// https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/
- 'react-native': 'react-native-web'
- }
+ 'react-native': 'react-native-web',
+ },
},
// @remove-on-eject-begin
// Resolve loaders (webpack plugins for CSS, images, transpilation) from the
// directory of `react-scripts` itself rather than the project directory.
resolveLoader: {
- root: paths.ownNodeModules,
- moduleTemplates: ['*-loader']
+ modules: [
+ paths.ownNodeModules,
+ // Lerna hoists everything, so we need to look in our app directory
+ paths.appNodeModules,
+ ],
},
// @remove-on-eject-end
module: {
- // First, run the linter.
- // It's important to do this before Babel processes the JS.
- preLoaders: [
+ rules: [
+ // Disable require.ensure as it's not a standard language feature.
+ { parser: { requireEnsure: false } },
+ // First, run the linter.
+ // It's important to do this before Babel processes the JS.
{
test: /\.(js|jsx)$/,
- loader: 'eslint',
- include: paths.appSrc
- }
- ],
- loaders: [
+ enforce: 'pre',
+ use: [
+ {
+ // @remove-on-eject-begin
+ // Point ESLint to our predefined config.
+ options: {
+ // TODO: consider separate config for production,
+ // e.g. to enable no-console and no-debugger only in production.
+ baseConfig: {
+ extends: ['react-app'],
+ },
+ useEslintrc: false,
+ },
+ // @remove-on-eject-end
+ loader: 'eslint-loader',
+ },
+ ],
+ include: paths.appSrc,
+ },
// ** ADDING/UPDATING LOADERS **
// The "url" loader handles all assets unless explicitly excluded.
// The `exclude` list *must* be updated with every change to loader extensions.
// When adding a new loader, you must add its `test`
// as a new entry in the `exclude` list in the "url" loader.
- // "url" loader embeds assets smaller than specified size as data URLs to avoid requests.
- // Otherwise, it acts like the "file" loader.
+ // "file" loader makes sure those assets end up in the `build` folder.
+ // When you `import` an asset, you get its filename.
{
exclude: [
/\.html$/,
/\.(js|jsx)$/,
/\.css$/,
/\.json$/,
- /\.svg$/
+ /\.bmp$/,
+ /\.gif$/,
+ /\.jpe?g$/,
+ /\.png$/,
],
- loader: 'url',
- query: {
+ loader: 'file-loader',
+ options: {
+ name: 'static/media/[name].[hash:8].[ext]',
+ },
+ },
+ // "url" loader works just like "file" loader but it also embeds
+ // assets smaller than specified size as data URLs to avoid requests.
+ {
+ test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/],
+ loader: 'url-loader',
+ options: {
limit: 10000,
- name: 'static/media/[name].[hash:8].[ext]'
- }
+ name: 'static/media/[name].[hash:8].[ext]',
+ },
},
// Process JS with Babel.
{
test: /\.(js|jsx)$/,
include: paths.appSrc,
- loader: 'babel',
+ loader: 'babel-loader',
// @remove-on-eject-begin
- query: {
+ options: {
babelrc: false,
presets: [require.resolve('babel-preset-react-app')],
},
@@ -166,51 +189,42 @@ module.exports = {
{
test: /\.css$/,
loader: ExtractTextPlugin.extract(
- 'style',
- 'css?importLoaders=1!postcss',
- extractTextPluginOptions
- )
+ Object.assign(
+ {
+ fallback: 'style-loader',
+ use: [
+ {
+ loader: 'css-loader',
+ options: {
+ importLoaders: 1,
+ },
+ },
+ {
+ loader: 'postcss-loader',
+ options: {
+ ident: 'postcss', // https://webpack.js.org/guides/migrating/#complex-options
+ plugins: () => [
+ autoprefixer({
+ browsers: [
+ '>1%',
+ 'last 4 versions',
+ 'Firefox ESR',
+ 'not ie < 9', // React doesn't support IE8 anyway
+ ],
+ }),
+ ],
+ },
+ },
+ ],
+ },
+ extractTextPluginOptions
+ )
+ ),
// Note: this won't work without `new ExtractTextPlugin()` in `plugins`.
},
- // JSON is not enabled by default in Webpack but both Node and Browserify
- // allow it implicitly so we also enable it.
- {
- test: /\.json$/,
- loader: 'json'
- },
- // "file" loader for svg
- {
- test: /\.svg$/,
- loader: 'file',
- query: {
- name: 'static/media/[name].[hash:8].[ext]'
- }
- }
// ** STOP ** Are you adding a new loader?
// Remember to add the new extension(s) to the "url" loader exclusion list.
- ]
- },
- // @remove-on-eject-begin
- // Point ESLint to our predefined config.
- eslint: {
- // TODO: consider separate config for production,
- // e.g. to enable no-console and no-debugger only in production.
- configFile: path.join(__dirname, '../.eslintrc'),
- useEslintrc: false
- },
- // @remove-on-eject-end
- // We use PostCSS for autoprefixing only.
- postcss: function() {
- return [
- autoprefixer({
- browsers: [
- '>1%',
- 'last 4 versions',
- 'Firefox ESR',
- 'not ie < 9', // React doesn't support IE8 anyway
- ]
- }),
- ];
+ ],
},
plugins: [
// Makes some environment variables available in index.html.
@@ -233,46 +247,45 @@ module.exports = {
keepClosingSlash: true,
minifyJS: true,
minifyCSS: true,
- minifyURLs: true
- }
+ minifyURLs: true,
+ },
}),
// Makes some environment variables available to the JS code, for example:
// if (process.env.NODE_ENV === 'production') { ... }. See `./env.js`.
// It is absolutely essential that NODE_ENV was set to production here.
// Otherwise React will be compiled in the very slow development mode.
new webpack.DefinePlugin(env.stringified),
- // This helps ensure the builds are consistent if source hasn't changed:
- new webpack.optimize.OccurrenceOrderPlugin(),
- // Try to dedupe duplicated modules, if any:
- new webpack.optimize.DedupePlugin(),
// Minify the code.
new webpack.optimize.UglifyJsPlugin({
compress: {
screw_ie8: true, // React doesn't support IE8
- warnings: false
+ warnings: false,
},
mangle: {
- screw_ie8: true
+ screw_ie8: true,
},
output: {
comments: false,
- screw_ie8: true
- }
+ screw_ie8: true,
+ },
+ sourceMap: true,
}),
// Note: this won't work without ExtractTextPlugin.extract(..) in `loaders`.
- new ExtractTextPlugin(cssFilename),
+ new ExtractTextPlugin({
+ filename: cssFilename,
+ }),
// Generate a manifest file which contains a mapping of all asset filenames
// to their corresponding output file so that tools can pick it up without
// having to parse `index.html`.
new ManifestPlugin({
- fileName: 'asset-manifest.json'
- })
+ fileName: 'asset-manifest.json',
+ }),
],
// Some libraries import Node modules but don't use them in the browser.
// Tell Webpack to provide empty mocks for them so importing them works.
node: {
fs: 'empty',
net: 'empty',
- tls: 'empty'
- }
+ tls: 'empty',
+ },
};
diff --git a/packages/react-scripts/config/webpackDevServer.config.js b/packages/react-scripts/config/webpackDevServer.config.js
new file mode 100644
index 00000000000..37d9d1a750e
--- /dev/null
+++ b/packages/react-scripts/config/webpackDevServer.config.js
@@ -0,0 +1,63 @@
+// @remove-on-eject-begin
+/**
+ * Copyright (c) 2015-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+// @remove-on-eject-end
+'use strict';
+
+const config = require('./webpack.config.dev');
+const paths = require('./paths');
+
+const protocol = process.env.HTTPS === 'true' ? 'https' : 'http';
+const host = process.env.HOST || 'localhost';
+
+module.exports = {
+ // Enable gzip compression of generated files.
+ compress: true,
+ // Silence WebpackDevServer's own logs since they're generally not useful.
+ // It will still show compile warnings and errors with this setting.
+ clientLogLevel: 'none',
+ // By default WebpackDevServer serves physical files from current directory
+ // in addition to all the virtual build products that it serves from memory.
+ // This is confusing because those files won’t automatically be available in
+ // production build folder unless we copy them. However, copying the whole
+ // project directory is dangerous because we may expose sensitive files.
+ // Instead, we establish a convention that only files in `public` directory
+ // get served. Our build script will copy `public` into the `build` folder.
+ // In `index.html`, you can get URL of `public` folder with %PUBLIC_URL%:
+ //
+ // In JavaScript code, you can access it with `process.env.PUBLIC_URL`.
+ // Note that we only recommend to use `public` folder as an escape hatch
+ // for files like `favicon.ico`, `manifest.json`, and libraries that are
+ // for some reason broken when imported through Webpack. If you just want to
+ // use an image, put it in `src` and `import` it from JavaScript instead.
+ contentBase: paths.appPublic,
+ // By default files from `contentBase` will not trigger a page reload.
+ watchContentBase: true,
+ // Enable hot reloading server. It will provide /sockjs-node/ endpoint
+ // for the WebpackDevServer client so it can learn when the files were
+ // updated. The WebpackDevServer client is included as an entry point
+ // in the Webpack development configuration. Note that only changes
+ // to CSS are currently hot reloaded. JS changes will refresh the browser.
+ hot: true,
+ // It is important to tell WebpackDevServer to use the same "root" path
+ // as we specified in the config. In development, we always serve from /.
+ publicPath: config.output.publicPath,
+ // WebpackDevServer is noisy by default so we emit custom message instead
+ // by listening to the compiler events with `compiler.plugin` calls above.
+ quiet: true,
+ // Reportedly, this avoids CPU overload on some systems.
+ // https://github.com/facebookincubator/create-react-app/issues/293
+ watchOptions: {
+ ignored: /node_modules/,
+ },
+ // Enable HTTPS if the HTTPS environment variable is set to 'true'
+ https: protocol === 'https',
+ host: host,
+ overlay: false,
+};
diff --git a/packages/react-scripts/fixtures/kitchensink/.babelrc b/packages/react-scripts/fixtures/kitchensink/.babelrc
index c14b2828d16..14397221e3b 100644
--- a/packages/react-scripts/fixtures/kitchensink/.babelrc
+++ b/packages/react-scripts/fixtures/kitchensink/.babelrc
@@ -1,3 +1,4 @@
{
- "presets": ["react-app"]
+ "presets": ["react-app"],
+ "plugins": ["babel-plugin-transform-es2015-modules-commonjs"]
}
diff --git a/packages/react-scripts/fixtures/kitchensink/.template.dependencies.json b/packages/react-scripts/fixtures/kitchensink/.template.dependencies.json
index 50511b3d16a..a20139318c1 100644
--- a/packages/react-scripts/fixtures/kitchensink/.template.dependencies.json
+++ b/packages/react-scripts/fixtures/kitchensink/.template.dependencies.json
@@ -1,6 +1,7 @@
{
"dependencies": {
"babel-register": "6.22.0",
+ "babel-plugin-transform-es2015-modules-commonjs": "6.22.0",
"babel-polyfill": "6.20.0",
"chai": "3.5.0",
"jsdom": "9.8.3",
diff --git a/packages/react-scripts/fixtures/kitchensink/integration/env.test.js b/packages/react-scripts/fixtures/kitchensink/integration/env.test.js
index e7b3afe42ed..b90d12ab12e 100644
--- a/packages/react-scripts/fixtures/kitchensink/integration/env.test.js
+++ b/packages/react-scripts/fixtures/kitchensink/integration/env.test.js
@@ -1,33 +1,53 @@
-import { expect } from 'chai'
-import initDOM from './initDOM'
+/**
+ * Copyright (c) 2015-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
+import { expect } from 'chai';
+import initDOM from './initDOM';
describe('Integration', () => {
describe('Environment variables', () => {
it('file env variables', async () => {
- const doc = await initDOM('file-env-variables')
+ const doc = await initDOM('file-env-variables');
- expect(doc.getElementById('feature-file-env-variables').textContent).to.equal('fromtheenvfile.')
- })
+ expect(
+ doc.getElementById('feature-file-env-variables').textContent
+ ).to.equal('fromtheenvfile.');
+ });
it('NODE_PATH', async () => {
- const doc = await initDOM('node-path')
+ const doc = await initDOM('node-path');
- expect(doc.getElementById('feature-node-path').childElementCount).to.equal(4)
- })
+ expect(
+ doc.getElementById('feature-node-path').childElementCount
+ ).to.equal(4);
+ });
it('PUBLIC_URL', async () => {
- const doc = await initDOM('public-url')
-
- const prefix = process.env.NODE_ENV === 'development' ? '' : 'http://www.example.org/spa';
- expect(doc.getElementById('feature-public-url').textContent).to.equal(`${prefix}.`)
- expect(doc.querySelector('head link[rel="shortcut icon"]').getAttribute('href'))
- .to.equal(`${prefix}/favicon.ico`)
- })
+ const doc = await initDOM('public-url');
+
+ const prefix = process.env.NODE_ENV === 'development'
+ ? ''
+ : 'http://www.example.org/spa';
+ expect(doc.getElementById('feature-public-url').textContent).to.equal(
+ `${prefix}.`
+ );
+ expect(
+ doc.querySelector('head link[rel="shortcut icon"]').getAttribute('href')
+ ).to.equal(`${prefix}/favicon.ico`);
+ });
it('shell env variables', async () => {
- const doc = await initDOM('shell-env-variables')
-
- expect(doc.getElementById('feature-shell-env-variables').textContent).to.equal('fromtheshell.')
- })
- })
-})
+ const doc = await initDOM('shell-env-variables');
+
+ expect(
+ doc.getElementById('feature-shell-env-variables').textContent
+ ).to.equal('fromtheshell.');
+ });
+ });
+});
diff --git a/packages/react-scripts/fixtures/kitchensink/integration/initDOM.js b/packages/react-scripts/fixtures/kitchensink/integration/initDOM.js
index 7cf8134b79f..4d6f531ea84 100644
--- a/packages/react-scripts/fixtures/kitchensink/integration/initDOM.js
+++ b/packages/react-scripts/fixtures/kitchensink/integration/initDOM.js
@@ -1,56 +1,78 @@
-const fs = require('fs')
-const http = require('http')
-const jsdom = require('jsdom')
-const path = require('path')
-const { expect } = require('chai')
+/**
+ * Copyright (c) 2015-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
-let getMarkup
-let resourceLoader
+const fs = require('fs');
+const http = require('http');
+const jsdom = require('jsdom');
+const path = require('path');
+const { expect } = require('chai');
+
+let getMarkup;
+let resourceLoader;
if (process.env.E2E_FILE) {
const file = path.isAbsolute(process.env.E2E_FILE)
? process.env.E2E_FILE
- : path.join(process.cwd(), process.env.E2E_FILE)
+ : path.join(process.cwd(), process.env.E2E_FILE);
- const markup = fs.readFileSync(file, 'utf8')
- getMarkup = () => markup
+ const markup = fs.readFileSync(file, 'utf8');
+ getMarkup = () => markup;
- const pathPrefix = process.env.PUBLIC_URL.replace(/^https?:\/\/[^\/]+\/?/, '')
+ const pathPrefix = process.env.PUBLIC_URL.replace(/^https?:\/\/[^/]+\/?/, '');
- resourceLoader = (resource, callback) => callback(
- null,
- fs.readFileSync(path.join(path.dirname(file), resource.url.pathname.replace(pathPrefix, '')), 'utf8')
- )
+ resourceLoader = (resource, callback) =>
+ callback(
+ null,
+ fs.readFileSync(
+ path.join(
+ path.dirname(file),
+ resource.url.pathname.replace(pathPrefix, '')
+ ),
+ 'utf8'
+ )
+ );
} else if (process.env.E2E_URL) {
getMarkup = () => new Promise(resolve => {
- http.get(process.env.E2E_URL, (res) => {
- let rawData = ''
- res.on('data', chunk => rawData += chunk)
- res.on('end', () => resolve(rawData))
- })
- })
-
- resourceLoader = (resource, callback) => resource.defaultFetch(callback)
+ http.get(process.env.E2E_URL, res => {
+ let rawData = '';
+ res.on('data', chunk => rawData += chunk);
+ res.on('end', () => resolve(rawData));
+ });
+ });
+
+ resourceLoader = (resource, callback) => resource.defaultFetch(callback);
} else {
- it.only('can run jsdom (at least one of "E2E_FILE" or "E2E_URL" environment variables must be provided)', () => {
- expect(new Error('This isn\'t the error you are looking for.')).to.be.undefined()
- })
+ it.only(
+ 'can run jsdom (at least one of "E2E_FILE" or "E2E_URL" environment variables must be provided)',
+ () => {
+ expect(
+ new Error("This isn't the error you are looking for.")
+ ).to.be.undefined();
+ }
+ );
}
export default feature => new Promise(async resolve => {
- const markup = await getMarkup()
- const host = process.env.E2E_URL || 'http://www.example.org/spa:3000'
+ const markup = await getMarkup();
+ const host = process.env.E2E_URL || 'http://www.example.org/spa:3000';
const doc = jsdom.jsdom(markup, {
features: {
FetchExternalResources: ['script', 'css'],
ProcessExternalResources: ['script'],
},
- created: (_, win) => win.addEventListener('ReactFeatureDidMount', () => resolve(doc), true),
+ created: (_, win) =>
+ win.addEventListener('ReactFeatureDidMount', () => resolve(doc), true),
deferClose: true,
resourceLoader,
url: `${host}#${feature}`,
virtualConsole: jsdom.createVirtualConsole().sendTo(console),
- })
+ });
- doc.close()
-})
+ doc.close();
+});
diff --git a/packages/react-scripts/fixtures/kitchensink/integration/syntax.test.js b/packages/react-scripts/fixtures/kitchensink/integration/syntax.test.js
index c8b7fbbc508..fc2a717befe 100644
--- a/packages/react-scripts/fixtures/kitchensink/integration/syntax.test.js
+++ b/packages/react-scripts/fixtures/kitchensink/integration/syntax.test.js
@@ -1,96 +1,135 @@
-import { expect } from 'chai'
-import initDOM from './initDOM'
+/**
+ * Copyright (c) 2015-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
+import { expect } from 'chai';
+import initDOM from './initDOM';
describe('Integration', () => {
describe('Language syntax', () => {
it('array destructuring', async () => {
- const doc = await initDOM('array-destructuring')
+ const doc = await initDOM('array-destructuring');
- expect(doc.getElementById('feature-array-destructuring').childElementCount).to.equal(4)
- })
+ expect(
+ doc.getElementById('feature-array-destructuring').childElementCount
+ ).to.equal(4);
+ });
it('array spread', async () => {
- const doc = await initDOM('array-spread')
+ const doc = await initDOM('array-spread');
- expect(doc.getElementById('feature-array-spread').childElementCount).to.equal(4)
- })
+ expect(
+ doc.getElementById('feature-array-spread').childElementCount
+ ).to.equal(4);
+ });
it('async/await', async () => {
- const doc = await initDOM('async-await')
+ const doc = await initDOM('async-await');
- expect(doc.getElementById('feature-async-await').childElementCount).to.equal(4)
- })
+ expect(
+ doc.getElementById('feature-async-await').childElementCount
+ ).to.equal(4);
+ });
it('class properties', async () => {
- const doc = await initDOM('class-properties')
+ const doc = await initDOM('class-properties');
- expect(doc.getElementById('feature-class-properties').childElementCount).to.equal(4)
- })
+ expect(
+ doc.getElementById('feature-class-properties').childElementCount
+ ).to.equal(4);
+ });
it('computed properties', async () => {
- const doc = await initDOM('computed-properties')
+ const doc = await initDOM('computed-properties');
- expect(doc.getElementById('feature-computed-properties').childElementCount).to.equal(4)
- })
+ expect(
+ doc.getElementById('feature-computed-properties').childElementCount
+ ).to.equal(4);
+ });
it('custom interpolation', async () => {
- const doc = await initDOM('custom-interpolation')
+ const doc = await initDOM('custom-interpolation');
- expect(doc.getElementById('feature-custom-interpolation').childElementCount).to.equal(4)
- })
+ expect(
+ doc.getElementById('feature-custom-interpolation').childElementCount
+ ).to.equal(4);
+ });
it('default parameters', async () => {
- const doc = await initDOM('default-parameters')
+ const doc = await initDOM('default-parameters');
- expect(doc.getElementById('feature-default-parameters').childElementCount).to.equal(4)
- })
+ expect(
+ doc.getElementById('feature-default-parameters').childElementCount
+ ).to.equal(4);
+ });
it('destructuring and await', async () => {
- const doc = await initDOM('destructuring-and-await')
+ const doc = await initDOM('destructuring-and-await');
- expect(doc.getElementById('feature-destructuring-and-await').childElementCount).to.equal(4)
- })
+ expect(
+ doc.getElementById('feature-destructuring-and-await').childElementCount
+ ).to.equal(4);
+ });
it('generators', async () => {
- const doc = await initDOM('generators')
+ const doc = await initDOM('generators');
- expect(doc.getElementById('feature-generators').childElementCount).to.equal(4)
- })
+ expect(
+ doc.getElementById('feature-generators').childElementCount
+ ).to.equal(4);
+ });
it('object destructuring', async () => {
- const doc = await initDOM('object-destructuring')
+ const doc = await initDOM('object-destructuring');
- expect(doc.getElementById('feature-object-destructuring').childElementCount).to.equal(4)
- })
+ expect(
+ doc.getElementById('feature-object-destructuring').childElementCount
+ ).to.equal(4);
+ });
it('object spread', async () => {
- const doc = await initDOM('object-spread')
+ const doc = await initDOM('object-spread');
- expect(doc.getElementById('feature-object-spread').childElementCount).to.equal(4)
- })
+ expect(
+ doc.getElementById('feature-object-spread').childElementCount
+ ).to.equal(4);
+ });
it('promises', async () => {
- const doc = await initDOM('promises')
+ const doc = await initDOM('promises');
- expect(doc.getElementById('feature-promises').childElementCount).to.equal(4)
- })
+ expect(doc.getElementById('feature-promises').childElementCount).to.equal(
+ 4
+ );
+ });
it('rest + default', async () => {
- const doc = await initDOM('rest-and-default')
+ const doc = await initDOM('rest-and-default');
- expect(doc.getElementById('feature-rest-and-default').childElementCount).to.equal(4)
- })
+ expect(
+ doc.getElementById('feature-rest-and-default').childElementCount
+ ).to.equal(4);
+ });
it('rest parameters', async () => {
- const doc = await initDOM('rest-parameters')
+ const doc = await initDOM('rest-parameters');
- expect(doc.getElementById('feature-rest-parameters').childElementCount).to.equal(4)
- })
+ expect(
+ doc.getElementById('feature-rest-parameters').childElementCount
+ ).to.equal(4);
+ });
it('template interpolation', async () => {
- const doc = await initDOM('template-interpolation')
-
- expect(doc.getElementById('feature-template-interpolation').childElementCount).to.equal(4)
- })
- })
-})
+ const doc = await initDOM('template-interpolation');
+
+ expect(
+ doc.getElementById('feature-template-interpolation').childElementCount
+ ).to.equal(4);
+ });
+ });
+});
diff --git a/packages/react-scripts/fixtures/kitchensink/integration/webpack.test.js b/packages/react-scripts/fixtures/kitchensink/integration/webpack.test.js
index 9e2826b8fc6..031786e0ee7 100644
--- a/packages/react-scripts/fixtures/kitchensink/integration/webpack.test.js
+++ b/packages/react-scripts/fixtures/kitchensink/integration/webpack.test.js
@@ -1,44 +1,63 @@
-import { expect } from 'chai'
-import initDOM from './initDOM'
+/**
+ * Copyright (c) 2015-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
+import { expect } from 'chai';
+import initDOM from './initDOM';
describe('Integration', () => {
describe('Webpack plugins', () => {
it('css inclusion', async () => {
- const doc = await initDOM('css-inclusion')
+ const doc = await initDOM('css-inclusion');
- expect(doc.getElementsByTagName('style')[0].textContent.replace(/\s/g, ''))
- .to.match(/#feature-css-inclusion\{background:.+;color:.+}/)
- })
+ expect(
+ doc.getElementsByTagName('style')[0].textContent.replace(/\s/g, '')
+ ).to.match(/#feature-css-inclusion\{background:.+;color:.+}/);
+ });
it('image inclusion', async () => {
- const doc = await initDOM('image-inclusion')
+ const doc = await initDOM('image-inclusion');
- expect(doc.getElementById('feature-image-inclusion').src).to.match(/^data:image\/jpeg;base64.+==$/)
- })
+ expect(doc.getElementById('feature-image-inclusion').src).to.match(
+ /^data:image\/jpeg;base64.+==$/
+ );
+ });
it('no ext inclusion', async () => {
- const doc = await initDOM('no-ext-inclusion')
+ const doc = await initDOM('no-ext-inclusion');
- expect(doc.getElementById('feature-no-ext-inclusion').textContent)
- .to.equal('This is just a file without an extension.')
- })
+ expect(doc.getElementById('feature-no-ext-inclusion').href).to.match(
+ /\/static\/media\/aFileWithoutExt\.[a-f0-9]{8}\.bin$/
+ );
+ });
it('json inclusion', async () => {
- const doc = await initDOM('json-inclusion')
+ const doc = await initDOM('json-inclusion');
- expect(doc.getElementById('feature-json-inclusion').textContent).to.equal('This is an abstract.')
- })
+ expect(doc.getElementById('feature-json-inclusion').textContent).to.equal(
+ 'This is an abstract.'
+ );
+ });
it('svg inclusion', async () => {
- const doc = await initDOM('svg-inclusion')
+ const doc = await initDOM('svg-inclusion');
- expect(doc.getElementById('feature-svg-inclusion').src).to.match(/\/static\/media\/logo\..+\.svg$/)
- })
+ expect(doc.getElementById('feature-svg-inclusion').src).to.match(
+ /\/static\/media\/logo\..+\.svg$/
+ );
+ });
it('unknown ext inclusion', async () => {
- const doc = await initDOM('unknown-ext-inclusion')
-
- expect(doc.getElementById('feature-unknown-ext-inclusion').textContent).to.equal('Whoooo, spooky!.')
- })
- })
-})
+ const doc = await initDOM('unknown-ext-inclusion');
+
+ expect(doc.getElementById('feature-unknown-ext-inclusion').href).to.match(
+ /\/static\/media\/aFileWithExt\.[a-f0-9]{8}\.unknown$/
+ );
+ });
+ });
+});
diff --git a/packages/react-scripts/fixtures/kitchensink/src/App.js b/packages/react-scripts/fixtures/kitchensink/src/App.js
index 36abe50d87a..67de182b59e 100644
--- a/packages/react-scripts/fixtures/kitchensink/src/App.js
+++ b/packages/react-scripts/fixtures/kitchensink/src/App.js
@@ -1,9 +1,18 @@
+/**
+ * Copyright (c) 2015-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
import React, { Component, PropTypes, createElement } from 'react';
class BuiltEmitter extends Component {
static propTypes = {
- feature: PropTypes.func.isRequired
- }
+ feature: PropTypes.func.isRequired,
+ };
componentDidMount() {
const { feature } = this.props;
@@ -22,12 +31,12 @@ class BuiltEmitter extends Component {
render() {
const {
props: { feature },
- handleReady
+ handleReady,
} = this;
return (
);
@@ -47,81 +56,113 @@ class App extends Component {
const feature = location.hash.slice(1);
switch (feature) {
case 'array-destructuring':
- require.ensure([], () => this.setFeature(require('./features/syntax/ArrayDestructuring').default));
+ import(
+ './features/syntax/ArrayDestructuring'
+ ).then(f => this.setFeature(f.default));
break;
case 'array-spread':
- require.ensure([], () => this.setFeature(require('./features/syntax/ArraySpread').default));
+ import('./features/syntax/ArraySpread').then(f =>
+ this.setFeature(f.default));
break;
case 'async-await':
- require.ensure([], () => this.setFeature(require('./features/syntax/AsyncAwait').default));
+ import('./features/syntax/AsyncAwait').then(f =>
+ this.setFeature(f.default));
break;
case 'class-properties':
- require.ensure([], () => this.setFeature(require('./features/syntax/ClassProperties').default));
+ import('./features/syntax/ClassProperties').then(f =>
+ this.setFeature(f.default));
break;
case 'computed-properties':
- require.ensure([], () => this.setFeature(require('./features/syntax/ComputedProperties').default));
+ import(
+ './features/syntax/ComputedProperties'
+ ).then(f => this.setFeature(f.default));
break;
case 'css-inclusion':
- require.ensure([], () => this.setFeature(require('./features/webpack/CssInclusion').default));
+ import('./features/webpack/CssInclusion').then(f =>
+ this.setFeature(f.default));
break;
case 'custom-interpolation':
- require.ensure([], () => this.setFeature(require('./features/syntax/CustomInterpolation').default));
+ import(
+ './features/syntax/CustomInterpolation'
+ ).then(f => this.setFeature(f.default));
break;
case 'default-parameters':
- require.ensure([], () => this.setFeature(require('./features/syntax/DefaultParameters').default));
+ import('./features/syntax/DefaultParameters').then(f =>
+ this.setFeature(f.default));
break;
case 'destructuring-and-await':
- require.ensure([], () => this.setFeature(require('./features/syntax/DestructuringAndAwait').default));
+ import(
+ './features/syntax/DestructuringAndAwait'
+ ).then(f => this.setFeature(f.default));
break;
case 'file-env-variables':
- require.ensure([], () => this.setFeature(require('./features/env/FileEnvVariables').default));
+ import('./features/env/FileEnvVariables').then(f =>
+ this.setFeature(f.default));
break;
case 'generators':
- require.ensure([], () => this.setFeature(require('./features/syntax/Generators').default));
+ import('./features/syntax/Generators').then(f =>
+ this.setFeature(f.default));
break;
case 'image-inclusion':
- require.ensure([], () => this.setFeature(require('./features/webpack/ImageInclusion').default));
+ import('./features/webpack/ImageInclusion').then(f =>
+ this.setFeature(f.default));
break;
case 'json-inclusion':
- require.ensure([], () => this.setFeature(require('./features/webpack/JsonInclusion').default));
+ import('./features/webpack/JsonInclusion').then(f =>
+ this.setFeature(f.default));
break;
case 'node-path':
- require.ensure([], () => this.setFeature(require('./features/env/NodePath').default));
+ import('./features/env/NodePath').then(f => this.setFeature(f.default));
break;
case 'no-ext-inclusion':
- require.ensure([], () => this.setFeature(require('./features/webpack/NoExtInclusion').default));
+ import('./features/webpack/NoExtInclusion').then(f =>
+ this.setFeature(f.default));
break;
case 'object-destructuring':
- require.ensure([], () => this.setFeature(require('./features/syntax/ObjectDestructuring').default));
+ import(
+ './features/syntax/ObjectDestructuring'
+ ).then(f => this.setFeature(f.default));
break;
case 'object-spread':
- require.ensure([], () => this.setFeature(require('./features/syntax/ObjectSpread').default));
+ import('./features/syntax/ObjectSpread').then(f =>
+ this.setFeature(f.default));
break;
case 'promises':
- require.ensure([], () => this.setFeature(require('./features/syntax/Promises').default));
+ import('./features/syntax/Promises').then(f =>
+ this.setFeature(f.default));
break;
case 'public-url':
- require.ensure([], () => this.setFeature(require('./features/env/PublicUrl').default));
+ import('./features/env/PublicUrl').then(f =>
+ this.setFeature(f.default));
break;
case 'rest-and-default':
- require.ensure([], () => this.setFeature(require('./features/syntax/RestAndDefault').default));
+ import('./features/syntax/RestAndDefault').then(f =>
+ this.setFeature(f.default));
break;
case 'rest-parameters':
- require.ensure([], () => this.setFeature(require('./features/syntax/RestParameters').default));
+ import('./features/syntax/RestParameters').then(f =>
+ this.setFeature(f.default));
break;
case 'shell-env-variables':
- require.ensure([], () => this.setFeature(require('./features/env/ShellEnvVariables').default));
+ import('./features/env/ShellEnvVariables').then(f =>
+ this.setFeature(f.default));
break;
case 'svg-inclusion':
- require.ensure([], () => this.setFeature(require('./features/webpack/SvgInclusion').default));
+ import('./features/webpack/SvgInclusion').then(f =>
+ this.setFeature(f.default));
break;
case 'template-interpolation':
- require.ensure([], () => this.setFeature(require('./features/syntax/TemplateInterpolation').default));
+ import(
+ './features/syntax/TemplateInterpolation'
+ ).then(f => this.setFeature(f.default));
break;
case 'unknown-ext-inclusion':
- require.ensure([], () => this.setFeature(require('./features/webpack/UnknownExtInclusion').default));
+ import(
+ './features/webpack/UnknownExtInclusion'
+ ).then(f => this.setFeature(f.default));
break;
- default: throw new Error(`Missing feature "${feature}"`);
+ default:
+ throw new Error(`Missing feature "${feature}"`);
}
}
diff --git a/packages/react-scripts/fixtures/kitchensink/src/absoluteLoad.js b/packages/react-scripts/fixtures/kitchensink/src/absoluteLoad.js
index dc769fe1e53..0d01bc0a227 100644
--- a/packages/react-scripts/fixtures/kitchensink/src/absoluteLoad.js
+++ b/packages/react-scripts/fixtures/kitchensink/src/absoluteLoad.js
@@ -1,6 +1,15 @@
+/**
+ * Copyright (c) 2015-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
export default () => [
{ id: 1, name: '1' },
{ id: 2, name: '2' },
{ id: 3, name: '3' },
- { id: 4, name: '4' }
-]
+ { id: 4, name: '4' },
+];
diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/env/FileEnvVariables.js b/packages/react-scripts/fixtures/kitchensink/src/features/env/FileEnvVariables.js
index c7b7c5d537d..a8a1e98fe71 100644
--- a/packages/react-scripts/fixtures/kitchensink/src/features/env/FileEnvVariables.js
+++ b/packages/react-scripts/fixtures/kitchensink/src/features/env/FileEnvVariables.js
@@ -1,5 +1,16 @@
-import React from 'react'
+/**
+ * Copyright (c) 2015-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
+import React from 'react';
export default () => (
- {process.env.REACT_APP_FILE_ENV_MESSAGE}.
-)
+
+ {process.env.REACT_APP_FILE_ENV_MESSAGE}.
+
+);
diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/env/FileEnvVariables.test.js b/packages/react-scripts/fixtures/kitchensink/src/features/env/FileEnvVariables.test.js
index c9d802be975..5a0fed4c649 100644
--- a/packages/react-scripts/fixtures/kitchensink/src/features/env/FileEnvVariables.test.js
+++ b/packages/react-scripts/fixtures/kitchensink/src/features/env/FileEnvVariables.test.js
@@ -1,3 +1,12 @@
+/**
+ * Copyright (c) 2015-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
import React from 'react';
import ReactDOM from 'react-dom';
import FileEnvVariables from './FileEnvVariables';
diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/env/NodePath.js b/packages/react-scripts/fixtures/kitchensink/src/features/env/NodePath.js
index deef80d20ac..eb1a45c0f12 100644
--- a/packages/react-scripts/fixtures/kitchensink/src/features/env/NodePath.js
+++ b/packages/react-scripts/fixtures/kitchensink/src/features/env/NodePath.js
@@ -1,10 +1,19 @@
-import React, { Component, PropTypes } from 'react'
-import load from 'absoluteLoad'
+/**
+ * Copyright (c) 2015-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
+import React, { Component, PropTypes } from 'react';
+import load from 'absoluteLoad';
export default class extends Component {
static propTypes = {
- onReady: PropTypes.func.isRequired
- }
+ onReady: PropTypes.func.isRequired,
+ };
constructor(props) {
super(props);
@@ -23,9 +32,7 @@ export default class extends Component {
render() {
return (
- {this.state.users.map(user => (
-
{user.name}
- ))}
+ {this.state.users.map(user =>
{user.name}
)}
);
}
diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/env/NodePath.test.js b/packages/react-scripts/fixtures/kitchensink/src/features/env/NodePath.test.js
index 81487d55968..7e076dade75 100644
--- a/packages/react-scripts/fixtures/kitchensink/src/features/env/NodePath.test.js
+++ b/packages/react-scripts/fixtures/kitchensink/src/features/env/NodePath.test.js
@@ -1,3 +1,12 @@
+/**
+ * Copyright (c) 2015-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
import React from 'react';
import ReactDOM from 'react-dom';
import NodePath from './NodePath';
diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/env/PublicUrl.js b/packages/react-scripts/fixtures/kitchensink/src/features/env/PublicUrl.js
index bbb7b958b61..4ea9b96f8b2 100644
--- a/packages/react-scripts/fixtures/kitchensink/src/features/env/PublicUrl.js
+++ b/packages/react-scripts/fixtures/kitchensink/src/features/env/PublicUrl.js
@@ -1,5 +1,14 @@
-import React from 'react'
+/**
+ * Copyright (c) 2015-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
+import React from 'react';
export default () => (
{process.env.PUBLIC_URL}.
-)
+);
diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/env/PublicUrl.test.js b/packages/react-scripts/fixtures/kitchensink/src/features/env/PublicUrl.test.js
index 31e699ece0b..c9e1be0e94a 100644
--- a/packages/react-scripts/fixtures/kitchensink/src/features/env/PublicUrl.test.js
+++ b/packages/react-scripts/fixtures/kitchensink/src/features/env/PublicUrl.test.js
@@ -1,3 +1,12 @@
+/**
+ * Copyright (c) 2015-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
import React from 'react';
import ReactDOM from 'react-dom';
import PublicUrl from './PublicUrl';
diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/env/ShellEnvVariables.js b/packages/react-scripts/fixtures/kitchensink/src/features/env/ShellEnvVariables.js
index 37b80ec6097..8449097d69a 100644
--- a/packages/react-scripts/fixtures/kitchensink/src/features/env/ShellEnvVariables.js
+++ b/packages/react-scripts/fixtures/kitchensink/src/features/env/ShellEnvVariables.js
@@ -1,5 +1,16 @@
-import React from 'react'
+/**
+ * Copyright (c) 2015-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
+import React from 'react';
export default () => (
- {process.env.REACT_APP_SHELL_ENV_MESSAGE}.
-)
+
+ {process.env.REACT_APP_SHELL_ENV_MESSAGE}.
+
+);
diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/env/ShellEnvVariables.test.js b/packages/react-scripts/fixtures/kitchensink/src/features/env/ShellEnvVariables.test.js
index 981bee67c26..13707697591 100644
--- a/packages/react-scripts/fixtures/kitchensink/src/features/env/ShellEnvVariables.test.js
+++ b/packages/react-scripts/fixtures/kitchensink/src/features/env/ShellEnvVariables.test.js
@@ -1,3 +1,12 @@
+/**
+ * Copyright (c) 2015-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
import React from 'react';
import ReactDOM from 'react-dom';
import ShellEnvVariables from './ShellEnvVariables';
diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ArrayDestructuring.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ArrayDestructuring.js
index d07271ed6fc..3d18a5edeac 100644
--- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ArrayDestructuring.js
+++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ArrayDestructuring.js
@@ -1,18 +1,22 @@
-import React, { Component, PropTypes } from 'react'
+/**
+ * Copyright (c) 2015-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
+import React, { Component, PropTypes } from 'react';
function load() {
- return [
- [1, '1'],
- [2, '2'],
- [3, '3'],
- [4, '4']
- ];
+ return [[1, '1'], [2, '2'], [3, '3'], [4, '4']];
}
export default class extends Component {
static propTypes = {
- onReady: PropTypes.func.isRequired
- }
+ onReady: PropTypes.func.isRequired,
+ };
constructor(props) {
super(props);
@@ -33,7 +37,7 @@ export default class extends Component {
);
diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ArrayDestructuring.test.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ArrayDestructuring.test.js
index 05d14263d25..42dde0f1c35 100644
--- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ArrayDestructuring.test.js
+++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ArrayDestructuring.test.js
@@ -1,3 +1,12 @@
+/**
+ * Copyright (c) 2015-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
import React from 'react';
import ReactDOM from 'react-dom';
import ArrayDestructuring from './ArrayDestructuring';
diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ArraySpread.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ArraySpread.js
index 6cb2f6162c4..4f9b174eb6f 100644
--- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ArraySpread.js
+++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ArraySpread.js
@@ -1,18 +1,27 @@
-import React, { Component, PropTypes } from 'react'
+/**
+ * Copyright (c) 2015-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
+import React, { Component, PropTypes } from 'react';
function load(users) {
return [
{ id: 1, name: '1' },
{ id: 2, name: '2' },
{ id: 3, name: '3' },
- ...users
+ ...users,
];
}
export default class extends Component {
static propTypes = {
- onReady: PropTypes.func.isRequired
- }
+ onReady: PropTypes.func.isRequired,
+ };
constructor(props) {
super(props);
@@ -31,9 +40,7 @@ export default class extends Component {
render() {
return (
- {this.state.users.map(user => (
-
{user.name}
- ))}
+ {this.state.users.map(user =>
{user.name}
)}
);
}
diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ArraySpread.test.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ArraySpread.test.js
index a2191cf1c14..9ed7633ea35 100644
--- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ArraySpread.test.js
+++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ArraySpread.test.js
@@ -1,3 +1,12 @@
+/**
+ * Copyright (c) 2015-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
import React from 'react';
import ReactDOM from 'react-dom';
import ArraySpread from './ArraySpread';
diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/AsyncAwait.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/AsyncAwait.js
index 9fe920514a1..6924d4f92d8 100644
--- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/AsyncAwait.js
+++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/AsyncAwait.js
@@ -1,18 +1,27 @@
-import React, { Component, PropTypes } from 'react'
+/**
+ * Copyright (c) 2015-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
+import React, { Component, PropTypes } from 'react';
async function load() {
return [
{ id: 1, name: '1' },
{ id: 2, name: '2' },
{ id: 3, name: '3' },
- { id: 4, name: '4' }
+ { id: 4, name: '4' },
];
}
export default class extends Component {
static propTypes = {
- onReady: PropTypes.func.isRequired
- }
+ onReady: PropTypes.func.isRequired,
+ };
constructor(props) {
super(props);
@@ -31,9 +40,7 @@ export default class extends Component {
render() {
return (
- {this.state.users.map(user => (
-
{user.name}
- ))}
+ {this.state.users.map(user =>
{user.name}
)}
);
}
diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/AsyncAwait.test.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/AsyncAwait.test.js
index bc60c5b58f0..02713981799 100644
--- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/AsyncAwait.test.js
+++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/AsyncAwait.test.js
@@ -1,3 +1,12 @@
+/**
+ * Copyright (c) 2015-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
import React from 'react';
import ReactDOM from 'react-dom';
import AsyncAwait from './AsyncAwait';
diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ClassProperties.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ClassProperties.js
index 726eba1524c..7be21952da5 100644
--- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ClassProperties.js
+++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ClassProperties.js
@@ -1,27 +1,34 @@
-import React, { Component, PropTypes } from 'react'
+/**
+ * Copyright (c) 2015-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
+import React, { Component, PropTypes } from 'react';
export default class extends Component {
static propTypes = {
- onReady: PropTypes.func.isRequired
- }
+ onReady: PropTypes.func.isRequired,
+ };
users = [
{ id: 1, name: '1' },
{ id: 2, name: '2' },
{ id: 3, name: '3' },
- { id: 4, name: '4' }
+ { id: 4, name: '4' },
];
componentDidMount() {
- this.props.onReady()
+ this.props.onReady();
}
render() {
return (
- {this.users.map(user => (
-
{user.name}
- ))}
+ {this.users.map(user =>
{user.name}
)}
);
}
diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ClassProperties.test.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ClassProperties.test.js
index 898916b2f9a..5b038e76d90 100644
--- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ClassProperties.test.js
+++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ClassProperties.test.js
@@ -1,3 +1,12 @@
+/**
+ * Copyright (c) 2015-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
import React from 'react';
import ReactDOM from 'react-dom';
import ClassProperties from './ClassProperties';
diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ComputedProperties.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ComputedProperties.js
index 04dc7ba109b..fc64c2a86e3 100644
--- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ComputedProperties.js
+++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ComputedProperties.js
@@ -1,18 +1,27 @@
-import React, { Component, PropTypes } from 'react'
+/**
+ * Copyright (c) 2015-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
+import React, { Component, PropTypes } from 'react';
function load(prefix) {
return [
- { id: 1, [prefix + 'name']: '1' },
- { id: 2, [prefix + 'name']: '2' },
- { id: 3, [prefix + 'name']: '3' },
- { id: 4, [prefix + 'name']: '4' }
+ { id: 1, [`${prefix} name`]: '1' },
+ { id: 2, [`${prefix} name`]: '2' },
+ { id: 3, [`${prefix} name`]: '3' },
+ { id: 4, [`${prefix} name`]: '4' },
];
}
export default class extends Component {
static propTypes = {
- onReady: PropTypes.func.isRequired
- }
+ onReady: PropTypes.func.isRequired,
+ };
constructor(props) {
super(props);
diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ComputedProperties.test.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ComputedProperties.test.js
index 0aa3d4d7ec6..91b697fe0a0 100644
--- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ComputedProperties.test.js
+++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ComputedProperties.test.js
@@ -1,3 +1,12 @@
+/**
+ * Copyright (c) 2015-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
import React from 'react';
import ReactDOM from 'react-dom';
import ComputedProperties from './ComputedProperties';
diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/CustomInterpolation.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/CustomInterpolation.js
index c80f14dc882..e97902545e1 100644
--- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/CustomInterpolation.js
+++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/CustomInterpolation.js
@@ -1,23 +1,34 @@
-import React, { Component, PropTypes } from 'react'
-
-const styled = ([style]) => style.trim()
- .split(/\s*;\s*/)
- .map(rule => rule.split(/\s*:\s*/))
- .reduce((rules, rule) => ({ ...rules, [rule[0]]: rule[1] }), {});
+/**
+ * Copyright (c) 2015-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
+import React, { Component, PropTypes } from 'react';
+
+const styled = ([style]) =>
+ style
+ .trim()
+ .split(/\s*;\s*/)
+ .map(rule => rule.split(/\s*:\s*/))
+ .reduce((rules, rule) => ({ ...rules, [rule[0]]: rule[1] }), {});
function load() {
return [
{ id: 1, name: '1' },
{ id: 2, name: '2' },
{ id: 3, name: '3' },
- { id: 4, name: '4' }
+ { id: 4, name: '4' },
];
}
export default class extends Component {
static propTypes = {
- onReady: PropTypes.func.isRequired
- }
+ onReady: PropTypes.func.isRequired,
+ };
constructor(props) {
super(props);
diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/CustomInterpolation.test.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/CustomInterpolation.test.js
index 79af8dc5f6b..ac468db76a8 100644
--- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/CustomInterpolation.test.js
+++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/CustomInterpolation.test.js
@@ -1,3 +1,12 @@
+/**
+ * Copyright (c) 2015-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
import React from 'react';
import ReactDOM from 'react-dom';
import CustomInterpolation from './CustomInterpolation';
diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/DefaultParameters.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/DefaultParameters.js
index 0d7b77d87e3..74bbe4d3c17 100644
--- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/DefaultParameters.js
+++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/DefaultParameters.js
@@ -1,18 +1,27 @@
-import React, { Component, PropTypes } from 'react'
+/**
+ * Copyright (c) 2015-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
+import React, { Component, PropTypes } from 'react';
function load(id = 0) {
return [
{ id: id + 1, name: '1' },
{ id: id + 2, name: '2' },
{ id: id + 3, name: '3' },
- { id: id + 4, name: '4' }
+ { id: id + 4, name: '4' },
];
}
export default class extends Component {
static propTypes = {
- onReady: PropTypes.func.isRequired
- }
+ onReady: PropTypes.func.isRequired,
+ };
constructor(props) {
super(props);
@@ -31,9 +40,7 @@ export default class extends Component {
render() {
return (
- {this.state.users.map(user => (
-
{user.name}
- ))}
+ {this.state.users.map(user =>
{user.name}
)}
);
}
diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/DefaultParameters.test.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/DefaultParameters.test.js
index c4a336563ac..26d5184eb11 100644
--- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/DefaultParameters.test.js
+++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/DefaultParameters.test.js
@@ -1,3 +1,12 @@
+/**
+ * Copyright (c) 2015-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
import React from 'react';
import ReactDOM from 'react-dom';
import DefaultParameters from './DefaultParameters';
diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/DestructuringAndAwait.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/DestructuringAndAwait.js
index 40f51754202..ede416944fc 100644
--- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/DestructuringAndAwait.js
+++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/DestructuringAndAwait.js
@@ -1,18 +1,29 @@
-import React, { Component, PropTypes } from 'react'
+/**
+ * Copyright (c) 2015-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
+import React, { Component, PropTypes } from 'react';
async function load() {
- return { users: [
- { id: 1, name: '1' },
- { id: 2, name: '2' },
- { id: 3, name: '3' },
- { id: 4, name: '4' }
- ] };
+ return {
+ users: [
+ { id: 1, name: '1' },
+ { id: 2, name: '2' },
+ { id: 3, name: '3' },
+ { id: 4, name: '4' },
+ ],
+ };
}
export default class extends Component {
static propTypes = {
- onReady: PropTypes.func.isRequired
- }
+ onReady: PropTypes.func.isRequired,
+ };
constructor(props) {
super(props);
@@ -31,9 +42,7 @@ export default class extends Component {
render() {
return (
- {this.state.users.map(user => (
-
{user.name}
- ))}
+ {this.state.users.map(user =>
{user.name}
)}
);
}
diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/DestructuringAndAwait.test.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/DestructuringAndAwait.test.js
index 96b361c742e..c7d74d8012b 100644
--- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/DestructuringAndAwait.test.js
+++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/DestructuringAndAwait.test.js
@@ -1,3 +1,12 @@
+/**
+ * Copyright (c) 2015-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
import React from 'react';
import ReactDOM from 'react-dom';
import DestructuringAndAwait from './DestructuringAndAwait';
diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/Generators.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/Generators.js
index 6bb64f9103f..77b7bffd252 100644
--- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/Generators.js
+++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/Generators.js
@@ -1,6 +1,15 @@
-import React, { Component, PropTypes } from 'react'
+/**
+ * Copyright (c) 2015-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
-function * load(limit) {
+import React, { Component, PropTypes } from 'react';
+
+function* load(limit) {
let i = 1;
while (i <= limit) {
yield { id: i, name: i };
@@ -10,8 +19,8 @@ function * load(limit) {
export default class extends Component {
static propTypes = {
- onReady: PropTypes.func.isRequired
- }
+ onReady: PropTypes.func.isRequired,
+ };
constructor(props) {
super(props);
@@ -33,9 +42,7 @@ export default class extends Component {
render() {
return (
- {this.state.users.map(user => (
-
{user.name}
- ))}
+ {this.state.users.map(user =>
{user.name}
)}
);
}
diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/Generators.test.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/Generators.test.js
index 4e6b8d1d9ad..3bbe2d4f703 100644
--- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/Generators.test.js
+++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/Generators.test.js
@@ -1,3 +1,12 @@
+/**
+ * Copyright (c) 2015-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
import React from 'react';
import ReactDOM from 'react-dom';
import Generators from './Generators';
diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ObjectDestructuring.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ObjectDestructuring.js
index 3235a99104c..14fa6969ee5 100644
--- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ObjectDestructuring.js
+++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ObjectDestructuring.js
@@ -1,18 +1,27 @@
-import React, { Component, PropTypes } from 'react'
+/**
+ * Copyright (c) 2015-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
+import React, { Component, PropTypes } from 'react';
function load() {
return [
{ id: 1, name: '1' },
{ id: 2, name: '2' },
{ id: 3, name: '3' },
- { id: 4, name: '4' }
+ { id: 4, name: '4' },
];
}
export default class extends Component {
static propTypes = {
- onReady: PropTypes.func.isRequired
- }
+ onReady: PropTypes.func.isRequired,
+ };
constructor(props) {
super(props);
@@ -33,7 +42,7 @@ export default class extends Component {
);
diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ObjectDestructuring.test.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ObjectDestructuring.test.js
index 0a21b291bc6..503b2cb11b6 100644
--- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ObjectDestructuring.test.js
+++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ObjectDestructuring.test.js
@@ -1,3 +1,12 @@
+/**
+ * Copyright (c) 2015-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
import React from 'react';
import ReactDOM from 'react-dom';
import ObjectDestructuring from './ObjectDestructuring';
diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ObjectSpread.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ObjectSpread.js
index fb43bf8676e..bf3fb26b80c 100644
--- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ObjectSpread.js
+++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ObjectSpread.js
@@ -1,18 +1,27 @@
-import React, { Component, PropTypes } from 'react'
+/**
+ * Copyright (c) 2015-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
+import React, { Component, PropTypes } from 'react';
function load(baseUser) {
return [
{ id: 1, name: '1', ...baseUser },
{ id: 2, name: '2', ...baseUser },
{ id: 3, name: '3', ...baseUser },
- { id: 4, name: '4', ...baseUser }
+ { id: 4, name: '4', ...baseUser },
];
}
export default class extends Component {
static propTypes = {
- onReady: PropTypes.func.isRequired
- }
+ onReady: PropTypes.func.isRequired,
+ };
constructor(props) {
super(props);
diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ObjectSpread.test.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ObjectSpread.test.js
index 4ca5d2b9ab1..09a92ce05a2 100644
--- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ObjectSpread.test.js
+++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ObjectSpread.test.js
@@ -1,3 +1,12 @@
+/**
+ * Copyright (c) 2015-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
import React from 'react';
import ReactDOM from 'react-dom';
import ObjectSpread from './ObjectSpread';
diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/Promises.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/Promises.js
index 63f38fed473..26438012cf2 100644
--- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/Promises.js
+++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/Promises.js
@@ -1,18 +1,27 @@
-import React, { Component, PropTypes } from 'react'
+/**
+ * Copyright (c) 2015-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
+import React, { Component, PropTypes } from 'react';
function load() {
return Promise.resolve([
{ id: 1, name: '1' },
{ id: 2, name: '2' },
{ id: 3, name: '3' },
- { id: 4, name: '4' }
+ { id: 4, name: '4' },
]);
}
export default class extends Component {
static propTypes = {
- onReady: PropTypes.func.isRequired
- }
+ onReady: PropTypes.func.isRequired,
+ };
constructor(props) {
super(props);
@@ -32,9 +41,7 @@ export default class extends Component {
render() {
return (
- {this.state.users.map(user => (
-
{user.name}
- ))}
+ {this.state.users.map(user =>
{user.name}
)}
);
}
diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/Promises.test.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/Promises.test.js
index 36c5984a4b5..88ba04fe3b9 100644
--- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/Promises.test.js
+++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/Promises.test.js
@@ -1,12 +1,22 @@
+/**
+ * Copyright (c) 2015-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
import React from 'react';
import ReactDOM from 'react-dom';
-import Promises from './Promises';
describe('promises', () => {
it('renders without crashing', () => {
const div = document.createElement('div');
- return new Promise(resolve => {
- ReactDOM.render(, div);
+ return import('./Promises').then(({ default: Promises }) => {
+ return new Promise(resolve => {
+ ReactDOM.render(, div);
+ });
});
});
});
diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/RestAndDefault.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/RestAndDefault.js
index 7783868ab4d..411ce33d4b9 100644
--- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/RestAndDefault.js
+++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/RestAndDefault.js
@@ -1,18 +1,27 @@
-import React, { Component, PropTypes } from 'react'
+/**
+ * Copyright (c) 2015-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
+import React, { Component, PropTypes } from 'react';
function load({ id, ...rest } = { id: 0, user: { id: 42, name: '42' } }) {
return [
{ id: id + 1, name: '1' },
{ id: id + 2, name: '2' },
{ id: id + 3, name: '3' },
- rest.user
+ rest.user,
];
}
export default class extends Component {
static propTypes = {
- onReady: PropTypes.func.isRequired
- }
+ onReady: PropTypes.func.isRequired,
+ };
constructor(props) {
super(props);
@@ -31,9 +40,7 @@ export default class extends Component {
render() {
return (
- {this.state.users.map(user => (
-
{user.name}
- ))}
+ {this.state.users.map(user =>
{user.name}
)}
);
}
diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/RestAndDefault.test.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/RestAndDefault.test.js
index 22a91be0847..e48b7dc59b9 100644
--- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/RestAndDefault.test.js
+++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/RestAndDefault.test.js
@@ -1,3 +1,12 @@
+/**
+ * Copyright (c) 2015-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
import React from 'react';
import ReactDOM from 'react-dom';
import RestAndDefault from './RestAndDefault';
diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/RestParameters.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/RestParameters.js
index cf216ce01f2..aaca55c0f96 100644
--- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/RestParameters.js
+++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/RestParameters.js
@@ -1,18 +1,27 @@
-import React, { Component, PropTypes } from 'react'
+/**
+ * Copyright (c) 2015-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
+import React, { Component, PropTypes } from 'react';
function load({ id = 0, ...rest }) {
return [
{ id: id + 1, name: '1' },
{ id: id + 2, name: '2' },
{ id: id + 3, name: '3' },
- rest.user
+ rest.user,
];
}
export default class extends Component {
static propTypes = {
- onReady: PropTypes.func.isRequired
- }
+ onReady: PropTypes.func.isRequired,
+ };
constructor(props) {
super(props);
@@ -31,9 +40,7 @@ export default class extends Component {
render() {
return (
- {this.state.users.map(user => (
-
{user.name}
- ))}
+ {this.state.users.map(user =>
{user.name}
)}
);
}
diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/RestParameters.test.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/RestParameters.test.js
index f1f8e35e370..c1eb90e0dbd 100644
--- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/RestParameters.test.js
+++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/RestParameters.test.js
@@ -1,3 +1,12 @@
+/**
+ * Copyright (c) 2015-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
import React from 'react';
import ReactDOM from 'react-dom';
import RestParameters from './RestParameters';
diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/TemplateInterpolation.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/TemplateInterpolation.js
index dd6bf49b11d..738a0b103ef 100644
--- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/TemplateInterpolation.js
+++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/TemplateInterpolation.js
@@ -1,18 +1,27 @@
-import React, { Component, PropTypes } from 'react'
+/**
+ * Copyright (c) 2015-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
+import React, { Component, PropTypes } from 'react';
function load(name) {
return [
{ id: 1, name: `${name}1` },
{ id: 2, name: `${name}2` },
{ id: 3, name: `${name}3` },
- { id: 4, name: `${name}4` }
+ { id: 4, name: `${name}4` },
];
}
export default class extends Component {
static propTypes = {
- onReady: PropTypes.func.isRequired
- }
+ onReady: PropTypes.func.isRequired,
+ };
constructor(props) {
super(props);
@@ -31,9 +40,7 @@ export default class extends Component {
render() {
return (
- {this.state.users.map(user => (
-
{user.name}
- ))}
+ {this.state.users.map(user =>
{user.name}
)}
);
}
diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/TemplateInterpolation.test.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/TemplateInterpolation.test.js
index 41a5fad2c5f..ff32baaedd0 100644
--- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/TemplateInterpolation.test.js
+++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/TemplateInterpolation.test.js
@@ -1,3 +1,12 @@
+/**
+ * Copyright (c) 2015-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
import React from 'react';
import ReactDOM from 'react-dom';
import TemplateInterpolation from './TemplateInterpolation';
diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/webpack/CssInclusion.js b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/CssInclusion.js
index f35d11e0a82..ab7c9a2d86e 100644
--- a/packages/react-scripts/fixtures/kitchensink/src/features/webpack/CssInclusion.js
+++ b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/CssInclusion.js
@@ -1,6 +1,13 @@
-import React from 'react'
-import './assets/style.css'
+/**
+ * Copyright (c) 2015-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
-export default () => (
-
;
diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/webpack/CssInclusion.test.js b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/CssInclusion.test.js
index f3e10a441a8..e315ee33b38 100644
--- a/packages/react-scripts/fixtures/kitchensink/src/features/webpack/CssInclusion.test.js
+++ b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/CssInclusion.test.js
@@ -1,3 +1,12 @@
+/**
+ * Copyright (c) 2015-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
import React from 'react';
import ReactDOM from 'react-dom';
import CssInclusion from './CssInclusion';
diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/webpack/ImageInclusion.js b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/ImageInclusion.js
index d793408a5c7..a6ca7aaa818 100644
--- a/packages/react-scripts/fixtures/kitchensink/src/features/webpack/ImageInclusion.js
+++ b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/ImageInclusion.js
@@ -1,6 +1,15 @@
-import React from 'react'
-import tiniestCat from './assets/tiniest-cat.jpg'
+/**
+ * Copyright (c) 2015-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
+import React from 'react';
+import tiniestCat from './assets/tiniest-cat.jpg';
export default () => (
-)
+);
diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/webpack/ImageInclusion.test.js b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/ImageInclusion.test.js
index 85e68d51e85..042d2da3088 100644
--- a/packages/react-scripts/fixtures/kitchensink/src/features/webpack/ImageInclusion.test.js
+++ b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/ImageInclusion.test.js
@@ -1,3 +1,12 @@
+/**
+ * Copyright (c) 2015-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
import React from 'react';
import ReactDOM from 'react-dom';
import ImageInclusion from './ImageInclusion';
diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/webpack/JsonInclusion.js b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/JsonInclusion.js
index 8050b9cfd6c..e81f7639736 100644
--- a/packages/react-scripts/fixtures/kitchensink/src/features/webpack/JsonInclusion.js
+++ b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/JsonInclusion.js
@@ -1,6 +1,13 @@
-import React from 'react'
-import { abstract } from './assets/abstract.json'
+/**
+ * Copyright (c) 2015-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
-export default () => (
- {abstract}
-)
+import React from 'react';
+import { abstract } from './assets/abstract.json';
+
+export default () => {abstract};
diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/webpack/JsonInclusion.test.js b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/JsonInclusion.test.js
index 70043bd0503..ee150f629a6 100644
--- a/packages/react-scripts/fixtures/kitchensink/src/features/webpack/JsonInclusion.test.js
+++ b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/JsonInclusion.test.js
@@ -1,3 +1,12 @@
+/**
+ * Copyright (c) 2015-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
import React from 'react';
import ReactDOM from 'react-dom';
import JsonInclusion from './JsonInclusion';
diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/webpack/NoExtInclusion.js b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/NoExtInclusion.js
index 70b2d2b2155..7f824c2f292 100644
--- a/packages/react-scripts/fixtures/kitchensink/src/features/webpack/NoExtInclusion.js
+++ b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/NoExtInclusion.js
@@ -1,10 +1,19 @@
-import React from 'react'
-import aFileWithoutExt from './assets/aFileWithoutExt'
+/**
+ * Copyright (c) 2015-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
+import React from 'react';
+import aFileWithoutExt from './assets/aFileWithoutExt';
const text = aFileWithoutExt.includes('base64')
? atob(aFileWithoutExt.split('base64,')[1]).trim()
- : aFileWithoutExt
+ : aFileWithoutExt;
export default () => (
-
{text}.
-)
+ aFileWithoutExt
+);
diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/webpack/NoExtInclusion.test.js b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/NoExtInclusion.test.js
index 666f94f384c..a08b5d21b0c 100644
--- a/packages/react-scripts/fixtures/kitchensink/src/features/webpack/NoExtInclusion.test.js
+++ b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/NoExtInclusion.test.js
@@ -1,3 +1,12 @@
+/**
+ * Copyright (c) 2015-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
import React from 'react';
import ReactDOM from 'react-dom';
import NoExtInclusion from './NoExtInclusion';
diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/webpack/SvgInclusion.js b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/SvgInclusion.js
index 7c2fdb2e44e..8876021aed6 100644
--- a/packages/react-scripts/fixtures/kitchensink/src/features/webpack/SvgInclusion.js
+++ b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/SvgInclusion.js
@@ -1,6 +1,13 @@
-import React from 'react'
-import logo from './assets/logo.svg'
+/**
+ * Copyright (c) 2015-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
-export default () => (
-
-)
+import React from 'react';
+import logo from './assets/logo.svg';
+
+export default () => ;
diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/webpack/SvgInclusion.test.js b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/SvgInclusion.test.js
index 507da01403c..585c6c19d8a 100644
--- a/packages/react-scripts/fixtures/kitchensink/src/features/webpack/SvgInclusion.test.js
+++ b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/SvgInclusion.test.js
@@ -1,3 +1,12 @@
+/**
+ * Copyright (c) 2015-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
import React from 'react';
import ReactDOM from 'react-dom';
import SvgInclusion from './SvgInclusion';
diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/webpack/UnknownExtInclusion.js b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/UnknownExtInclusion.js
index 30aeccd6fb7..70b046e9532 100644
--- a/packages/react-scripts/fixtures/kitchensink/src/features/webpack/UnknownExtInclusion.js
+++ b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/UnknownExtInclusion.js
@@ -1,10 +1,19 @@
-import React from 'react'
-import aFileWithExtUnknown from './assets/aFileWithExt.unknown'
+/**
+ * Copyright (c) 2015-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
+import React from 'react';
+import aFileWithExtUnknown from './assets/aFileWithExt.unknown';
const text = aFileWithExtUnknown.includes('base64')
? atob(aFileWithExtUnknown.split('base64,')[1]).trim()
- : aFileWithExtUnknown
+ : aFileWithExtUnknown;
export default () => (
-
{text}.
-)
+ aFileWithExtUnknown
+);
diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/webpack/UnknownExtInclusion.test.js b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/UnknownExtInclusion.test.js
index 46724e0a27b..73a8016e17b 100644
--- a/packages/react-scripts/fixtures/kitchensink/src/features/webpack/UnknownExtInclusion.test.js
+++ b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/UnknownExtInclusion.test.js
@@ -1,3 +1,12 @@
+/**
+ * Copyright (c) 2015-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
import React from 'react';
import ReactDOM from 'react-dom';
import UnknownExtInclusion from './UnknownExtInclusion';
diff --git a/packages/react-scripts/fixtures/kitchensink/src/index.js b/packages/react-scripts/fixtures/kitchensink/src/index.js
index 0ea36197ba1..46fb0dd2e55 100644
--- a/packages/react-scripts/fixtures/kitchensink/src/index.js
+++ b/packages/react-scripts/fixtures/kitchensink/src/index.js
@@ -1,8 +1,14 @@
+/**
+ * Copyright (c) 2015-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
-ReactDOM.render(
- ,
- document.getElementById('root')
-);
+ReactDOM.render(, document.getElementById('root'));
diff --git a/packages/react-scripts/fixtures/kitchensink/src/subfolder/lol.js b/packages/react-scripts/fixtures/kitchensink/src/subfolder/lol.js
index 6c7375d5479..979cb3e7206 100644
--- a/packages/react-scripts/fixtures/kitchensink/src/subfolder/lol.js
+++ b/packages/react-scripts/fixtures/kitchensink/src/subfolder/lol.js
@@ -1 +1,12 @@
-module.exports = function() { return `haha` }
+/**
+ * Copyright (c) 2015-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
+module.exports = function() {
+ return `haha`;
+};
diff --git a/packages/react-scripts/package.json b/packages/react-scripts/package.json
index b774b88d941..3e951ab9ad3 100644
--- a/packages/react-scripts/package.json
+++ b/packages/react-scripts/package.json
@@ -1,6 +1,6 @@
{
"name": "react-scripts",
- "version": "0.9.0",
+ "version": "0.9.4",
"description": "Configuration and scripts for Create React App.",
"repository": "facebookincubator/create-react-app",
"license": "BSD-3-Clause",
@@ -11,8 +11,6 @@
"url": "https://github.com/facebookincubator/create-react-app/issues"
},
"files": [
- ".babelrc",
- ".eslintrc",
"bin",
"config",
"scripts",
@@ -23,48 +21,43 @@
"react-scripts": "./bin/react-scripts.js"
},
"dependencies": {
- "autoprefixer": "6.7.2",
- "babel-core": "6.22.1",
+ "autoprefixer": "6.7.7",
+ "babel-core": "6.23.1",
"babel-eslint": "7.1.1",
"babel-jest": "18.0.0",
- "babel-loader": "6.2.10",
- "babel-preset-react-app": "^2.1.0",
+ "babel-loader": "7.0.0-alpha.3",
+ "babel-preset-react-app": "^2.1.1",
"babel-runtime": "^6.20.0",
"case-sensitive-paths-webpack-plugin": "1.1.4",
"chalk": "1.1.3",
"connect-history-api-fallback": "1.3.0",
"cross-spawn": "4.0.2",
- "css-loader": "0.26.1",
- "detect-port": "1.0.1",
+ "css-loader": "0.27.3",
+ "detect-port": "1.1.1",
"dotenv": "2.0.0",
- "eslint": "3.8.1",
- "eslint-config-react-app": "^0.5.1",
- "eslint-loader": "1.6.0",
+ "eslint": "3.16.1",
+ "eslint-config-react-app": "^0.6.1",
+ "eslint-loader": "1.7.0",
"eslint-plugin-flowtype": "2.21.0",
"eslint-plugin-import": "2.0.1",
- "eslint-plugin-jsx-a11y": "2.2.3",
+ "eslint-plugin-jsx-a11y": "4.0.0",
"eslint-plugin-react": "6.4.1",
- "extract-text-webpack-plugin": "1.0.1",
- "file-loader": "0.10.0",
- "filesize": "3.3.0",
+ "extract-text-webpack-plugin": "2.1.0",
+ "file-loader": "0.10.1",
"fs-extra": "0.30.0",
- "gzip-size": "3.0.0",
- "html-webpack-plugin": "2.24.0",
+ "html-webpack-plugin": "2.28.0",
"http-proxy-middleware": "0.17.3",
"jest": "18.1.0",
- "json-loader": "0.5.4",
"object-assign": "4.1.1",
- "postcss-loader": "1.2.2",
+ "postcss-loader": "1.3.3",
"promise": "7.1.1",
- "react-dev-utils": "^0.5.0",
- "recursive-readdir": "2.1.0",
- "strip-ansi": "3.0.1",
- "style-loader": "0.13.1",
- "url-loader": "0.5.7",
- "webpack": "1.14.0",
- "webpack-dev-server": "1.16.2",
+ "react-dev-utils": "^0.5.2",
+ "style-loader": "0.16.0",
+ "url-loader": "0.5.8",
+ "webpack": "2.3.2",
+ "webpack-dev-server": "2.4.2",
"webpack-manifest-plugin": "1.1.0",
- "whatwg-fetch": "2.0.2"
+ "whatwg-fetch": "2.0.3"
},
"devDependencies": {
"react": "^15.3.0",
diff --git a/packages/react-scripts/scripts/build.js b/packages/react-scripts/scripts/build.js
index 7c953c3544e..fe4ec959d4d 100644
--- a/packages/react-scripts/scripts/build.js
+++ b/packages/react-scripts/scripts/build.js
@@ -8,118 +8,57 @@
* of patent rights can be found in the PATENTS file in the same directory.
*/
// @remove-on-eject-end
+'use strict';
// Do this as the first thing so that any code reading it knows the right env.
process.env.NODE_ENV = 'production';
+// Makes the script crash on unhandled rejections instead of silently
+// ignoring them. In the future, promise rejections that are not handled will
+// terminate the Node.js process with a non-zero exit code.
+process.on('unhandledRejection', err => {
+ throw err;
+});
+
// Load environment variables from .env file. Suppress warnings using silent
// if this file is missing. dotenv will never modify any environment variables
// that have already been set.
// https://github.com/motdotla/dotenv
-require('dotenv').config({silent: true});
-
-var chalk = require('chalk');
-var fs = require('fs-extra');
-var path = require('path');
-var url = require('url');
-var filesize = require('filesize');
-var gzipSize = require('gzip-size').sync;
-var webpack = require('webpack');
-var config = require('../config/webpack.config.prod');
-var paths = require('../config/paths');
-var checkRequiredFiles = require('react-dev-utils/checkRequiredFiles');
-var recursive = require('recursive-readdir');
-var stripAnsi = require('strip-ansi');
-
-var useYarn = fs.existsSync(paths.yarnLockFile);
+require('dotenv').config({ silent: true });
+
+const chalk = require('chalk');
+const fs = require('fs-extra');
+const path = require('path');
+const url = require('url');
+const webpack = require('webpack');
+const config = require('../config/webpack.config.prod');
+const paths = require('../config/paths');
+const checkRequiredFiles = require('react-dev-utils/checkRequiredFiles');
+const FileSizeReporter = require('react-dev-utils/FileSizeReporter');
+
+const measureFileSizesBeforeBuild = FileSizeReporter.measureFileSizesBeforeBuild;
+const printFileSizesAfterBuild = FileSizeReporter.printFileSizesAfterBuild;
+const useYarn = fs.existsSync(paths.yarnLockFile);
// Warn and crash if required files are missing
if (!checkRequiredFiles([paths.appHtml, paths.appIndexJs])) {
process.exit(1);
}
-// Input: /User/dan/app/build/static/js/main.82be8.js
-// Output: /static/js/main.js
-function removeFileNameHash(fileName) {
- return fileName
- .replace(paths.appBuild, '')
- .replace(/\/?(.*)(\.\w+)(\.js|\.css)/, (match, p1, p2, p3) => p1 + p3);
-}
-
-// Input: 1024, 2048
-// Output: "(+1 KB)"
-function getDifferenceLabel(currentSize, previousSize) {
- var FIFTY_KILOBYTES = 1024 * 50;
- var difference = currentSize - previousSize;
- var fileSize = !Number.isNaN(difference) ? filesize(difference) : 0;
- if (difference >= FIFTY_KILOBYTES) {
- return chalk.red('+' + fileSize);
- } else if (difference < FIFTY_KILOBYTES && difference > 0) {
- return chalk.yellow('+' + fileSize);
- } else if (difference < 0) {
- return chalk.green(fileSize);
- } else {
- return '';
- }
-}
-
// First, read the current file sizes in build directory.
// This lets us display how much they changed later.
-recursive(paths.appBuild, (err, fileNames) => {
- var previousSizeMap = (fileNames || [])
- .filter(fileName => /\.(js|css)$/.test(fileName))
- .reduce((memo, fileName) => {
- var contents = fs.readFileSync(fileName);
- var key = removeFileNameHash(fileName);
- memo[key] = gzipSize(contents);
- return memo;
- }, {});
-
+measureFileSizesBeforeBuild(paths.appBuild).then(previousFileSizes => {
// Remove all content but keep the directory so that
// if you're in it, you don't end up in Trash
fs.emptyDirSync(paths.appBuild);
// Start the webpack build
- build(previousSizeMap);
+ build(previousFileSizes);
// Merge with the public folder
copyPublicFolder();
});
-// Print a detailed summary of build files.
-function printFileSizes(stats, previousSizeMap) {
- var assets = stats.toJson().assets
- .filter(asset => /\.(js|css)$/.test(asset.name))
- .map(asset => {
- var fileContents = fs.readFileSync(paths.appBuild + '/' + asset.name);
- var size = gzipSize(fileContents);
- var previousSize = previousSizeMap[removeFileNameHash(asset.name)];
- var difference = getDifferenceLabel(size, previousSize);
- return {
- folder: path.join('build', path.dirname(asset.name)),
- name: path.basename(asset.name),
- size: size,
- sizeLabel: filesize(size) + (difference ? ' (' + difference + ')' : '')
- };
- });
- assets.sort((a, b) => b.size - a.size);
- var longestSizeLabelLength = Math.max.apply(null,
- assets.map(a => stripAnsi(a.sizeLabel).length)
- );
- assets.forEach(asset => {
- var sizeLabel = asset.sizeLabel;
- var sizeLength = stripAnsi(sizeLabel).length;
- if (sizeLength < longestSizeLabelLength) {
- var rightPadding = ' '.repeat(longestSizeLabelLength - sizeLength);
- sizeLabel += rightPadding;
- }
- console.log(
- ' ' + sizeLabel +
- ' ' + chalk.dim(asset.folder + path.sep) + chalk.cyan(asset.name)
- );
- });
-}
-
// Print out errors
function printErrors(summary, errors) {
console.log(chalk.red(summary));
@@ -131,9 +70,18 @@ function printErrors(summary, errors) {
}
// Create the production build and print the deployment instructions.
-function build(previousSizeMap) {
+function build(previousFileSizes) {
console.log('Creating an optimized production build...');
- webpack(config).run((err, stats) => {
+
+ let compiler;
+ try {
+ compiler = webpack(config);
+ } catch (err) {
+ printErrors('Failed to compile.', [err]);
+ process.exit(1);
+ }
+
+ compiler.run((err, stats) => {
if (err) {
printErrors('Failed to compile.', [err]);
process.exit(1);
@@ -145,85 +93,111 @@ function build(previousSizeMap) {
}
if (process.env.CI && stats.compilation.warnings.length) {
- printErrors('Failed to compile. When process.env.CI = true, warnings are treated as failures. Most CI servers set this automatically.', stats.compilation.warnings);
- process.exit(1);
- }
+ printErrors(
+ 'Failed to compile. When process.env.CI = true, warnings are treated as failures. Most CI servers set this automatically.',
+ stats.compilation.warnings
+ );
+ process.exit(1);
+ }
console.log(chalk.green('Compiled successfully.'));
console.log();
console.log('File sizes after gzip:');
console.log();
- printFileSizes(stats, previousSizeMap);
+ printFileSizesAfterBuild(stats, previousFileSizes);
console.log();
- var openCommand = process.platform === 'win32' ? 'start' : 'open';
- var appPackage = require(paths.appPackageJson);
- var publicUrl = paths.publicUrl;
- var publicPath = config.output.publicPath;
- var publicPathname = url.parse(publicPath).pathname;
+ const appPackage = require(paths.appPackageJson);
+ const publicUrl = paths.publicUrl;
+ const publicPath = config.output.publicPath;
+ const publicPathname = url.parse(publicPath).pathname;
if (publicUrl && publicUrl.indexOf('.github.io/') !== -1) {
// "homepage": "http://user.github.io/project"
- console.log('The project was built assuming it is hosted at ' + chalk.green(publicPathname) + '.');
- console.log('You can control this with the ' + chalk.green('homepage') + ' field in your ' + chalk.cyan('package.json') + '.');
+ console.log(
+ `The project was built assuming it is hosted at ${chalk.green(publicPathname)}.`
+ );
+ console.log(
+ `You can control this with the ${chalk.green('homepage')} field in your ${chalk.cyan('package.json')}.`
+ );
console.log();
- console.log('The ' + chalk.cyan('build') + ' folder is ready to be deployed.');
- console.log('To publish it at ' + chalk.green(publicUrl) + ', run:');
+ 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');
+ console.log(` ${chalk.cyan('yarn')} add --dev gh-pages`);
} else {
- console.log(' ' + chalk.cyan('npm') + ' install --save-dev gh-pages');
+ 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(
+ `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(` ${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(' ' + chalk.cyan(useYarn ? 'yarn' : 'npm') + ' run deploy');
+ console.log(` ${chalk.cyan(useYarn ? 'yarn' : 'npm')} run deploy`);
console.log();
} else if (publicPath !== '/') {
// "homepage": "http://mywebsite.com/project"
- console.log('The project was built assuming it is hosted at ' + chalk.green(publicPath) + '.');
- console.log('You can control this with the ' + chalk.green('homepage') + ' field in your ' + chalk.cyan('package.json') + '.');
+ console.log(
+ `The project was built assuming it is hosted at ${chalk.green(publicPath)}.`
+ );
+ console.log(
+ `You can control this with the ${chalk.green('homepage')} field in your ${chalk.cyan('package.json')}.`
+ );
console.log();
- console.log('The ' + chalk.cyan('build') + ' folder is ready to be deployed.');
+ console.log(`The ${chalk.cyan('build')} folder is ready to be deployed.`);
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(
+ `The project was built assuming it is hosted at ${chalk.green(publicUrl)}.`
+ );
+ console.log(
+ `You can control this with the ${chalk.green('homepage')} field in your ${chalk.cyan('package.json')}.`
+ );
console.log();
} else {
// no homepage
- console.log('The project was built assuming it is hosted at the server root.');
- console.log('To override this, specify the ' + chalk.green('homepage') + ' in your ' + chalk.cyan('package.json') + '.');
- console.log('For example, add this to build it for GitHub Pages:')
+ console.log(
+ '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(
+ ` ${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('You may also serve it locally with a static server:')
+ const build = path.relative(process.cwd(), paths.appBuild);
+ console.log(`The ${chalk.cyan(build)} folder is ready to be deployed.`);
+ console.log('You may serve it with a static server:');
console.log();
if (useYarn) {
- console.log(' ' + chalk.cyan('yarn') + ' global add pushstate-server');
+ console.log(` ${chalk.cyan('yarn')} global add serve`);
} else {
- console.log(' ' + chalk.cyan('npm') + ' install -g pushstate-server');
+ console.log(` ${chalk.cyan('npm')} install -g serve`);
}
- console.log(' ' + chalk.cyan('pushstate-server') + ' build');
- console.log(' ' + chalk.cyan(openCommand) + ' http://localhost:9000');
+ console.log(` ${chalk.cyan('serve')} -s build`);
console.log();
}
});
@@ -232,6 +206,6 @@ function build(previousSizeMap) {
function copyPublicFolder() {
fs.copySync(paths.appPublic, paths.appBuild, {
dereference: true,
- filter: file => file !== paths.appHtml
+ filter: file => file !== paths.appHtml,
});
}
diff --git a/packages/react-scripts/scripts/eject.js b/packages/react-scripts/scripts/eject.js
index a8ee0fc3102..e07a57ba5e7 100644
--- a/packages/react-scripts/scripts/eject.js
+++ b/packages/react-scripts/scripts/eject.js
@@ -1,3 +1,4 @@
+// @remove-file-on-eject
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
@@ -6,16 +7,25 @@
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
-
-var createJestConfig = require('../utils/createJestConfig');
-var fs = require('fs-extra');
-var path = require('path');
-var paths = require('../config/paths');
-var prompt = require('react-dev-utils/prompt');
-var spawnSync = require('cross-spawn').sync;
-var chalk = require('chalk');
-var green = chalk.green;
-var cyan = chalk.cyan;
+'use strict';
+
+// Makes the script crash on unhandled rejections instead of silently
+// ignoring them. In the future, promise rejections that are not handled will
+// terminate the Node.js process with a non-zero exit code.
+process.on('unhandledRejection', err => {
+ throw err;
+});
+
+const fs = require('fs-extra');
+const path = require('path');
+const spawnSync = require('cross-spawn').sync;
+const chalk = require('chalk');
+const prompt = require('react-dev-utils/prompt');
+const paths = require('../config/paths');
+const createJestConfig = require('./utils/createJestConfig');
+
+const green = chalk.green;
+const cyan = chalk.cyan;
prompt(
'Are you sure you want to eject? This action is permanent.',
@@ -28,120 +38,132 @@ prompt(
console.log('Ejecting...');
- var ownPath = path.join(__dirname, '..');
- var appPath = path.join(ownPath, '..', '..');
+ const ownPath = paths.ownPath;
+ const appPath = paths.appPath;
function verifyAbsent(file) {
if (fs.existsSync(path.join(appPath, file))) {
console.error(
- '`' + file + '` already exists in your app folder. We cannot ' +
- 'continue as you would lose all the changes in that file or directory. ' +
- 'Please move or delete it (maybe make a copy for backup) and run this ' +
- 'command again.'
+ `\`${file}\` already exists in your app folder. We cannot ` +
+ 'continue as you would lose all the changes in that file or directory. ' +
+ 'Please move or delete it (maybe make a copy for backup) and run this ' +
+ 'command again.'
);
process.exit(1);
}
}
- var folders = [
- 'config',
- path.join('config', 'jest'),
- 'scripts'
- ];
-
- var files = [
- path.join('config', 'env.js'),
- path.join('config', 'paths.js'),
- path.join('config', 'polyfills.js'),
- path.join('config', 'webpack.config.dev.js'),
- path.join('config', 'webpack.config.prod.js'),
- path.join('config', 'jest', 'cssTransform.js'),
- path.join('config', 'jest', 'fileTransform.js'),
- path.join('scripts', 'build.js'),
- path.join('scripts', 'start.js'),
- path.join('scripts', 'test.js')
- ];
+ const folders = ['config', 'config/jest', 'scripts', 'scripts/utils'];
+
+ // Make shallow array of files paths
+ const files = folders.reduce(
+ (files, folder) => {
+ return files.concat(
+ fs
+ .readdirSync(path.join(ownPath, folder))
+ // set full path
+ .map(file => path.join(ownPath, folder, file))
+ // omit dirs from file list
+ .filter(file => fs.lstatSync(file).isFile())
+ );
+ },
+ []
+ );
// Ensure that the app folder is clean and we won't override any files
folders.forEach(verifyAbsent);
files.forEach(verifyAbsent);
- // Copy the files over
- folders.forEach(function(folder) {
- fs.mkdirSync(path.join(appPath, folder))
+ console.log();
+ console.log(cyan(`Copying files into ${appPath}`));
+
+ folders.forEach(folder => {
+ fs.mkdirSync(path.join(appPath, folder));
});
- console.log();
- console.log(cyan('Copying files into ' + appPath));
- files.forEach(function(file) {
- console.log(' Adding ' + cyan(file) + ' to the project');
- var content = fs
- .readFileSync(path.join(ownPath, file), 'utf8')
+ files.forEach(file => {
+ let content = fs.readFileSync(file, 'utf8');
+
+ // Skip flagged files
+ if (content.match(/\/\/ @remove-file-on-eject/)) {
+ return;
+ }
+ content = content
// Remove dead code from .js files on eject
- .replace(/\/\/ @remove-on-eject-begin([\s\S]*?)\/\/ @remove-on-eject-end/mg, '')
+ .replace(
+ /\/\/ @remove-on-eject-begin([\s\S]*?)\/\/ @remove-on-eject-end/mg,
+ ''
+ )
// Remove dead code from .applescript files on eject
- .replace(/-- @remove-on-eject-begin([\s\S]*?)-- @remove-on-eject-end/mg, '')
+ .replace(
+ /-- @remove-on-eject-begin([\s\S]*?)-- @remove-on-eject-end/mg,
+ ''
+ )
.trim() + '\n';
- fs.writeFileSync(path.join(appPath, file), content);
+ console.log(` Adding ${cyan(file.replace(ownPath, ''))} to the project`);
+ fs.writeFileSync(file.replace(ownPath, appPath), content);
});
console.log();
- var ownPackage = require(path.join(ownPath, 'package.json'));
- var appPackage = require(path.join(appPath, 'package.json'));
- var babelConfig = JSON.parse(fs.readFileSync(path.join(ownPath, '.babelrc'), 'utf8'));
- var eslintConfig = JSON.parse(fs.readFileSync(path.join(ownPath, '.eslintrc'), 'utf8'));
+ const ownPackage = require(path.join(ownPath, 'package.json'));
+ const appPackage = require(path.join(appPath, 'package.json'));
console.log(cyan('Updating the dependencies'));
- var ownPackageName = ownPackage.name;
+ const ownPackageName = ownPackage.name;
if (appPackage.devDependencies[ownPackageName]) {
- console.log(' Removing ' + cyan(ownPackageName) + ' from devDependencies');
+ console.log(` Removing ${cyan(ownPackageName)} from devDependencies`);
delete appPackage.devDependencies[ownPackageName];
}
if (appPackage.dependencies[ownPackageName]) {
- console.log(' Removing ' + cyan(ownPackageName) + ' from dependencies');
+ console.log(` Removing ${cyan(ownPackageName)} from dependencies`);
delete appPackage.dependencies[ownPackageName];
}
- Object.keys(ownPackage.dependencies).forEach(function (key) {
+ Object.keys(ownPackage.dependencies).forEach(key => {
// For some reason optionalDependencies end up in dependencies after install
if (ownPackage.optionalDependencies[key]) {
return;
}
- console.log(' Adding ' + cyan(key) + ' to devDependencies');
+ console.log(` Adding ${cyan(key)} to devDependencies`);
appPackage.devDependencies[key] = ownPackage.dependencies[key];
});
console.log();
console.log(cyan('Updating the scripts'));
delete appPackage.scripts['eject'];
- Object.keys(appPackage.scripts).forEach(function (key) {
- appPackage.scripts[key] = appPackage.scripts[key]
- .replace(/react-scripts (\w+)/g, 'node scripts/$1.js');
- console.log(
- ' Replacing ' +
- cyan('"react-scripts ' + key + '"') +
- ' with ' +
- cyan('"node scripts/' + key + '.js"')
- );
+ Object.keys(appPackage.scripts).forEach(key => {
+ Object.keys(ownPackage.bin).forEach(binKey => {
+ const regex = new RegExp(binKey + ' (\\w+)', 'g');
+ appPackage.scripts[key] = appPackage.scripts[key].replace(
+ regex,
+ 'node scripts/$1.js'
+ );
+ console.log(
+ ` Replacing ${cyan(`"${binKey} ${key}"`)} with ${cyan(`"node scripts/${key}.js"`)}`
+ );
+ });
});
console.log();
console.log(cyan('Configuring package.json'));
// Add Jest config
- console.log(' Adding ' + cyan('Jest') + ' configuration');
+ console.log(` Adding ${cyan('Jest')} configuration`);
appPackage.jest = createJestConfig(
- filePath => path.join('', filePath),
+ filePath => path.posix.join('', filePath),
null,
true
);
// Add Babel config
-
- console.log(' Adding ' + cyan('Babel') + ' preset');
- appPackage.babel = babelConfig;
+ console.log(` Adding ${cyan('Babel')} preset`);
+ appPackage.babel = {
+ presets: ['react-app'],
+ };
// Add ESlint config
- console.log(' Adding ' + cyan('ESLint') +' configuration');
- appPackage.eslintConfig = eslintConfig;
+ console.log(` Adding ${cyan('ESLint')} configuration`);
+ appPackage.eslintConfig = {
+ extends: 'react-app',
+ };
fs.writeFileSync(
path.join(appPath, 'package.json'),
@@ -149,19 +171,30 @@ prompt(
);
console.log();
+ // "Don't destroy what isn't ours"
+ if (ownPath.indexOf(appPath) === 0) {
+ try {
+ // remove react-scripts and react-scripts binaries from app node_modules
+ Object.keys(ownPackage.bin).forEach(binKey => {
+ fs.removeSync(path.join(appPath, 'node_modules', '.bin', binKey));
+ });
+ fs.removeSync(ownPath);
+ } catch (e) {
+ // It's not essential that this succeeds
+ }
+ }
+
if (fs.existsSync(paths.yarnLockFile)) {
console.log(cyan('Running yarn...'));
- fs.removeSync(ownPath);
- spawnSync('yarnpkg', [], {stdio: 'inherit'});
+ spawnSync('yarnpkg', [], { stdio: 'inherit' });
} else {
console.log(cyan('Running npm install...'));
- fs.removeSync(ownPath);
- spawnSync('npm', ['install'], {stdio: 'inherit'});
+ spawnSync('npm', ['install'], { stdio: 'inherit' });
}
console.log(green('Ejected successfully!'));
console.log();
console.log(green('Please consider sharing why you ejected in this survey:'));
console.log(green(' http://goo.gl/forms/Bi6CZjk1EqsdelXk1'));
- console.log()
-})
+ console.log();
+});
diff --git a/packages/react-scripts/scripts/init.js b/packages/react-scripts/scripts/init.js
index 864005ecac2..87d87e621e7 100644
--- a/packages/react-scripts/scripts/init.js
+++ b/packages/react-scripts/scripts/init.js
@@ -1,3 +1,4 @@
+// @remove-file-on-eject
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
@@ -6,17 +7,35 @@
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
+'use strict';
-var fs = require('fs-extra');
-var path = require('path');
-var spawn = require('cross-spawn');
-var chalk = require('chalk');
+// Makes the script crash on unhandled rejections instead of silently
+// ignoring them. In the future, promise rejections that are not handled will
+// terminate the Node.js process with a non-zero exit code.
+process.on('unhandledRejection', err => {
+ throw err;
+});
-module.exports = function(appPath, appName, verbose, originalDirectory, template) {
- var ownPackageName = require(path.join(__dirname, '..', 'package.json')).name;
- var ownPath = path.join(appPath, 'node_modules', ownPackageName);
- var appPackage = require(path.join(appPath, 'package.json'));
- var useYarn = fs.existsSync(path.join(appPath, 'yarn.lock'));
+const fs = require('fs-extra');
+const path = require('path');
+const spawn = require('cross-spawn');
+const chalk = require('chalk');
+
+module.exports = function(
+ appPath,
+ appName,
+ verbose,
+ originalDirectory,
+ template
+) {
+ const ownPackageName = require(path.join(
+ __dirname,
+ '..',
+ 'package.json'
+ )).name;
+ const ownPath = path.join(appPath, 'node_modules', ownPackageName);
+ const appPackage = require(path.join(appPath, 'package.json'));
+ const useYarn = fs.existsSync(path.join(appPath, 'yarn.lock'));
// Copy over some of the devDependencies
appPackage.dependencies = appPackage.dependencies || {};
@@ -24,10 +43,10 @@ module.exports = function(appPath, appName, verbose, originalDirectory, template
// Setup the script rules
appPackage.scripts = {
- 'start': 'react-scripts start',
- 'build': 'react-scripts build',
- 'test': 'react-scripts test --env=jsdom',
- 'eject': 'react-scripts eject'
+ start: 'react-scripts start',
+ build: 'react-scripts build',
+ test: 'react-scripts test --env=jsdom',
+ eject: 'react-scripts eject',
};
fs.writeFileSync(
@@ -35,110 +54,145 @@ module.exports = function(appPath, appName, verbose, originalDirectory, template
JSON.stringify(appPackage, null, 2)
);
- var readmeExists = fs.existsSync(path.join(appPath, 'README.md'));
+ const readmeExists = fs.existsSync(path.join(appPath, 'README.md'));
if (readmeExists) {
- fs.renameSync(path.join(appPath, 'README.md'), path.join(appPath, 'README.old.md'));
+ fs.renameSync(
+ path.join(appPath, 'README.md'),
+ path.join(appPath, 'README.old.md')
+ );
}
// Copy the files for the user
- var templatePath = template ? path.resolve(originalDirectory, template) : path.join(ownPath, 'template');
+ const templatePath = template
+ ? path.resolve(originalDirectory, template)
+ : path.join(ownPath, 'template');
if (fs.existsSync(templatePath)) {
fs.copySync(templatePath, appPath);
} else {
- console.error('Could not locate supplied template: ' + chalk.green(templatePath));
+ console.error(
+ `Could not locate supplied template: ${chalk.green(templatePath)}`
+ );
return;
}
// Rename gitignore after the fact to prevent npm from renaming it to .npmignore
// See: https://github.com/npm/npm/issues/1862
- fs.move(path.join(appPath, 'gitignore'), path.join(appPath, '.gitignore'), [], function (err) {
- if (err) {
- // Append if there's already a `.gitignore` file there
- if (err.code === 'EEXIST') {
- var data = fs.readFileSync(path.join(appPath, 'gitignore'));
- fs.appendFileSync(path.join(appPath, '.gitignore'), data);
- fs.unlinkSync(path.join(appPath, 'gitignore'));
- } else {
- throw err;
+ fs.move(
+ path.join(appPath, 'gitignore'),
+ path.join(appPath, '.gitignore'),
+ [],
+ err => {
+ if (err) {
+ // Append if there's already a `.gitignore` file there
+ if (err.code === 'EEXIST') {
+ const data = fs.readFileSync(path.join(appPath, 'gitignore'));
+ fs.appendFileSync(path.join(appPath, '.gitignore'), data);
+ fs.unlinkSync(path.join(appPath, 'gitignore'));
+ } else {
+ throw err;
+ }
}
}
- });
+ );
- // Run yarn or npm for react and react-dom
- // TODO: having to do two npm/yarn installs is bad, can we avoid it?
- var command;
- var args;
+ let command;
+ let args;
if (useYarn) {
command = 'yarnpkg';
args = ['add'];
} else {
command = 'npm';
- args = [
- 'install',
- '--save',
- verbose && '--verbose'
- ].filter(function(e) { return e; });
+ args = ['install', '--save', verbose && '--verbose'].filter(e => e);
}
args.push('react', 'react-dom');
// Install additional template dependencies, if present
- var templateDependenciesPath = path.join(appPath, '.template.dependencies.json');
+ const templateDependenciesPath = path.join(
+ appPath,
+ '.template.dependencies.json'
+ );
if (fs.existsSync(templateDependenciesPath)) {
- var templateDependencies = require(templateDependenciesPath).dependencies;
- args = args.concat(Object.keys(templateDependencies).map(function (key) {
- return key + '@' + templateDependencies[key];
- }));
+ const templateDependencies = require(templateDependenciesPath).dependencies;
+ args = args.concat(
+ Object.keys(templateDependencies).map(key => {
+ return `${key}@${templateDependencies[key]}`;
+ })
+ );
fs.unlinkSync(templateDependenciesPath);
}
- console.log('Installing react and react-dom using ' + command + '...');
- console.log();
+ // Install react and react-dom for backward compatibility with old CRA cli
+ // which doesn't install react and react-dom along with react-scripts
+ // or template is presetend (via --internal-testing-template)
+ if (!isReactInstalled(appPackage) || template) {
+ console.log(`Installing react and react-dom using ${command}...`);
+ console.log();
- var proc = spawn(command, args, {stdio: 'inherit'});
- proc.on('close', function (code) {
- if (code !== 0) {
- console.error('`' + command + ' ' + args.join(' ') + '` failed');
+ const proc = spawn.sync(command, args, { stdio: 'inherit' });
+ if (proc.status !== 0) {
+ console.error(`\`${command} ${args.join(' ')}\` failed`);
return;
}
+ }
- // Display the most elegant way to cd.
- // This needs to handle an undefined originalDirectory for
- // backward compatibility with old global-cli's.
- var cdpath;
- if (originalDirectory &&
- path.join(originalDirectory, appName) === appPath) {
- cdpath = appName;
- } else {
- cdpath = appPath;
- }
+ // Display the most elegant way to cd.
+ // This needs to handle an undefined originalDirectory for
+ // backward compatibility with old global-cli's.
+ let cdpath;
+ if (originalDirectory && path.join(originalDirectory, appName) === appPath) {
+ cdpath = appName;
+ } else {
+ cdpath = appPath;
+ }
+ // Change displayed command to yarn instead of yarnpkg
+ const displayedCommand = useYarn ? 'yarn' : 'npm';
+
+ console.log();
+ console.log(`Success! Created ${appName} at ${appPath}`);
+ console.log('Inside that directory, you can run several commands:');
+ console.log();
+ console.log(chalk.cyan(` ${displayedCommand} start`));
+ console.log(' Starts the development server.');
+ console.log();
+ console.log(
+ chalk.cyan(` ${displayedCommand} ${useYarn ? '' : 'run '}build`)
+ );
+ console.log(' Bundles the app into static files for production.');
+ console.log();
+ console.log(chalk.cyan(` ${displayedCommand} test`));
+ console.log(' Starts the test runner.');
+ console.log();
+ console.log(
+ chalk.cyan(` ${displayedCommand} ${useYarn ? '' : 'run '}eject`)
+ );
+ console.log(
+ ' Removes this tool and copies build dependencies, configuration files'
+ );
+ console.log(
+ ' and scripts into the app directory. If you do this, you can’t go back!'
+ );
+ console.log();
+ console.log('We suggest that you begin by typing:');
+ console.log();
+ console.log(chalk.cyan(' cd'), cdpath);
+ console.log(` ${chalk.cyan(`${displayedCommand} start`)}`);
+ if (readmeExists) {
console.log();
- console.log('Success! Created ' + appName + ' at ' + appPath);
- console.log('Inside that directory, you can run several commands:');
- console.log();
- console.log(chalk.cyan(' ' + command + ' start'));
- console.log(' Starts the development server.');
- console.log();
- console.log(chalk.cyan(' ' + command + ' run build'));
- console.log(' Bundles the app into static files for production.');
- console.log();
- console.log(chalk.cyan(' ' + command + ' test'));
- console.log(' Starts the test runner.');
- console.log();
- console.log(chalk.cyan(' ' + command + ' run eject'));
- console.log(' Removes this tool and copies build dependencies, configuration files');
- console.log(' and scripts into the app directory. If you do this, you can’t go back!');
- console.log();
- console.log('We suggest that you begin by typing:');
- console.log();
- console.log(chalk.cyan(' cd'), cdpath);
- console.log(' ' + chalk.cyan(command + ' start'));
- if (readmeExists) {
- console.log();
- console.log(chalk.yellow('You had a `README.md` file, we renamed it to `README.old.md`'));
- }
- console.log();
- console.log('Happy hacking!');
- });
+ console.log(
+ chalk.yellow(
+ 'You had a `README.md` file, we renamed it to `README.old.md`'
+ )
+ );
+ }
+ console.log();
+ console.log('Happy hacking!');
};
+
+function isReactInstalled(appPackage) {
+ const dependencies = appPackage.dependencies || {};
+
+ return typeof dependencies.react !== 'undefined' &&
+ typeof dependencies['react-dom'] !== 'undefined';
+}
diff --git a/packages/react-scripts/scripts/start.js b/packages/react-scripts/scripts/start.js
index c326b9b94d9..12cce8ed313 100644
--- a/packages/react-scripts/scripts/start.js
+++ b/packages/react-scripts/scripts/start.js
@@ -8,6 +8,14 @@
* of patent rights can be found in the PATENTS file in the same directory.
*/
// @remove-on-eject-end
+'use strict';
+
+// Makes the script crash on unhandled rejections instead of silently
+// ignoring them. In the future, promise rejections that are not handled will
+// terminate the Node.js process with a non-zero exit code.
+process.on('unhandledRejection', err => {
+ throw err;
+});
process.env.NODE_ENV = 'development';
@@ -15,27 +23,26 @@ process.env.NODE_ENV = 'development';
// if this file is missing. dotenv will never modify any environment variables
// that have already been set.
// https://github.com/motdotla/dotenv
-require('dotenv').config({silent: true});
-
-var chalk = require('chalk');
-var webpack = require('webpack');
-var WebpackDevServer = require('webpack-dev-server');
-var historyApiFallback = require('connect-history-api-fallback');
-var httpProxyMiddleware = require('http-proxy-middleware');
-var detect = require('detect-port');
-var clearConsole = require('react-dev-utils/clearConsole');
-var checkRequiredFiles = require('react-dev-utils/checkRequiredFiles');
-var formatWebpackMessages = require('react-dev-utils/formatWebpackMessages');
-var getProcessForPort = require('react-dev-utils/getProcessForPort');
-var openBrowser = require('react-dev-utils/openBrowser');
-var prompt = require('react-dev-utils/prompt');
-var fs = require('fs');
-var config = require('../config/webpack.config.dev');
-var paths = require('../config/paths');
-
-var useYarn = fs.existsSync(paths.yarnLockFile);
-var cli = useYarn ? 'yarn' : 'npm';
-var isInteractive = process.stdout.isTTY;
+require('dotenv').config({ silent: true });
+
+const fs = require('fs');
+const chalk = require('chalk');
+const detect = require('detect-port');
+const WebpackDevServer = require('webpack-dev-server');
+const clearConsole = require('react-dev-utils/clearConsole');
+const checkRequiredFiles = require('react-dev-utils/checkRequiredFiles');
+const getProcessForPort = require('react-dev-utils/getProcessForPort');
+const openBrowser = require('react-dev-utils/openBrowser');
+const prompt = require('react-dev-utils/prompt');
+const paths = require('../config/paths');
+const config = require('../config/webpack.config.dev');
+const devServerConfig = require('../config/webpackDevServer.config');
+const createWebpackCompiler = require('./utils/createWebpackCompiler');
+const addWebpackMiddleware = require('./utils/addWebpackMiddleware');
+
+const useYarn = fs.existsSync(paths.yarnLockFile);
+const cli = useYarn ? 'yarn' : 'npm';
+const isInteractive = process.stdout.isTTY;
// Warn and crash if required files are missing
if (!checkRequiredFiles([paths.appHtml, paths.appIndexJs])) {
@@ -43,239 +50,40 @@ if (!checkRequiredFiles([paths.appHtml, paths.appIndexJs])) {
}
// Tools like Cloud9 rely on this.
-var DEFAULT_PORT = process.env.PORT || 3000;
-var compiler;
-var handleCompile;
-
-// You can safely remove this after ejecting.
-// We only use this block for testing of Create React App itself:
-var isSmokeTest = process.argv.some(arg => arg.indexOf('--smoke-test') > -1);
-if (isSmokeTest) {
- handleCompile = function (err, stats) {
- if (err || stats.hasErrors() || stats.hasWarnings()) {
- process.exit(1);
- } else {
- process.exit(0);
- }
- };
-}
-
-function setupCompiler(host, port, protocol) {
- // "Compiler" is a low-level interface to Webpack.
- // It lets us listen to some events and provide our own custom messages.
- compiler = webpack(config, handleCompile);
+const DEFAULT_PORT = parseInt(process.env.PORT, 10) || 3000;
- // "invalid" event fires when you have changed a file, and Webpack is
- // recompiling a bundle. WebpackDevServer takes care to pause serving the
- // bundle, so if you refresh, it'll wait instead of serving the old one.
- // "invalid" is short for "bundle invalidated", it doesn't imply any errors.
- compiler.plugin('invalid', function() {
- if (isInteractive) {
- clearConsole();
- }
- console.log('Compiling...');
- });
-
- var isFirstCompile = true;
-
- // "done" event fires when Webpack has finished recompiling the bundle.
- // Whether or not you have warnings or errors, you will get this event.
- compiler.plugin('done', function(stats) {
- if (isInteractive) {
- clearConsole();
- }
-
- // We have switched off the default Webpack output in WebpackDevServer
- // options so we are going to "massage" the warnings and errors and present
- // them in a readable focused way.
- var messages = formatWebpackMessages(stats.toJson({}, true));
- var isSuccessful = !messages.errors.length && !messages.warnings.length;
- var showInstructions = isSuccessful && (isInteractive || isFirstCompile);
-
- if (isSuccessful) {
- console.log(chalk.green('Compiled successfully!'));
- }
-
- if (showInstructions) {
+function run(port) {
+ const protocol = process.env.HTTPS === 'true' ? 'https' : 'http';
+ const host = process.env.HOST || 'localhost';
+
+ // Create a webpack compiler that is configured with custom messages.
+ const compiler = createWebpackCompiler(
+ config,
+ function onReady(showInstructions) {
+ if (!showInstructions) {
+ return;
+ }
console.log();
console.log('The app is running at:');
console.log();
- console.log(' ' + chalk.cyan(protocol + '://' + host + ':' + port + '/'));
+ console.log(` ${chalk.cyan(`${protocol}://${host}:${port}/`)}`);
console.log();
console.log('Note that the development build is not optimized.');
- console.log('To create a production build, use ' + chalk.cyan(cli + ' run build') + '.');
+ console.log(
+ `To create a production build, use ${chalk.cyan(`${cli} run build`)}.`
+ );
console.log();
- isFirstCompile = false;
}
+ );
- // If errors exist, only show errors.
- if (messages.errors.length) {
- console.log(chalk.red('Failed to compile.'));
- console.log();
- messages.errors.forEach(message => {
- console.log(message);
- console.log();
- });
- return;
- }
-
- // Show warnings if no errors were found.
- if (messages.warnings.length) {
- console.log(chalk.yellow('Compiled with warnings.'));
- console.log();
- messages.warnings.forEach(message => {
- console.log(message);
- console.log();
- });
- // Teach some ESLint tricks.
- console.log('You may use special comments to disable some warnings.');
- console.log('Use ' + chalk.yellow('// eslint-disable-next-line') + ' to ignore the next line.');
- console.log('Use ' + chalk.yellow('/* eslint-disable */') + ' to ignore all warnings in a file.');
- }
- });
-}
-
-// We need to provide a custom onError function for httpProxyMiddleware.
-// It allows us to log custom error messages on the console.
-function onProxyError(proxy) {
- return function(err, req, res){
- var host = req.headers && req.headers.host;
- console.log(
- chalk.red('Proxy error:') + ' Could not proxy request ' + chalk.cyan(req.url) +
- ' from ' + chalk.cyan(host) + ' to ' + chalk.cyan(proxy) + '.'
- );
- console.log(
- 'See https://nodejs.org/api/errors.html#errors_common_system_errors for more information (' +
- chalk.cyan(err.code) + ').'
- );
- console.log();
-
- // And immediately send the proper error response to the client.
- // Otherwise, the request will eventually timeout with ERR_EMPTY_RESPONSE on the client side.
- if (res.writeHead && !res.headersSent) {
- res.writeHead(500);
- }
- res.end('Proxy error: Could not proxy request ' + req.url + ' from ' +
- host + ' to ' + proxy + ' (' + err.code + ').'
- );
- }
-}
-
-function addMiddleware(devServer) {
- // `proxy` lets you to specify a fallback server during development.
- // Every unrecognized request will be forwarded to it.
- var proxy = require(paths.appPackageJson).proxy;
- devServer.use(historyApiFallback({
- // Paths with dots should still use the history fallback.
- // See https://github.com/facebookincubator/create-react-app/issues/387.
- disableDotRule: true,
- // For single page apps, we generally want to fallback to /index.html.
- // However we also want to respect `proxy` for API calls.
- // So if `proxy` is specified, we need to decide which fallback to use.
- // We use a heuristic: 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, don’t use `proxy`.
- htmlAcceptHeaders: proxy ?
- ['text/html'] :
- ['text/html', '*/*']
- }));
- if (proxy) {
- if (typeof proxy !== 'string') {
- console.log(chalk.red('When specified, "proxy" in package.json must be a string.'));
- console.log(chalk.red('Instead, the type of "proxy" was "' + typeof proxy + '".'));
- console.log(chalk.red('Either remove "proxy" from package.json, or make it a string.'));
- process.exit(1);
- }
-
- // Otherwise, if proxy is specified, we will let it handle any request.
- // There are a few exceptions which we won't send to the proxy:
- // - /index.html (served as HTML5 history API fallback)
- // - /*.hot-update.json (WebpackDevServer uses this too for hot reloading)
- // - /sockjs-node/* (WebpackDevServer uses this for hot reloading)
- // Tip: use https://jex.im/regulex/ to visualize the regex
- var mayProxy = /^(?!\/(index\.html$|.*\.hot-update\.json$|sockjs-node\/)).*$/;
-
- // Pass the scope regex both to Express and to the middleware for proxying
- // of both HTTP and WebSockets to work without false positives.
- var hpm = httpProxyMiddleware(pathname => mayProxy.test(pathname), {
- target: proxy,
- logLevel: 'silent',
- onProxyReq: function(proxyReq, req, res) {
- // Browers may send Origin headers even with same-origin
- // requests. To prevent CORS issues, we have to change
- // the Origin to match the target URL.
- if (proxyReq.getHeader('origin')) {
- proxyReq.setHeader('origin', proxy);
- }
- },
- onError: onProxyError(proxy),
- secure: false,
- changeOrigin: true,
- ws: true
- });
- devServer.use(mayProxy, hpm);
-
- // Listen for the websocket 'upgrade' event and upgrade the connection.
- // If this is not done, httpProxyMiddleware will not try to upgrade until
- // an initial plain HTTP request is made.
- devServer.listeningApp.on('upgrade', hpm.upgrade);
- }
-
- // Finally, by now we have certainly resolved the URL.
- // It may be /index.html, so let the dev server try serving it again.
- devServer.use(devServer.middleware);
-}
-
-function runDevServer(host, port, protocol) {
- var devServer = new WebpackDevServer(compiler, {
- // Enable gzip compression of generated files.
- compress: true,
- // Silence WebpackDevServer's own logs since they're generally not useful.
- // It will still show compile warnings and errors with this setting.
- clientLogLevel: 'none',
- // By default WebpackDevServer serves physical files from current directory
- // in addition to all the virtual build products that it serves from memory.
- // This is confusing because those files won’t automatically be available in
- // production build folder unless we copy them. However, copying the whole
- // project directory is dangerous because we may expose sensitive files.
- // Instead, we establish a convention that only files in `public` directory
- // get served. Our build script will copy `public` into the `build` folder.
- // In `index.html`, you can get URL of `public` folder with %PUBLIC_URL%:
- //
- // In JavaScript code, you can access it with `process.env.PUBLIC_URL`.
- // Note that we only recommend to use `public` folder as an escape hatch
- // for files like `favicon.ico`, `manifest.json`, and libraries that are
- // for some reason broken when imported through Webpack. If you just want to
- // use an image, put it in `src` and `import` it from JavaScript instead.
- contentBase: paths.appPublic,
- // Enable hot reloading server. It will provide /sockjs-node/ endpoint
- // for the WebpackDevServer client so it can learn when the files were
- // updated. The WebpackDevServer client is included as an entry point
- // in the Webpack development configuration. Note that only changes
- // to CSS are currently hot reloaded. JS changes will refresh the browser.
- hot: true,
- // It is important to tell WebpackDevServer to use the same "root" path
- // as we specified in the config. In development, we always serve from /.
- publicPath: config.output.publicPath,
- // WebpackDevServer is noisy by default so we emit custom message instead
- // by listening to the compiler events with `compiler.plugin` calls above.
- quiet: true,
- // Reportedly, this avoids CPU overload on some systems.
- // https://github.com/facebookincubator/create-react-app/issues/293
- watchOptions: {
- ignored: /node_modules/
- },
- // Enable HTTPS if the HTTPS environment variable is set to 'true'
- https: protocol === "https",
- host: host
- });
+ // Serve webpack assets generated by the compiler over a web sever.
+ const devServer = new WebpackDevServer(compiler, devServerConfig);
// Our custom middleware proxies requests to /index.html or a remote API.
- addMiddleware(devServer);
+ addWebpackMiddleware(devServer);
// Launch WebpackDevServer.
- devServer.listen(port, (err, result) => {
+ devServer.listen(port, err => {
if (err) {
return console.log(err);
}
@@ -286,17 +94,10 @@ function runDevServer(host, port, protocol) {
console.log(chalk.cyan('Starting the development server...'));
console.log();
- openBrowser(protocol + '://' + host + ':' + port + '/');
+ openBrowser(`${protocol}://${host}:${port}/`);
});
}
-function run(port) {
- var protocol = process.env.HTTPS === 'true' ? "https" : "http";
- var host = process.env.HOST || 'localhost';
- setupCompiler(host, port, protocol);
- runDevServer(host, port, protocol);
-}
-
// We attempt to use the default port but if it is busy, we offer the user to
// run on a different port. `detect()` Promise resolves to the next free port.
detect(DEFAULT_PORT).then(port => {
@@ -307,11 +108,11 @@ detect(DEFAULT_PORT).then(port => {
if (isInteractive) {
clearConsole();
- var existingProcess = getProcessForPort(DEFAULT_PORT);
- var question =
- chalk.yellow('Something is already running on port ' + DEFAULT_PORT + '.' +
- ((existingProcess) ? ' Probably:\n ' + existingProcess : '')) +
- '\n\nWould you like to run the app on another port instead?';
+ const existingProcess = getProcessForPort(DEFAULT_PORT);
+ const question = chalk.yellow(
+ `Something is already running on port ${DEFAULT_PORT}.` +
+ `${existingProcess ? ` Probably:\n ${existingProcess}` : ''}`
+ ) + '\n\nWould you like to run the app on another port instead?';
prompt(question, true).then(shouldChangePort => {
if (shouldChangePort) {
@@ -319,6 +120,8 @@ detect(DEFAULT_PORT).then(port => {
}
});
} else {
- console.log(chalk.red('Something is already running on port ' + DEFAULT_PORT + '.'));
+ console.log(
+ chalk.red(`Something is already running on port ${DEFAULT_PORT}.`)
+ );
}
});
diff --git a/packages/react-scripts/scripts/test.js b/packages/react-scripts/scripts/test.js
index 9de5181d739..5c395999d97 100644
--- a/packages/react-scripts/scripts/test.js
+++ b/packages/react-scripts/scripts/test.js
@@ -8,15 +8,23 @@
* of patent rights can be found in the PATENTS file in the same directory.
*/
// @remove-on-eject-end
+'use strict';
process.env.NODE_ENV = 'test';
process.env.PUBLIC_URL = '';
+// Makes the script crash on unhandled rejections instead of silently
+// ignoring them. In the future, promise rejections that are not handled will
+// terminate the Node.js process with a non-zero exit code.
+process.on('unhandledRejection', err => {
+ throw err;
+});
+
// Load environment variables from .env file. Suppress warnings using silent
// if this file is missing. dotenv will never modify any environment variables
// that have already been set.
// https://github.com/motdotla/dotenv
-require('dotenv').config({silent: true});
+require('dotenv').config({ silent: true });
const jest = require('jest');
const argv = process.argv.slice(2);
@@ -28,13 +36,18 @@ if (!process.env.CI && argv.indexOf('--coverage') < 0) {
// @remove-on-eject-begin
// This is not necessary after eject because we embed config into package.json.
-const createJestConfig = require('../utils/createJestConfig');
+const createJestConfig = require('./utils/createJestConfig');
const path = require('path');
const paths = require('../config/paths');
-argv.push('--config', JSON.stringify(createJestConfig(
- relativePath => path.resolve(__dirname, '..', relativePath),
- path.resolve(paths.appSrc, '..'),
- false
-)));
+argv.push(
+ '--config',
+ JSON.stringify(
+ createJestConfig(
+ relativePath => path.resolve(__dirname, '..', relativePath),
+ path.resolve(paths.appSrc, '..'),
+ false
+ )
+ )
+);
// @remove-on-eject-end
jest.run(argv);
diff --git a/packages/react-scripts/scripts/utils/addWebpackMiddleware.js b/packages/react-scripts/scripts/utils/addWebpackMiddleware.js
new file mode 100644
index 00000000000..d2a97507237
--- /dev/null
+++ b/packages/react-scripts/scripts/utils/addWebpackMiddleware.js
@@ -0,0 +1,132 @@
+// @remove-on-eject-begin
+/**
+ * Copyright (c) 2015-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+// @remove-on-eject-end
+'use strict';
+
+const chalk = require('chalk');
+const historyApiFallback = require('connect-history-api-fallback');
+const httpProxyMiddleware = require('http-proxy-middleware');
+const paths = require('../../config/paths');
+
+// We need to provide a custom onError function for httpProxyMiddleware.
+// It allows us to log custom error messages on the console.
+function onProxyError(proxy) {
+ return (err, req, res) => {
+ const host = req.headers && req.headers.host;
+ console.log(
+ chalk.red('Proxy error:') +
+ ' Could not proxy request ' +
+ chalk.cyan(req.url) +
+ ' from ' +
+ chalk.cyan(host) +
+ ' to ' +
+ chalk.cyan(proxy) +
+ '.'
+ );
+ console.log(
+ 'See https://nodejs.org/api/errors.html#errors_common_system_errors for more information (' +
+ chalk.cyan(err.code) +
+ ').'
+ );
+ console.log();
+
+ // And immediately send the proper error response to the client.
+ // Otherwise, the request will eventually timeout with ERR_EMPTY_RESPONSE on the client side.
+ if (res.writeHead && !res.headersSent) {
+ res.writeHead(500);
+ }
+ res.end(
+ 'Proxy error: Could not proxy request ' +
+ req.url +
+ ' from ' +
+ host +
+ ' to ' +
+ proxy +
+ ' (' +
+ err.code +
+ ').'
+ );
+ };
+}
+
+module.exports = function addWebpackMiddleware(devServer) {
+ // `proxy` lets you to specify a fallback server during development.
+ // Every unrecognized request will be forwarded to it.
+ const proxy = require(paths.appPackageJson).proxy;
+ devServer.use(
+ historyApiFallback({
+ // Paths with dots should still use the history fallback.
+ // See https://github.com/facebookincubator/create-react-app/issues/387.
+ disableDotRule: true,
+ // For single page apps, we generally want to fallback to /index.html.
+ // However we also want to respect `proxy` for API calls.
+ // So if `proxy` is specified, we need to decide which fallback to use.
+ // We use a heuristic: 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, don’t use `proxy`.
+ htmlAcceptHeaders: proxy ? ['text/html'] : ['text/html', '*/*'],
+ })
+ );
+ if (proxy) {
+ if (typeof proxy !== 'string') {
+ console.log(
+ chalk.red('When specified, "proxy" in package.json must be a string.')
+ );
+ console.log(
+ chalk.red('Instead, the type of "proxy" was "' + typeof proxy + '".')
+ );
+ console.log(
+ chalk.red(
+ 'Either remove "proxy" from package.json, or make it a string.'
+ )
+ );
+ process.exit(1);
+ }
+
+ // Otherwise, if proxy is specified, we will let it handle any request.
+ // There are a few exceptions which we won't send to the proxy:
+ // - /index.html (served as HTML5 history API fallback)
+ // - /*.hot-update.json (WebpackDevServer uses this too for hot reloading)
+ // - /sockjs-node/* (WebpackDevServer uses this for hot reloading)
+ // Tip: use https://jex.im/regulex/ to visualize the regex
+ const mayProxy = /^(?!\/(index\.html$|.*\.hot-update\.json$|sockjs-node\/)).*$/;
+
+ // Pass the scope regex both to Express and to the middleware for proxying
+ // of both HTTP and WebSockets to work without false positives.
+ const hpm = httpProxyMiddleware(pathname => mayProxy.test(pathname), {
+ target: proxy,
+ logLevel: 'silent',
+ onProxyReq: proxyReq => {
+ // Browers may send Origin headers even with same-origin
+ // requests. To prevent CORS issues, we have to change
+ // the Origin to match the target URL.
+ if (proxyReq.getHeader('origin')) {
+ proxyReq.setHeader('origin', proxy);
+ }
+ },
+ onError: onProxyError(proxy),
+ secure: false,
+ changeOrigin: true,
+ ws: true,
+ xfwd: true,
+ });
+ devServer.use(mayProxy, hpm);
+
+ // Listen for the websocket 'upgrade' event and upgrade the connection.
+ // If this is not done, httpProxyMiddleware will not try to upgrade until
+ // an initial plain HTTP request is made.
+ devServer.listeningApp.on('upgrade', hpm.upgrade);
+ }
+
+ // Finally, by now we have certainly resolved the URL.
+ // It may be /index.html, so let the dev server try serving it again.
+ devServer.use(devServer.middleware);
+};
diff --git a/packages/react-scripts/utils/createJestConfig.js b/packages/react-scripts/scripts/utils/createJestConfig.js
similarity index 76%
rename from packages/react-scripts/utils/createJestConfig.js
rename to packages/react-scripts/scripts/utils/createJestConfig.js
index f1c67c018f1..5ba7fd16cb2 100644
--- a/packages/react-scripts/utils/createJestConfig.js
+++ b/packages/react-scripts/scripts/utils/createJestConfig.js
@@ -1,3 +1,4 @@
+// @remove-file-on-eject
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
@@ -6,16 +7,17 @@
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
-
-// Note: this file does not exist after ejecting.
+'use strict';
const fs = require('fs');
-const paths = require('../config/paths');
+const paths = require('../../config/paths');
module.exports = (resolve, rootDir, isEjecting) => {
// Use this instead of `paths.testsSetup` to avoid putting
// an absolute filename into configuration after ejecting.
- const setupTestsFile = fs.existsSync(paths.testsSetup) ? '/src/setupTests.js' : undefined;
+ const setupTestsFile = fs.existsSync(paths.testsSetup)
+ ? '/src/setupTests.js'
+ : undefined;
// TODO: I don't know if it's safe or not to just use / as path separator
// in Jest configs. We need help from somebody with Windows to determine this.
@@ -24,23 +26,21 @@ module.exports = (resolve, rootDir, isEjecting) => {
setupFiles: [resolve('config/polyfills.js')],
setupTestFrameworkScriptFile: setupTestsFile,
testPathIgnorePatterns: [
- '[/\\\\](build|docs|node_modules|scripts)[/\\\\]'
+ '[/\\\\](build|docs|node_modules|scripts)[/\\\\]',
],
testEnvironment: 'node',
testURL: 'http://localhost',
transform: {
- '^.+\\.(js|jsx)$': isEjecting ?
- '/node_modules/babel-jest'
+ '^.+\\.(js|jsx)$': isEjecting
+ ? '/node_modules/babel-jest'
: resolve('config/jest/babelTransform.js'),
'^.+\\.css$': resolve('config/jest/cssTransform.js'),
'^(?!.*\\.(js|jsx|css|json)$)': resolve('config/jest/fileTransform.js'),
},
- transformIgnorePatterns: [
- '[/\\\\]node_modules[/\\\\].+\\.(js|jsx)$'
- ],
+ transformIgnorePatterns: ['[/\\\\]node_modules[/\\\\].+\\.(js|jsx)$'],
moduleNameMapper: {
- '^react-native$': 'react-native-web'
- }
+ '^react-native$': 'react-native-web',
+ },
};
if (rootDir) {
config.rootDir = rootDir;
diff --git a/packages/react-scripts/scripts/utils/createWebpackCompiler.js b/packages/react-scripts/scripts/utils/createWebpackCompiler.js
new file mode 100644
index 00000000000..a333165b082
--- /dev/null
+++ b/packages/react-scripts/scripts/utils/createWebpackCompiler.js
@@ -0,0 +1,119 @@
+// @remove-on-eject-begin
+/**
+ * Copyright (c) 2015-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+// @remove-on-eject-end
+'use strict';
+
+const chalk = require('chalk');
+const webpack = require('webpack');
+const clearConsole = require('react-dev-utils/clearConsole');
+const formatWebpackMessages = require('react-dev-utils/formatWebpackMessages');
+
+const isInteractive = process.stdout.isTTY;
+let handleCompile;
+
+// You can safely remove this after ejecting.
+// We only use this block for testing of Create React App itself:
+const isSmokeTest = process.argv.some(arg => arg.indexOf('--smoke-test') > -1);
+if (isSmokeTest) {
+ handleCompile = (err, stats) => {
+ if (err || stats.hasErrors() || stats.hasWarnings()) {
+ process.exit(1);
+ } else {
+ process.exit(0);
+ }
+ };
+}
+
+module.exports = function createWebpackCompiler(config, onReadyCallback) {
+ // "Compiler" is a low-level interface to Webpack.
+ // It lets us listen to some events and provide our own custom messages.
+ let compiler;
+ try {
+ compiler = webpack(config, handleCompile);
+ } catch (err) {
+ console.log(chalk.red('Failed to compile.'));
+ console.log();
+ console.log(err.message || err);
+ console.log();
+ process.exit(1);
+ }
+
+ // "invalid" event fires when you have changed a file, and Webpack is
+ // recompiling a bundle. WebpackDevServer takes care to pause serving the
+ // bundle, so if you refresh, it'll wait instead of serving the old one.
+ // "invalid" is short for "bundle invalidated", it doesn't imply any errors.
+ compiler.plugin('invalid', () => {
+ if (isInteractive) {
+ clearConsole();
+ }
+ console.log('Compiling...');
+ });
+
+ let isFirstCompile = true;
+
+ // "done" event fires when Webpack has finished recompiling the bundle.
+ // Whether or not you have warnings or errors, you will get this event.
+ compiler.plugin('done', stats => {
+ if (isInteractive) {
+ clearConsole();
+ }
+
+ // We have switched off the default Webpack output in WebpackDevServer
+ // options so we are going to "massage" the warnings and errors and present
+ // them in a readable focused way.
+ const messages = formatWebpackMessages(stats.toJson({}, true));
+ const isSuccessful = !messages.errors.length && !messages.warnings.length;
+ const showInstructions = isSuccessful && (isInteractive || isFirstCompile);
+
+ if (isSuccessful) {
+ console.log(chalk.green('Compiled successfully!'));
+ }
+
+ if (typeof onReadyCallback === 'function') {
+ onReadyCallback(showInstructions);
+ }
+ isFirstCompile = false;
+
+ // If errors exist, only show errors.
+ if (messages.errors.length) {
+ console.log(chalk.red('Failed to compile.'));
+ console.log();
+ messages.errors.forEach(message => {
+ console.log(message);
+ console.log();
+ });
+ return;
+ }
+
+ // Show warnings if no errors were found.
+ if (messages.warnings.length) {
+ console.log(chalk.yellow('Compiled with warnings.'));
+ console.log();
+ messages.warnings.forEach(message => {
+ console.log(message);
+ console.log();
+ });
+ // Teach some ESLint tricks.
+ console.log('You may use special comments to disable some warnings.');
+ console.log(
+ 'Use ' +
+ chalk.yellow('// eslint-disable-next-line') +
+ ' to ignore the next line.'
+ );
+ console.log(
+ 'Use ' +
+ chalk.yellow('/* eslint-disable */') +
+ ' to ignore all warnings in a file.'
+ );
+ }
+ });
+
+ return compiler;
+};
diff --git a/packages/react-scripts/template/README.md b/packages/react-scripts/template/README.md
index c49da3e8d34..147c9280e24 100644
--- a/packages/react-scripts/template/README.md
+++ b/packages/react-scripts/template/README.md
@@ -13,20 +13,24 @@ You can find the most recent version of this guide [here](https://github.com/fac
- [npm test](#npm-test)
- [npm run build](#npm-run-build)
- [npm run eject](#npm-run-eject)
+- [Supported Language Features and Polyfills](#supported-language-features-and-polyfills)
- [Syntax Highlighting in the Editor](#syntax-highlighting-in-the-editor)
- [Displaying Lint Output in the Editor](#displaying-lint-output-in-the-editor)
+- [Debugging in the Editor](#debugging-in-the-editor)
- [Changing the Page ``](#changing-the-page-title)
- [Installing a Dependency](#installing-a-dependency)
- [Importing a Component](#importing-a-component)
- [Adding a Stylesheet](#adding-a-stylesheet)
- [Post-Processing CSS](#post-processing-css)
-- [Adding Images and Fonts](#adding-images-and-fonts)
+- [Adding a CSS Preprocessor (Sass, Less etc.)](#adding-a-css-preprocessor-sass-less-etc)
+- [Adding Images, Fonts, and Files](#adding-images-fonts-and-files)
- [Using the `public` Folder](#using-the-public-folder)
- [Changing the HTML](#changing-the-html)
- [Adding Assets Outside of the Module System](#adding-assets-outside-of-the-module-system)
- [When to Use the `public` Folder](#when-to-use-the-public-folder)
- [Using Global Variables](#using-global-variables)
- [Adding Bootstrap](#adding-bootstrap)
+ - [Using a Custom Theme](#using-a-custom-theme)
- [Adding Flow](#adding-flow)
- [Adding Custom Environment Variables](#adding-custom-environment-variables)
- [Referencing Environment Variables in the HTML](#referencing-environment-variables-in-the-html)
@@ -39,6 +43,7 @@ You can find the most recent version of this guide [here](https://github.com/fac
- [Proxying API Requests in Development](#proxying-api-requests-in-development)
- [Using HTTPS in Development](#using-https-in-development)
- [Generating Dynamic `` Tags on the Server](#generating-dynamic-meta-tags-on-the-server)
+- [Pre-Rendering into Static HTML Files](#pre-rendering-into-static-html-files)
- [Injecting Data from the Server into the Page](#injecting-data-from-the-server-into-the-page)
- [Running Tests](#running-tests)
- [Filename Conventions](#filename-conventions)
@@ -57,8 +62,11 @@ You can find the most recent version of this guide [here](https://github.com/fac
- [Developing Components in Isolation](#developing-components-in-isolation)
- [Making a Progressive Web App](#making-a-progressive-web-app)
- [Deployment](#deployment)
+ - [Static Server](#static-server)
+ - [Other Solutions](#other-solutions)
- [Serving Apps with Client-Side Routing](#serving-apps-with-client-side-routing)
- [Building for Relative Paths](#building-for-relative-paths)
+ - [Azure](#azure)
- [Firebase](#firebase)
- [GitHub Pages](#github-pages)
- [Heroku](#heroku)
@@ -170,6 +178,29 @@ Instead, it will copy all the configuration files and the transitive dependencie
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.
+## Supported Language Features and Polyfills
+
+This project supports a superset of the latest JavaScript standard.
+In addition to [ES6](https://github.com/lukehoban/es6features) syntax features, it also supports:
+
+* [Exponentiation Operator](https://github.com/rwaldron/exponentiation-operator) (ES2016).
+* [Async/await](https://github.com/tc39/ecmascript-asyncawait) (ES2017).
+* [Object Rest/Spread Properties](https://github.com/sebmarkbage/ecmascript-rest-spread) (stage 3 proposal).
+* [Class Fields and Static Properties](https://github.com/tc39/proposal-class-public-fields) (stage 2 proposal).
+* [JSX](https://facebook.github.io/react/docs/introducing-jsx.html) and [Flow](https://flowtype.org/) syntax.
+
+Learn more about [different proposal stages](https://babeljs.io/docs/plugins/#presets-stage-x-experimental-presets-).
+
+While we recommend to use experimental proposals with some caution, Facebook heavily uses these features in the product code, so we intend to provide [codemods](https://medium.com/@cpojer/effective-javascript-codemods-5a6686bb46fb) if any of these proposals change in the future.
+
+Note that **the project only includes a few ES6 [polyfills](https://en.wikipedia.org/wiki/Polyfill)**:
+
+* [`Object.assign()`](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/assign) via [`object-assign`](https://github.com/sindresorhus/object-assign).
+* [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) via [`promise`](https://github.com/then/promise).
+* [`fetch()`](https://developer.mozilla.org/en/docs/Web/API/Fetch_API) via [`whatwg-fetch`](https://github.com/github/fetch).
+
+If you use any other ES6+ features that need **runtime support** (such as `Array.from()` or `Symbol`), make sure you are including the appropriate polyfills manually, or that the browsers you are targeting already support them.
+
## Syntax Highlighting in the Editor
To configure the syntax highlighting in your favorite text editor, head to the [relevant Babel documentation page](https://babeljs.io/docs/editors) and follow the instructions. Some of the most popular editors are covered.
@@ -196,11 +227,11 @@ You would need to install an ESLint plugin for your editor first.
>VS Code ESLint plugin automatically detects Create React App's configuration file. So you do not need to create `eslintrc.json` at the root directory, except when you want to add your own rules. In that case, you should include CRA's config by adding this line:
>```js
-{
- // ...
- "extends": "react-app"
-}
-```
+>{
+> // ...
+> "extends": "react-app"
+>}
+>```
Then add this block to the `package.json` file of your project:
@@ -216,20 +247,49 @@ Then add this block to the `package.json` file of your project:
Finally, you will need to install some packages *globally*:
```sh
-npm install -g eslint-config-react-app@0.3.0 eslint@3.8.1 babel-eslint@7.0.0 eslint-plugin-react@6.4.1 eslint-plugin-import@2.0.1 eslint-plugin-jsx-a11y@2.2.3 eslint-plugin-flowtype@2.21.0
+npm install -g eslint-config-react-app@0.3.0 eslint@3.8.1 babel-eslint@7.0.0 eslint-plugin-react@6.4.1 eslint-plugin-import@2.0.1 eslint-plugin-jsx-a11y@4.0.0 eslint-plugin-flowtype@2.21.0
```
We recognize that this is suboptimal, but it is currently required due to the way we hide the ESLint dependency. The ESLint team is already [working on a solution to this](https://github.com/eslint/eslint/issues/3458) so this may become unnecessary in a couple of months.
+## Debugging in the Editor
+
+**This feature is currently only supported by [Visual Studio Code](https://code.visualstudio.com) editor.**
+
+Visual Studio Code supports live-editing and debugging out of the box with Create React App. This enables you as a developer to write and debug your React code without leaving the editor, and most importantly it enables you to have a continuous development workflow, where context switching is minimal, as you don’t have to switch between tools.
+
+You would need to have the latest version of [VS Code](https://code.visualstudio.com) and VS Code [Chrome Debugger Extension](https://marketplace.visualstudio.com/items?itemName=msjsdiag.debugger-for-chrome) installed.
+
+Then add the block below to your `launch.json` file and put it inside the `.vscode` folder in your app’s root directory.
+
+```json
+{
+ "version": "0.2.0",
+ "configurations": [{
+ "name": "Chrome",
+ "type": "chrome",
+ "request": "launch",
+ "url": "http://localhost:3000",
+ "webRoot": "${workspaceRoot}/src",
+ "userDataDir": "${workspaceRoot}/.vscode/chrome",
+ "sourceMapPathOverrides": {
+ "webpack:///src/*": "${webRoot}/*"
+ }
+ }]
+}
+```
+
+Start your app by running `npm start`, and start debugging in VS Code by pressing `F5` or by clicking the green debug icon. You can now write code, set breakpoints, make changes to the code, and debug your newly modified code—all from your editor.
+
## Changing the Page ``
You can find the source HTML file in the `public` folder of the generated project. You may edit the `` tag in it to change the title from “React App” to anything else.
-Note that normally you wouldn't edit files in the `public` folder very often. For example, [adding a stylesheet](#adding-a-stylesheet) is done without touching the HTML.
+Note that normally you wouldn’t edit files in the `public` folder very often. For example, [adding a stylesheet](#adding-a-stylesheet) is done without touching the HTML.
If you need to dynamically update the page title based on the content, you can use the browser [`document.title`](https://developer.mozilla.org/en-US/docs/Web/API/Document/title) API. For more complex scenarios when you want to change the title from React components, you can use [React Helmet](https://github.com/nfl/react-helmet), a third party library.
-Finally, if you use a custom server for your app in production and want to modify the title before it gets sent to the browser, you can follow advice in [this section](#generating-dynamic-meta-tags-on-the-server).
+If you use a custom server for your app in production and want to modify the title before it gets sent to the browser, you can follow advice in [this section](#generating-dynamic-meta-tags-on-the-server). Alternatively, you can pre-build each page as a static HTML file which then loads the JavaScript bundle, which is covered [here](#pre-rendering-into-static-html-files).
## Installing a Dependency
@@ -351,13 +411,70 @@ becomes this:
}
```
-There is currently no support for preprocessors such as Less, or for sharing variables across CSS files.
+If you need to disable autoprefixing for some reason, [follow this section](https://github.com/postcss/autoprefixer#disabling).
+
+## Adding a CSS Preprocessor (Sass, Less etc.)
+
+Generally, we recommend that you don’t reuse the same CSS classes across different components. For example, instead of using a `.Button` CSS class in `` and `` components, we recommend creating a `