package-cost
Version:
Gets NPM package size - packed, unpacked, bundled, compressed - including dependencies recursively.
161 lines (152 loc) • 5.65 kB
JavaScript
const { argv } = process
const refs = []
/* c8 ignore start */
const sorts = {
package: ({ name, version }) => `${name}@${version}`,
deps: ({ depCount }) => depCount,
packed: ({ tarSize }) => tarSize,
unpacked: ({ rawSize }) => rawSize,
bundled: ({ bundleSize }) => bundleSize,
minified: ({ miniSize }) => miniSize,
gzipped: ({ gzipSize }) => gzipSize,
deflated: ({ deflateSize }) => deflateSize,
brotlied: ({ brotliSize }) => brotliSize
}
/* c8 ignore end */
let clean, write, parallel, extent, noRecurse, analyseAll, verbose, json, table, sort, direction
for (let i = 2, l = argv.length; i < l; ++i) {
const arg = argv[i]
const match = /^(-|--)([a-zA-Z]+)$/.exec(arg)
if (match) {
const args = match[1] === '-' ? match[2].split('') : [match[2]]
for (const arg of args) {
switch (arg) {
case 'c': case 'clean-cache':
clean = true
continue
case 'w': case 'write-cache':
write = true
continue
case 'p': case 'parallel':
parallel = +argv[++i]
if (!(parallel > 0)) {
console.error(`parallel not greater than zero: "${argv[i]}"`)
process.exit(1)
}
continue
case 'e': case 'extent':
extent = argv[++i]
if (extent !== 'none' && extent !== 'all') {
console.error(`invalid extent: "${argv[i]}"`)
process.exit(1)
}
continue
case 'n': case 'no-recurse':
noRecurse = true
continue
case 'a': case 'analyse-all':
analyseAll = true
continue
case 'j': case 'json':
json = true
continue
case 't': case 'table':
table = true
continue
case 's': case 'sort':
sort = argv[++i]
if (!sorts[sort]) {
console.error(`invalid sort column: "${argv[i]}"`)
process.exit(1)
}
continue
case 'd': case 'direction':
direction = argv[++i]
if (direction !== 'asc' && direction !== 'desc') {
console.error(`invalid sort direction: "${argv[i]}"`)
process.exit(1)
}
continue
case 'v': case 'verbose':
verbose = true
continue
case 'V': case 'version':
console.log(require('../package.json').version)
process.exit(0)
case 'h': case 'help':
require('./help')()
}
console.error(`unknown option: "${match[0]}"`)
process.exit(1)
}
continue
}
refs.push(arg)
}
const { estimatePkgSizes, cleanCache, writeCache } = require('.')
if (!refs.length) {
if (clean)
(async () => {
try {
await cleanCache()
} catch (err) {
console.error(verbose ? err : err.message)
process.exitCode = 1
}
})()
else {
console.log('No packages provided.\n')
require('./help')()
}
} else {
const { formatSize, pluralize } = require('./util')
function padSize(size) {
return formatSize(size).padEnd(9)
}
function printProgress({ name, version, tarSize, rawSize, bundleSize, miniSize, gzipSize, deflateSize, brotliSize, depCount }, { print }) {
const deps = depCount !== undefined ? `${pluralize(depCount, 'dependency', 'dependencies')}, ` : /* c8 ignore next */ ''
const bundled = bundleSize ? `, ${formatSize(bundleSize)} bundled, ${formatSize(miniSize)} minified, ${formatSize(gzipSize)} gzipped, ${formatSize(deflateSize)} deflated, ${formatSize(brotliSize)} brotlied` : /* c8 ignore next */ ''
print(`${name}@${version}: ${deps}${formatSize(tarSize)} packed, ${formatSize(rawSize)} unpacked${bundled}\n`)
}
function printTable(pkgs) {
let maxLen = 7, maxDeps = 4
for (const { name, version, depCount } of pkgs) {
const len = `${name}@${version}`.length
if (maxLen < len) maxLen = len
const deps = String(depCount).length
/* c8 ignore next */
if (maxDeps < deps) maxDeps = deps
}
console.log(`${'package'.padEnd(maxLen)} ${'deps'.padEnd(maxDeps)} packed unpacked bundled minified gzipped deflated brotlied`)
if (sort) {
const sorter = sorts[sort]
/* c8 ignore start */
const dir = direction !== 'desc' ? 1 : -1
pkgs = pkgs.sort((left, right) => sorter(left) < sorter(right) ? -dir : sorter(left) > sorter(right) ? dir : 0)
/* c8 ignore end */
}
for (const { name, version, tarSize, rawSize, bundleSize, miniSize, gzipSize, deflateSize, brotliSize, depCount } of pkgs) {
const id = `${name}@${version}`
/* c8 ignore start */
const deps = depCount !== undefined ? String(depCount).padEnd(maxDeps) : ' '.repeat(maxDeps)
const bundled = bundleSize ? `${padSize(bundleSize)} ${padSize(miniSize)} ${padSize(gzipSize)} ${padSize(deflateSize)} ${padSize(brotliSize)}` : ''
/* c8 ignore end */
console.log(`${id.padEnd(maxLen)} ${deps} ${padSize(tarSize)} ${padSize(rawSize)} ${bundled}`)
}
}
(async () => {
try {
const progress = json || table ? undefined : printProgress
if (extent === undefined) extent = noRecurse ? 'none' : analyseAll ? 'all' : undefined
if (clean) await cleanCache({ verbose })
const pkgs = await estimatePkgSizes(refs, { progress, parallel, extent, verbose })
if (write) await writeCache({ verbose })
if (json) console.log(JSON.stringify(pkgs))
else if (table) printTable(pkgs)
} catch (err) {
console.error(verbose ? err : err.message)
process.exitCode = 1
}
})()
}