From 6396c606457d2c03837806660ac597ee6ade94c6 Mon Sep 17 00:00:00 2001
From: Richard van der Hoff <richard@matrix.org>
Date: Tue, 25 Oct 2016 17:07:43 +0100
Subject: [PATCH 1/2] Put a cachebuster in the names of CSS and JS files

This means that clients can do better caching of assets, as it will mean we are
no longer reliant on etags to ensure that clients get a fresh version.

We inhibit the cachebuster for `npm start`, so that we don't get millions of
copies of the bundles on dev boxes.
---
 .gitignore                        |  1 +
 package.json                      |  7 ++++---
 {vector => src/vector}/index.html | 10 ++++++----
 webpack.config.js                 | 24 +++++++++++++++++++++---
 4 files changed, 32 insertions(+), 10 deletions(-)
 rename {vector => src/vector}/index.html (92%)

diff --git a/.gitignore b/.gitignore
index 2abed01f..766f41c0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,6 +8,7 @@
 /vector/bundle.*
 /vector/emojione/
 /vector/config.json
+/vector/index.html
 /vector/olm.*
 .DS_Store
 npm-debug.log
diff --git a/package.json b/package.json
index 95eff531..bcc1ea4d 100644
--- a/package.json
+++ b/package.json
@@ -22,13 +22,13 @@
     "build:dev": "npm run build:emojione && npm run build:css && npm run build:bundle:dev",
     "package": "scripts/package.sh",
     "start:emojione": "cpx \"node_modules/emojione/assets/svg/*\" vector/emojione/svg/ -w",
-    "start:js": "webpack -w --progress",
-    "start:js:prod": "NODE_ENV=production webpack -w --progress",
+    "start:js": "webpack -w --progress --no-cache-buster",
+    "start:js:prod": "NODE_ENV=production webpack -w --progress --no-cache-buster",
     "start:skins:css": "mkdirp build && catw \"src/skins/vector/css/**/*.css\" -o build/components.css",
     "//cache": "Note the -c 1 below due to https://code.google.com/p/chromium/issues/detail?id=508270",
     "start": "node scripts/babelcheck.js && parallelshell \"npm run start:emojione\" \"npm run start:js\" \"npm run start:skins:css\" \"http-server -c 1 vector\"",
     "start:prod": "parallelshell \"npm run start:emojione\" \"npm run start:js:prod\" \"npm run start:skins:css\" \"http-server -c 1 vector\"",
-    "clean": "rimraf build lib vector/olm.* vector/bundle.* vector/emojione",
+    "clean": "rimraf build lib vector/olm.* vector/bundle.* vector/emojione vector/index.html",
     "prepublish": "npm run build:css && npm run build:compile",
     "test": "karma start --single-run=true --autoWatch=false --browsers PhantomJS --colors=false",
     "test:multi": "karma start"
@@ -80,6 +80,7 @@
     "emojione": "^2.2.3",
     "expect": "^1.16.0",
     "fs-extra": "^0.30.0",
+    "html-webpack-plugin": "^2.24.0",
     "http-server": "^0.8.4",
     "json-loader": "^0.5.3",
     "karma": "^0.13.22",
diff --git a/vector/index.html b/src/vector/index.html
similarity index 92%
rename from vector/index.html
rename to src/vector/index.html
index 8a536d61..73cdd2df 100644
--- a/vector/index.html
+++ b/src/vector/index.html
@@ -20,14 +20,16 @@
     <meta name="msapplication-TileImage" content="vector-icons/mstile-144x144.png">
     <meta name="msapplication-config" content="vector-icons/browserconfig.xml">
     <meta name="theme-color" content="#ffffff">
+    <% for(var i=0; i<htmlWebpackPlugin.files.css.length; i++) {%>
+       <link href="<%= htmlWebpackPlugin.files.css[i] %>" rel="stylesheet">
+    <% } %>
   </head>
   <body style="height: 100%;">
     <section id="matrixchat" style="height: 100%;"></section>
-    <!-- load olm, if possible. -->
-    <script src="olm.js"></script>
-    <script src="bundle.js"></script>
     <noscript>Sorry, Riot requires JavaScript to be enabled.</noscript>
-    <link rel="stylesheet" href="bundle.css">
+    <% for(var i=0; i<htmlWebpackPlugin.files.js.length; i++) {%>
+       <script src="<%= htmlWebpackPlugin.files.js[i] %>"></script>
+    <% } %>
     <img src="img/warning.svg" width="24" height="23" style="visibility: hidden; position: absolute; top: 0px; left: 0px;"/>
     <audio id="messageAudio">
         <source src="media/message.ogg" type="audio/ogg" />
diff --git a/webpack.config.js b/webpack.config.js
index 4d5747f6..cc5edf60 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -1,6 +1,16 @@
 var path = require('path');
 var webpack = require('webpack');
 var ExtractTextPlugin = require("extract-text-webpack-plugin");
+var HtmlWebpackPlugin = require('html-webpack-plugin');
+
+var cachebuster = true;
+
+for (var i=0; i < process.argv.length; i++) {
+    var arg = process.argv[i];
+    if (arg == "--no-cache-buster") {
+        cachebuster = false;
+    }
+}
 
 module.exports = {
     entry: {
@@ -39,7 +49,7 @@ module.exports = {
     },
     output: {
         path: path.join(__dirname, "vector"),
-        filename: "[name].js",
+        filename: "[name]" + (cachebuster ? ".[chunkhash]" : "") + ".js",
         devtoolModuleFilenameTemplate: function(info) {
             // Reading input source maps gives only relative paths here for
             // everything. Until I figure out how to fix this, this is a
@@ -73,8 +83,16 @@ module.exports = {
             }
         }),
 
-        new ExtractTextPlugin("bundle.css", {
-            allChunks: true
+        new ExtractTextPlugin(
+            "[name]" + (cachebuster ? ".[contenthash]" : "") + ".css",
+            {
+                allChunks: true
+            }
+        ),
+
+        new HtmlWebpackPlugin({
+            template: './src/vector/index.html',
+            inject: false, // we inject the links ourselves via the template
         }),
     ],
     devtool: 'source-map'

From 31ed719df19b08642e46c14b945225c8a072f158 Mon Sep 17 00:00:00 2001
From: Richard van der Hoff <richard@matrix.org>
Date: Wed, 26 Oct 2016 16:52:26 +0100
Subject: [PATCH 2/2] webpack: Improve comment on HtmlWebpackPlugin

---
 webpack.config.js | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/webpack.config.js b/webpack.config.js
index cc5edf60..bfd233b5 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -92,7 +92,12 @@ module.exports = {
 
         new HtmlWebpackPlugin({
             template: './src/vector/index.html',
-            inject: false, // we inject the links ourselves via the template
+
+            // we inject the links ourselves via the template, because
+            // HtmlWebpackPlugin wants to put the script tags either at the
+            // bottom of <head> or the bottom of <body>, and I'm a bit scared
+            // about moving them.
+            inject: false,
         }),
     ],
     devtool: 'source-map'