Ver Fonte

Merge pull request #962 from transloadit/website-sizes

Update stats page with bundle sizes for each package.
Renée Kooi há 6 anos atrás
pai
commit
044250d706

+ 24 - 0
package-lock.json

@@ -9091,6 +9091,24 @@
       "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=",
       "dev": true
     },
+    "gzip-size": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-5.0.0.tgz",
+      "integrity": "sha512-5iI7omclyqrnWw4XbXAmGhPsABkSIDQonv2K0h61lybgofWa6iZyvrI3r2zsJH4P8Nb64fFVzlvfhs0g7BBxAA==",
+      "dev": true,
+      "requires": {
+        "duplexer": "^0.1.1",
+        "pify": "^3.0.0"
+      },
+      "dependencies": {
+        "pify": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+          "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
+          "dev": true
+        }
+      }
+    },
     "handlebars": {
       "version": "4.0.10",
       "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.0.10.tgz",
@@ -16876,6 +16894,12 @@
       "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=",
       "dev": true
     },
+    "pretty-bytes": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.1.0.tgz",
+      "integrity": "sha512-wa5+qGVg9Yt7PB6rYm3kXlKzgzgivYTLRandezh43jjRqgyDyP+9YxfJpJiLs9yKD1WeU8/OvtToWpW7255FtA==",
+      "dev": true
+    },
     "pretty-format": {
       "version": "22.4.3",
       "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-22.4.3.tgz",

+ 2 - 0
package.json

@@ -44,6 +44,7 @@
     "fakefile": "0.0.9",
     "github-contributors-list": "1.2.3",
     "glob": "^7.1.2",
+    "gzip-size": "^5.0.0",
     "isomorphic-fetch": "2.2.1",
     "jest": "^22.4.4",
     "json3": "^3.3.2",
@@ -60,6 +61,7 @@
     "postcss": "^6.0.23",
     "postcss-safe-important": "^1.1.0",
     "pre-commit": "^1.2.2",
+    "pretty-bytes": "^5.1.0",
     "react": "^16.4.1",
     "react-dom": "^16.4.1",
     "redux": "^4.0.0",

+ 29 - 30
website/themes/uppy/layout/stats.ejs

@@ -2,36 +2,6 @@
 
 <div class="Content js-Content <%- page.type ? page.type + ' with-sidebar' : '' %>">
   <h1><%- page.title %></h1>
-  <div class="Stats-bundleSizes">
-    <strong class="underline">Bundle Sizes</strong>
-    <dl>
-      <% for (var type in theme.uppy_bundle_kb_sizes) { %>
-        <% var kb = theme.uppy_bundle_kb_sizes[type]; %>
-        <dt>
-          <% if (kb === 'N/A') { %>
-            <%- type %>
-          <% } else { %>
-            <a href="/uppy/<%- type %>"><%- type %></a>
-          <% }%>
-        </dt>
-        <dd class="
-          <% if (kb > 100) { %>
-            red
-          <% } %>
-          <% if (kb < 50) { %>
-            green
-          <% } %>
-        ">
-
-          <% if (kb === 'N/A') { %>
-            <%- kb %>
-          <% } else { %>
-            <%- kb %> Kb
-          <% }%>
-        </dd>
-      <% } %>
-    </dl>
-  </div>
 
   <p class="Stats-infoText">
     To keep Uppy lightweight, we’re aiming to carefully select what packages we include.
@@ -50,6 +20,35 @@
   <a href="http://hughsk.io/disc/">disc</a>.
   <hr />
 
+  <h2 id="bundle-sizes">Bundle Sizes</h2>
+  <p>
+    Below are the minified and gzipped sizes for each Uppy package. Note that this includes the dependencies for each package, some of which are shared when you install multiple plugins—for example, the <code>@uppy/dropbox</code> and <code>@uppy/instagram</code> package are both over 11kB including dependencies, but only sum up to about 15kB when they are used together.
+  </p>
+  <table class="Stats-bundleSizes">
+    <thead>
+      <tr>
+        <th class="Stats-bundleSizeHeader">Package</th>
+        <th class="Stats-bundleSizeHeader">Minified</th>
+        <th class="Stats-bundleSizeHeader">Gzip</th>
+      </tr>
+    </thead>
+    <tbody>
+      <% for (const [name, sizes] of Object.entries(theme.uppy_bundle_kb_sizes)) { %>
+        <% const { minified, gzipped, prettyMinified, prettyGzipped } = sizes %>
+        <tr>
+          <td><a class="Stats-package" target="_blank" href="https://npmjs.com/package/<%= name %>"><%= name %></a></td>
+          <td><%= prettyMinified %></td>
+          <td class="
+            <% if (gzipped > 30 * 1000) { %>Stats-large<% } %>
+            <% if (gzipped < 10 * 1000) { %>Stats-small<% } %>
+          ">
+            <%= prettyGzipped %>
+          </td>
+        </tr>
+      <% } %>
+    </tbody>
+  </table>
+
   <h2>Browser support</h2>
 
   <p>This reflects the current state of Uppy and is updated with every change.</p>

+ 10 - 43
website/themes/uppy/source/css/_stats.scss

@@ -11,52 +11,19 @@
 
 .Stats-bundleSizes {
   margin-bottom: 1em;
+  width: 100%;
 
-  @media #{$screen-large} {
-    max-width: 320px;
-    float: right;
-    margin-right: -320px;
-    padding-left: 50px;
-  }
+  th { text-align: left; }
 }
 
