From 555c593059ca525d0ca22549b2c4881c4973a56e Mon Sep 17 00:00:00 2001 From: Wyatt Johnson Date: Thu, 18 May 2017 11:08:46 -0600 Subject: [PATCH 1/3] Added gzip compression to bundle assets --- app.js | 10 ++++++++++ package.json | 2 ++ routes/index.js | 14 ++++++++++++-- webpack.config.js | 8 ++++++++ yarn.lock | 43 +++++++++++++++++++++++++++++++++++++++---- 5 files changed, 71 insertions(+), 6 deletions(-) diff --git a/app.js b/app.js index 9aca8b0ef..1ec1db78a 100644 --- a/app.js +++ b/app.js @@ -10,6 +10,7 @@ const enabled = require('debug').enabled; const errors = require('./errors'); const {createGraphOptions} = require('./graph'); const apollo = require('graphql-server-express'); +const accepts = require('accepts'); const app = express(); @@ -31,6 +32,15 @@ app.use(helmet({ frameguard: false })); app.use(bodyParser.json()); +app.get('*.js', (req, res, next) => { + const accept = accepts(req); + if (accept.encoding(['gzip']) === 'gzip') { + req.url = `${req.url}.gz`; + res.set('Content-Encoding', 'gzip'); + } + + next(); +}); app.use('/client', express.static(path.join(__dirname, 'dist'))); app.use('/public', express.static(path.join(__dirname, 'public'))); app.set('views', path.join(__dirname, 'views')); diff --git a/package.json b/package.json index fe7552414..76d822033 100644 --- a/package.json +++ b/package.json @@ -50,6 +50,7 @@ }, "homepage": "https://github.com/coralproject/talk#readme", "dependencies": { + "accepts": "^1.3.3", "app-module-path": "^2.2.0", "bcrypt": "^1.0.2", "body-parser": "^1.17.1", @@ -131,6 +132,7 @@ "chai-as-promised": "^6.0.0", "chai-http": "^3.0.0", "common-tags": "^1.4.0", + "compression-webpack-plugin": "^0.4.0", "copy-webpack-plugin": "^4.0.0", "css-loader": "^0.27.3", "dialog-polyfill": "^0.4.4", diff --git a/routes/index.js b/routes/index.js index 448bd6964..f1992e83d 100644 --- a/routes/index.js +++ b/routes/index.js @@ -8,8 +8,18 @@ const router = express.Router(); router.use('/api/v1', require('./api')); router.use('/admin', require('./admin')); router.use('/embed', require('./embed')); -router.get('/embed.js', (req, res) => res.sendFile(path.join(__dirname, '../dist/embed.js'))); -router.get('/embed.js.map', (req, res) => res.sendFile(path.join(__dirname, '../dist/embed.js.map'))); + +/** + * Serves a file based on a relative path. + */ +const serveFile = (filename) => (req, res) => res.sendFile(path.join(__dirname, filename)); + +/** + * Serves the embed javascript files. + */ +router.get('/embed.js', serveFile('../dist/embed.js')); +router.get('/embed.js.gz', serveFile('../dist/embed.js.gz')); +router.get('/embed.js.map', serveFile('../dist/embed.js.map')); if (process.env.NODE_ENV !== 'production') { router.use('/assets', require('./assets')); diff --git a/webpack.config.js b/webpack.config.js index 2d751f8b2..5072ec77a 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -1,5 +1,6 @@ const path = require('path'); const fs = require('fs'); +const CompressionPlugin = require('compression-webpack-plugin'); const autoprefixer = require('autoprefixer'); const precss = require('precss'); const Copy = require('copy-webpack-plugin'); @@ -145,6 +146,13 @@ module.exports = { }), new webpack.EnvironmentPlugin({ 'TALK_PLUGINS_JSON': '{}' + }), + new CompressionPlugin({ + asset: '[path].gz[query]', + algorithm: 'gzip', + test: /\.(js)$/, + threshold: 10240, + minRatio: 0.8 }) ], resolveLoader: { diff --git a/yarn.lock b/yarn.lock index ef1afebfc..3cbe44a2b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -67,7 +67,7 @@ abbrev@1, abbrev@1.0.x: version "1.0.9" resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.0.9.tgz#91b4792588a7738c25f35dd6f63752a2f8776135" -accepts@~1.3.3: +accepts@^1.3.3, accepts@~1.3.3: version "1.3.3" resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.3.tgz#c3ca7434938648c3e0d9c1e328dd68b622c284ca" dependencies: @@ -334,6 +334,10 @@ async-each@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d" +async@0.2.x: + version "0.2.10" + resolved "https://registry.yarnpkg.com/async/-/async-0.2.10.tgz#b6bbe0b0674b9d719708ca38de8c237cb526c3d1" + async@1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/async/-/async-1.2.1.tgz#a4816a17cd5ff516dfa2c7698a453369b9790de0" @@ -1807,6 +1811,15 @@ component-emitter@^1.2.0: version "1.2.1" resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6" +compression-webpack-plugin@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/compression-webpack-plugin/-/compression-webpack-plugin-0.4.0.tgz#811de04215f811ea6a12d4d8aed8457d758f13ac" + dependencies: + async "0.2.x" + webpack-sources "^0.1.0" + optionalDependencies: + node-zopfli "^2.0.0" + concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" @@ -2290,6 +2303,12 @@ default-require-extensions@^1.0.0: dependencies: strip-bom "^2.0.0" +defaults@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.3.tgz#c656051e9817d9ff08ed881477f3fe4019f3ef7d" + dependencies: + clone "^1.0.2" + define-properties@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.2.tgz#83a73f2fea569898fb737193c8f873caf6d45c94" @@ -5322,7 +5341,7 @@ mute-stream@0.0.7: version "0.0.7" resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" -nan@2.5.0, nan@^2.3.0, nan@^2.4.0: +nan@2.5.0, nan@^2.0.0, nan@^2.3.0, nan@^2.4.0: version "2.5.0" resolved "https://registry.yarnpkg.com/nan/-/nan-2.5.0.tgz#aa8f1e34531d807e9e27755b234b4a6ec0c152a8" @@ -5433,7 +5452,7 @@ node-libs-browser@^2.0.0: util "^0.10.3" vm-browserify "0.0.4" -node-pre-gyp@0.6.32, node-pre-gyp@^0.6.29: +node-pre-gyp@0.6.32, node-pre-gyp@^0.6.29, node-pre-gyp@^0.6.4: version "0.6.32" resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.6.32.tgz#fc452b376e7319b3d255f5f34853ef6fd8fe1fd5" dependencies: @@ -5461,6 +5480,15 @@ node-redis-warlock@~0.2.0: node-redis-scripty "0.0.5" uuid "^2.0.1" +node-zopfli@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/node-zopfli/-/node-zopfli-2.0.2.tgz#a7a473ae92aaea85d4c68d45bbf2c944c46116b8" + dependencies: + commander "^2.8.1" + defaults "^1.0.2" + nan "^2.0.0" + node-pre-gyp "^0.6.4" + nodemailer-direct-transport@3.3.2: version "3.3.2" resolved "https://registry.yarnpkg.com/nodemailer-direct-transport/-/nodemailer-direct-transport-3.3.2.tgz#e96fafb90358560947e569017d97e60738a50a86" @@ -7508,7 +7536,7 @@ sort-keys@^1.0.0: dependencies: is-plain-obj "^1.0.0" -source-list-map@^0.1.7: +source-list-map@^0.1.7, source-list-map@~0.1.7: version "0.1.8" resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-0.1.8.tgz#c550b2ab5427f6b3f21f5afead88c4f5587b2106" @@ -8254,6 +8282,13 @@ webidl-conversions@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.1.tgz#8015a17ab83e7e1b311638486ace81da6ce206a0" +webpack-sources@^0.1.0: + version "0.1.5" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-0.1.5.tgz#aa1f3abf0f0d74db7111c40e500b84f966640750" + dependencies: + source-list-map "~0.1.7" + source-map "~0.5.3" + webpack-sources@^0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-0.2.3.tgz#17c62bfaf13c707f9d02c479e0dcdde8380697fb" From 12713dae8650341dc5568a68dd3be164f6ff6822 Mon Sep 17 00:00:00 2001 From: Wyatt Johnson Date: Thu, 18 May 2017 11:18:08 -0600 Subject: [PATCH 2/3] Removed unused assets --- .../coral-embed-stream/public/samplearticle.html | 16 ---------------- client/lib/pym.v1.min.js | 2 -- webpack.config.js | 6 +----- 3 files changed, 1 insertion(+), 23 deletions(-) delete mode 100644 client/coral-embed-stream/public/samplearticle.html delete mode 100644 client/lib/pym.v1.min.js diff --git a/client/coral-embed-stream/public/samplearticle.html b/client/coral-embed-stream/public/samplearticle.html deleted file mode 100644 index 454cb249c..000000000 --- a/client/coral-embed-stream/public/samplearticle.html +++ /dev/null @@ -1,16 +0,0 @@ - - - - -
-

Lorem ipsum

-

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut lobortis sollicitudin eros a ornare. Curabitur dignissim vestibulum massa non rhoncus. Cras laoreet ante vel nunc hendrerit, ac imperdiet neque egestas. Suspendisse aliquet iaculis fermentum. Pellentesque interdum nec elit sed tincidunt. Donec volutpat, tellus posuere laoreet consequat, mi lacus laoreet massa, sed vehicula mauris velit non lectus. Integer non enim nec neque congue faucibus porttitor sit amet dui.

-

Nunc pharetra orci id diam feugiat, vitae rutrum magna efficitur. Morbi porttitor blandit lorem, et facilisis tellus luctus at. Morbi tincidunt eget nisl id placerat. Nullam consectetur quam vel mauris lacinia, non consectetur est faucibus. Duis cursus auctor nulla nec sagittis. Aenean sem erat, ultrices a hendrerit consectetur, accumsan non lorem. Integer ac neque sed magna sodales vulputate at quis neque. Praesent eget ornare lacus. Donec ultricies, dolor eget commodo faucibus, arcu velit ullamcorper tellus, in cursus tellus elit sed urna. Suspendisse in consequat magna. Duis vel ullamcorper tortor, vel cursus libero. Proin et nisi luctus ligula faucibus luctus. Morbi pulvinar, justo ac feugiat elementum, libero tellus congue justo, pharetra ultrices felis felis id leo. Integer mattis quam tempus libero porta, ac pretium ligula elementum.

-
- - -
- - diff --git a/client/lib/pym.v1.min.js b/client/lib/pym.v1.min.js deleted file mode 100644 index 7aa54058d..000000000 --- a/client/lib/pym.v1.min.js +++ /dev/null @@ -1,2 +0,0 @@ -/*! pym.js - v1.1.2 - 2016-10-25 */ -!function(a){"function"==typeof define&&define.amd?define(a):"undefined"!=typeof module&&module.exports?module.exports=a():window.pym=a.call(this)}(function(){var a="xPYMx",b={},c=function(a){var b=new RegExp("[\\?&]"+a.replace(/[\[]/,"\\[").replace(/[\]]/,"\\]")+"=([^&#]*)"),c=b.exec(location.search);return null===c?"":decodeURIComponent(c[1].replace(/\+/g," "))},d=function(a,b){if("*"===b.xdomain||a.origin.match(new RegExp(b.xdomain+"$")))return!0},e=function(b,c,d){var e=["pym",b,c,d];return e.join(a)},f=function(b){var c=["pym",b,"(\\S+)","(.*)"];return new RegExp("^"+c.join(a)+"$")},g=function(){for(var a=b.autoInitInstances.length,c=a-1;c>=0;c--){var d=b.autoInitInstances[c];d.el.getElementsByTagName("iframe").length&&d.el.getElementsByTagName("iframe")[0].contentWindow||b.autoInitInstances.splice(c,1)}};return b.autoInitInstances=[],b.autoInit=function(){var a=document.querySelectorAll("[data-pym-src]:not([data-pym-auto-initialized])"),c=a.length;g();for(var d=0;d-1&&(b=this.url.substring(c,this.url.length),this.url=this.url.substring(0,c)),this.url.indexOf("?")<0?this.url+="?":this.url+="&",this.iframe.src=this.url+"initialWidth="+a+"&childId="+this.id+"&parentTitle="+encodeURIComponent(document.title)+"&parentUrl="+encodeURIComponent(window.location.href)+b,this.iframe.setAttribute("width","100%"),this.iframe.setAttribute("scrolling","no"),this.iframe.setAttribute("marginheight","0"),this.iframe.setAttribute("frameborder","0"),this.settings.title&&this.iframe.setAttribute("title",this.settings.title),void 0!==this.settings.allowfullscreen&&this.settings.allowfullscreen!==!1&&this.iframe.setAttribute("allowfullscreen",""),void 0!==this.settings.sandbox&&"string"==typeof this.settings.sandbox&&this.iframe.setAttribute("sandbox",this.settings.sandbox),this.settings.id&&(document.getElementById(this.settings.id)||this.iframe.setAttribute("id",this.settings.id)),this.settings.name&&this.iframe.setAttribute("name",this.settings.name);this.el.firstChild;)this.el.removeChild(this.el.firstChild);this.el.appendChild(this.iframe),window.addEventListener("resize",this._onResize)},this._onResize=function(){this.sendWidth()}.bind(this),this._fire=function(a,b){if(a in this.messageHandlers)for(var c=0;c ({ from: path.join(__dirname, 'client', `coral-embed-${embed}`, 'style'), to: path.join(__dirname, 'dist', 'embed', embed) - })), - { - from: path.join(__dirname, 'client', 'lib'), - to: path.join(__dirname, 'dist', 'embed', 'stream') - } + })) ]), autoprefixer, precss, From 4dc83aaf6358c9a5b4b58c6b5b7818ef9b9ca5a2 Mon Sep 17 00:00:00 2001 From: Wyatt Johnson Date: Thu, 18 May 2017 11:27:28 -0600 Subject: [PATCH 3/3] added middleware wrap --- app.js | 31 +++++++++++++++++++++++-------- webpack.config.js | 21 +++++++++++++-------- 2 files changed, 36 insertions(+), 16 deletions(-) diff --git a/app.js b/app.js index 1ec1db78a..868ceee4c 100644 --- a/app.js +++ b/app.js @@ -32,17 +32,32 @@ app.use(helmet({ frameguard: false })); app.use(bodyParser.json()); -app.get('*.js', (req, res, next) => { - const accept = accepts(req); - if (accept.encoding(['gzip']) === 'gzip') { - req.url = `${req.url}.gz`; - res.set('Content-Encoding', 'gzip'); - } - next(); -}); +//============================================================================== +// STATIC FILES +//============================================================================== + +// If the application is in production mode, then add gzip rewriting for the +// content. +if (process.env.NODE_ENV === 'production') { + app.get('*.js', (req, res, next) => { + const accept = accepts(req); + if (accept.encoding(['gzip']) === 'gzip') { + req.url = `${req.url}.gz`; + res.set('Content-Encoding', 'gzip'); + } + + next(); + }); +} + app.use('/client', express.static(path.join(__dirname, 'dist'))); app.use('/public', express.static(path.join(__dirname, 'public'))); + +//============================================================================== +// VIEW CONFIGURATION +//============================================================================== + app.set('views', path.join(__dirname, 'views')); app.set('view engine', 'ejs'); diff --git a/webpack.config.js b/webpack.config.js index 6a05f31b6..78b111579 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -37,7 +37,7 @@ const buildEmbeds = [ 'stream' ]; -module.exports = { +const config = { devtool: 'cheap-module-source-map', entry: Object.assign({}, { 'embed': [ @@ -142,13 +142,6 @@ module.exports = { }), new webpack.EnvironmentPlugin({ 'TALK_PLUGINS_JSON': '{}' - }), - new CompressionPlugin({ - asset: '[path].gz[query]', - algorithm: 'gzip', - test: /\.(js)$/, - threshold: 10240, - minRatio: 0.8 }) ], resolveLoader: { @@ -168,3 +161,15 @@ module.exports = { ] } }; + +if (process.env.NODE_ENV === 'production') { + config.plugins.push(new CompressionPlugin({ + asset: '[path].gz[query]', + algorithm: 'gzip', + test: /\.(js)$/, + threshold: 10240, + minRatio: 0.8 + })); +} + +module.exports = config;