Skip to content

Commit a373beb

Browse files
committed
Add scripts/check-electron-sdk-size.ts
1 parent 7f862c7 commit a373beb

File tree

3 files changed

+137
-1
lines changed

3 files changed

+137
-1
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,4 @@ docs/
3030
test-results/
3131
playwright-report/
3232
.vscode
33+
/.claude/settings.local.json

scripts/check-electron-sdk-size.ts

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
import * as fs from 'node:fs'
2+
import * as path from 'node:path'
3+
import * as os from 'node:os'
4+
import { printLog, printError, runMain, formatSize } from './lib/executionUtils.ts'
5+
import { command } from './lib/command.ts'
6+
7+
const SAMPLE_APP_NAME = 'electron-size-test-app'
8+
9+
runMain(() => {
10+
printLog('Starting Electron SDK size check...\n')
11+
12+
// Create temporary directory for the sample app
13+
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'electron-sdk-size-'))
14+
const appDir = path.join(tempDir, SAMPLE_APP_NAME)
15+
16+
try {
17+
printLog(`Creating sample Electron app in ${appDir} ...`)
18+
createElectronApp(tempDir)
19+
20+
printLog('Packaging base app...')
21+
const baseSize = packageApp(appDir)
22+
printLog(`Base app size: ${formatSize(baseSize)}\n`)
23+
24+
printLog('Installing Electron SDK...')
25+
installElectronSdk(appDir)
26+
27+
printLog('Instrumenting app with SDK...')
28+
instrumentApp(appDir)
29+
30+
printLog('Packaging instrumented app...')
31+
const instrumentedSize = packageApp(appDir)
32+
printLog(`Instrumented app size: ${formatSize(instrumentedSize)}\n`)
33+
34+
// Calculate overhead
35+
const overhead = instrumentedSize - baseSize
36+
37+
printLog(`SDK Overhead: ${formatSize(overhead, { includeSign: true })}`)
38+
} catch (error) {
39+
printError('Failed to check Electron SDK size:', error)
40+
throw error
41+
} finally {
42+
// Cleanup temporary directory
43+
printLog('\nCleaning up temporary files...')
44+
fs.rmSync(tempDir, { recursive: true, force: true })
45+
}
46+
})
47+
48+
function createElectronApp(tempDir: string): void {
49+
// Use create-electron-app to scaffold a new app
50+
// Using --template=webpack to get a standard webpack-based setup
51+
command`npm create electron-app@latest ${SAMPLE_APP_NAME} -- --template=webpack`
52+
.withCurrentWorkingDirectory(tempDir)
53+
.run()
54+
}
55+
56+
function installElectronSdk(appDir: string): void {
57+
const electronPackagePath = path.join(import.meta.dirname, '../packages/electron')
58+
59+
command`yarn build`.withCurrentWorkingDirectory(electronPackagePath).run()
60+
61+
command`npm install @datadog/electron@file:${electronPackagePath}`.withCurrentWorkingDirectory(appDir).run()
62+
}
63+
64+
function instrumentApp(appDir: string): void {
65+
// Update the main entry point to initialize the SDK
66+
// Electron Forge with webpack template uses src/main.js as the main entry
67+
const mainJsPath = path.join(appDir, 'src', 'main.js')
68+
const currentMainJs = fs.readFileSync(mainJsPath, 'utf8')
69+
70+
const instrumentedMainJs = `import { ddElectron } from '@datadog/electron/main';
71+
72+
// Initialize Datadog Electron SDK
73+
ddElectron.init({
74+
clientToken: 'pub0000000000000000000000000000000',
75+
site: 'datadoghq.com',
76+
service: 'electron-size-test',
77+
env: 'test',
78+
});
79+
80+
${currentMainJs}
81+
`
82+
fs.writeFileSync(mainJsPath, instrumentedMainJs)
83+
}
84+
85+
function packageApp(appDir: string): number {
86+
// Clean previous build
87+
const outDir = path.join(appDir, 'out')
88+
if (fs.existsSync(outDir)) {
89+
fs.rmSync(outDir, { recursive: true, force: true })
90+
}
91+
92+
// Package the app using electron-forge
93+
command`npm run package`.withCurrentWorkingDirectory(appDir).run()
94+
95+
// Find the macOS .app bundle
96+
const appBundlePath = findMacOSAppBundle(outDir)
97+
98+
if (!appBundlePath) {
99+
throw new Error('Could not find .app bundle in out directory')
100+
}
101+
102+
// Calculate size of the entire app bundle
103+
return getDirectorySize(appBundlePath)
104+
}
105+
106+
function findMacOSAppBundle(outDir: string): string | null {
107+
// On macOS, Electron Forge outputs: out/electron-size-test-app-darwin-arm64/electron-size-test-app.app
108+
const pattern = path.join(outDir, '**/*.app')
109+
const matches = fs.globSync(pattern, { cwd: outDir })
110+
111+
if (matches.length > 0) {
112+
const match = matches[0]
113+
return path.isAbsolute(match) ? match : path.join(outDir, match)
114+
}
115+
116+
return null
117+
}
118+
119+
function getDirectorySize(dirPath: string): number {
120+
// Use du utility to calculate disk usage
121+
// -s: display only total for each argument
122+
// -k: show size in kilobytes
123+
const output = command`du -sk ${dirPath}`.run()
124+
125+
// du output format: "12345\t/path/to/directory"
126+
const sizeInKb = parseInt(output.split('\t')[0], 10)
127+
128+
// Convert kilobytes to bytes
129+
return sizeInKb * 1024
130+
}

scripts/lib/executionUtils.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,12 @@ export function formatSize(bytes: number | null, { includeSign = false } = {}):
5555
return `${sign}${Math.round(bytes)} B`
5656
}
5757

58-
return `${sign}${(bytes / 1024).toFixed(2)} KiB`
58+
const kib = bytes / 1024
59+
if (kib > -1024 && kib < 1024) {
60+
return `${sign}${kib.toFixed(2)} KiB`
61+
}
62+
63+
return `${sign}${(kib / 1024).toFixed(2)} MiB`
5964
}
6065

6166
export function formatPercentage(percentage: number, { includeSign = false } = {}): string {

0 commit comments

Comments
 (0)