├── .eslintrc.js ├── .gitignore ├── .travis.yml ├── CHANGELOG.md ├── LICENSE ├── PATENTS ├── README.md ├── bin └── react-scripts.js ├── config ├── babel.dev.js ├── babel.prod.js ├── eslint.js ├── flow │ ├── css.js.flow │ └── file.js.flow ├── webpack.config.dev.js └── webpack.config.prod.js ├── global-cli ├── index.js └── package.json ├── package.json ├── scripts ├── build.js ├── eject.js ├── init.js ├── openChrome.applescript └── start.js ├── tasks ├── e2e.sh └── release.sh └── template ├── README.md ├── favicon.ico ├── index.html └── src ├── App.css ├── App.js ├── index.css ├── index.js └── logo.svg /.eslintrc.js: -------------------------------------------------------------------------------- 1 | const clientESLintConfig = require('./config/eslint'); 2 | 3 | module.exports = Object.assign({}, clientESLintConfig, { 4 | env: Object.assign({}, clientESLintConfig.env, { 5 | node: true 6 | }) 7 | }); 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | build 3 | .DS_Store 4 | *.tgz 5 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | --- 2 | language: node_js 3 | node_js: 4 | - 4 5 | - 6 6 | cache: 7 | directories: 8 | - global-cli/node_modules 9 | - node_modules 10 | script: tasks/e2e.sh 11 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 0.1.0 (July 22, 2016) 2 | 3 | * Initial public release 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD License 2 | 3 | For create-react-app software 4 | 5 | Copyright (c) 2016-present, Facebook, Inc. All rights reserved. 6 | 7 | Redistribution and use in source and binary forms, with or without modification, 8 | are permitted provided that the following conditions are met: 9 | 10 | * Redistributions of source code must retain the above copyright notice, this 11 | list of conditions and the following disclaimer. 12 | 13 | * Redistributions in binary form must reproduce the above copyright notice, 14 | this list of conditions and the following disclaimer in the documentation 15 | and/or other materials provided with the distribution. 16 | 17 | * Neither the name Facebook nor the names of its contributors may be used to 18 | endorse or promote products derived from this software without specific 19 | prior written permission. 20 | 21 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 22 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 23 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 25 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 26 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 27 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 28 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 30 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | -------------------------------------------------------------------------------- /PATENTS: -------------------------------------------------------------------------------- 1 | Additional Grant of Patent Rights Version 2 2 | 3 | "Software" means the create-react-app software distributed by Facebook, Inc. 4 | 5 | Facebook, Inc. ("Facebook") hereby grants to each recipient of the Software 6 | ("you") a perpetual, worldwide, royalty-free, non-exclusive, irrevocable 7 | (subject to the termination provision below) license under any Necessary 8 | Claims, to make, have made, use, sell, offer to sell, import, and otherwise 9 | transfer the Software. For avoidance of doubt, no license is granted under 10 | Facebook’s rights in any patent claims that are infringed by (i) modifications 11 | to the Software made by you or any third party or (ii) the Software in 12 | combination with any software or other technology. 13 | 14 | The license granted hereunder will terminate, automatically and without notice, 15 | if you (or any of your subsidiaries, corporate affiliates or agents) initiate 16 | directly or indirectly, or take a direct financial interest in, any Patent 17 | Assertion: (i) against Facebook or any of its subsidiaries or corporate 18 | affiliates, (ii) against any party if such Patent Assertion arises in whole or 19 | in part from any software, technology, product or service of Facebook or any of 20 | its subsidiaries or corporate affiliates, or (iii) against any party relating 21 | to the Software. Notwithstanding the foregoing, if Facebook or any of its 22 | subsidiaries or corporate affiliates files a lawsuit alleging patent 23 | infringement against you in the first instance, and you respond by filing a 24 | patent infringement counterclaim in that lawsuit against that party that is 25 | unrelated to the Software, the license granted hereunder will not terminate 26 | under section (i) of this paragraph due to such counterclaim. 27 | 28 | A "Necessary Claim" is a claim of a patent owned by Facebook that is 29 | necessarily infringed by the Software standing alone. 30 | 31 | A "Patent Assertion" is any lawsuit or other action alleging direct, indirect, 32 | or contributory infringement or inducement to infringe any patent, including a 33 | cross-claim or counterclaim. 34 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Create React App 2 | 3 | Create React apps with no build configuration. 4 | 5 | ## tl;dr 6 | 7 | ```sh 8 | npm install -g create-react-app 9 | 10 | create-react-app my-app 11 | cd my-app/ 12 | npm start 13 | 14 | ``` 15 | 16 | Then open [http://localhost:3000/](http://localhost:3000/) to see your app.
17 | When you’re ready to deploy to production, create a minified bundle with `npm run build`. 18 | 19 | npm start 20 | 21 | ## Getting Started 22 | 23 | ### Installation 24 | 25 | Install it once globally: 26 | 27 | ```sh 28 | npm install -g create-react-app 29 | ``` 30 | 31 | **You’ll need to have Node >= 4 on your machine**. We 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. 32 | 33 | **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. 34 | 35 | ### Creating an App 36 | 37 | To create a new app, run: 38 | 39 | ```sh 40 | create-react-app my-app 41 | cd my-app 42 | ``` 43 | 44 | It will create a directory called `my-app` inside the current folder.
45 | Inside that directory, it will generate the initial project structure and install the transient dependencies: 46 | 47 | ``` 48 | my-app/ 49 | README.md 50 | index.html 51 | favicon.ico 52 | node_modules/ 53 | package.json 54 | src/ 55 | App.css 56 | App.js 57 | index.css 58 | index.js 59 | logo.svg 60 | ``` 61 | 62 | No configuration or complicated folder structures, just the files you need to build your app.
63 | Once the installation is done, you can run some commands inside the project folder: 64 | 65 | ### `npm start` 66 | 67 | Runs the app in development mode.
68 | Open [http://localhost:3000](http://localhost:3000) to view it in the browser. 69 | 70 | The page will reload if you make edits.
71 | You will see the build errors and lint warnings in the console. 72 | 73 | Build errors 74 | 75 | ### `npm run build` 76 | 77 | Builds the app for production to the `build` folder.
78 | It correctly bundles React in production mode and optimizes the build for the best performance. 79 | 80 | The build is minified and the filenames include the hashes.
81 | Your app is ready to be deployed! 82 | 83 | ## How Do I?... 84 | 85 | The generated project will include a guide in its README. 86 | You can also read its latest version [here](https://github.com/facebookincubator/create-react-app/blob/master/template/README.md). 87 | 88 | ## Philosophy 89 | 90 | * **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. 91 | 92 | * **Zero Configuration:** There are no configuration files or command line options. Configuring both development and production builds is handled for you so you can focus on writing code. 93 | 94 | * **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. 95 | 96 | ## Why Use This? 97 | 98 | **If you’re getting started** with React, use `create-react-app` to automate the build of your app. There is no configuration file, and `react-scripts` is the only extra build dependency in your `package.json`. Your environment will have everything you need to build a modern React app: 99 | 100 | * React, JSX, and ES6 support. 101 | * Language extras beyond ES6 like the object spread operator. 102 | * A dev server that lints for common errors. 103 | * Import CSS and image files directly from JavaScript. 104 | * Autoprefixed CSS, so you don’t need `-webkit` or other prefixes. 105 | * A `build` script to bundle JS, CSS, and images for production, with sourcemaps. 106 | 107 | **The feature set is intentionally limited**. It doesn’t support advanced features such as server rendering or CSS modules. Currently, it doesn’t support testing either. The tool is also **non-configurable** because it is hard to provide a cohesive experience and easy updates across a set of tools when the user can tweak anything. 108 | 109 | **You don’t have to use this.** Historically it has been easy to [gradually adopt](https://www.youtube.com/watch?v=BF58ZJ1ZQxY) React. However many people create new single-page React apps from scratch every day. We’ve heard [loud](https://medium.com/@ericclemmons/javascript-fatigue-48d4011b6fc4) and [clear](https://twitter.com/thomasfuchs/status/708675139253174273) that this process can be error-prone and tedious, especially if this is your first JavaScript build stack. This project is an attempt to figure out a good way to start developing React apps. 110 | 111 | ### Converting to a Custom Setup 112 | 113 | **If you’re a power user** and you aren’t happy with the default configuration, you can “eject” from the tool and use it as a boilerplate generator. 114 | 115 | Running `npm run eject` copies all the configuration files and the transient dependencies (Webpack, Babel, ESLint, etc) right into your project so you have full control over them. Commands like `npm start` and `npm run build` will still work, but they will point to the copied scripts so you can tweak them. At this point, you’re on your own. 116 | 117 | **Note: this is a one-way operation. Once you `eject`, you can’t go back!** 118 | 119 | 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. 120 | 121 | ## Limitations 122 | 123 | Some features are currently **not supported**: 124 | 125 | * Server rendering. 126 | * Testing. 127 | * Some experimental syntax extensions (e.g. decorators). 128 | * CSS Modules. 129 | * LESS or Sass. 130 | * Hot reloading of components. 131 | 132 | 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. 133 | 134 | ## What’s Inside? 135 | 136 | The tools used by Create React App are subject to change. 137 | Currently it is a thin layer on top of many amazing community projects, such as: 138 | 139 | * [webpack](https://webpack.github.io/) with [webpack-dev-server](https://github.com/webpack/webpack-dev-server), [html-webpack-plugin](https://github.com/ampedandwired/html-webpack-plugin) and [style-loader](https://github.com/webpack/style-loader) 140 | * [Babel](http://babeljs.io/) with ES6 and extensions used by Facebook (JSX, [object spread](https://github.com/sebmarkbage/ecmascript-rest-spread/commits/master), [class properties](https://github.com/jeffmo/es-class-public-fields)) 141 | * [Autoprefixer](https://github.com/postcss/autoprefixer) 142 | * [ESLint](http://eslint.org/) 143 | * and more. 144 | 145 | All of them are transient dependencies of the provided npm package. 146 | 147 | ## Contributing 148 | 149 | Clone the repo and run `npm install` in the root and the `global-cli` folder. 150 | 151 | Once it is done, you can modify any file locally and run `npm start` or `npm run build` just like in a generated project. 152 | If you want to try out the end-to-end flow with the global CLI, you can do this too: 153 | 154 | ``` 155 | npm run create-react-app my-app 156 | cd my-app 157 | ``` 158 | 159 | and then run `npm start` or `npm run build`. 160 | 161 | ## Acknowledgements 162 | 163 | We are grateful to the authors of existing related projects for their ideas and collaboration: 164 | 165 | * [@eanplatter](https://github.com/eanplatter) 166 | * [@insin](https://github.com/insin) 167 | * [@mxstbr](https://github.com/mxstbr) 168 | 169 | ## Alternatives 170 | 171 | If you don’t agree with the choices made in this project, you might want to explore alternatives with different tradeoffs: 172 | 173 | * [enclave](https://github.com/eanplatter/enclave) 174 | * [nwb](https://github.com/insin/nwb) 175 | * [motion](https://github.com/motion/motion) 176 | * [rackt-cli](https://github.com/mzabriskie/rackt-cli) 177 | * [budō](https://github.com/mattdesl/budo) 178 | * [rwb](https://github.com/petehunt/rwb) 179 | 180 | You can also use module bundlers like [webpack](http://webpack.github.io) and [Browserify](http://browserify.org/) directly. 181 | React documentation includes [a walkthrough](https://facebook.github.io/react/docs/package-management.html) on this topic. 182 | -------------------------------------------------------------------------------- /bin/react-scripts.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | var path = require('path'); 3 | var spawn = require('cross-spawn'); 4 | var script = process.argv[2]; 5 | var args = process.argv.slice(3); 6 | 7 | switch (script) { 8 | case 'build': 9 | case 'start': 10 | case 'eject': 11 | spawn( 12 | 'node', 13 | [path.resolve(__dirname, '..', 'scripts', script)].concat(args), 14 | {stdio: 'inherit'} 15 | ); 16 | break; 17 | default: 18 | console.log('Unknown script "' + script + '".'); 19 | console.log('Perhaps you need to update react-scripts?'); 20 | break; 21 | } 22 | -------------------------------------------------------------------------------- /config/babel.dev.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 10 | module.exports = { 11 | cacheDirectory: true, 12 | presets: [ 13 | 'babel-preset-es2015', 14 | 'babel-preset-es2016', 15 | 'babel-preset-react' 16 | ].map(require.resolve), 17 | plugins: [ 18 | 'babel-plugin-syntax-trailing-function-commas', 19 | 'babel-plugin-transform-class-properties', 20 | 'babel-plugin-transform-object-rest-spread' 21 | ].map(require.resolve) 22 | }; 23 | -------------------------------------------------------------------------------- /config/babel.prod.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 10 | module.exports = { 11 | presets: [ 12 | 'babel-preset-es2015', 13 | 'babel-preset-es2016', 14 | 'babel-preset-react' 15 | ].map(require.resolve), 16 | plugins: [ 17 | 'babel-plugin-syntax-trailing-function-commas', 18 | 'babel-plugin-transform-class-properties', 19 | 'babel-plugin-transform-object-rest-spread', 20 | 'babel-plugin-transform-react-constant-elements' 21 | ].map(require.resolve) 22 | }; 23 | -------------------------------------------------------------------------------- /config/eslint.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 10 | // Inspired by https://github.com/airbnb/javascript but less opinionated. 11 | 12 | // We use eslint-loader so even warnings are very visibile. 13 | // This is why we only use "WARNING" level for potential errors, 14 | // and we don't use "ERROR" level at all. 15 | 16 | // In the future, we might create a separate list of rules for production. 17 | // It would probably be more strict. 18 | 19 | var WARNING = 1; 20 | 21 | module.exports = { 22 | root: true, 23 | 24 | parser: 'babel-eslint', 25 | 26 | // import plugin is termporarily disabled, scroll below to see why 27 | plugins: ['react'/*, 'import'*/], 28 | 29 | env: { 30 | es6: true, 31 | commonjs: true, 32 | browser: true 33 | }, 34 | 35 | parserOptions: { 36 | ecmaVersion: 6, 37 | sourceType: 'module', 38 | ecmaFeatures: { 39 | jsx: true, 40 | generators: true, 41 | experimentalObjectRestSpread: true 42 | } 43 | }, 44 | 45 | settings: { 46 | 'import/ignore': [ 47 | 'node_modules', 48 | '\\.(json|css|jpg|png|gif|eot|svg|ttf|woff|woff2|mp4|webm)$', 49 | ], 50 | 'import/extensions': ['.js'], 51 | 'import/resolver': { 52 | node: { 53 | extensions: ['.js', '.json'] 54 | } 55 | } 56 | }, 57 | 58 | rules: { 59 | // http://eslint.org/docs/rules/ 60 | 'array-callback-return': WARNING, 61 | 'default-case': [WARNING, { commentPattern: '^no default$' }], 62 | 'dot-location': [WARNING, 'property'], 63 | eqeqeq: [WARNING, 'allow-null'], 64 | 'guard-for-in': WARNING, 65 | 'new-cap': [WARNING, { newIsCap: true }], 66 | 'new-parens': WARNING, 67 | 'no-array-constructor': WARNING, 68 | 'no-caller': WARNING, 69 | 'no-cond-assign': [WARNING, 'always'], 70 | 'no-const-assign': WARNING, 71 | 'no-control-regex': WARNING, 72 | 'no-delete-var': WARNING, 73 | 'no-dupe-args': WARNING, 74 | 'no-dupe-class-members': WARNING, 75 | 'no-dupe-keys': WARNING, 76 | 'no-duplicate-case': WARNING, 77 | 'no-empty-character-class': WARNING, 78 | 'no-empty-pattern': WARNING, 79 | 'no-eval': WARNING, 80 | 'no-ex-assign': WARNING, 81 | 'no-extend-native': WARNING, 82 | 'no-extra-bind': WARNING, 83 | 'no-extra-label': WARNING, 84 | 'no-fallthrough': WARNING, 85 | 'no-func-assign': WARNING, 86 | 'no-implied-eval': WARNING, 87 | 'no-invalid-regexp': WARNING, 88 | 'no-iterator': WARNING, 89 | 'no-label-var': WARNING, 90 | 'no-labels': [WARNING, { allowLoop: false, allowSwitch: false }], 91 | 'no-lone-blocks': WARNING, 92 | 'no-loop-func': WARNING, 93 | 'no-mixed-operators': [WARNING, { 94 | groups: [ 95 | ['+', '-', '*', '/', '%', '**'], 96 | ['&', '|', '^', '~', '<<', '>>', '>>>'], 97 | ['==', '!=', '===', '!==', '>', '>=', '<', '<='], 98 | ['&&', '||'], 99 | ['in', 'instanceof'] 100 | ], 101 | allowSamePrecedence: false 102 | }], 103 | 'no-multi-str': WARNING, 104 | 'no-native-reassign': WARNING, 105 | 'no-negated-in-lhs': WARNING, 106 | 'no-new-func': WARNING, 107 | 'no-new-object': WARNING, 108 | 'no-new-symbol': WARNING, 109 | 'no-new-wrappers': WARNING, 110 | 'no-obj-calls': WARNING, 111 | 'no-octal': WARNING, 112 | 'no-octal-escape': WARNING, 113 | 'no-redeclare': WARNING, 114 | 'no-regex-spaces': WARNING, 115 | 'no-restricted-syntax': [ 116 | WARNING, 117 | 'LabeledStatement', 118 | 'WithStatement', 119 | ], 120 | 'no-return-assign': WARNING, 121 | 'no-script-url': WARNING, 122 | 'no-self-assign': WARNING, 123 | 'no-self-compare': WARNING, 124 | 'no-sequences': WARNING, 125 | 'no-shadow-restricted-names': WARNING, 126 | 'no-sparse-arrays': WARNING, 127 | 'no-this-before-super': WARNING, 128 | 'no-throw-literal': WARNING, 129 | 'no-undef': WARNING, 130 | 'no-unexpected-multiline': WARNING, 131 | 'no-unreachable': WARNING, 132 | 'no-unused-expressions': WARNING, 133 | 'no-unused-labels': WARNING, 134 | 'no-unused-vars': [WARNING, { vars: 'local', args: 'none' }], 135 | 'no-use-before-define': [WARNING, 'nofunc'], 136 | 'no-useless-computed-key': WARNING, 137 | 'no-useless-concat': WARNING, 138 | 'no-useless-constructor': WARNING, 139 | 'no-useless-escape': WARNING, 140 | 'no-useless-rename': [WARNING, { 141 | ignoreDestructuring: false, 142 | ignoreImport: false, 143 | ignoreExport: false, 144 | }], 145 | 'no-with': WARNING, 146 | 'no-whitespace-before-property': WARNING, 147 | 'operator-assignment': [WARNING, 'always'], 148 | radix: WARNING, 149 | 'require-yield': WARNING, 150 | 'rest-spread-spacing': [WARNING, 'never'], 151 | strict: [WARNING, 'never'], 152 | 'unicode-bom': [WARNING, 'never'], 153 | 'use-isnan': WARNING, 154 | 'valid-typeof': WARNING, 155 | 156 | // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/ 157 | 158 | // TODO: import rules are temporarily disabled because they don't play well 159 | // with how eslint-loader only checks the file you change. So if module A 160 | // imports module B, and B is missing a default export, the linter will 161 | // record this as an issue in module A. Now if you fix module B, the linter 162 | // will not be aware that it needs to re-lint A as well, so the error 163 | // will stay until the next restart, which is really confusing. 164 | 165 | // This is probably fixable with a patch to eslint-loader. 166 | // When file A is saved, we want to invalidate all files that import it 167 | // *and* that currently have lint errors. This should fix the problem. 168 | 169 | // 'import/default': WARNING, 170 | // 'import/export': WARNING, 171 | // 'import/named': WARNING, 172 | // 'import/namespace': WARNING, 173 | // 'import/no-amd': WARNING, 174 | // 'import/no-duplicates': WARNING, 175 | // 'import/no-extraneous-dependencies': WARNING, 176 | // 'import/no-named-as-default': WARNING, 177 | // 'import/no-named-as-default-member': WARNING, 178 | // 'import/no-unresolved': [WARNING, { commonjs: true }], 179 | 180 | // https://github.com/yannickcr/eslint-plugin-react/tree/master/docs/rules 181 | 'react/jsx-equals-spacing': [WARNING, 'never'], 182 | 'react/jsx-handler-names': [WARNING, { 183 | eventHandlerPrefix: 'handle', 184 | eventHandlerPropPrefix: 'on', 185 | }], 186 | 'react/jsx-no-duplicate-props': [WARNING, { ignoreCase: true }], 187 | 'react/jsx-no-undef': WARNING, 188 | 'react/jsx-pascal-case': [WARNING, { 189 | allowAllCaps: true, 190 | ignore: [], 191 | }], 192 | 'react/jsx-uses-react': WARNING, 193 | 'react/jsx-uses-vars': WARNING, 194 | 'react/no-deprecated': WARNING, 195 | 'react/no-direct-mutation-state': WARNING, 196 | 'react/no-is-mounted': WARNING, 197 | 'react/react-in-jsx-scope': WARNING, 198 | 'react/require-render-return': WARNING 199 | } 200 | }; 201 | -------------------------------------------------------------------------------- /config/flow/css.js.flow: -------------------------------------------------------------------------------- 1 | // @flow 2 | -------------------------------------------------------------------------------- /config/flow/file.js.flow: -------------------------------------------------------------------------------- 1 | // @flow 2 | declare export default string; 3 | -------------------------------------------------------------------------------- /config/webpack.config.dev.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 10 | var path = require('path'); 11 | var autoprefixer = require('autoprefixer'); 12 | var webpack = require('webpack'); 13 | var HtmlWebpackPlugin = require('html-webpack-plugin'); 14 | 15 | // TODO: hide this behind a flag and eliminate dead code on eject. 16 | // This shouldn't be exposed to the user. 17 | var isInNodeModules = 'node_modules' === 18 | path.basename(path.resolve(path.join(__dirname, '..', '..'))); 19 | var relativePath = isInNodeModules ? '../../..' : '..'; 20 | var isInDebugMode = process.argv.some(arg => 21 | arg.indexOf('--debug-template') > -1 22 | ); 23 | if (isInDebugMode) { 24 | relativePath = '../template'; 25 | } 26 | var srcPath = path.resolve(__dirname, relativePath, 'src'); 27 | var nodeModulesPath = path.join(__dirname, '..', 'node_modules'); 28 | var indexHtmlPath = path.resolve(__dirname, relativePath, 'index.html'); 29 | var faviconPath = path.resolve(__dirname, relativePath, 'favicon.ico'); 30 | var buildPath = path.join(__dirname, isInNodeModules ? '../../..' : '..', 'build'); 31 | 32 | module.exports = { 33 | devtool: 'eval', 34 | entry: [ 35 | require.resolve('webpack-dev-server/client') + '?http://localhost:3000', 36 | require.resolve('webpack/hot/dev-server'), 37 | path.join(srcPath, 'index') 38 | ], 39 | output: { 40 | // Next line is not used in dev but WebpackDevServer crashes without it: 41 | path: buildPath, 42 | pathinfo: true, 43 | filename: 'bundle.js', 44 | publicPath: '/' 45 | }, 46 | resolve: { 47 | extensions: ['', '.js'], 48 | }, 49 | resolveLoader: { 50 | root: nodeModulesPath, 51 | moduleTemplates: ['*-loader'] 52 | }, 53 | module: { 54 | preLoaders: [ 55 | { 56 | test: /\.js$/, 57 | loader: 'eslint', 58 | include: srcPath, 59 | } 60 | ], 61 | loaders: [ 62 | { 63 | test: /\.js$/, 64 | include: srcPath, 65 | loader: 'babel', 66 | query: require('./babel.dev') 67 | }, 68 | { 69 | test: /\.css$/, 70 | include: srcPath, 71 | loader: 'style!css!postcss' 72 | }, 73 | { 74 | test: /\.json$/, 75 | loader: 'json' 76 | }, 77 | { 78 | test: /\.(jpg|png|gif|eot|svg|ttf|woff|woff2)$/, 79 | loader: 'file', 80 | }, 81 | { 82 | test: /\.(mp4|webm)$/, 83 | loader: 'url?limit=10000' 84 | } 85 | ] 86 | }, 87 | eslint: { 88 | configFile: path.join(__dirname, 'eslint.js'), 89 | useEslintrc: false 90 | }, 91 | postcss: function() { 92 | return [autoprefixer]; 93 | }, 94 | plugins: [ 95 | new HtmlWebpackPlugin({ 96 | inject: true, 97 | template: indexHtmlPath, 98 | favicon: faviconPath, 99 | }), 100 | new webpack.DefinePlugin({ 'process.env.NODE_ENV': '"development"' }), 101 | // Note: only CSS is currently hot reloaded 102 | new webpack.HotModuleReplacementPlugin() 103 | ] 104 | }; 105 | -------------------------------------------------------------------------------- /config/webpack.config.prod.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 10 | var path = require('path'); 11 | var autoprefixer = require('autoprefixer'); 12 | var webpack = require('webpack'); 13 | var HtmlWebpackPlugin = require('html-webpack-plugin'); 14 | var ExtractTextPlugin = require('extract-text-webpack-plugin'); 15 | 16 | // TODO: hide this behind a flag and eliminate dead code on eject. 17 | // This shouldn't be exposed to the user. 18 | var isInNodeModules = 'node_modules' === 19 | path.basename(path.resolve(path.join(__dirname, '..', '..'))); 20 | var relativePath = isInNodeModules ? '../../..' : '..'; 21 | if (process.argv[2] === '--debug-template') { 22 | relativePath = '../template'; 23 | } 24 | var srcPath = path.resolve(__dirname, relativePath, 'src'); 25 | var nodeModulesPath = path.join(__dirname, '..', 'node_modules'); 26 | var indexHtmlPath = path.resolve(__dirname, relativePath, 'index.html'); 27 | var faviconPath = path.resolve(__dirname, relativePath, 'favicon.ico'); 28 | var buildPath = path.join(__dirname, isInNodeModules ? '../../..' : '..', 'build'); 29 | 30 | module.exports = { 31 | bail: true, 32 | devtool: 'source-map', 33 | entry: path.join(srcPath, 'index'), 34 | output: { 35 | path: buildPath, 36 | filename: '[name].[chunkhash].js', 37 | chunkFilename: '[name].[chunkhash].chunk.js', 38 | // TODO: this wouldn't work for e.g. GH Pages. 39 | // Good news: we can infer it from package.json :-) 40 | publicPath: '/' 41 | }, 42 | resolve: { 43 | extensions: ['', '.js'], 44 | }, 45 | resolveLoader: { 46 | root: nodeModulesPath, 47 | moduleTemplates: ['*-loader'] 48 | }, 49 | module: { 50 | preLoaders: [ 51 | { 52 | test: /\.js$/, 53 | loader: 'eslint', 54 | include: srcPath 55 | } 56 | ], 57 | loaders: [ 58 | { 59 | test: /\.js$/, 60 | include: srcPath, 61 | loader: 'babel', 62 | query: require('./babel.prod') 63 | }, 64 | { 65 | test: /\.css$/, 66 | include: srcPath, 67 | // Disable autoprefixer in css-loader itself: 68 | // https://github.com/webpack/css-loader/issues/281 69 | // We already have it thanks to postcss. 70 | loader: ExtractTextPlugin.extract('style', 'css?-autoprefixer!postcss') 71 | }, 72 | { 73 | test: /\.json$/, 74 | loader: 'json' 75 | }, 76 | { 77 | test: /\.(jpg|png|gif|eot|svg|ttf|woff|woff2)$/, 78 | loader: 'file', 79 | }, 80 | { 81 | test: /\.(mp4|webm)$/, 82 | loader: 'url?limit=10000' 83 | } 84 | ] 85 | }, 86 | eslint: { 87 | // TODO: consider separate config for production, 88 | // e.g. to enable no-console and no-debugger only in prod. 89 | configFile: path.join(__dirname, 'eslint.js'), 90 | useEslintrc: false 91 | }, 92 | postcss: function() { 93 | return [autoprefixer]; 94 | }, 95 | plugins: [ 96 | new HtmlWebpackPlugin({ 97 | inject: true, 98 | template: indexHtmlPath, 99 | favicon: faviconPath, 100 | minify: { 101 | removeComments: true, 102 | collapseWhitespace: true, 103 | removeRedundantAttributes: true, 104 | useShortDoctype: true, 105 | removeEmptyAttributes: true, 106 | removeStyleLinkTypeAttributes: true, 107 | keepClosingSlash: true, 108 | minifyJS: true, 109 | minifyCSS: true, 110 | minifyURLs: true 111 | } 112 | }), 113 | new webpack.DefinePlugin({ 'process.env.NODE_ENV': '"production"' }), 114 | new webpack.optimize.OccurrenceOrderPlugin(), 115 | new webpack.optimize.DedupePlugin(), 116 | new webpack.optimize.UglifyJsPlugin({ 117 | compressor: { 118 | screw_ie8: true, 119 | warnings: false 120 | }, 121 | mangle: { 122 | screw_ie8: true 123 | }, 124 | output: { 125 | comments: false, 126 | screw_ie8: true 127 | } 128 | }), 129 | new ExtractTextPlugin('[name].[contenthash].css') 130 | ] 131 | }; 132 | -------------------------------------------------------------------------------- /global-cli/index.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | /** 4 | * Copyright (c) 2015-present, Facebook, Inc. 5 | * All rights reserved. 6 | * 7 | * This source code is licensed under the BSD-style license found in the 8 | * LICENSE file in the root directory of this source tree. An additional grant 9 | * of patent rights can be found in the PATENTS file in the same directory. 10 | */ 11 | 12 | // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 13 | // /!\ DO NOT MODIFY THIS FILE /!\ 14 | // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 15 | // 16 | // create-react-app is installed globally on people's computers. This means 17 | // that it is extremely difficult to have them upgrade the version and 18 | // because there's only one global version installed, it is very prone to 19 | // breaking changes. 20 | // 21 | // The only job of create-react-app is to init the repository and then 22 | // forward all the commands to the local version of create-react-app. 23 | // 24 | // If you need to add a new command, please add it to the scripts/ folder. 25 | // 26 | // The only reason to modify this file is to add more warnings and 27 | // troubleshooting information for the `create-react-app` command. 28 | // 29 | // Do not make breaking changes! We absolutely don't want to have to 30 | // tell people to update their global version of create-react-app. 31 | // 32 | // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 33 | // /!\ DO NOT MODIFY THIS FILE /!\ 34 | // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 35 | 36 | 'use strict'; 37 | 38 | var fs = require('fs'); 39 | var path = require('path'); 40 | var spawn = require('cross-spawn'); 41 | var chalk = require('chalk'); 42 | var semver = require('semver'); 43 | var argv = require('minimist')(process.argv.slice(2)); 44 | 45 | /** 46 | * Arguments: 47 | * --version - to print current version 48 | * --verbose - to print logs while init 49 | * --scripts-version 50 | * Example of valid values: 51 | * - a specific npm version: "0.22.0-rc1" 52 | * - a .tgz archive from any npm repo: "https://registry.npmjs.org/react-scripts/-/react-scripts-0.20.0.tgz" 53 | * - a package prepared with `npm pack`: "/Users/home/vjeux/create-react-app/react-scripts-0.22.0.tgz" 54 | */ 55 | var commands = argv._; 56 | if (commands.length === 0) { 57 | console.error( 58 | 'Usage: create-react-app [--verbose]' 59 | ); 60 | process.exit(1); 61 | } 62 | 63 | if (argv.version) { 64 | console.log('create-react-app version: ' + require('./package.json').version); 65 | process.exit(); 66 | } 67 | 68 | createApp(commands[0], argv.verbose, argv['scripts-version']); 69 | 70 | function createApp(name, verbose, version) { 71 | if (fs.existsSync(name)) { 72 | console.log('The directory `' + name + '` already exists. Aborting.'); 73 | process.exit(1); 74 | } 75 | 76 | var root = path.resolve(name); 77 | var appName = path.basename(root); 78 | 79 | console.log( 80 | 'Creating a new React app in ' + root + '.' 81 | ); 82 | console.log(); 83 | 84 | fs.mkdirSync(root); 85 | 86 | var packageJson = { 87 | name: appName, 88 | version: '0.0.1', 89 | private: true, 90 | }; 91 | fs.writeFileSync(path.join(root, 'package.json'), JSON.stringify(packageJson)); 92 | process.chdir(root); 93 | 94 | console.log('Installing packages. This might take a couple minutes.'); 95 | console.log('Installing react-scripts from npm...'); 96 | 97 | run(root, appName, version, verbose); 98 | } 99 | 100 | function run(root, appName, version, verbose) { 101 | var args = [ 102 | 'install', 103 | verbose && '--verbose', 104 | '--save-dev', 105 | '--save-exact', 106 | getInstallPackage(version), 107 | ].filter(function(e) { return e; }); 108 | var proc = spawn('npm', args, {stdio: 'inherit'}); 109 | proc.on('close', function (code) { 110 | if (code !== 0) { 111 | console.error('`npm ' + args.join(' ') + '` failed'); 112 | return; 113 | } 114 | 115 | var scriptsPath = path.resolve( 116 | process.cwd(), 117 | 'node_modules', 118 | 'react-scripts', 119 | 'scripts', 120 | 'init.js' 121 | ); 122 | var init = require(scriptsPath); 123 | init(root, appName, verbose); 124 | }); 125 | } 126 | 127 | function getInstallPackage(version) { 128 | var packageToInstall = 'react-scripts'; 129 | var validSemver = semver.valid(version); 130 | if (validSemver) { 131 | packageToInstall += '@' + validSemver; 132 | } else if (version) { 133 | // for tar.gz or alternative paths 134 | packageToInstall = version; 135 | } 136 | return packageToInstall; 137 | } 138 | 139 | function checkNodeVersion() { 140 | var packageJsonPath = path.resolve( 141 | process.cwd(), 142 | 'node_modules', 143 | 'react-scripts', 144 | 'package.json' 145 | ); 146 | var packageJson = require(packageJsonPath); 147 | if (!packageJson.engines || !packageJson.engines.node) { 148 | return; 149 | } 150 | 151 | if (!semver.satisfies(process.version, packageJson.engines.node)) { 152 | console.error( 153 | chalk.red( 154 | 'You are currently running Node %s but create-react-app requires %s.' + 155 | ' Please use a supported version of Node.\n' 156 | ), 157 | process.version, 158 | packageJson.engines.node 159 | ); 160 | } 161 | } 162 | -------------------------------------------------------------------------------- /global-cli/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "create-react-app", 3 | "version": "0.1.0", 4 | "keywords": [ 5 | "react" 6 | ], 7 | "description": "Create React apps with no build configuration.", 8 | "repository": "facebookincubator/create-react-app", 9 | "license": "BSD-3-Clause", 10 | "bugs": { 11 | "url": "https://github.com/facebookincubator/create-react-app/issues" 12 | }, 13 | "engines": { 14 | "node": ">=4.0.0" 15 | }, 16 | "files": [ 17 | "index.js" 18 | ], 19 | "bin": { 20 | "create-react-app": "./index.js" 21 | }, 22 | "dependencies": { 23 | "chalk": "^1.1.1", 24 | "cross-spawn": "^4.0.0", 25 | "minimist": "^1.2.0", 26 | "semver": "^5.0.3" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-scripts", 3 | "version": "0.1.0", 4 | "description": "Configuration and scripts for Create React App.", 5 | "repository": "facebookincubator/create-react-app", 6 | "license": "BSD-3-Clause", 7 | "bugs": { 8 | "url": "https://github.com/facebookincubator/create-react-app/issues" 9 | }, 10 | "scripts": { 11 | "start": "node scripts/start.js --debug-template", 12 | "build": "node scripts/build.js --debug-template", 13 | "create-react-app": "node global-cli/index.js --scripts-version \"$PWD/`npm pack`\"" 14 | }, 15 | "files": [ 16 | "LICENSE", 17 | "PATENTS", 18 | "bin", 19 | "config", 20 | "scripts", 21 | "template" 22 | ], 23 | "bin": { 24 | "react-scripts": "./bin/react-scripts.js" 25 | }, 26 | "dependencies": { 27 | "autoprefixer": "6.3.7", 28 | "babel-core": "6.10.4", 29 | "babel-eslint": "6.1.2", 30 | "babel-loader": "6.2.4", 31 | "babel-plugin-syntax-trailing-function-commas": "6.8.0", 32 | "babel-plugin-transform-class-properties": "6.10.2", 33 | "babel-plugin-transform-object-rest-spread": "6.8.0", 34 | "babel-plugin-transform-react-constant-elements": "6.9.1", 35 | "babel-preset-es2015": "6.9.0", 36 | "babel-preset-es2016": "6.11.3", 37 | "babel-preset-react": "6.11.1", 38 | "chalk": "1.1.3", 39 | "cross-spawn": "4.0.0", 40 | "css-loader": "0.23.1", 41 | "eslint": "3.1.1", 42 | "eslint-loader": "1.4.1", 43 | "eslint-plugin-import": "1.10.3", 44 | "eslint-plugin-react": "5.2.2", 45 | "extract-text-webpack-plugin": "1.0.1", 46 | "file-loader": "0.9.0", 47 | "fs-extra": "^0.30.0", 48 | "html-webpack-plugin": "2.22.0", 49 | "json-loader": "0.5.4", 50 | "opn": "4.0.2", 51 | "postcss-loader": "0.9.1", 52 | "rimraf": "2.5.3", 53 | "style-loader": "0.13.1", 54 | "url-loader": "0.5.7", 55 | "webpack": "1.13.1", 56 | "webpack-dev-server": "1.14.1" 57 | }, 58 | "devDependencies": { 59 | "bundle-deps": "^1.0.0", 60 | "react": "^15.2.1", 61 | "react-dom": "^15.2.1" 62 | }, 63 | "optionalDependencies": { 64 | "fsevents": "1.0.14" 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /scripts/build.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 10 | process.env.NODE_ENV = 'production'; 11 | 12 | var path = require('path'); 13 | var rimrafSync = require('rimraf').sync; 14 | var webpack = require('webpack'); 15 | var config = require('../config/webpack.config.prod'); 16 | 17 | var isInNodeModules = 'node_modules' === 18 | path.basename(path.resolve(path.join(__dirname, '..', '..'))); 19 | var relative = isInNodeModules ? '../..' : '.'; 20 | rimrafSync(relative + '/build'); 21 | 22 | webpack(config).run(function(err, stats) { 23 | if (err) { 24 | console.error('Failed to create a production build. Reason:'); 25 | console.error(err.message || err); 26 | process.exit(1); 27 | } 28 | 29 | var openCommand = process.platform === 'win32' ? 'start' : 'open'; 30 | console.log('Successfully generated a bundle in the build folder!'); 31 | console.log(); 32 | console.log('You can now serve it with any static server, for example:'); 33 | console.log(' cd build'); 34 | console.log(' npm install -g http-server'); 35 | console.log(' hs'); 36 | console.log(' ' + openCommand + ' http://localhost:8080'); 37 | console.log(); 38 | console.log('The bundle is optimized and ready to be deployed to production.'); 39 | }); 40 | -------------------------------------------------------------------------------- /scripts/eject.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 10 | var fs = require('fs'); 11 | var path = require('path'); 12 | var rl = require('readline'); 13 | var rimrafSync = require('rimraf').sync; 14 | var spawnSync = require('cross-spawn').sync; 15 | 16 | var prompt = function(question, cb) { 17 | var rlInterface = rl.createInterface({ 18 | input: process.stdin, 19 | output: process.stdout, 20 | }); 21 | rlInterface.question(question + '\n', function(answer) { 22 | rlInterface.close(); 23 | cb(answer); 24 | }) 25 | } 26 | 27 | prompt('Are you sure you want to eject? This action is permanent. [y/N]', function(answer) { 28 | var shouldEject = answer && ( 29 | answer.toLowerCase() === 'y' || 30 | answer.toLowerCase() === 'yes' 31 | ); 32 | if (!shouldEject) { 33 | console.log('Close one! Eject aborted.'); 34 | process.exit(1); 35 | } 36 | 37 | console.log('Ejecting...'); 38 | console.log(); 39 | 40 | var selfPath = path.join(__dirname, '..'); 41 | var hostPath = path.join(selfPath, '..', '..'); 42 | var files = [ 43 | path.join('config', 'babel.dev.js'), 44 | path.join('config', 'babel.prod.js'), 45 | path.join('config', 'flow', 'css.js.flow'), 46 | path.join('config', 'flow', 'file.js.flow'), 47 | path.join('config', 'eslint.js'), 48 | path.join('config', 'webpack.config.dev.js'), 49 | path.join('config', 'webpack.config.prod.js'), 50 | path.join('scripts', 'build.js'), 51 | path.join('scripts', 'start.js'), 52 | path.join('scripts', 'openChrome.applescript') 53 | ]; 54 | 55 | // Ensure that the host folder is clean and we won't override any files 56 | files.forEach(function(file) { 57 | if (fs.existsSync(path.join(hostPath, file))) { 58 | console.error( 59 | '`' + file + '` already exists in your app folder. We cannot ' + 60 | 'continue as you would lose all the changes in that file or directory. ' + 61 | 'Please delete it (maybe make a copy for backup) and run this ' + 62 | 'command again.' 63 | ); 64 | process.exit(1); 65 | } 66 | }); 67 | 68 | // Copy the files over 69 | fs.mkdirSync(path.join(hostPath, 'config')); 70 | fs.mkdirSync(path.join(hostPath, 'config', 'flow')); 71 | fs.mkdirSync(path.join(hostPath, 'scripts')); 72 | 73 | files.forEach(function(file) { 74 | console.log('Copying ' + file + ' to ' + hostPath); 75 | var content = fs 76 | .readFileSync(path.join(selfPath, file), 'utf8') 77 | // Remove license header from JS 78 | .replace(/^\/\*\*(\*(?!\/)|[^*])*\*\//, '') 79 | // Remove license header from AppleScript 80 | .replace(/^--.*\n/gm, '') 81 | .trim() + '\n'; 82 | fs.writeFileSync(path.join(hostPath, file), content); 83 | }); 84 | console.log(); 85 | 86 | var selfPackage = require(path.join(selfPath, 'package.json')); 87 | var hostPackage = require(path.join(hostPath, 'package.json')); 88 | 89 | console.log('Removing dependency: react-scripts'); 90 | delete hostPackage.devDependencies['react-scripts']; 91 | 92 | Object.keys(selfPackage.dependencies).forEach(function (key) { 93 | // For some reason optionalDependencies end up in dependencies after install 94 | if (selfPackage.optionalDependencies[key]) { 95 | return; 96 | } 97 | console.log('Adding dependency: ' + key); 98 | hostPackage.devDependencies[key] = selfPackage.dependencies[key]; 99 | }); 100 | 101 | console.log('Updating scripts'); 102 | Object.keys(hostPackage.scripts).forEach(function (key) { 103 | hostPackage.scripts[key] = 'node ./scripts/' + key + '.js' 104 | }); 105 | delete hostPackage.scripts['eject']; 106 | 107 | console.log('Writing package.json'); 108 | fs.writeFileSync( 109 | path.join(hostPath, 'package.json'), 110 | JSON.stringify(hostPackage, null, 2) 111 | ); 112 | console.log(); 113 | 114 | console.log('Running npm install...'); 115 | rimrafSync(selfPath); 116 | spawnSync('npm', ['install'], {stdio: 'inherit'}); 117 | console.log('Ejected successfully!'); 118 | console.log(); 119 | 120 | console.log('Please consider sharing why you ejected in this survey:'); 121 | console.log(' http://goo.gl/forms/Bi6CZjk1EqsdelXk1'); 122 | console.log(); 123 | }); 124 | -------------------------------------------------------------------------------- /scripts/init.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 10 | var fs = require('fs-extra'); 11 | var path = require('path'); 12 | var spawn = require('cross-spawn'); 13 | 14 | module.exports = function(hostPath, appName, verbose) { 15 | var selfPath = path.join(hostPath, 'node_modules', 'react-scripts'); 16 | 17 | var hostPackage = require(path.join(hostPath, 'package.json')); 18 | var selfPackage = require(path.join(selfPath, 'package.json')); 19 | 20 | // Copy over some of the devDependencies 21 | hostPackage.dependencies = hostPackage.dependencies || {}; 22 | ['react', 'react-dom'].forEach(function (key) { 23 | hostPackage.dependencies[key] = selfPackage.devDependencies[key]; 24 | }); 25 | 26 | // Setup the script rules 27 | hostPackage.scripts = {}; 28 | ['start', 'build', 'eject'].forEach(function(command) { 29 | hostPackage.scripts[command] = 'react-scripts ' + command; 30 | }); 31 | 32 | fs.writeFileSync( 33 | path.join(hostPath, 'package.json'), 34 | JSON.stringify(hostPackage, null, 2) 35 | ); 36 | 37 | // Copy the files for the user 38 | fs.copySync(path.join(selfPath, 'template'), hostPath); 39 | 40 | // Run another npm install for react and react-dom 41 | console.log('Installing react and react-dom from npm...'); 42 | // TODO: having to do two npm installs is bad, can we avoid it? 43 | var args = [ 44 | 'install', 45 | verbose && '--verbose' 46 | ].filter(function(e) { return e; }); 47 | var proc = spawn('npm', args, {stdio: 'inherit'}); 48 | proc.on('close', function (code) { 49 | if (code !== 0) { 50 | console.error('`npm ' + args.join(' ') + '` failed'); 51 | return; 52 | } 53 | 54 | // Make sure to display the right way to cd 55 | var cdpath; 56 | if (path.join(process.cwd(), appName) === hostPath) { 57 | cdpath = appName; 58 | } else { 59 | cdpath = hostPath; 60 | } 61 | 62 | console.log('Success! Created ' + appName + ' at ' + hostPath + '.'); 63 | console.log(); 64 | console.log('Inside that directory, you can run several commands:'); 65 | console.log(' * npm start: Starts the development server.'); 66 | console.log(' * npm run build: Bundles the app into static files for production.'); 67 | console.log(' * npm run eject: Removes this tool. If you do this, you can’t go back!'); 68 | console.log(); 69 | console.log('We suggest that you begin by typing:'); 70 | console.log(' cd', cdpath); 71 | console.log(' npm start'); 72 | console.log(); 73 | console.log('Happy hacking!'); 74 | }); 75 | }; 76 | -------------------------------------------------------------------------------- /scripts/openChrome.applescript: -------------------------------------------------------------------------------- 1 | -- Copyright (c) 2015-present, Facebook, Inc. 2 | -- All rights reserved. 3 | -- 4 | -- This source code is licensed under the BSD-style license found in the 5 | -- LICENSE file in the root directory of this source tree. An additional grant 6 | -- of patent rights can be found in the PATENTS file in the same directory. 7 | on run argv 8 | set theURL to item 1 of argv 9 | 10 | tell application "Chrome" 11 | 12 | if (count every window) = 0 then 13 | make new window 14 | end if 15 | 16 | -- Find a tab currently running the debugger 17 | set found to false 18 | set theTabIndex to -1 19 | repeat with theWindow in every window 20 | set theTabIndex to 0 21 | repeat with theTab in every tab of theWindow 22 | set theTabIndex to theTabIndex + 1 23 | if theTab's URL is theURL then 24 | set found to true 25 | exit repeat 26 | end if 27 | end repeat 28 | 29 | if found then 30 | exit repeat 31 | end if 32 | end repeat 33 | 34 | if found then 35 | tell theTab to reload 36 | set index of theWindow to 1 37 | set theWindow's active tab index to theTabIndex 38 | else 39 | tell window 1 40 | activate 41 | make new tab with properties {URL:theURL} 42 | end tell 43 | end if 44 | end tell 45 | end run 46 | -------------------------------------------------------------------------------- /scripts/start.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 10 | process.env.NODE_ENV = 'development'; 11 | 12 | var path = require('path'); 13 | var chalk = require('chalk'); 14 | var webpack = require('webpack'); 15 | var WebpackDevServer = require('webpack-dev-server'); 16 | var config = require('../config/webpack.config.dev'); 17 | var execSync = require('child_process').execSync; 18 | var opn = require('opn'); 19 | 20 | // TODO: hide this behind a flag and eliminate dead code on eject. 21 | // This shouldn't be exposed to the user. 22 | var handleCompile; 23 | var isSmokeTest = process.argv.some(arg => 24 | arg.indexOf('--smoke-test') > -1 25 | ); 26 | if (isSmokeTest) { 27 | handleCompile = function (err, stats) { 28 | if (err || stats.hasErrors() || stats.hasWarnings()) { 29 | process.exit(1); 30 | } else { 31 | process.exit(0); 32 | } 33 | }; 34 | } 35 | 36 | var friendlySyntaxErrorLabel = 'Syntax error:'; 37 | 38 | function isLikelyASyntaxError(message) { 39 | return message.indexOf(friendlySyntaxErrorLabel) !== -1; 40 | } 41 | 42 | // This is a little hacky. 43 | // It would be easier if webpack provided a rich error object. 44 | 45 | function formatMessage(message) { 46 | return message 47 | // Make some common errors shorter: 48 | .replace( 49 | // Babel syntax error 50 | 'Module build failed: SyntaxError:', 51 | friendlySyntaxErrorLabel 52 | ) 53 | .replace( 54 | // Webpack file not found error 55 | /Module not found: Error: Cannot resolve 'file' or 'directory'/, 56 | 'Module not found:' 57 | ) 58 | // Internal stacks are generally useless so we strip them 59 | .replace(/^\s*at\s.*:\d+:\d+[\s\)]*\n/gm, '') // at ... ...:x:y 60 | // Webpack loader names obscure CSS filenames 61 | .replace('./~/css-loader!./~/postcss-loader!', ''); 62 | } 63 | 64 | function clearConsole() { 65 | process.stdout.write('\x1B[2J\x1B[0f'); 66 | } 67 | 68 | var compiler = webpack(config, handleCompile); 69 | compiler.plugin('invalid', function () { 70 | clearConsole(); 71 | console.log('Compiling...'); 72 | }); 73 | compiler.plugin('done', function (stats) { 74 | clearConsole(); 75 | var hasErrors = stats.hasErrors(); 76 | var hasWarnings = stats.hasWarnings(); 77 | if (!hasErrors && !hasWarnings) { 78 | console.log(chalk.green('Compiled successfully!')); 79 | console.log(); 80 | console.log('The app is running at http://localhost:3000/'); 81 | console.log(); 82 | return; 83 | } 84 | 85 | var json = stats.toJson(); 86 | var formattedErrors = json.errors.map(message => 87 | 'Error in ' + formatMessage(message) 88 | ); 89 | var formattedWarnings = json.warnings.map(message => 90 | 'Warning in ' + formatMessage(message) 91 | ); 92 | 93 | if (hasErrors) { 94 | console.log(chalk.red('Failed to compile.')); 95 | console.log(); 96 | if (formattedErrors.some(isLikelyASyntaxError)) { 97 | // If there are any syntax errors, show just them. 98 | // This prevents a confusing ESLint parsing error 99 | // preceding a much more useful Babel syntax error. 100 | formattedErrors = formattedErrors.filter(isLikelyASyntaxError); 101 | } 102 | formattedErrors.forEach(message => { 103 | console.log(message); 104 | console.log(); 105 | }); 106 | // If errors exist, ignore warnings. 107 | return; 108 | } 109 | 110 | if (hasWarnings) { 111 | console.log(chalk.yellow('Compiled with warnings.')); 112 | console.log(); 113 | formattedWarnings.forEach(message => { 114 | console.log(message); 115 | console.log(); 116 | }); 117 | 118 | console.log('You may use special comments to disable some warnings.'); 119 | console.log('Use ' + chalk.yellow('// eslint-disable-next-line') + ' to ignore the next line.'); 120 | console.log('Use ' + chalk.yellow('/* eslint-disable */') + ' to ignore all warnings in a file.'); 121 | } 122 | }); 123 | 124 | function openBrowser() { 125 | if (process.platform === 'darwin') { 126 | try { 127 | // Try our best to reuse existing tab 128 | // on OS X Google Chrome with AppleScript 129 | execSync('ps cax | grep "Google Chrome"'); 130 | execSync( 131 | 'osascript ' + 132 | path.resolve(__dirname, './openChrome.applescript') + 133 | ' http://localhost:3000/' 134 | ); 135 | return; 136 | } catch (err) { 137 | // Ignore errors. 138 | } 139 | } 140 | // Fallback to opn 141 | // (It will always open new tab) 142 | opn('http://localhost:3000/'); 143 | } 144 | 145 | new WebpackDevServer(compiler, { 146 | historyApiFallback: true, 147 | hot: true, // Note: only CSS is currently hot reloaded 148 | publicPath: config.output.publicPath, 149 | quiet: true 150 | }).listen(3000, 'localhost', function (err, result) { 151 | if (err) { 152 | return console.log(err); 153 | } 154 | 155 | clearConsole(); 156 | console.log(chalk.cyan('Starting the development server...')); 157 | console.log(); 158 | openBrowser(); 159 | }); 160 | -------------------------------------------------------------------------------- /tasks/e2e.sh: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2015-present, Facebook, Inc. 2 | # All rights reserved. 3 | # 4 | # This source code is licensed under the BSD-style license found in the 5 | # LICENSE file in the root directory of this source tree. An additional grant 6 | # of patent rights can be found in the PATENTS file in the same directory. 7 | 8 | # Start in tests/ even if run from root directory 9 | cd "$(dirname "$0")" 10 | 11 | # Exit the script on any command with non 0 return code 12 | # We assume that all the commands in the pipeline set their return code 13 | # properly and that we do not need to validate that the output is correct 14 | set -e 15 | 16 | # Echo every command being executed 17 | set -x 18 | 19 | # npm pack the two directories to make sure they are valid npm modules 20 | initial_path=$PWD 21 | cd .. 22 | 23 | # A hacky way to avoid bundling dependencies. 24 | # Packing with them enabled takes too much memory, and Travis crashes. 25 | # End to end script is meant to run on Travis so it's not a big deal. 26 | # If you run it locally, you'll need to `git checkout -- package.json`. 27 | perl -i -p0e 's/bundledDependencies.*?]/bundledDependencies": []/s' package.json 28 | 29 | # Pack react-scripts 30 | npm install 31 | scripts_path=$PWD/`npm pack` 32 | 33 | # lint 34 | ./node_modules/.bin/eslint --ignore-path .gitignore ./ 35 | 36 | # Test local start command 37 | npm start -- --smoke-test 38 | 39 | # Test local build command 40 | npm run build 41 | 42 | # Check for expected output 43 | test -e build/*.html 44 | test -e build/*.js 45 | 46 | # Pack CLI 47 | cd global-cli 48 | npm install 49 | cli_path=$PWD/`npm pack` 50 | 51 | # Install the cli in a temporary location ( http://unix.stackexchange.com/a/84980 ) 52 | temp_cli_path=`mktemp -d 2>/dev/null || mktemp -d -t 'temp_cli_path'` 53 | cd $temp_cli_path 54 | npm install $cli_path 55 | 56 | # Install the app in a temporary location 57 | temp_app_path=`mktemp -d 2>/dev/null || mktemp -d -t 'temp_app_path'` 58 | cd $temp_app_path 59 | node "$temp_cli_path"/node_modules/create-react-app/index.js --scripts-version=$scripts_path test-app 60 | cd test-app 61 | 62 | # Test the build 63 | npm run build 64 | 65 | # Check for expected output 66 | test -e build/*.html 67 | test -e build/*.js 68 | 69 | # Test the server 70 | npm start -- --smoke-test 71 | 72 | # Eject and test the build 73 | echo yes | npm run eject 74 | npm run build 75 | 76 | # Check for expected output 77 | test -e build/*.html 78 | test -e build/*.js 79 | 80 | # Test the server 81 | npm start -- --smoke-test 82 | 83 | # Cleanup 84 | cd $initial_path 85 | rm -rf $temp_cli_path $temp_app_path 86 | -------------------------------------------------------------------------------- /tasks/release.sh: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2015-present, Facebook, Inc. 2 | # All rights reserved. 3 | # 4 | # This source code is licensed under the BSD-style license found in the 5 | # LICENSE file in the root directory of this source tree. An additional grant 6 | # of patent rights can be found in the PATENTS file in the same directory. 7 | 8 | # Start in tests/ even if run from root directory 9 | cd "$(dirname "$0")" 10 | 11 | # Exit the script on any command with non 0 return code 12 | # We assume that all the commands in the pipeline set their return code 13 | # properly and that we do not need to validate that the output is correct 14 | set -e 15 | 16 | # Echo every command being executed 17 | set -x 18 | 19 | # Go to root 20 | cd .. 21 | 22 | # You can only release with npm >= 3 23 | if [ $(npm -v | head -c 1) -lt 3 ]; then 24 | echo "Releasing requires npm >= 3. Aborting."; 25 | exit 1; 26 | fi; 27 | 28 | if [ -n "$(git status --porcelain)" ]; then 29 | echo "Your git status is not clean. Aborting."; 30 | exit 1; 31 | fi 32 | 33 | # Force dedupe 34 | npm dedupe 35 | 36 | # Don't bundle fsevents because it is optional and OS X-only 37 | # Since it's in optionalDependencies, it will attempt install outside bundle 38 | rm -rf node_modules/fsevents 39 | 40 | # This modifies package.json to copy all dependencies to bundledDependencies 41 | # We will revert package.json back after release to avoid doing it every time 42 | node ./node_modules/.bin/bundle-deps 43 | 44 | # Go! 45 | npm publish "$@" 46 | 47 | # Discard changes to package.json 48 | git checkout -- . 49 | -------------------------------------------------------------------------------- /template/README.md: -------------------------------------------------------------------------------- 1 | Below you will find some information on how to perform common tasks. 2 | You can find the most recent version of this guide [here](https://github.com/facebookincubator/create-react-app/blob/master/template/README.md). 3 | 4 | ## Sending Feedback 5 | 6 | We are always open to [your feedback](https://github.com/facebookincubator/create-react-app/issues). 7 | 8 | ## Folder Structure 9 | 10 | After creation, you project should look like this: 11 | 12 | ``` 13 | my-app/ 14 | README.md 15 | index.html 16 | favicon.ico 17 | node_modules/ 18 | package.json 19 | src/ 20 | App.css 21 | App.js 22 | index.css 23 | index.js 24 | logo.svg 25 | ``` 26 | 27 | For the project to build, **these files must exist with exact filenames**: 28 | 29 | * `index.html` is the page template; 30 | * `favicon.ico` is the icon you see in the browser tab; 31 | * `src/index.js` is the JavaScript entry point. 32 | 33 | You can delete or rename the other files. 34 | 35 | You may create subdirectories inside `src`. For faster rebuilds, only files inside `src` are processed by Webpack. 36 | You need to **put any JS and CSS files inside `src`**, or Webpack won’t see them. 37 | 38 | You can, however, create more top-level directories. 39 | They will not be included in the production build so you can use them for things like documentation. 40 | 41 | ## Available Scripts 42 | 43 | In the project directory, you can run: 44 | 45 | ### `npm start` 46 | 47 | Runs the app in the development mode.
48 | Open [http://localhost:3000](http://localhost:3000) to view it in the browser. 49 | 50 | The page will reload if you make edits.
51 | You will also see any lint errors in the console. 52 | 53 | ### `npm run build` 54 | 55 | Builds the app for production to the `build` folder.
56 | It correctly bundles React in production mode and optimizes the build for the best performance. 57 | 58 | The build is minified and the filenames include the hashes.
59 | Your app is ready to be deployed! 60 | 61 | ### `npm run eject` 62 | 63 | **Note: this is a one-way operation. Once you `eject`, you can’t go back!** 64 | 65 | If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project. 66 | 67 | Instead, it will copy all the configuration files and the transient dependencies (Webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own. 68 | 69 | 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. 70 | 71 | ## How To... 72 | 73 | ### Import a Component 74 | 75 | This project setup supports ES6 modules thanks to Babel. 76 | While you can still use `require()` and `module.exports`, we encourage you to use [`import` and `export`](http://exploringjs.com/es6/ch_modules.html) instead. 77 | 78 | For example: 79 | 80 | ### `Button.js` 81 | 82 | ```js 83 | import React, { Component } from 'react'; 84 | 85 | class Button extends Component { 86 | render() { 87 | // ... 88 | } 89 | } 90 | 91 | export default Button; // Don’t forget to use export default! 92 | ``` 93 | 94 | ### `DangerButton.js` 95 | 96 | ```js 97 | import React, { Component } from 'react'; 98 | import Button from './Button'; // Import a component from another file 99 | 100 | class DangerButton extends Component { 101 | render() { 102 | return