From 13231a8af4c117befd9bd5e995cb665f9ccc2024 Mon Sep 17 00:00:00 2001 From: Nolan Lawson Date: Sun, 14 Jan 2018 17:50:29 -0800 Subject: [PATCH] improve bundle size, add webpack-bundle-analyzer --- package-lock.json | 61 +++++++++++++++++++ package.json | 1 + routes/_utils/asyncModules.js | 7 ++- routes/settings/instances/[instanceName].html | 4 +- routes/settings/instances/add.html | 5 +- templates/main.js | 3 +- webpack.client.config.js | 25 ++++++-- 7 files changed, 95 insertions(+), 11 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5011df4a..8593822d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -216,6 +216,11 @@ "resolved": "https://registry.npmjs.org/async-foreach/-/async-foreach-0.1.3.tgz", "integrity": "sha1-NhIfhFwFeBct5Bmpfb6x0W7DRUI=" }, + "async-limiter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", + "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==" + }, "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -1340,6 +1345,11 @@ "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" }, + "ejs": { + "version": "2.5.7", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-2.5.7.tgz", + "integrity": "sha1-zIcsFoiArjxxiXYv1f/ACJbJUYo=" + }, "electron-releases": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/electron-releases/-/electron-releases-2.1.0.tgz", @@ -1818,6 +1828,11 @@ "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=" }, + "filesize": { + "version": "3.5.11", + "resolved": "https://registry.npmjs.org/filesize/-/filesize-3.5.11.tgz", + "integrity": "sha512-ZH7loueKBoDb7yG9esn1U+fgq7BzlzW6NRi5/rMdxIZ05dj7GFD/Xc5rq2CDt5Yq86CyfSYVyx4242QQNZbx1g==" + }, "fill-range": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", @@ -3019,6 +3034,14 @@ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" }, + "gzip-size": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-3.0.0.tgz", + "integrity": "sha1-VGGI6b3DN/Zzdy+BZgRks4nc5SA=", + "requires": { + "duplexer": "0.1.1" + } + }, "har-validator": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz", @@ -4617,6 +4640,11 @@ "wrappy": "1.0.2" } }, + "opener": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/opener/-/opener-1.4.3.tgz", + "integrity": "sha1-XG2ixdflgx6P+jlklQ+NZnSskLg=" + }, "optimist": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", @@ -7120,6 +7148,11 @@ } } }, + "ultron": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", + "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==" + }, "underscore": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.7.0.tgz", @@ -7644,6 +7677,24 @@ } } }, + "webpack-bundle-analyzer": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-2.9.2.tgz", + "integrity": "sha1-Y+2G63HMTNqG9o5oWoRTC6ASZEk=", + "requires": { + "acorn": "5.3.0", + "chalk": "1.1.3", + "commander": "2.12.2", + "ejs": "2.5.7", + "express": "4.16.2", + "filesize": "3.5.11", + "gzip-size": "3.0.0", + "lodash": "4.17.4", + "mkdirp": "0.5.1", + "opener": "1.4.3", + "ws": "4.0.0" + } + }, "webpack-hot-middleware": { "version": "2.21.0", "resolved": "https://registry.npmjs.org/webpack-hot-middleware/-/webpack-hot-middleware-2.21.0.tgz", @@ -7754,6 +7805,16 @@ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, + "ws": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-4.0.0.tgz", + "integrity": "sha512-QYslsH44bH8O7/W2815u5DpnCpXWpEK44FmaHffNwgJI4JMaSZONgPBTOfrxJ29mXKbXak+LsJ2uAkDTYq2ptQ==", + "requires": { + "async-limiter": "1.0.0", + "safe-buffer": "5.1.1", + "ultron": "1.1.1" + } + }, "xml2js": { "version": "0.4.19", "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz", diff --git a/package.json b/package.json index d2d681f8..29c2ffef 100644 --- a/package.json +++ b/package.json @@ -40,6 +40,7 @@ "uglifyjs-webpack-plugin": "^1.1.5", "url-search-params": "^0.10.0", "webpack": "^3.10.0", + "webpack-bundle-analyzer": "^2.9.2", "yargs": "^10.1.1" }, "engines": { diff --git a/routes/_utils/asyncModules.js b/routes/_utils/asyncModules.js index 562bf34d..409f5b91 100644 --- a/routes/_utils/asyncModules.js +++ b/routes/_utils/asyncModules.js @@ -9,6 +9,11 @@ const importURLSearchParams = () => import( }) }) +const importToast = () => import( + /* webpackChunkName: 'toast' */ './toast' + ).then(mod => mod.toast) + export { - importURLSearchParams + importURLSearchParams, + importToast } \ No newline at end of file diff --git a/routes/settings/instances/[instanceName].html b/routes/settings/instances/[instanceName].html index 8825a4bf..ec68580d 100644 --- a/routes/settings/instances/[instanceName].html +++ b/routes/settings/instances/[instanceName].html @@ -96,7 +96,7 @@ import { themes } from '../../_static/themes' import { switchToTheme } from '../../_utils/themeEngine' import { goto } from 'sapper/runtime.js' - import { toast } from '../../_utils/toast' + import { importToast } from '../../_utils/asyncModules' export default { components: { @@ -159,7 +159,7 @@ }) this.store.save() switchToTheme(instanceThemes[newInstance] || 'default') - toast.say(`Logged out of ${instanceName}`) + importToast().then(toast => toast.say(`Logged out of ${instanceName}`)) goto('/settings/instances') } } diff --git a/routes/settings/instances/add.html b/routes/settings/instances/add.html index 0d8f93cb..1d96a173 100644 --- a/routes/settings/instances/add.html +++ b/routes/settings/instances/add.html @@ -56,7 +56,7 @@ import { store } from '../../_utils/store' import { goto } from 'sapper/runtime.js' import { switchToTheme } from '../../_utils/themeEngine' - import { toast } from '../../_utils/toast' + import { importToast } from '../../_utils/asyncModules' import LoadingMask from '../../_components/LoadingMask' const REDIRECT_URI = (typeof location !== 'undefined' ? @@ -89,6 +89,7 @@ if (process.env.NODE_ENV !== 'production') { console.error(err) } + const toast = await importToast() toast.say(`Error: ${err.message || err.name}. Is this a valid Mastodon instance?`) } finally { this.set({loading: false}) @@ -99,6 +100,7 @@ let loggedInInstances = this.store.get('loggedInInstances') instanceName = instanceName.replace(/^https?:\/\//, '').replace('/$', '') if (Object.keys(loggedInInstances).includes(instanceName)) { + const toast = await importToast() toast.say(`You've already logged in to ${instanceName}`) return } @@ -120,6 +122,7 @@ this.set({loading: true}) await this.registerNewInstance(code) } catch (err) { + const toast = await importToast() toast.say(`Error: ${err.message || err.name}. Failed to connect to instance.`) } finally { this.set({loading: false}) diff --git a/templates/main.js b/templates/main.js index 2f3817d6..6495f78a 100644 --- a/templates/main.js +++ b/templates/main.js @@ -1,5 +1,4 @@ import { init } from 'sapper/runtime.js' -import toast from '../routes/_utils/toast.js' // polyfills Promise.all([ @@ -11,7 +10,7 @@ Promise.all([ if (navigator.serviceWorker && navigator.serviceWorker.controller) { navigator.serviceWorker.controller.onstatechange = (e) => { if (e.target.state === 'redundant') { - toast.say('App update available. Reload to update.'); + importToast().then(toast => toast.say('App update available. Reload to update.')); } } } diff --git a/webpack.client.config.js b/webpack.client.config.js index ebbfc283..b5cd8848 100644 --- a/webpack.client.config.js +++ b/webpack.client.config.js @@ -1,7 +1,8 @@ -const webpack = require('webpack'); -const config = require('sapper/webpack/config.js'); -const ExtractTextPlugin = require('extract-text-webpack-plugin'); -const UglifyJSPlugin = require('uglifyjs-webpack-plugin'); +const webpack = require('webpack') +const config = require('sapper/webpack/config.js') +const ExtractTextPlugin = require('extract-text-webpack-plugin') +const UglifyJSPlugin = require('uglifyjs-webpack-plugin') +const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin const isDev = config.dev; @@ -56,10 +57,24 @@ module.exports = { ].concat(isDev ? [ new webpack.HotModuleReplacementPlugin() ] : [ + new webpack.DefinePlugin({ + 'process.browser': true, + 'process.env.NODE_ENV': '"production"' + }), /* disable while https://github.com/sveltejs/sapper/issues/79 is open */ //new ExtractTextPlugin('main.css'), new webpack.optimize.ModuleConcatenationPlugin(), - new UglifyJSPlugin() + new UglifyJSPlugin(), + new BundleAnalyzerPlugin({ // generates report.html and stats.json + analyzerMode: 'static', + generateStatsFile: true, + statsOptions: { + // allows usage with http://chrisbateman.github.io/webpack-visualizer/ + chunkModules: true, + }, + openAnalyzer: false, + logLevel: 'silent', // do not bother Webpacker, who runs with --json and parses stdout + }), ]).filter(Boolean), devtool: isDev && 'inline-source-map' };