File Size Impact
@jsenv/file-size-impact
analyzes a pull request's impact on file sizes and posts the results as a comment in your GitHub PR.
- ✅ Catch size impacts before merging pull requests
- 📦 Track compressed file sizes (gzip, brotli)
- 📊 Create meaningful reports by grouping files
- 🔄 Integrate with any CI/CD platform (GitHub Actions, Jenkins, etc.)
Quick Start
npm install --save-dev @jsenv/file-size-impact
- Create a file size tracking script
- Set up your CI workflow
- Get size impact comments on every PR!
Table of Contents
Pull Request Comment
Here's how the PR comments look with explanations:
Text | How to read it |
---|---|
"remaining files (+4.71%)" | There is a group of files named "remaining files" and pull request has an overall impact of +4.71% on these files. |
"21.6 kB (+4.11 kB / +23.55%)" | The size after merge is 21.6 kB. Pull request adds 4.11 kB representing an increase of 23.55% of the size before merge. |
"Unmodified (4)" | Sum of files in that group that are not impacted by the pull request. |
Total (5) | Sum of files in that group. |
Installation
Step 1: Create a file size report script
First, create a script that generates your file size report:
// file_size.mjs
import { generateFileSizeReport } from "@jsenv/file-size-impact";
export const fileSizeReport = await generateFileSizeReport({
log: process.argv.includes("--log"),
rootDirectoryUrl: new URL("./", import.meta.url),
trackingConfig: {
dist: {
"./dist/**/*": true,
"./dist/**/*.map": false,
},
},
});
Test it locally:
node ./file_size.mjs --log
Step 2: Create a report script
// report_file_size_impact.mjs
import {
reportFileSizeImpactInGitHubPullRequest,
readGitHubWorkflowEnv,
} from "@jsenv/file-size-impact";
await reportFileSizeImpactInGitHubPullRequest({
...readGitHubWorkflowEnv(),
buildCommand: "npm run dist",
fileSizeReportUrl: new URL("./file_size.mjs#fileSizeReport", import.meta.url),
});
GitHub Workflow
Create a GitHub Actions workflow file:
# .github/workflows/file_size_impact.yml
name: file size impact
on: pull_request
jobs:
file_size_impact:
runs-on: ubuntu-latest
name: file size impact
steps:
- name: Setup git
uses: actions/checkout@v3
- name: Setup node
uses: actions/setup-node@v3
with:
node-version: "18.3.0"
- name: Setup npm
run: npm install
- name: Report file size impact
run: node ./report_file_size_impact.mjs
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
That's it! Now your PRs will automatically get file size impact comments.
Other Tools
If you want to use another CI tool like Jenkins:
- Create a GitHub token with
repo
scope at https://github.com/settings/tokens/new - Update your report script to provide environment variables:
// report_file_size_impact.mjs for Jenkins
import { reportFileSizeImpactInGitHubPullRequest } from "@jsenv/file-size-impact";
await reportFileSizeImpactInGitHubPullRequest({
rootDirectoryUrl: process.env.WORKSPACE, // Jenkins workspace
repositoryOwner: process.env.GITHUB_REPO_OWNER,
repositoryName: process.env.GITHUB_REPO_NAME,
pullRequestNumber: process.env.PULL_REQUEST_NUMBER,
githubToken: process.env.GITHUB_TOKEN,
buildCommand: "npm run dist",
fileSizeReportUrl: new URL("./file_size.mjs#fileSizeReport", import.meta.url),
runLink: {
url: process.env.BUILD_URL,
text: `${process.env.JOB_NAME}#${process.env.BUILD_ID}`,
},
});
- Configure your CI job to execute the necessary git commands:
git init
git remote add origin $GITHUB_REPOSITORY_URL
git fetch --no-tags --prune origin $PULL_REQUEST_HEAD_REF
git checkout origin/$PULL_REQUEST_HEAD_REF
npm install
node ./report_file_size_impact.mjs
How it Works
The file size impact analysis follows these steps:
- Checkout pull request base branch
- Execute an install command (npm install by default)
- Run a build command (npm run-script build by default)
- Generate a baseline file size report
- Merge pull request into its base
- Rebuild files
- Generate a second file size report
- Analyze differences between the two reports
- Post or update a comment in the pull request
API Reference
generateFileSizeReport
Scans the filesystem to compute file sizes with optional transformations:
import {
generateFileSizeReport,
raw,
gzip,
brotli,
} from "@jsenv/file-size-impact";
const fileSizeReport = await generateFileSizeReport({
rootDirectoryUrl: new URL("./", import.meta.url),
trackingConfig: {
"critical files": {
"./dist/main.js": true,
"./dist/main.css": true,
},
"remaining files": {
"./dist/**/*.js": true,
"./dist/**/*.css": true,
"./dist/main.js": false, // Exclude files already in "critical files"
"./dist/main.css": false, // Exclude files already in "critical files"
},
},
transformations: { raw, gzip, brotli },
});
Options
- rootDirectoryUrl: Project root directory (required)
- trackingConfig: File groups to track (optional)
- transformations: Size transformations, like compression (optional)
- manifestConfig: Configuration for files with dynamic names (optional)
reportFileSizeImpactInGitHubPullRequest
Analyzes PR impact and posts a comment with results:
import { reportFileSizeImpactInGitHubPullRequest } from "@jsenv/file-size-impact";
await reportFileSizeImpactInGitHubPullRequest({
logLevel: "info",
rootDirectoryUrl: "file:///directory",
githubToken: "xxx",
repositoryOwner: "jsenv",
repositoryName: "file-size-impact",
pullRequestNumber: 10,
installCommand: "npm install",
buildCommand: "npm run build",