From 4f5b63ca9ce9712da21348175cce54ae0322e254 Mon Sep 17 00:00:00 2001 From: Daniel Lando Date: Tue, 3 Oct 2023 16:09:21 +0200 Subject: [PATCH] fix: diagnostic folder size and humanize size --- README.md | 6 +++++ prelude/diagnostic.js | 55 ++++++++++++++++++++++++++++++++++++++----- 2 files changed, 55 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 61e0400e1..50cb1e552 100644 --- a/README.md +++ b/README.md @@ -208,6 +208,12 @@ Pass `--debug` to `pkg` to get a log of packaging process. If you have issues with some particular file (seems not packaged into executable), it may be useful to look through the log. +In order to get more detailed logs on startup, after you packaged your application using `--debug`, you can start your application with the environment variable `DEBUG_PKG` set to `1` or `2` if you want more verbose debugging. This will load `prelude/diagnostic.js` that will print the snapshot tree and the symlink table, when set to `2` it will also mock `fs` in order to print logs when a method is called. + +This is useful to see what's included in your bundle and detect possible missing files or large files that could be removed from it in order to reduce the size of the executable. + +You can also use `SIZE_LIMIT_PKG` and `FOLDER_LIMIT_PKG` to print files/folders that are larger than the specified size limit (in bytes). By default, the size limit is set to 5MB for files and 10MB for folders. + ### Bytecode (reproducibility) By default, your source code is precompiled to v8 bytecode before being written diff --git a/prelude/diagnostic.js b/prelude/diagnostic.js index 343048c6d..5b513ed08 100644 --- a/prelude/diagnostic.js +++ b/prelude/diagnostic.js @@ -4,14 +4,40 @@ 'use strict'; +function humanSize(bytes) { + const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB']; + + if (bytes === 0) { + return 'n/a'; + } + + const i = Math.floor(Math.log(bytes) / Math.log(1024)); + + if (i === 0) { + return `${bytes} ${sizes[i]}`; + } + + return `${(bytes / 1024 ** i).toFixed(1)} ${sizes[i]}`; +} + (function installDiagnostic() { const fs = require('fs'); const path = require('path'); const win32 = process.platform === 'win32'; + const sizeLimit = process.env.SIZE_LIMIT_PKG + ? parseInt(process.env.SIZE_LIMIT_PKG, 10) + : 5 * 1024 * 1024; + const folderLimit = process.env.FOLDER_LIMIT_PKG + ? parseInt(process.env.FOLDER_LIMIT_PKG, 10) + : 10 * 1024 * 1024; + if (process.env.DEBUG_PKG === '2') { console.log(Object.entries(DICT)); } + + const overSized = []; + function dumpLevel(filename, level, tree) { let totalSize = 0; const d = fs.readdirSync(filename); @@ -21,22 +47,33 @@ const isSymbolicLink2 = f !== realPath; const s = fs.statSync(f); - totalSize += s.size; if (s.isDirectory() && !isSymbolicLink2) { const tree1 = []; - totalSize += dumpLevel(f, level + 1, tree1); + const startIndex = overSized.length; + const folderSize = dumpLevel(f, level + 1, tree1); + totalSize += folderSize; const str = (' '.padStart(level * 2, ' ') + d[j]).padEnd(40, ' ') + - (totalSize.toString().padStart(10, ' ') + + (humanSize(folderSize).padStart(10, ' ') + (isSymbolicLink2 ? `=> ${realPath}` : ' ')); tree.push(str); tree1.forEach((x) => tree.push(x)); + + if (folderSize > folderLimit) { + overSized.splice(startIndex, 0, str); + } } else { + totalSize += s.size; const str = (' '.padStart(level * 2, ' ') + d[j]).padEnd(40, ' ') + - (s.size.toString().padStart(10, ' ') + + (humanSize(s.size).padStart(10, ' ') + (isSymbolicLink2 ? `=> ${realPath}` : ' ')); + + if (s.size > sizeLimit) { + overSized.push(str); + } + tree.push(str); } } @@ -62,7 +99,13 @@ const totalSize = dumpLevel(startFolder, 1, tree); console.log(tree.join('\n')); - console.log('Total size = ', totalSize); + console.log('Total size = ', humanSize(totalSize)); + + if (overSized.length > 0) { + console.log('------------------------------- oversized files'); + console.log(overSized.join('\n')); + } + if (process.env.DEBUG_PKG === '2') { wrap(fs, 'openSync'); wrap(fs, 'open'); @@ -90,4 +133,4 @@ wrap(fs, 'access'); } } -})(); +})(); \ No newline at end of file