From 76cd9ea32b80b8e6c49e7fe5597e8cc5e0e1dfa7 Mon Sep 17 00:00:00 2001
From: Shriyans <shriyansbhatnagar@gmail.com>
Date: Sun, 21 May 2017 23:41:50 +0900
Subject: [PATCH 1/4] added vendor to paths

---
 packages/react-scripts/config/paths.js | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/packages/react-scripts/config/paths.js b/packages/react-scripts/config/paths.js
index 42ec8374a..5934e73fa 100644
--- a/packages/react-scripts/config/paths.js
+++ b/packages/react-scripts/config/paths.js
@@ -55,6 +55,7 @@ module.exports = {
   appPublic: resolveApp('public'),
   appHtml: resolveApp('public/index.html'),
   appIndexJs: resolveApp('src/index.js'),
+  appVendorJs: resolveApp('src/vendor.js'),
   appPackageJson: resolveApp('package.json'),
   appSrc: resolveApp('src'),
   yarnLockFile: resolveApp('yarn.lock'),
@@ -75,6 +76,7 @@ module.exports = {
   appPublic: resolveApp('public'),
   appHtml: resolveApp('public/index.html'),
   appIndexJs: resolveApp('src/index.js'),
+  appVendorJs: resolveApp('src/vendor.js'),
   appPackageJson: resolveApp('package.json'),
   appSrc: resolveApp('src'),
   yarnLockFile: resolveApp('yarn.lock'),
@@ -104,6 +106,7 @@ if (
     appPublic: resolveOwn('template/public'),
     appHtml: resolveOwn('template/public/index.html'),
     appIndexJs: resolveOwn('template/src/index.js'),
+    appVendorJs: resolveOwn('template/src/vendor.js'),
     appPackageJson: resolveOwn('package.json'),
     appSrc: resolveOwn('template/src'),
     yarnLockFile: resolveOwn('template/yarn.lock'),
-- 
GitLab


From fa83243da061b3414b1df0e1ac4160483ce48d65 Mon Sep 17 00:00:00 2001
From: Shriyans <shriyansbhatnagar@gmail.com>
Date: Sun, 21 May 2017 23:56:14 +0900
Subject: [PATCH 2/4] added support for vendor bundling

---
 .../config/webpack.config.prod.js             | 29 +++++++++++++++++--
 packages/react-scripts/package.json           |  1 +
 2 files changed, 28 insertions(+), 2 deletions(-)

diff --git a/packages/react-scripts/config/webpack.config.prod.js b/packages/react-scripts/config/webpack.config.prod.js
index 3de2775e0..37a795eb4 100644
--- a/packages/react-scripts/config/webpack.config.prod.js
+++ b/packages/react-scripts/config/webpack.config.prod.js
@@ -12,7 +12,9 @@
 
 const autoprefixer = require('autoprefixer');
 const path = require('path');
+const fs = require('fs');
 const webpack = require('webpack');
+const WebpackMd5Hash = require('webpack-md5-hash');
 const HtmlWebpackPlugin = require('html-webpack-plugin');
 const ExtractTextPlugin = require('extract-text-webpack-plugin');
 const ManifestPlugin = require('webpack-manifest-plugin');
@@ -53,6 +55,18 @@ const extractTextPluginOptions = shouldUseRelativeAssetPaths
   ? // Making sure that the publicPath goes back to to build folder.
     { publicPath: Array(cssFilename.split('/').length).join('../') }
   : {};
+// Check if vendor file exists
+const checkIfVendorFileExists = fs.existsSync(paths.appVendorJs);
+// If the vendor file exists, add an entry point for vendor,
+// and a seperate entry for polyfills and app index file,
+// otherwise keep only polyfills and app index.
+const appEntryFiles = [require.resolve('./polyfills'), paths.appIndexJs];
+const entryFiles = checkIfVendorFileExists
+  ? {
+      vendor: paths.appVendorJs,
+      main: appEntryFiles,
+    }
+  : appEntryFiles;
 
 // This is the production configuration.
 // It compiles slowly and is focused on producing a fast and minimal bundle.
@@ -63,8 +77,8 @@ module.exports = {
   // We generate sourcemaps in production. This is slow but gives good results.
   // You can exclude the *.map files from the build during deployment.
   devtool: 'source-map',
-  // In production, we only want to load the polyfills and the app code.
-  entry: [require.resolve('./polyfills'), paths.appIndexJs],
+  // Add the entry point based on whether vendor file exists.
+  entry: entryFiles,
   output: {
     // The build folder.
     path: paths.appBuild,
@@ -278,6 +292,17 @@ module.exports = {
     // It is absolutely essential that NODE_ENV was set to production here.
     // Otherwise React will be compiled in the very slow development mode.
     new webpack.DefinePlugin(env.stringified),
+    // We need to extract out the runtime into a separate manifest file.
+    // more info: https://webpack.js.org/guides/code-splitting-libraries/#manifest-file
+    new webpack.optimize.CommonsChunkPlugin({
+      // Check if vendor file exists, if it does,
+      // generate a seperate chucks for vendor and manifest file
+      // else don't generate any common chunck
+      names: checkIfVendorFileExists ? ['vendor', 'manifest'] : [],
+    }),
+    // Need this plugin for deterministic hashing
+    // until this issue is resolved: https://github.com/webpack/webpack/issues/1315
+    new WebpackMd5Hash(),
     // Minify the code.
     new webpack.optimize.UglifyJsPlugin({
       compress: {
diff --git a/packages/react-scripts/package.json b/packages/react-scripts/package.json
index a304b22d7..a108b97e3 100644
--- a/packages/react-scripts/package.json
+++ b/packages/react-scripts/package.json
@@ -58,6 +58,7 @@
     "webpack": "2.5.1",
     "webpack-dev-server": "2.4.5",
     "webpack-manifest-plugin": "1.1.0",
+    "webpack-md5-hash": "0.0.5",
     "whatwg-fetch": "2.0.3"
   },
   "devDependencies": {
-- 
GitLab


From b7a0757dcb3e95282c463dc69beb38390842d9dc Mon Sep 17 00:00:00 2001
From: Shriyans <shriyansbhatnagar@gmail.com>
Date: Tue, 23 May 2017 15:38:11 +0900
Subject: [PATCH 3/4] fixed configuration for long term caching

in context of the acticle linked in https://github.com/facebookincubator/create-react-app/issues/2328
---
 .../config/webpack.config.prod.js             | 48 ++++++++++++++-----
 packages/react-scripts/package.json           |  2 +-
 2 files changed, 37 insertions(+), 13 deletions(-)

diff --git a/packages/react-scripts/config/webpack.config.prod.js b/packages/react-scripts/config/webpack.config.prod.js
index 37a795eb4..812b0c82f 100644
--- a/packages/react-scripts/config/webpack.config.prod.js
+++ b/packages/react-scripts/config/webpack.config.prod.js
@@ -14,7 +14,7 @@ const autoprefixer = require('autoprefixer');
 const path = require('path');
 const fs = require('fs');
 const webpack = require('webpack');
-const WebpackMd5Hash = require('webpack-md5-hash');
+const NameAllModulesPlugin = require('name-all-modules-plugin');
 const HtmlWebpackPlugin = require('html-webpack-plugin');
 const ExtractTextPlugin = require('extract-text-webpack-plugin');
 const ManifestPlugin = require('webpack-manifest-plugin');
@@ -264,6 +264,41 @@ module.exports = {
     ],
   },
   plugins: [
+    // configuration for vendor splitting and long term caching
+    // more info: https://medium.com/webpack/predictable-long-term-caching-with-webpack-d3eee1d3fa31
+    new webpack.NamedModulesPlugin(),
+    new webpack.NamedChunksPlugin(chunk => {
+      if (chunk.name) {
+        return chunk.name;
+      }
+      return chunk.modules
+        .map(m => path.relative(m.context, m.request))
+        .join('_');
+    }),
+    new webpack.optimize.CommonsChunkPlugin(
+      // Check if vendor file exists, if it does,
+      // generate a seperate chucks for vendor
+      // else don't generate any common chunck
+      checkIfVendorFileExists
+        ? {
+            name: 'vendor',
+            minChunks: Infinity,
+          }
+        : { names: [] }
+    ),
+    // We need to extract out the runtime into a separate manifest file.
+    // more info: https://webpack.js.org/guides/code-splitting-libraries/#manifest-file
+    new webpack.optimize.CommonsChunkPlugin(
+      // Check if vendor file exists, if it does,
+      // generate a seperate chucks for manifest file
+      // else don't generate any common chunck
+      checkIfVendorFileExists
+        ? {
+            name: 'manifest',
+          }
+        : { names: [] }
+    ),
+    new NameAllModulesPlugin(),
     // Makes some environment variables available in index.html.
     // The public URL is available as %PUBLIC_URL% in index.html, e.g.:
     // <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
@@ -292,17 +327,6 @@ module.exports = {
     // It is absolutely essential that NODE_ENV was set to production here.
     // Otherwise React will be compiled in the very slow development mode.
     new webpack.DefinePlugin(env.stringified),
-    // We need to extract out the runtime into a separate manifest file.
-    // more info: https://webpack.js.org/guides/code-splitting-libraries/#manifest-file
-    new webpack.optimize.CommonsChunkPlugin({
-      // Check if vendor file exists, if it does,
-      // generate a seperate chucks for vendor and manifest file
-      // else don't generate any common chunck
-      names: checkIfVendorFileExists ? ['vendor', 'manifest'] : [],
-    }),
-    // Need this plugin for deterministic hashing
-    // until this issue is resolved: https://github.com/webpack/webpack/issues/1315
-    new WebpackMd5Hash(),
     // Minify the code.
     new webpack.optimize.UglifyJsPlugin({
       compress: {
diff --git a/packages/react-scripts/package.json b/packages/react-scripts/package.json
index d1e7b768a..2878f58d3 100644
--- a/packages/react-scripts/package.json
+++ b/packages/react-scripts/package.json
@@ -46,6 +46,7 @@
     "fs-extra": "3.0.1",
     "html-webpack-plugin": "2.28.0",
     "jest": "20.0.3",
+    "name-all-modules-plugin": "^1.0.1",
     "object-assign": "4.1.1",
     "postcss-flexbugs-fixes": "3.0.0",
     "postcss-loader": "2.0.5",
@@ -58,7 +59,6 @@
     "webpack": "2.5.1",
     "webpack-dev-server": "2.4.5",
     "webpack-manifest-plugin": "1.1.0",
-    "webpack-md5-hash": "0.0.5",
     "whatwg-fetch": "2.0.3"
   },
   "devDependencies": {
-- 
GitLab


From 9345cfaf8a35ce76170334e2d116f988b46c552b Mon Sep 17 00:00:00 2001
From: Shriyans <shriyansbhatnagar@gmail.com>
Date: Tue, 23 May 2017 17:52:09 +0900
Subject: [PATCH 4/4] added defer attribute to scripts

---
 packages/react-scripts/config/webpack.config.prod.js | 6 ++++++
 packages/react-scripts/package.json                  | 1 +
 2 files changed, 7 insertions(+)

diff --git a/packages/react-scripts/config/webpack.config.prod.js b/packages/react-scripts/config/webpack.config.prod.js
index 812b0c82f..32231f118 100644
--- a/packages/react-scripts/config/webpack.config.prod.js
+++ b/packages/react-scripts/config/webpack.config.prod.js
@@ -16,6 +16,7 @@ const fs = require('fs');
 const webpack = require('webpack');
 const NameAllModulesPlugin = require('name-all-modules-plugin');
 const HtmlWebpackPlugin = require('html-webpack-plugin');
+const ScriptExtHtmlWebpackPlugin = require('script-ext-html-webpack-plugin');
 const ExtractTextPlugin = require('extract-text-webpack-plugin');
 const ManifestPlugin = require('webpack-manifest-plugin');
 const InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin');
@@ -322,6 +323,11 @@ module.exports = {
         minifyURLs: true,
       },
     }),
+    // This ensures that the browser will load the scripts in parallel,
+    // but execute them in the order they appear in the document.
+    new ScriptExtHtmlWebpackPlugin({
+      defaultAttribute: 'defer',
+    }),
     // Makes some environment variables available to the JS code, for example:
     // if (process.env.NODE_ENV === 'production') { ... }. See `./env.js`.
     // It is absolutely essential that NODE_ENV was set to production here.
diff --git a/packages/react-scripts/package.json b/packages/react-scripts/package.json
index 2878f58d3..641ce7264 100644
--- a/packages/react-scripts/package.json
+++ b/packages/react-scripts/package.json
@@ -53,6 +53,7 @@
     "promise": "7.1.1",
     "react-dev-utils": "^1.0.3",
     "react-error-overlay": "^1.0.3",
+    "script-ext-html-webpack-plugin": "^1.8.0",
     "style-loader": "0.17.0",
     "sw-precache-webpack-plugin": "0.9.1",
     "url-loader": "0.5.8",
-- 
GitLab