-.Stats-bundleSizes {
-  strong.underline {
-    display: inline-block;
-    border-bottom: 1px solid #eee;
-    margin-bottom: 5px;
-  }
-
-  dl {
-    @include clearfix;
-    width: 100%;
-    padding: 0;
-    margin: 0;
-    line-height: 1.5;
-  }
-
-  dt {
-    float: left;
-    width: 50%;
-    padding: 0;
-    margin: 0;
-    a {
-      color: #e02177;
-    }
-  }
-
-  dd {
-    float: left;
-    width: 50%;
-    padding: 0;
-    margin: 0;
-    &.red {
-      color: red;
-    }
-    &.green {
-      color: #3FC33F;
-    }
-  }
+a.Stats-package {
+  color: #e02177;
+}
+.Stats-large {
+  color: red;
+}
+.Stats-small {
+  color: #3FC33F;
 }
 
 .Disc {

+ 127 - 59
website/update.js

@@ -1,84 +1,152 @@
-var fs = require('fs')
-var path = require('path')
-var chalk = require('chalk')
-var exec = require('child_process').exec
-var YAML = require('js-yaml')
+const fs = require('fs')
+const path = require('path')
+const chalk = require('chalk')
+const { exec } = require('child_process')
+const YAML = require('js-yaml')
+const { promisify } = require('util')
+const gzipSize = require('gzip-size')
+const bytes = require('pretty-bytes')
+const browserify = require('browserify')
 
-var webRoot = __dirname
-var uppyRoot = path.join(__dirname, '../packages/uppy')
+const webRoot = __dirname
+const uppyRoot = path.join(__dirname, '../packages/uppy')
 
-var configPath = webRoot + '/themes/uppy/_config.yml'
-var version = require(uppyRoot + '/package.json').version
+const configPath = path.join(webRoot, '/themes/uppy/_config.yml')
+const { version } = require(path.join(uppyRoot, '/package.json'))
 
-var defaultConfig = {
+const defaultConfig = {
   comment: 'Auto updated by update.js',
   uppy_version_anchor: '001',
   uppy_version: '0.0.1',
-  uppy_bundle_kb_sizes: {
-    'uppy.js': 'N/A'
-  },
+  uppy_bundle_kb_sizes: {},
   config: {}
 }
 
-var loadedConfig
-var buf
-try {
-  buf = fs.readFileSync(configPath, 'utf-8')
-  loadedConfig = YAML.safeLoad(buf)
-} catch (e) {
+// Keeping a whitelist so utils etc are excluded
+// It may be easier to maintain a blacklist instead
+const packages = [
+  'uppy',
+  '@uppy/core',
+  '@uppy/dashboard',
+  '@uppy/drag-drop',
+  '@uppy/file-input',
+  '@uppy/webcam',
+  '@uppy/dropbox',
+  '@uppy/google-drive',
+  '@uppy/instagram',
+  '@uppy/url',
+  '@uppy/tus',
+  '@uppy/xhr-upload',
+  '@uppy/aws-s3',
+  '@uppy/aws-s3-multipart',
+  '@uppy/status-bar',
+  '@uppy/progress-bar',
+  '@uppy/informer',
+  '@uppy/transloadit',
+  '@uppy/form',
+  '@uppy/golden-retriever',
+  '@uppy/react',
+  '@uppy/thumbnail-generator',
+  '@uppy/store-default',
+  '@uppy/store-redux'
+]
 
+const excludes = {
+  '@uppy/react': ['react']
 }
 
-// Inject current Uppy version and sizes in website's _config.yml
-// @todo: Refer to actual minified builds in dist:
-var locations = {
-  'uppy.js': uppyRoot + '/dist/uppy.js',
-  'uppy.js.gz': uppyRoot + '/dist/uppy.js.gz',
-  'uppy.min.js': uppyRoot + '/dist/uppy.min.js',
-  'uppy.min.js.gz': uppyRoot + '/dist/uppy.min.js.gz',
-  'uppy.css': uppyRoot + '/dist/uppy.css',
-  'uppy.css.gz': uppyRoot + '/dist/uppy.css.gz',
-  'uppy.min.css': uppyRoot + '/dist/uppy.min.css',
-  'uppy.min.css.gz': uppyRoot + '/dist/uppy.min.css.gz'
+update().catch((err) => {
+  console.error(err)
+  process.exit(1)
+})
+
+async function getMinifiedSize (pkg, name) {
+  const b = browserify(pkg)
+  if (name !== '@uppy/core' && name !== 'uppy') {
+    b.exclude('@uppy/core')
+  }
+  if (excludes[name]) {
+    b.exclude(excludes[name])
+  }
+  b.plugin('tinyify')
+
+  const bundle = await promisify(b.bundle).call(b)
+  const gzipped = await gzipSize(bundle)
+
+  return {
+    minified: bundle.length,
+    gzipped
+  }
+}
+
+async function updateSizes (config) {
+  console.info(chalk.grey('Generating bundle sizes…'))
+  const padTarget = packages.reduce((max, cur) => Math.max(max, cur.length), 0) + 2
+
+  const sizesPromise = Promise.all(
+    packages.map(async (pkg) => {
+      const result = await getMinifiedSize(path.join(__dirname, '../packages', pkg), pkg)
+      console.info(chalk.green(
+        // ✓ @uppy/pkgname:     10.0 kB min  / 2.0 kB gz
+        `  ✓ ${pkg}: ${' '.repeat(padTarget - pkg.length)}` +
+        `${bytes(result.minified)} min`.padEnd(10) +
+        ` / ${bytes(result.gzipped)} gz`
+      ))
+      return Object.assign(result, {
+        prettyMinified: bytes(result.minified),
+        prettyGzipped: bytes(result.gzipped)
+      })
+    })
+  ).then((list) => {
+    const map = {}
+    list.forEach((size, i) => {
+      map[packages[i]] = size
+    })
+    return map
+  })
+
+  config.uppy_bundle_kb_sizes = await sizesPromise
 }
 
-var scanConfig = {}
-for (var type in locations) {
-  var filepath = locations[type]
-  var filesize = 0
+async function injectBuiltFiles () {
+  const cmds = [
+    `mkdir -p ${path.join(webRoot, '/themes/uppy/source/uppy')}`,
+    `cp -vfR ${path.join(uppyRoot, '/dist/*')} ${path.join(webRoot, '/themes/uppy/source/uppy/')}`
+  ].join(' && ')
+
+  const { stdout } = await promisify(exec)(cmds)
+  stdout.trim().split('\n').forEach(function (line) {
+    console.info(chalk.green('✓ injected: '), chalk.grey(line))
+  })
+}
+
+async function readConfig () {
   try {
-    filesize = fs.statSync(filepath, 'utf-8').size
-    filesize = (filesize / 1024).toFixed(2)
-  } catch (e) {
-    filesize = 'N/A'
-  }
-  if (!scanConfig.uppy_bundle_kb_sizes) {
-    scanConfig.uppy_bundle_kb_sizes = {}
+    const buf = await promisify(fs.readFile)(configPath, 'utf8')
+    return YAML.safeLoad(buf)
+  } catch (err) {
+    return {}
   }
-  scanConfig.uppy_bundle_kb_sizes[type] = filesize
 }
 
-scanConfig['uppy_version'] = version
-scanConfig['uppy_version_anchor'] = version.replace(/[^\d]+/g, '')
+async function update () {
+  const config = await readConfig()
 
-var saveConfig = Object.assign({}, defaultConfig, loadedConfig, scanConfig)
-fs.writeFileSync(configPath, YAML.safeDump(saveConfig), 'utf-8')
-console.info(chalk.green('✓ rewritten: '), chalk.dim(configPath))
+  config.uppy_version = version
+  config.uppy_version_anchor = version.replace(/[^\d]+/g, '')
+  await updateSizes(config)
 
-var cmds = [
-  'mkdir -p ' + webRoot + '/themes/uppy/source/uppy',
-  'cp -vfR ' + uppyRoot + '/dist/* ' + webRoot + '/themes/uppy/source/uppy/'
-].join(' && ')
+  const saveConfig = Object.assign({}, defaultConfig, config)
+  await promisify(fs.writeFile)(configPath, YAML.safeDump(saveConfig), 'utf-8')
+  console.info(chalk.green('✓ rewritten: '), chalk.grey(configPath))
 
-exec(cmds, function (error, stdout, stderr) {
-  if (error) {
+  try {
+    await injectBuiltFiles()
+  } catch (error) {
     console.error(
       chalk.red('x failed to inject: '),
-      chalk.dim('uppy bundle into site, because: ' + error)
+      chalk.grey('uppy bundle into site, because: ' + error)
     )
-    return
+    process.exit(1)
   }
-  stdout.trim().split('\n').forEach(function (line) {
-    console.info(chalk.green('✓ injected: '), chalk.dim(line))
-  })
-})
+}