Skip to content

Commit

Permalink
v2.2.0
Browse files Browse the repository at this point in the history
  • Loading branch information
benelan committed Feb 18, 2022
1 parent e7e7143 commit f7c21e0
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 31 deletions.
37 changes: 29 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ Provides sizes for an application's production build.
| --------- | ---------------------------------------------------------------------------- | ------ |
| buildPath | path from the current working directory to the application's build directory | string |

The function returns a `Promise` which resolves an object with three properties.
The function returns a `Promise` which resolves an object with three properties (`Promise<{ mainBundleSize: number, buildSize:number, buildFileCount: number}>`).

| Return Property | Description | Type |
| --------------- | --------------------------------------------------- | ------ |
Expand All @@ -107,13 +107,13 @@ The function returns a `Promise` which resolves an object with three properties.

Formats bytes to a human readable size.

| Parameter | Description | Type |
| ------------------- | ------------------------------------------------------ | ------- |
| bytes | bytes to format into human readable size | number |
| decimals (optional) | number of decimal points for rounding (default is `2`) | number |
| binary (optional) | binary or decimal conversion (default is `true`) | boolean |
| Parameter | Description | Type |
| ------------------- | ------------------------------------------------ | ------- |
| bytes | bytes to format into human readable size | number |
| decimals (optional) | decimal precision for rounding(default is `2`) | number |
| binary (optional) | binary or decimal conversion (default is `true`) | boolean |

The function returns a `string` of a human readable size with units.
The function returns a human readable size with units (`string`).

### getFiles

Expand All @@ -123,9 +123,30 @@ Returns all files in a directory (recursively).
| ------------- | ----------------------------------------------------------------------------- | ------ |
| directoryPath | path from the current working directory to the directory containing the files | string |

The function returns a `Promise` which resolves an array of objects with two properties.
The function returns a `Promise` which resolves an array of objects with two properties (`Promise<{path: string, name: string}[]>`).

| Return Property | Description | Type |
| --------------- | ------------------------- | ------ |
| path | absolute path of the file | string |
| name | name of the file | string |

### filterFilesByType

Filters files by filetype.

| Parameter | Description | Type |
| --------- | ----------------------------------------------- | ------------------------------ |
| files | files from the [`getFiles`](#getfiles) function | {path: string, name: string}[] |
| type | file type, e.g. "js", "css", "tsx", etc. | string |

The function returns the files filtered by type (`{path: string, name: string}[]`).

### getFileSizes

Gets file sizes.

| Parameter | Description | Type |
| --------- | ----------------------------------------------- | ------------------------------ |
| files | files from the [`getFiles`](#getfiles) function | {path: string, name: string}[] |

The function returns a `Promise` which resolves an array of file sizes (`Promise<numbers[]>`).
57 changes: 37 additions & 20 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@ const {

/**
* Returns all files in a directory (recursively)
* @param {string} directoryPath - path to the build directory
* @param {string} directoryPath - path from the current working directory to the directory containing the files
* @returns {Promise<{path: string, name: string}[]>} file path and name
*/
const getFiles = async (directoryPath) => {
const entries = await readdir(directoryPath, { withFileTypes: true });
const files = entries
.filter((file) => !file.isDirectory())
.map((file) => ({ ...file, path: resolve(directoryPath, file.name) }));

const directories = entries.filter((folder) => folder.isDirectory());

for (const directory of directories) {
Expand All @@ -27,23 +28,39 @@ const getFiles = async (directoryPath) => {

/**
* Formats bytes to a human readable size
* @param {number} bytes - the byte file size to convert
* @param {number} [decimals=2] - number of decimal points to round
* @param {number} bytes - bytes to format into human readable size
* @param {number} [decimals=2] - decimal precision for rounding
* @param {boolean} [binary=true] - binary or decimal conversion
* @returns human readable file size with units
* @returns {string} human readable file size with units
*/

const formatBytes = (bytes, decimals = 2, binary = true) => {
if (bytes === 0) return "0 Bytes";

const unitSizes = ["Bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
const k = binary ? 1024 : 1000; // binary vs decimal conversion
const d = decimals < 0 ? 0 : decimals;
const d = !decimals || decimals < 0 ? 0 : decimals; // no negative decimal precision
const i = Math.floor(Math.log(bytes) / Math.log(k));

return `${parseFloat((bytes / Math.pow(k, i)).toFixed(d))} ${unitSizes[i]}`;
};

/**
* Filters files by filetype
* @param {{path: string, name: string}[]} files - files from the `getFiles` function
* @param {string} type - file type, e.g. "js", "css", "tsx", etc.
* @returns {{path: string, name: string}[]} - files filtered by filetype
*/
const filterFilesByType = (files, type) =>
files.filter((file) => new RegExp(`.${type}$`, "i").test(file.name));

/**
* Gets file sizes
* @param {{path: string, name: string}[]} files - files from the `getFiles` function
* @returns {Promise<number[]>} sizes of the files
*/
const getFileSizes = async (files) =>
await Promise.all(files.map(async (file) => (await stat(file.path)).size));

/**
* Provides sizes for an application's production build
* @param {string} buildPath - path from the current working directory to the build directory
Expand All @@ -54,26 +71,26 @@ const formatBytes = (bytes, decimals = 2, binary = true) => {
*/
const getBuildSizes = async (buildPath) => {
const build = resolve(process.cwd(), buildPath);

const buildFiles = await getFiles(build);

// largest javascript file
const mainBundleSize = Math.max(
...(await Promise.all(
buildFiles
.filter((file) => /.js$/.test(file.name))
.map(async (file) => (await stat(file.path)).size)
))
...(await getFileSizes(filterFilesByType(buildFiles, "js")))
);
// sum of file sizes
const buildSize = (await getFileSizes(buildFiles)).reduce(
(count, fileSize) => count + fileSize,
0
);

const buildSize = (
await Promise.all(
buildFiles.map(async (file) => (await stat(file.path)).size)
)
).reduce((count, fileSize) => count + fileSize, 0);

const buildFileCount = buildFiles.length;

return { mainBundleSize, buildSize, buildFileCount };
};

module.exports = { getBuildSizes, getFiles, formatBytes };
module.exports = {
getBuildSizes,
formatBytes,
getFiles,
getFileSizes,
filterFilesByType,
};
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "build-sizes",
"version": "2.1.0",
"version": "2.2.0",
"description": "A small script that provides sizes of production builds to assist with optimization",
"keywords": [
"metrics",
Expand Down

0 comments on commit f7c21e0

Please sign in to comment.