1
1
mirror of https://github.com/primer/css.git synced 2024-12-28 08:31:58 +03:00
css/script/bundle-size-report

110 lines
3.2 KiB
Plaintext
Raw Normal View History

2019-04-26 23:12:00 +03:00
#!/usr/bin/env node
const fetch = require('node-fetch')
const filesize = require('filesize')
const minimist = require('minimist')
const {green, gray, yellow, red} = require('colorette')
const {table, getBorderCharacters} = require('table')
const options = minimist(process.argv.slice(2))
const DELTA = '±'
const VERSION = options.version || 'latest'
const QUIET = options.quiet || options.q || 0
const SORT = options.sort || options.s || 'gzip'
const ASCENDING = options.asc || options.a || false
const {name} = require('../package.json')
const unpkgBaseURL = `https://unpkg.com/${name}@${VERSION}/`
// ensure that K and B values line up vertically
const filesizeConfig = {symbols: {KB: 'K'}}
const prettySize = bytes => filesize(bytes, filesizeConfig)
const meta = require('../dist/meta.json')
Promise.all(
Object.values(meta.bundles).map(bundle => {
const entry = {
path: bundle.css,
local: require(`../${bundle.stats}`)
}
return fetch(unpkgBaseURL + bundle.stats)
.then(res => res.json())
.then(stats => (entry.remote = stats))
.then(() => entry)
})
).then(entries => {
const columns = [
{title: 'path', value: d => d.path, alignment: 'left'},
// CSS selector count
{title: 'selectors', value: d => d.local.selectors.total},
{title: DELTA, value: delta(d => d.selectors.total), id: 'selector-delta'},
// gzipped size (bytes)
{title: 'gzip size', value: d => prettySize(d.local.gzipSize), id: 'gzip'},
{title: DELTA, value: delta(d => d.gzipSize, prettySize), id: 'gzip-delta'},
// raw size (bytes)
{title: 'raw size', value: d => prettySize(d.local.size), id: 'size'},
{title: DELTA, value: delta(d => d.size, prettySize), id: 'size-delta'}
]
for (const [index, column] of Object.entries(columns)) {
column.index = index
}
const header = columns.map(c => c.title)
const data = entries.map(entry => columns.map(c => c.value(entry)))
if (SORT) {
const sortColumn = columns.find(c => c.id === SORT || c.title === SORT)
if (sortColumn) {
const order = ASCENDING ? (a, b) => (a - b) : (a, b) => (b - a)
const {index} = sortColumn
data.sort((a, b) => order(a[index].value, b[index].value))
} else {
console.warn(`No such sort column: "${SORT}"! Output will not be sorted.`)
}
}
const rows = data.map(cells => cells.map(String))
console.log(table([header].concat(rows), {
columns,
columnDefault: {
alignment: 'right'
},
border: getBorderCharacters('norc'),
drawHorizontalLine(index, size) {
return index <= 1 || index === size
}
}))
})
function delta(getter, format = String, options = {}) {
const {
moreIsGood = false,
badThreshold = 1000
} = options
return entry => {
const local = getter(entry.local)
const remote = getter(entry.remote)
const value = local - remote
if (value === 0) {
return {
value,
toString: () => ` ${gray(0)}`
}
} else {
const sign = value > 0 ? '+' : '-'
const num = Math.abs(value)
const good = moreIsGood ? value > 0 : value < 0
const color = good ? green : value >= badThreshold ? red : yellow
return {
value,
toString: () => color(`${sign} ${format(num)}`)
}
}
}
}