UNPKG

2.44 kBJavaScriptView Raw
1"use strict";
2
3/**
4 * Modules are the individual files within an asset.
5 */
6const { relative, resolve, sep } = require("path");
7const filesize = require("filesize");
8
9const PERCENT_MULTIPLIER = 100;
10const PERCENT_PRECISION = 3;
11
12// Convert to:
13// - existing source file name
14// - the path leading up to **just** the package (not including subpath).
15function _formatFileName(mod) {
16 const { fileName, baseName } = mod;
17
18 // Source file.
19 if (!baseName) {
20 return `{green-fg}.${sep}${relative(process.cwd(), resolve(fileName))}{/}`;
21 }
22
23 // Package
24 let parts = fileName.split(sep);
25 // Remove starting path.
26 const firstNmIdx = parts.indexOf("node_modules");
27 parts = parts.slice(firstNmIdx);
28
29 // Remove trailing path after package.
30 const lastNmIdx = parts.lastIndexOf("node_modules");
31 const isScoped = (parts[lastNmIdx + 1] || "").startsWith("@");
32 parts = parts.slice(0, lastNmIdx + (isScoped ? 3 : 2)); // eslint-disable-line no-magic-numbers
33
34 return parts.map(part => (part === "node_modules" ? "~" : `{yellow-fg}${part}{/}`)).join(sep);
35}
36
37function _formatPercentage(modSize, assetSize) {
38 const percentage = ((modSize / assetSize) * PERCENT_MULTIPLIER).toPrecision(PERCENT_PRECISION);
39
40 return `${percentage}%`;
41}
42
43function formatModules(mods) {
44 // We _could_ use the `asset.meta.full` from inspectpack, but that is for
45 // the entire module with boilerplate included. We instead do a percentage
46 // of the files we're counting here.
47 const assetSize = mods.reduce((count, mod) => count + mod.size.full, 0);
48
49 // First, process the modules into a map to normalize file paths.
50 const modsMap = mods.reduce((memo, mod) => {
51 // File name collapses to packages for dependencies.
52 // Aggregate into object.
53 const fileName = _formatFileName(mod);
54
55 // Add in information.
56 memo[fileName] = memo[fileName] || {
57 fileName,
58 num: 0,
59 size: 0
60 };
61 memo[fileName].num += 1;
62 memo[fileName].size += mod.size.full;
63
64 return memo;
65 }, {});
66
67 return [].concat(
68 [["Name", "Size", "Percent"]],
69 Object.keys(modsMap)
70 .map(fileName => modsMap[fileName])
71 .sort((a, b) => a.size < b.size) // sort largest first
72 .map(mod => [
73 `${mod.fileName} ${mod.num > 1 ? `(${mod.num})` : ""}`,
74 filesize(mod.size),
75 _formatPercentage(mod.size, assetSize)
76 ])
77 );
78}
79
80module.exports = {
81 formatModules,
82 _formatFileName,
83 _formatPercentage
84};