├── .gitignore ├── LICENSE ├── README.md ├── lerna.json ├── package.json ├── packages ├── create-react-scripts-babelrc │ ├── README.md │ ├── index.js │ └── package.json ├── create-react-scripts-dll │ ├── README.md │ ├── index.js │ ├── package.json │ └── yarn.lock ├── create-react-scripts-eslintrc │ ├── README.md │ ├── index.js │ └── package.json ├── create-react-scripts-graphql │ ├── README.md │ ├── index.js │ └── package.json ├── create-react-scripts-less │ ├── README.md │ ├── index.js │ ├── package.json │ └── yarn.lock ├── create-react-scripts-sass │ ├── README.md │ ├── index.js │ ├── package.json │ └── yarn.lock ├── create-react-scripts-ssr │ ├── README.md │ ├── config │ │ └── webpack.config.server.js │ ├── index.js │ ├── package.json │ ├── scripts │ │ ├── build-server.js │ │ └── start-server.js │ └── utils │ │ └── webpackHotDevClient.js ├── create-react-scripts-utils │ ├── README.md │ ├── getBabelLoader.js │ ├── getCssLoader.js │ ├── getEslintLoader.js │ ├── getFileLoader.js │ ├── getLoader.js │ ├── getUrlLoader.js │ ├── index.js │ └── package.json ├── create-react-scripts-workbox │ ├── README.md │ ├── index.js │ └── package.json ├── create-react-scripts │ ├── README.md │ ├── bin │ │ └── create-react-scripts.js │ ├── compose.js │ ├── index.js │ ├── package.json │ ├── rewire.js │ ├── scripts │ │ ├── build.js │ │ ├── start.js │ │ └── test.js │ └── yarn.lock ├── example-universal-react-app │ ├── .gitignore │ ├── README.md │ ├── README.old.md │ ├── crs.config.js │ ├── package.json │ ├── public │ │ ├── favicon.ico │ │ ├── manifest.json │ │ ├── offline.html │ │ └── workbox-sw.js │ ├── src │ │ ├── App.css │ │ ├── App.js │ │ ├── App.test.js │ │ ├── index.css │ │ ├── index.js │ │ ├── logo.svg │ │ ├── registerServiceWorker.js │ │ └── server.js │ └── yarn.lock └── react-scripts-web │ ├── README.md │ ├── bin │ └── react-scripts.js │ ├── crs.config.js │ └── package.json └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | .vscode/ 3 | node_modules/ 4 | build 5 | .DS_Store 6 | *.tgz 7 | lerna-debug.log 8 | npm-debug.log* 9 | yarn-debug.log* 10 | yarn-error.log* 11 | /.changelog -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Sze Ka Wai Raymond 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Deprecated 2 | I am sorry that this project is not in active development and no plan to support react-scripts 2.0. 3 | 4 | The main purpose I created this project is to easily extend the cra configuration to support the server-side-rendering. 5 | Recently, I have moved all my private projects to nextJs that no longer depend on react-scripts anymore. 6 | 7 | I would welcome if anyone who are interested to take over this project. 8 | 9 | To support react-scripts 2.0, there are some promising libraries there. 10 | 11 | https://github.com/rescripts/rescripts 12 | 13 | https://github.com/sharegate/craco 14 | 15 | ----------------- 16 | # Create React Scripts 17 | ----------------- 18 | If you are faimilar with React, you must have heard of [create-react-app](https://github.com/facebookincubator/create-react-app) announced by Facebook. 19 | create-react-app is great, you don't have to worry about the babel and webpack configuration before you start learning React. Its a good tool for React beginner. 20 | 21 | How about experienced user? Is create-react-app still good? Yes and No. All the configuration are hidden by `create-react-app`. Configurations are put inside the sub package called `react-scripts`. How can we modify the configuration hidden by `create-react-app`. 22 | 23 | ## 1. Eject 24 | `create-react-app` provides an official way to do that, which is `react-scripts eject`. By doing this way, it means that you cannot enjoy any benefit `create-react-app` will provide in the future. You have to maintain the configuration yourself and you may need to keep track of the updates from create-react-app. 25 | 26 | ## 2. Fork 27 | Another way to extend the configuration is using a Fork of `create-react-app`. By doing this way, its just better, it would be *easier* to keep track of the updates from `create-react-app`. But... you still need to maintain the fork repository yourself. Is it worth to maintain the whole repository if you only need some modification on the configuration like *sass* and *less* supports? 28 | 29 | ## 3. React App Rewired 30 | [react-app-rewired](https://github.com/timarney/react-app-rewired) is a moudle that you can easily extends the webpack and babel configuration by using `config.override.js`. But the `config.override.js` must be along with your project, and it is hard to share your configuration to your teammates as you cannot publish the modification into another version of `react-script`. 31 | 32 | ## 4. Roll Your Own Boilerplate 33 | If you choose this way, then you don't even need create-react-app. But as a experienced user, setup webpack and babel configuration is a time consuming tasks. create-react-app is an official tool, I believe the choice she taken is good reference. Usually we only want to extend the configuration instead of completely rewrite. 34 | 35 | ## 5. Create React Scripts 36 | I believe there are **No Perfect Configurations Unless You Create Your Own**. 37 | This module helps you **easily extend the `react-scripts` to your own version of `react-scripts`**. 38 | 39 | # Features 40 | ----------------- 41 | + **Easy to create your own `react-scripts` by just a simple configuration** 42 | + **Support similar way like what `react-app-rewired` did to modify the configuration** 43 | + **Able to customize script like building script `build:server` and `start:server` to support universal rendering** 44 | + **Composable react-scripts** 45 | 46 | # How it works? 47 | ---------------- 48 | This module make use of **require.cache**, the following modules are replaced. 49 | Use this module at **Your Own Risk**. 50 | 51 | This method would be broken if the implementaion or location of following files changed. 52 | + react-scripts/config/paths.js 53 | + react-scripts/config/env.js 54 | + react-scripts/config/webpack.config.dev.js 55 | + react-scripts/config/webpack.config.prod.js 56 | + react-scripts/config/webpackDevServer.config.js 57 | + react-scripts/scripts/util/createJestConfig.js 58 | 59 | All the above are pre-required and the require.cache got replaced according to your setting in `crs.config.js`. 60 | 61 | To understand more, you can see the rewire [source code](https://github.com/raymondsze/create-react-scripts/blob/master/packages/create-react-scripts/rewire.js) here. 62 | 63 | # Installation 64 | ----------------- 65 | `npm i -D react-scripts create-react-scripts` or `yarn add --dev react-scripts create-react-scripts` 66 | 67 | # How to use? 68 | ----------------- 69 | #### Option 1: Create your own react-scripts 70 | ##### Create a new node project 71 | use `npm init` or `yarn init` 72 | ##### Modify package.json 73 | Assume your script name is **custom-react-scripts** 74 | ```diff 75 | // package.json 76 | { 77 | "name": "custom-react-scripts", 78 | + "bin": { 79 | + custom-recat-scripts: "./bin/custom-react-scripts.js" 80 | + } 81 | + "main": "./crs.config.js" 82 | ... 83 | } 84 | ``` 85 | ##### Add bin/custom-react-scripts.js 86 | Create file `bin/custom-react-scripts.js` with following content 87 | ```js 88 | // /bin/custom-react-scripts.js 89 | const path = require('path'); 90 | 91 | // here we need to tell create-react-scripts whild folder to lookup crs.config.js 92 | require('create-react-scripts')(path.join(__dirname, '..')); 93 | ``` 94 | ##### Add crs.config.js 95 | Create file `crs.config.js` with following content 96 | ```js 97 | // /crs-config.js 98 | // The rewire procedule follow this life cycle 99 | // NODE_ENV==='development' env --> paths --> webpack --> devServer 100 | // NODE_ENV==='production' env --> paths --> webpack 101 | // NODE_ENV==='test' env --> paths --> jest 102 | 103 | module.exports = { 104 | // Optional: Rewire the env 105 | // the env is the return result of getClientEnvironment from 'react-script/config/env.js' 106 | env(env, NODE_ENV, argv) { 107 | // modify env here... 108 | return env; 109 | }, 110 | // Optional: Rewire the paths 111 | // the paths is from 'react-script/config/paths.js' 112 | paths(paths, NODE_ENV, argv) { 113 | // you can get the rewired env from 'this.env' 114 | // modify paths here... 115 | return paths; 116 | }, 117 | // Optional: Rewire the webpack.config 118 | // if NODE_ENV === 'production' 119 | // the webpack config is from 'react-script/config/webpack.config.prod.js' 120 | // if NODE_ENV === 'development' 121 | // the webpack config is from 'react-script/config/webpack.config.dev.js' 122 | webpack(webpackConfig, NODE_ENV, argv) { 123 | // you can get the rewired env from 'this.env' 124 | // you can get the rewired paths from 'this.paths' 125 | // modify webpackConfig here... 126 | return webpackConfig; 127 | }, 128 | // Optional: Rewire the webpackDevServer.config 129 | // the devServer is the return result of 'react-script/config/webpackDevServer.config.js' 130 | devServer: (webpackDevServerConfig, NODE_ENV, argv) { 131 | // you can get the rewired env from 'this.env' 132 | // you can get the rewired paths from 'this.paths' 133 | // you can get the rewired webpackConfig from 'this.webpack' 134 | // modify webpackDevServerConfig here... 135 | return webpackConfig; 136 | }, 137 | // Optional: Rewire the jest configuration 138 | // the jestConfig is the return result of 'react-script/scripts/utils/createJestConfig.js' 139 | jest(jestConfig, NODE_ENV, argv) { 140 | // you can get the rewired env from 'this.env' 141 | // you can get the rewired paths from 'this.paths' 142 | // modify jestConfig here... 143 | return jestConfig; 144 | }, 145 | // Optional: Add custom scripts 146 | scripts: { 147 | // you can add custom scripts here, for example 148 | // "start:server": path.join(__dirname, 'scripts/start-server.js') 149 | }, 150 | }; 151 | ``` 152 | ##### Publish 153 | Choose either one 154 | 1. Publish your `custom-react-scripts` using `npm publish` 155 | 2. make use of [`lerna`](https://github.com/lerna) to connect pacakges. 156 | 157 | ##### Change package.json of your project 158 | Modify pacakge.json to use `custom-react-scripts` instead of `react-scripts` 159 | ```diff 160 | // package.json of your react app 161 | { 162 | - "start": "react-scripts start", 163 | + "start": "custom-react-scripts start", 164 | - "build": "react-scripts build", 165 | + "build": "custom-react-scripts build", 166 | - "test": "react-scripts test --env=jsdom", 167 | + "test": "custom-react-scripts test --env=jsdom" 168 | } 169 | ``` 170 | #### Option 2: Customize configuration directly into your project. 171 | ##### Change package.json of your project 172 | Modify pacakge.json to use `custom-react-scripts` instead of `create-react-scripts` 173 | ```diff 174 | // package.json of your react app 175 | { 176 | - "start": "react-scripts start", 177 | + "start": "create-react-scripts start", 178 | - "build": "react-scripts build", 179 | + "build": "create-react-scripts build", 180 | - "test": "react-scripts test --env=jsdom", 181 | + "test": "create-react-scripts test --env=jsdom" 182 | } 183 | ``` 184 | ##### Add crs.config.js 185 | Create file `crs.config.js` like what we did in **Option1**. 186 | 187 | #### Option 3: Mix Option 1 and Option 2 188 | Modify pacakge.json to use `custom-react-scripts` instead of `create-react-scripts` 189 | ```diff 190 | // package.json of your react app 191 | { 192 | - "start": "react-scripts start", 193 | + "start": "create-react-scripts start", 194 | - "build": "react-scripts build", 195 | + "build": "create-react-scripts build", 196 | - "test": "react-scripts test --env=jsdom", 197 | + "test": "create-react-scripts test --env=jsdom" 198 | } 199 | ``` 200 | ##### Add crs.config.js 201 | Remember what we did in **Option1**'s package.json `"main": "./crs.config.js"` 202 | Now we can extend our `custom-react-scripts` in Option1. 203 | Create file `crs.config.js` with following content 204 | ```js 205 | // compose is a helper to merge multiple crs.config into one 206 | const { compose } = require('create-react-scripts'); 207 | module.exports = compose( 208 | // extend from custom-react-scripts 209 | require('custom-react-scripts'), 210 | { 211 | // Optional: Rewire the env 212 | // the env is the return result of getClientEnvironment from 'react-script/config/env.js' 213 | env(env, NODE_ENV, argv) { 214 | // modify env here... 215 | return env; 216 | }, 217 | // Optional: Rewire the paths 218 | // the paths is from 'react-script/config/paths.js' 219 | paths(paths, NODE_ENV, argv) { 220 | // you can get the rewired env from 'this.env' 221 | // modify paths here... 222 | return paths; 223 | }, 224 | // Optional: Rewire the webpack.config 225 | // if NODE_ENV === 'production' 226 | // the webpack config is from 'react-script/config/webpack.config.prod.js' 227 | // if NODE_ENV === 'development' 228 | // the webpack config is from 'react-script/config/webpack.config.dev.js' 229 | webpack(webpackConfig, NODE_ENV, argv) { 230 | // you can get the rewired env from 'this.env' 231 | // you can get the rewired paths from 'this.paths' 232 | // modify webpackConfig here... 233 | return webpackConfig; 234 | }, 235 | // Optional: Rewire the webpackDevServer.config 236 | // the devServer is the return result of 'react-script/config/webpackDevServer.config.js' 237 | devServer: (webpackDevServerConfig, NODE_ENV, argv) { 238 | // you can get the rewired env from 'this.env' 239 | // you can get the rewired paths from 'this.paths' 240 | // you can get the rewired webpackConfig from 'this.webpack' 241 | // modify webpackDevServerConfig here... 242 | return webpackConfig; 243 | }, 244 | // Optional: Rewire the jest configuration 245 | // the jestConfig is the return result of 'react-script/scripts/utils/createJestConfig.js' 246 | jest(jestConfig, NODE_ENV, argv) { 247 | // you can get the rewired env from 'this.env' 248 | // you can get the rewired paths from 'this.paths' 249 | // modify jestConfig here... 250 | return jestConfig; 251 | }, 252 | // Optional: Add custom scripts 253 | scripts: { 254 | // you can add custom scripts here, for example 255 | // "start:server": path.join(__dirname, 'scripts/start-server.js') 256 | }, 257 | } 258 | ); 259 | ``` 260 | 261 | # API 262 | -------------------------------- 263 | #### crs-config.js 264 | Rewire Target 265 | + [env](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/config/env.js) : The return result of *getClientEnvironment* of **react-scripts/config/env** 266 | + [paths](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/config/paths.js): The module.exports of **react-scripts/config/paths** 267 | + [webpack](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/config/webpack.config.dev.js): (NODE_ENV: development) The module.exports of **react-scripts/config/webpack.config.dev.js** 268 | + [webpack](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/config/webpack.config.prod.js): (NODE_ENV: production) The module.exports of **react-scripts/config/webpack.config.prod.js** 269 | + [devServer](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/config/webpackDevServer.config.js): The return result of module.exports of **react-scripts/config/webpackDevServer.config.js** 270 | + [jest](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/scripts/utils/createJestConfig.js): The return result of module.exports of **react-scripts/scripts/utils/createJestConfig.js** 271 | 272 | ### compose 273 | You can compose multiple crs-config together to a single crs-config. 274 | ```js 275 | const { compose } = require('create-react-scripts') 276 | const crsConfig1 = require('./crsConfig1'); 277 | const crsConfig2 = require('./crsConfig2'); 278 | .... 279 | const crsConfigN = require('./crsConfigN'); 280 | 281 | module.exports = compose(crsConfig1, crsConfig2, ..., crsConfigN); 282 | ``` 283 | 284 | ### rewire() 285 | ##### return: { env, paths, webpack, devServer, jest } 286 | + **env**: rewired createClientEnvironment function 287 | + **paths**: rewired paths 288 | + **webpack**: rewired webpackConfig 289 | + **devServer**: rewired createWebpackDevServerConfig function 290 | + **jest**: rewired createJestConfig function 291 | 292 | You can use the rewire function to obtain the rewired result. 293 | This function is useful for creating custom script. 294 | Example: 295 | **react-scripts-ssr/scripts/start-server.js** [[source](https://github.com/raymondsze/create-react-scripts/blob/master/packages/create-react-scripts-ssr/scripts/start-server.js)] 296 | **react-scripts-ssr/scripts/build-server.js** [[source](https://github.com/raymondsze/create-react-scripts/blob/master/packages/create-react-scripts-ssr/scripts/build-server.js)] 297 | ```js 298 | const { compose } = require('create-react-scripts') 299 | const crsConfig1 = require('./crsConfig1'); 300 | const crsConfig2 = require('./crsConfig2'); 301 | .... 302 | const crsConfigN = require('./crsConfigN'); 303 | 304 | module.exports = compose(crsConfig1, crsConfig2, ..., crsConfigN); 305 | ``` 306 | 307 | ----------------- 308 | # Why This Project Exists 309 | ----------------- 310 | #### Create React App - Zero Configuration? 311 | If you’re working with React, you’re probably familiar with the **create-react-app**. It’s an official command line interface for building React applications with **ZERO Configuration**. 312 | #### ZERO Configuration? How is it possible? 313 | **create-react-app** hides all the webpack configuration into a package **react-scripts**. 314 | With **create-react-app**, I can **enjoy all the configuration created by Facebook without any effort** and I don't need to configure myself. 315 | 316 | But... **you are not POSSIBLE to change the default configurations provided by Facebook create-react-app**. 317 | Facebook provided **2 options** to allow you to change the default configurations... 318 | 1. use the **eject** script, change the configuration. 319 | 2. **fork** the create-react-app, change and republish, keep the fork up-to-date. 320 | 321 | #### Eject or Fork? 322 | 1. **Eject** 323 | This is a one-way operation. Once you eject, you can’t go back! 324 | This command will remove the single build dependency from your project. 325 | So **you cannot enjoy any benefit or update from create-react-app in the future**. 326 | 327 | 2. **Fork** 328 | There are many fork versions of create-react-app. But normally **they only want some small changes to the configurations**... Why they need to **maintain a fork of create-react-app**? 329 | 330 | #### What most people want in create-react-app? 331 | 1. import sass support 332 | 2. import less support 333 | 3. server-side-rendering 334 | 4. vendor dll 335 | 5. .... 336 | 337 | However, all of them are postponed or even rejected **until the [Plugin System](https://github.com/facebookincubator/create-react-app/pull/2784) is supported by create-react-app.** 338 | But... **only plugin got approved by Facebook can be used**... 339 | >End-users (app developers) will only be able to use plugins which we approve and whitelist. 340 | Typically, this means it meets a set of criteria: 341 | 1.Use-case or functionality is popular 342 | 2.Adds value 343 | 3.Easy to maintain and underlying tools are stable 344 | 4.We have control to modify & publish updates to the package 345 | 346 | #### There are no perfect configurations unless you create your own 347 | I believe that **create-react-app is a good reference.** We just want to extend it to build our own react-scripts.... **Why I have to eject or fork?** 348 | 349 | #### react-app-rewired 350 | See the medium article https://medium.com/@timarney/but-i-dont-wanna-eject-3e3da5826e39 351 | This is a good tool that can just provide a **config.overrides.js** to modify the default configuration of **create-react-app**. 352 | But... 353 | The **config.overrides.js** must be along with your project... It is **not possible to create a custom version of react-scripts that could be shared with multiple projects**. 354 | 355 | #### How about create my own react-scripts based on create-react-app? 356 | This is why I created **create-react-scripts**. 357 | ##### create-react-scripts 358 | This package allow you to easily create your own 'react-scripts' based on 'react-scripts' package under create-react-app. 359 | 360 | 361 | ## Inspiration 362 | - [facebookincubator/create-react-app](https://github.com/facebookincubator/create-react-app) 363 | - [timarney/react-app-rewired](https://github.com/timarney/react-app-rewired) 364 | - [jaredpalmer/razzle](https://github.com/jaredpalmer/razzle) 365 | - [react-boilerplate/react-boilerplate](https://github.com/react-boilerplate/react-boilerplate) 366 | - [ctrlplusb/react-universally](https://github.com/ctrlplusb/react-universally) 367 | 368 | # Author 369 | ----------------- 370 | - [Raymond Sze](https://github.com/raymondsze) 371 | 372 | # License 373 | ----------------- 374 | MIT 375 | -------------------------------------------------------------------------------- /lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "lerna": "2.0.0-rc.5", 3 | "version": "independent", 4 | "packages": [ 5 | "packages/*" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "create-react-scripts", 3 | "version": "0.0.1", 4 | "private": true, 5 | "description": "Easily extend the react-scripts to your own version of react-scripts", 6 | "author": "Sze Ka Wai Raymond", 7 | "license": "MIT", 8 | "devDependencies": { 9 | "lerna": "^2.0.0-rc.5" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /packages/create-react-scripts-babelrc/README.md: -------------------------------------------------------------------------------- 1 | # create-react-scripts-babelrc 2 | ----------------- 3 | Mark **babelrc** option to true in [babel-loader](https://github.com/babel/babel-loader). 4 | This is very useful if you want to add some external babel feature into webpack build. 5 | 6 | Example Usage: 7 | ##### Modify crs.config 8 | Modify `crs.config` as below. 9 | ```js 10 | const { compose } = require('create-react-scripts'); 11 | module.exports = compose( 12 | ... 13 | require('create-react-scripts-babelrc')(), 14 | ); 15 | ``` 16 | 17 | ##### Create .babelrc 18 | Create `.babelrc` under your application folder 19 | For example, I want to enable `stage-0` and `decorator` supports. 20 | ``` 21 | { 22 | "presets": ["react-app", "stage-0"], 23 | "plugins": ["transform-decorators-legacy"] 24 | } 25 | ``` 26 | -------------------------------------------------------------------------------- /packages/create-react-scripts-babelrc/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const { getBabelLoader } = require('create-react-scripts-utils'); 4 | 5 | module.exports = options => ({ 6 | webpack(config, env) { 7 | // get the babel loader 8 | const loader = getBabelLoader(config); 9 | // obtain the options 10 | const options = loader.options || loader.query; 11 | // set the babelrc to true 12 | options.babelrc = true; 13 | return config; 14 | }, 15 | }); 16 | -------------------------------------------------------------------------------- /packages/create-react-scripts-babelrc/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "create-react-scripts-babelrc", 3 | "version": "0.1.4", 4 | "author": "Sze Ka Wai Raymond", 5 | "description": "Mark babelrc option to true to create-react-scripts", 6 | "license": "MIT", 7 | "repository": "raymondsze/create-react-scripts", 8 | "engines": { 9 | "node": ">=6" 10 | }, 11 | "files": [ 12 | "index.js" 13 | ], 14 | "bugs": { 15 | "url": "https://github.com/raymondsze/create-react-scripts/issues" 16 | }, 17 | "main": "index.js", 18 | "dependencies": { 19 | "create-react-scripts-utils": "^0.1.4" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /packages/create-react-scripts-dll/README.md: -------------------------------------------------------------------------------- 1 | # create-react-scripts-dll 2 | ----------------- 3 | Add [autodll-webpack-plugin](https://github.com/asfktz/autodll-webpack-plugin) support. 4 | This is useful to faster the webpack bundling time. 5 | Also, it make the code structing cleaner by separating the vendor related codes from your source codes. 6 | The pacakge specified in `vendor` section of `pacakge.json` would be bundled into `static/js/vendor:[hash:8].js`. 7 | 8 | ##### Modify crs.config 9 | Modify `crs.config` as below. 10 | ```js 11 | const { compose } = require('create-react-scripts') 12 | 13 | module.exports = compose( 14 | ... 15 | require('create-react-scripts-dll')(/* options passed to autodll-webpack-plugin */), 16 | ); 17 | ``` 18 | 19 | ##### Add vendor section to package.json 20 | Modify `package.json` under your application folder 21 | ```js 22 | { 23 | ... 24 | "vendor" [ 25 | "react", 26 | "react-dom" 27 | ] 28 | } 29 | ``` 30 | -------------------------------------------------------------------------------- /packages/create-react-scripts-dll/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | const webpack = require('webpack'); 5 | const AutoDllPlugin = require('autodll-webpack-plugin'); 6 | const AssetsPlugin = require('assets-webpack-plugin'); 7 | 8 | // Source maps are resource heavy and can cause out of memory issue for large source files. 9 | const shouldUseSourceMap = process.env.GENERATE_SOURCEMAP !== 'false'; 10 | 11 | module.exports = options => ({ 12 | webpack(config, env) { 13 | const appPackageJson = path.join(process.cwd(), 'package.json'); 14 | const vendor = require(appPackageJson).vendor || []; 15 | const dllPlugins = []; 16 | // uglify the vendor js if in production mode 17 | if (env === 'production') { 18 | dllPlugins.push(new webpack.optimize.UglifyJsPlugin({ 19 | compress: { 20 | warnings: false, 21 | comparisons: false, 22 | }, 23 | output: { 24 | comments: false, 25 | ascii_only: true, 26 | }, 27 | sourceMap: shouldUseSourceMap, 28 | })); 29 | } 30 | config.plugins.push( 31 | new AutoDllPlugin(Object.assign({ 32 | inject: true, 33 | filename: '[name].[hash:8].js', 34 | path: './static/js/', 35 | entry: { vendor }, 36 | plugins: dllPlugins, 37 | }, options)) 38 | ); 39 | return config; 40 | }, 41 | }); 42 | -------------------------------------------------------------------------------- /packages/create-react-scripts-dll/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "create-react-scripts-dll", 3 | "version": "0.1.5", 4 | "author": "Sze Ka Wai Raymond", 5 | "main": "index.js", 6 | "description": "Add auto-dll-webpack-plugin to create-react-scripts", 7 | "license": "MIT", 8 | "repository": "raymondsze/create-react-scripts", 9 | "engines": { 10 | "node": ">=6" 11 | }, 12 | "files": [ 13 | "index.js" 14 | ], 15 | "bugs": { 16 | "url": "https://github.com/raymondsze/create-react-scripts/issues" 17 | }, 18 | "dependencies": { 19 | "assets-webpack-plugin": "3.5.1", 20 | "autodll-webpack-plugin": "0.2.1", 21 | "webpack": "3.6.0", 22 | "webpack-dll-bundles-plugin": "^1.0.0-beta.5" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /packages/create-react-scripts-eslintrc/README.md: -------------------------------------------------------------------------------- 1 | # create-react-scripts-eslintrc 2 | ----------------- 3 | Mark **useEslintrc** option to true in [eslint-loader](https://github.com/MoOx/eslint-loader). 4 | This is very useful if you want to add some external eslint rules into webpack pre build. 5 | 6 | Example Usage: 7 | ##### Modify crs.config 8 | Modify `crs.config` as below. 9 | ```js 10 | const { compose } = require('create-react-scripts'); 11 | module.exports = compose( 12 | ... 13 | require('create-react-scripts-eslintrc')(), 14 | ); 15 | ``` 16 | 17 | ##### Create .eslintrc 18 | Create `.eslintrc` under your application folder 19 | For example, I want to use `airbnb` eslint styling. 20 | ``` 21 | { 22 | "parser": "babel-eslint", 23 | "extends": ["airbnb"] 24 | } 25 | ``` 26 | -------------------------------------------------------------------------------- /packages/create-react-scripts-eslintrc/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const { getEslintLoader } = require('create-react-scripts-utils'); 4 | 5 | module.exports = options => ({ 6 | webpack(config, env) { 7 | // get the eslint loader 8 | const loader = getEslintLoader(config); 9 | // obtain the options 10 | const options = loader.options || loader.query; 11 | // set the useEslintrc to true 12 | options.useEslintrc = true; 13 | return config; 14 | }, 15 | }); 16 | -------------------------------------------------------------------------------- /packages/create-react-scripts-eslintrc/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "create-react-scripts-eslintrc", 3 | "version": "0.1.4", 4 | "author": "Sze Ka Wai Raymond", 5 | "main": "index.js", 6 | "description": "Mark useEslintrc option to true to create-react-scripts", 7 | "license": "MIT", 8 | "repository": "raymondsze/create-react-scripts", 9 | "engines": { 10 | "node": ">=6" 11 | }, 12 | "files": [ 13 | "index.js" 14 | ], 15 | "bugs": { 16 | "url": "https://github.com/raymondsze/create-react-scripts/issues" 17 | }, 18 | "dependencies": { 19 | "create-react-scripts-utils": "^0.1.4" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /packages/create-react-scripts-graphql/README.md: -------------------------------------------------------------------------------- 1 | # create-react-scripts-graphql 2 | ----------------- 3 | This is useful if you use Apollo and you want to enable `.graphql/.gql` extension support. 4 | Add [graphql-tag/loader](https://github.com/apollographql/graphql-tag) support. 5 | Add [jest-transform-graphql](https://github.com/remind101/jest-transform-graphql) support. 6 | 7 | Example Usage: 8 | ##### Modify crs.config 9 | Modify `crs.config` as below. 10 | ```js 11 | const { compose } = require('create-react-scripts'); 12 | module.exports = compose( 13 | ... 14 | require('create-react-scripts-graphql')(/* options provided to graphql-tag/loader */), 15 | ); 16 | ``` -------------------------------------------------------------------------------- /packages/create-react-scripts-graphql/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const fs = require('fs'); 4 | const path = require('path'); 5 | const { getFileLoader } = require('create-react-scripts-utils'); 6 | 7 | module.exports = options => ({ 8 | webpack(config, env) { 9 | const fileLoader = getFileLoader(config); 10 | fileLoader.exclude.push(/\.(graphql|gql)$/); 11 | 12 | const graphqlRules = { 13 | test: /\.(graphql|gql)$/, 14 | exclude: /node_modules/, 15 | loader: require.resolve('graphql-tag/loader'), 16 | options: options, 17 | }; 18 | config.module.rules.push(graphqlRules); 19 | 20 | return config; 21 | }, 22 | jest(config, env) { 23 | config.transform = Object.assign(config.transform, { 24 | '\\.(gql|graphql)$': require.resolve('jest-transform-graphql'), 25 | }); 26 | return config; 27 | }, 28 | }); 29 | -------------------------------------------------------------------------------- /packages/create-react-scripts-graphql/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "create-react-scripts-graphql", 3 | "version": "0.1.5", 4 | "author": "Sze Ka Wai Raymond", 5 | "main": "index.js", 6 | "description": "Enable graphql-loader to create-react-scripts", 7 | "license": "MIT", 8 | "repository": "raymondsze/create-react-scripts", 9 | "engines": { 10 | "node": ">=6" 11 | }, 12 | "files": [ 13 | "index.js" 14 | ], 15 | "bugs": { 16 | "url": "https://github.com/raymondsze/create-react-scripts/issues" 17 | }, 18 | "dependencies": { 19 | "create-react-scripts-utils": "^0.1.4", 20 | "graphql": "0.10.5", 21 | "graphql-tag": "2.4.2", 22 | "jest-transform-graphql": "2.1.0" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /packages/create-react-scripts-less/README.md: -------------------------------------------------------------------------------- 1 | # create-react-scripts-less 2 | ----------------- 3 | Add [less-loader](https://github.com/webpack-contrib/less-loader) support. 4 | 5 | Example Usage: 6 | ##### Modify crs.config 7 | Modify `crs.config` as below. 8 | ```js 9 | const { compose } = require('create-react-scripts') 10 | 11 | module.exports = compose( 12 | require('create-react-scripts-less')(/* options passed to less-loader*/), 13 | ... 14 | ); 15 | ``` -------------------------------------------------------------------------------- /packages/create-react-scripts-less/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | const { getCssLoader, getFileLoader } = require('create-react-scripts-utils'); 5 | 6 | module.exports = options => ({ 7 | webpack(config, env) { 8 | const fileLoader = getFileLoader(config); 9 | fileLoader.exclude.push(/\.less$/); 10 | 11 | const cssRules = getCssLoader(config); 12 | let lessRules; 13 | if (env === 'production') { 14 | lessRules = { 15 | test: /\.less$/, 16 | loader: [].concat( 17 | cssRules.loader 18 | ).concat( 19 | [{ 20 | loader: require.resolve('less-loader'), 21 | options, 22 | }] 23 | ).filter(l => l) 24 | }; 25 | } else { 26 | lessRules = { 27 | test: /\.less$/, 28 | use: [].concat( 29 | cssRules.use 30 | ).concat( 31 | [{ 32 | loader: require.resolve('less-loader'), 33 | options, 34 | }] 35 | ).filter(l => l) 36 | }; 37 | } 38 | config.module.rules.push(lessRules); 39 | return config; 40 | }, 41 | }); 42 | -------------------------------------------------------------------------------- /packages/create-react-scripts-less/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "create-react-scripts-less", 3 | "version": "0.1.5", 4 | "author": "Sze Ka Wai Raymond", 5 | "main": "index.js", 6 | "description": "Enable less-loader to create-react-scripts", 7 | "license": "MIT", 8 | "repository": "raymondsze/create-react-scripts", 9 | "engines": { 10 | "node": ">=6" 11 | }, 12 | "files": [ 13 | "index.js" 14 | ], 15 | "bugs": { 16 | "url": "https://github.com/raymondsze/create-react-scripts/issues" 17 | }, 18 | "dependencies": { 19 | "create-react-scripts-utils": "^0.1.4", 20 | "less": "2.7.2", 21 | "less-loader": "4.0.5" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /packages/create-react-scripts-sass/README.md: -------------------------------------------------------------------------------- 1 | # create-react-scripts-sass 2 | ----------------- 3 | Add [sass-loader](https://github.com/webpack-contrib/sass-loader) support. 4 | 5 | Example Usage: 6 | ##### Modify crs.config 7 | Modify `crs.config` as below. 8 | ```js 9 | const { compose } = require('create-react-scripts') 10 | 11 | module.exports = compose( 12 | require('create-react-scripts-sass')(/* options passed to sass-loader*/), 13 | ... 14 | ); 15 | ``` -------------------------------------------------------------------------------- /packages/create-react-scripts-sass/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | const { getCssLoader, getFileLoader } = require('create-react-scripts-utils'); 5 | 6 | module.exports = options => ({ 7 | webpack(config, env) { 8 | const fileLoader = getFileLoader(config); 9 | fileLoader.exclude.push(/\.scss$/); 10 | 11 | const cssRules = getCssLoader(config); 12 | let sassRules; 13 | if (env === 'production') { 14 | sassRules = { 15 | test: /\.scss$/, 16 | loader: [].concat( 17 | cssRules.loader 18 | ).concat( 19 | [{ 20 | loader: require.resolve('sass-loader'), 21 | options, 22 | }] 23 | ).filter(l => l) 24 | }; 25 | } else { 26 | sassRules = { 27 | test: /\.scss$/, 28 | use: [].concat( 29 | cssRules.use 30 | ).concat( 31 | [{ 32 | loader: require.resolve('sass-loader'), 33 | options, 34 | }] 35 | ).filter(l => l) 36 | }; 37 | } 38 | config.module.rules.push(sassRules); 39 | return config; 40 | }, 41 | }); 42 | -------------------------------------------------------------------------------- /packages/create-react-scripts-sass/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "create-react-scripts-sass", 3 | "version": "0.1.5", 4 | "author": "Sze Ka Wai Raymond", 5 | "main": "index.js", 6 | "description": "Enable sass-loader to create-react-scripts", 7 | "license": "MIT", 8 | "repository": "raymondsze/create-react-scripts", 9 | "engines": { 10 | "node": ">=6" 11 | }, 12 | "files": [ 13 | "index.js" 14 | ], 15 | "bugs": { 16 | "url": "https://github.com/raymondsze/create-react-scripts/issues" 17 | }, 18 | "dependencies": { 19 | "create-react-scripts-utils": "^0.1.4", 20 | "node-sass": "4.5.3", 21 | "sass-loader": "6.0.6" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /packages/create-react-scripts-ssr/README.md: -------------------------------------------------------------------------------- 1 | # create-react-scripts-ssr 2 | ----------------- 3 | This module is useful if you want to make an universal app. 4 | 5 | # Important Note 6 | ----------------- 7 | + This Module **does not automate the Server-Side-Rendeirng.** 8 | + It just **make you able to require files that without js or json extensions in server side.** 9 | + The **index.html** is no longer necessary in universal app, and it could be cached by service-worker accidentally with default setting of create-react-app. 10 | This module will detect if **index-static.html** exists instead of **index.html** to apply HTML related webpack plugins. 11 | The generated html would also be **index-static.html** 12 | 13 | # Scripts 14 | ----------------- 15 | ### start:server 16 | start the both `client side bundling` and `server side bundling` webpack tasks in development mode. 17 | The server will auto reload if code changes. 18 | By default, **webpack-dev-server is running on port: 3001** while the **server is running on 3000**. 19 | The following environment variables are injected to `server side bundling` 20 | 21 | `HOST`: The host that the server should be running on. 22 | `PORT`: The port number that the server should be running on. 23 | `PROTOCOL`: The protocol that the server should be running on. 24 | `PUBLIC_URL`: The absolute url that the webpack-dev-server is running. 25 | 26 | **All client side log would be supressed in the console.** 27 | The client build is located in `build/client` 28 | The server build is located in `build/server` 29 | An assets json manifest is located in `build/assets.json`, which is useful for server-side-rendering. 30 | If autodll plugin is detected, an assets json manifest is located in `build/dll-assets.json`, which is useful for server-side-rendering. 31 | This script will start the `webpack-dev-server` and the `server.js` 32 | 33 | ### build:server 34 | trigger both `client side` and `server side` webpack tasks build. 35 | An assets json manifest is located in `build/assets.json`, which is useful for server-side-rendering. 36 | You can start the server by `node build/server` after build. 37 | 38 | # How it works? 39 | ---------------- 40 | Webpack bundle both different environment, the client side and the server side. 41 | Make use of [assets-webpack-plugin](https://github.com/kossnocorp/assets-webpack-plugin) to produce assets mapping so that server side can know the filename produced in client side build. 42 | 43 | # Usage 44 | --------------- 45 | ##### Modify crs.config 46 | Modify `crs.config` as below. 47 | ```js 48 | const { compose } = require('create-react-scripts') 49 | 50 | module.exports = compose( 51 | require('create-react-scripts-ssr')(), 52 | ... 53 | ); 54 | ``` 55 | 56 | ##### Modify package.json 57 | Modify `package.json` as below. 58 | ```diff 59 | { 60 | - "start": "react-scripts start", 61 | + "start": "create-react-scripts start", 62 | + "start:server": "create-react-scripts start:server", 63 | - "build": "react-scripts build", 64 | + "build": "create-react-scripts build", 65 | + "build:server": "create-react-scripts build:server", 66 | - "test": "react-scripts test --env=jsdom", 67 | + "test": "create-react-scripts test --env=jsdom" 68 | } 69 | ``` 70 | ##### Add Server.js 71 | Create `server.js` under `src` directory 72 | ```js 73 | import React from 'react'; 74 | import HTMLDocument from 'react-html-document'; 75 | import ReactDOMServer from 'react-dom/server'; 76 | import express from 'express'; 77 | import url from 'url'; 78 | import serveStatic from 'serve-static'; 79 | import path from 'path'; 80 | import fs from 'fs'; 81 | import App from './App'; 82 | 83 | // To obtain the actual HOST, PORT, and PROTOCOL 84 | const HOST = process.env.HOST || '0.0.0.0'; 85 | const PORT = parseInt(process.env.PORT, 10) || 5000; 86 | const PROTOCOL = process.env.PROTOCOL || 'http'; 87 | 88 | // Assets manifest path from client-side dll build (if create-react-scripts-dll is using) 89 | const DLL_ASSETS_PATH = path.join(process.cwd(), 'build/dll-assets.json'); 90 | // Assets manifest path from client-side build 91 | const ASSETS_PATH = path.join(process.cwd(), 'build/assets.json'); 92 | 93 | // Wait until client-side bundling finished so that assets.json is produced 94 | console.log('Waiting client-side bundling...'); 95 | while (!fs.existsSync(ASSETS_PATH)); 96 | 97 | // Read the assets 98 | const assets = { 99 | // make sure dll assets before the assets of client-side build 100 | // ensure browser require the vendor module first 101 | ...JSON.parse(fs.readFileSync(DLL_ASSETS_PATH)), 102 | ...JSON.parse(fs.readFileSync(ASSETS_PATH)), 103 | }; 104 | 105 | const app = express(); 106 | // in production, the serving files are under build/client folder 107 | if (process.env.NODE_ENV === 'production') { 108 | app.use(serveStatic(path.join(process.cwd(), 'build/client'), { index: false })); 109 | } 110 | 111 | // render the app 112 | app.get('*', async (req, res) => { 113 | // you may have some data prefetching logic here 114 | // ... 115 | res.set('content-type', 'text/html').send( 116 | ReactDOMServer.renderToStaticMarkup( 117 | 118 | 119 | 120 | 124 | 125 | 126 | 127 | React App 128 | { 129 | Object.values(assets).map(mod => mod.css ? ( 130 | 131 | ) : null) 132 | } 133 | 134 | 135 |
), 139 | }} 140 | /> 141 | { 142 | Object.values(assets).map(mod => mod.js ? ( 143 |