Comparing version 0.3.0 to 0.4.0
class BundleSizeAnalyser { | ||
constructor(fs, path, glob, gzipSize, brotliSize, chalk) { | ||
constructor(fs, path, glob, zlib, chalk) { | ||
this.fs = fs; | ||
this.path = path; | ||
this.glob = glob; | ||
this.gzipSize = gzipSize; // This is now an injected function | ||
this.brotliSize = brotliSize; // This is also an injected function | ||
this.zlib = zlib; | ||
this.chalk = chalk; | ||
@@ -13,2 +12,26 @@ this.results = {}; | ||
async calculateGzipSize(fileContent) { | ||
return new Promise((resolve, reject) => { | ||
this.zlib.gzip(fileContent, (err, result) => { | ||
if (err) { | ||
reject(new Error(`Gzip compression failed: ${err.message}`)); | ||
} else { | ||
resolve(result.length); | ||
} | ||
}); | ||
}); | ||
} | ||
async calculateBrotliSize(fileContent) { | ||
return new Promise((resolve, reject) => { | ||
this.zlib.brotliCompress(fileContent, (err, result) => { | ||
if (err) { | ||
reject(new Error(`Brotli compression failed: ${err.message}`)); | ||
} else { | ||
resolve(result.length); | ||
} | ||
}); | ||
}); | ||
} | ||
async loadConfig(configPath) { | ||
@@ -46,18 +69,2 @@ const configContent = await this.fs.readFile(configPath, 'utf8'); | ||
async calculateGzipSize(fileContent) { | ||
try { | ||
return await this.gzipSize(fileContent); | ||
} catch (error) { | ||
throw new Error(`Gzip compression failed: ${error.message}`); | ||
} | ||
} | ||
async calculateBrotliSize(fileContent) { | ||
try { | ||
return await this.brotliSize(fileContent); | ||
} catch (error) { | ||
throw new Error(`Brotli compression failed: ${error.message}`); | ||
} | ||
} | ||
async calculateSizes(filePaths, compression) { | ||
@@ -72,7 +79,7 @@ const fileContents = await this.batchReadFiles(filePaths); // Read all files in parallel | ||
if (compression.gzip) { | ||
gzipSize = await this.gzipSize(fileContent); | ||
gzipSize = await this.calculateGzipSize(fileContent); | ||
} | ||
if (compression.brotli) { | ||
brotliSize = await this.brotliSize(fileContent); | ||
brotliSize = await this.calculateBrotliSize(fileContent); | ||
} | ||
@@ -227,10 +234,28 @@ | ||
warnOnIncrease = defaults.warnOnIncrease || '5%', | ||
include, | ||
distFolderLocation, | ||
exclude: componentExclude = exclude | ||
} = componentConfig; | ||
const includePatterns = Array.isArray(include) ? include : [include]; | ||
// Resolve the dist folder path | ||
if (!distFolderLocation) { | ||
throw new Error(`Error: distFolderLocation is not defined for component: ${componentName}`); | ||
} | ||
const distFolderPath = this.path.resolve(process.cwd(), distFolderLocation); | ||
// Check if the folder exists before proceeding | ||
try { | ||
await this.fs.access(distFolderPath); | ||
} catch (err) { | ||
console.error(this.chalk.red(`Error: distFolderLocation ${distFolderPath} not found for component: ${componentName}`)); | ||
throw new Error(`Dist folder not found for component: ${componentName}`); | ||
} | ||
const includePattern = `${distFolderPath}/**/*.js`; // Automatically include all JS files in the folder | ||
// Handle exclusion patterns | ||
const excludePatterns = Array.isArray(componentExclude) ? componentExclude : [componentExclude]; | ||
const allJsFiles = await this.collectFiles(includePatterns, excludePatterns); | ||
// Collect all JS files from the folder, excluding specified patterns | ||
const allJsFiles = await this.collectFiles([includePattern], excludePatterns); | ||
@@ -301,4 +326,5 @@ // Filter in-memory for index.js, react.js, and other JS files | ||
} | ||
} | ||
export default BundleSizeAnalyser; |
@@ -8,2 +8,8 @@ # Changelog | ||
## [0.4.0] - 19-10-2024 | ||
### Changed | ||
- Switch to `distFolderLocation` in config instead of `includes` | ||
## [0.3.0] - 19-10-2024 | ||
@@ -10,0 +16,0 @@ |
36
index.js
@@ -11,28 +11,5 @@ #!/usr/bin/env node | ||
async function calculateGzipSize(fileContent) { | ||
return new Promise((resolve, reject) => { | ||
zlib.gzip(fileContent, (err, result) => { | ||
if (err) { | ||
reject(err); | ||
} else { | ||
resolve(result.length); | ||
} | ||
}); | ||
}); | ||
} | ||
async function calculateBrotliSize(fileContent) { | ||
return new Promise((resolve, reject) => { | ||
zlib.brotliCompress(fileContent, (err, result) => { | ||
if (err) { | ||
reject(err); | ||
} else { | ||
resolve(result.length); | ||
} | ||
}); | ||
}); | ||
} | ||
(async () => { | ||
const startTime = Date.now(); // Capture the start time | ||
const startTime = Date.now(); | ||
const program = new Command(); | ||
@@ -43,14 +20,13 @@ program.option('-c, --config <path>', 'Path to configuration file', 'compsizer.config.json'); | ||
const options = program.opts(); | ||
const configPath = path.resolve(process.cwd(), options.config); // Resolve config relative to the user's project | ||
const configPath = path.resolve(process.cwd(), options.config); | ||
try { | ||
const analyser = new BundleSizeAnalyser(fs, path, glob, calculateGzipSize, calculateBrotliSize, chalk); | ||
const analyser = new BundleSizeAnalyser(fs, path, glob, zlib, chalk); | ||
const config = await analyser.loadConfig(configPath); | ||
const success = await analyser.analyseComponents(config); // Capture success/failure | ||
const endTime = Date.now(); // Capture the end time | ||
const duration = (endTime - startTime) / 1000; // Calculate duration in seconds | ||
const success = await analyser.analyseComponents(config); | ||
const endTime = Date.now(); | ||
const duration = (endTime - startTime) / 1000; | ||
console.log(chalk.green.bold(`\ncompsizer analysis took: ${duration.toFixed(2)} seconds\n`)); | ||
// Exit based on the success status | ||
process.exit(success ? 0 : 1); | ||
@@ -57,0 +33,0 @@ |
{ | ||
"name": "compsizer", | ||
"version": "0.3.0", | ||
"version": "0.4.0", | ||
"description": "A tool for analysing the size of component packages in your monorepo.", | ||
@@ -5,0 +5,0 @@ "type": "module", |
@@ -67,2 +67,4 @@ | ||
**Note:** You can choose to place a single configuration file at the root of your repository and list all of your components in the `components` property together. However, please be aware that depending on how many components you add, it could take a while to generate the size reports for all of them at once. | ||
### Example Configuration (placed in each component package, e.g., `modal/compsizer.config.json`) | ||
@@ -84,6 +86,5 @@ | ||
"warnOnIncrease": "10%", | ||
"include": [ | ||
"./dist/**/*.js" | ||
] | ||
} | ||
"distFolderLocation": "./dist" | ||
}, | ||
// You could add more components here if placing this config at the root of your project. | ||
}, | ||
@@ -93,3 +94,2 @@ "defaults": { | ||
} | ||
} | ||
``` | ||
@@ -107,3 +107,3 @@ | ||
- `warnOnIncrease`: (string) Warn if the size increases by more than the specified percentage. | ||
- `include`: (array) Glob patterns specific to the component to include. | ||
- `distFolderLocation`: (string) Path pointing to the built component files. | ||
- `exclude`: (array) Glob patterns specific to the component to exclude. (Overrides the base `exclude`) | ||
@@ -110,0 +110,0 @@ - **defaults**: (object) Default settings that apply to all components. |
21532
308