From d62620ef70e60ee5fb0cf7a4738cf72793a3c6b6 Mon Sep 17 00:00:00 2001 From: Jakub Bogucki <610941+jakub300@users.noreply.github.com> Date: Thu, 6 Sep 2018 18:44:22 +0200 Subject: [PATCH] Add Bundle Report (#378) --- generators/app/templates/gulp/tasks/report.js | 231 ++++++++++++++++++ generators/app/templates/package.json | 3 + 2 files changed, 234 insertions(+) create mode 100644 generators/app/templates/gulp/tasks/report.js diff --git a/generators/app/templates/gulp/tasks/report.js b/generators/app/templates/gulp/tasks/report.js new file mode 100644 index 00000000..5b1ffdbe --- /dev/null +++ b/generators/app/templates/gulp/tasks/report.js @@ -0,0 +1,231 @@ +'use strict'; + +const path = require('path'); +const through = require('through2'); +const zlib = require('zlib'); +const http = require('http'); +const fs = require('fs'); +const explore = require('source-map-explorer'); +const os = require('os'); +const opn = require('opn'); + +const MEBIBYTE = 1024 * 1024; + +const files = {}; +const exploredCache = new Map(); + +function listFiles({ destBase }) { + return through.obj(function getInfoAboutFile(file, enc, callback) { + const relativePath = path.relative(destBase, file.path); + const bufferContents = Buffer.isBuffer(file.contents) + ? file.contents + : Buffer.from(file.contents); + + files[relativePath] = { + path: file.path, + hasSourceMap: false, + size: bufferContents.length, + sizeGzipped: -1, + notes: [], + }; + + zlib.gzip(bufferContents, (err, zipped) => { + if (err) { + throw err; + } + + files[relativePath].sizeGzipped = zipped.length; + callback(); + }); + + this.push(file); + }); +} + +function markSouceMaps({ destBase }) { + return through.obj((file, enc, callback) => { + const relativePath = path.relative(destBase, file.path); + + if (!files[relativePath]) { + return; + } + + if (file.sourceMap && file.sourceMap.preExistingComment) { + if (file.sourceMap.sources.length > 1) { + files[relativePath].hasSourceMap = true; + } else { + files[relativePath].notes.push('only one file'); + } + } + + callback(); + }); +} + +function escapeHTML(s) { + return s + .replace(/&/g, '&') + .replace(/"/g, '"') + .replace(//g, '>'); +} + +function hasFile(resolvedPath) { + if (!resolvedPath.endsWith('.html')) { + return false; + } + + const sourcePath = resolvedPath.slice(0, -5); + + return fs.existsSync(sourcePath); +} + +function formatSize(n) { + if (n < 1024) { + return `${n} B`; + } else if (n < MEBIBYTE) { + return `${(n / 1024).toFixed(2)} KiB`; + } + return `${(n / MEBIBYTE).toFixed(2)} MiB`; +} + +// https://github.com/shakyShane/dev-ip/blob/9f5a1b6154a16db88ca276c08426867c55924e61/lib/dev-ip.js +function getIp() { + const networkInterfaces = os.networkInterfaces(); + const matches = []; + + Object.keys(networkInterfaces).forEach(item => { + networkInterfaces[item].forEach(address => { + if (address.internal === false && address.family === 'IPv4') { + matches.push(address.address); + } + }); + }); + + return matches; +} + +function startServer({ destBase }) { + const root = path.resolve(destBase); + const server = http.createServer((req, res) => { + const { url } = req; + const resolvedPath = path.resolve(root, path.join(root, url)); + + if (!resolvedPath.startsWith(root)) { + res.writeHead(403); + res.end(); + return; + } + + if (url === '/') { + res.writeHead(200, { + 'Content-Type': 'text/html; charset=utf-8', + }); + + res.write( + `
Name | Size | Gzipped size | +Notes |
${ + file.hasSourceMap + ? `${escapedLink}` + : escapedLink + } | +${formatSize(file.size)} | +${formatSize(file.sizeGzipped)} | +${escapeHTML(file.notes.join(', '))} | +