website-htmx-rustelo-code/scripts/build/validate-wasm-bundle.nu

231 lines
7.2 KiB
Text
Raw Permalink Normal View History

2026-07-10 03:44:13 +01:00
#!/usr/bin/env nu
# WASM Bundle Validation Script for Rustelo Project
# Validates WASM bundle generation, size, and JavaScript bindings
def main [
--path: string = "." # Path to project root
--max-size: int = 5000000 # Maximum WASM size in bytes (5MB default)
--check-bindings # Verify JavaScript bindings exist
] {
print "🔍 Validating WASM bundle and JavaScript bindings..."
mut issues = []
# Check WASM files
let issues = ($issues | append (check_wasm_files $path $max_size))
# Check JavaScript bindings
if $check_bindings {
let issues = ($issues | append (check_js_bindings $path))
}
# Check site output
let issues = ($issues | append (check_site_output $path))
# Display results
if ($issues | is-empty) {
print "✅ WASM bundle validation passed!"
return 0
} else {
print "❌ WASM bundle validation issues found:"
for $issue in $issues {
print $" ($issue.severity): ($issue.message)"
if ($issue.fix?) {
print $" Fix: ($issue.fix)"
}
}
let errors = ($issues | where severity == "ERROR")
if not ($errors | is-empty) {
return 1
} else {
return 0
}
}
}
# Check WASM files in build directories
def check_wasm_files [path: string, max_size: int] {
mut issues = []
print "🔍 Checking WASM files..."
# Check target/front directory (cargo build output)
let wasm_build_dir = $"($path)/target/front/wasm32-unknown-unknown/debug"
if ($wasm_build_dir | path exists) {
let wasm_files = try {
ls $"($wasm_build_dir)/*.wasm" | get name
} catch {
[]
}
if ($wasm_files | is-empty) {
$issues = ($issues | append {
severity: "ERROR"
message: "No WASM files found in target/front directory"
fix: "Run 'cargo build --target wasm32-unknown-unknown --package client'"
})
} else {
for $wasm_file in $wasm_files {
let size = ($wasm_file | path stat | get size)
let name = ($wasm_file | path basename)
print $"(ansi green)✅ WASM file: ($name) (($size) bytes)(ansi reset)"
if $size > $max_size {
$issues = ($issues | append {
severity: "WARNING"
message: $"WASM file ($name) is large: ($size) bytes"
fix: "Consider optimizing WASM bundle size"
})
}
if $size < 1000 {
$issues = ($issues | append {
severity: "ERROR"
message: $"WASM file ($name) is suspiciously small: ($size) bytes"
fix: "Check if WASM build completed successfully"
})
}
}
}
} else {
$issues = ($issues | append {
severity: "ERROR"
message: "WASM build directory not found"
fix: "Run 'cargo build --target wasm32-unknown-unknown --package client'"
})
}
$issues
}
# Check JavaScript bindings generated by wasm-bindgen
def check_js_bindings [path: string] {
mut issues = []
print "🔍 Checking JavaScript bindings..."
# Check target/site/pkg directory (leptos output)
let pkg_dir = $"($path)/target/site/pkg"
if ($pkg_dir | path exists) {
# Check for JS files
let js_files = try {
ls $"($pkg_dir)/*.js" | get name
} catch {
[]
}
if ($js_files | is-empty) {
$issues = ($issues | append {
severity: "ERROR"
message: "No JavaScript binding files found"
fix: "Run 'cargo leptos build' to generate bindings"
})
} else {
for $js_file in $js_files {
let size = ($js_file | path stat | get size)
let name = ($js_file | path basename)
print $"(ansi green)✅ JS binding: ($name) (($size) bytes)(ansi reset)"
# Check for essential wasm-bindgen patterns
let content = try {
open $js_file
} catch {
""
}
let required_patterns = [
"wasm"
"init"
"memory"
]
for $pattern in $required_patterns {
if not ($content | str contains $pattern) {
$issues = ($issues | append {
severity: "WARNING"
message: $"JS binding ($name) missing expected pattern: ($pattern)"
fix: "Check wasm-bindgen generation"
})
}
}
}
}
} else {
$issues = ($issues | append {
severity: "WARNING"
message: "Leptos pkg directory not found"
fix: "Run 'cargo leptos build' to generate site output"
})
}
$issues
}
# Check site output directory
def check_site_output [path: string] {
mut issues = []
print "🔍 Checking site output..."
let site_dir = $"($path)/target/site"
if not ($site_dir | path exists) {
$issues = ($issues | append {
severity: "WARNING"
message: "Site output directory not found"
fix: "Run 'cargo leptos build'"
})
return $issues
}
# Check for essential files
let essential_files = [
"pkg" # WASM and JS bindings
"index.html" # Main HTML file (might not exist for SPA)
]
for $file in $essential_files {
let file_path = $"($site_dir)/($file)"
if ($file_path | path exists) {
if ($file | str ends-with ".html") {
let size = ($file_path | path stat | get size)
print $"(ansi green)✅ Site file: ($file) (($size) bytes)(ansi reset)"
} else {
print $"(ansi green)✅ Site directory: ($file)(ansi reset)"
}
} else {
# Only warn for missing files, not directories
if ($file | str ends-with ".html") {
$issues = ($issues | append {
severity: "INFO"
message: $"Optional site file not found: ($file)"
fix: "Normal for SPA applications"
})
}
}
}
# Report site structure
let site_contents = try {
ls $site_dir | get name | path basename
} catch {
[]
}
print $"(ansi blue)📁 Site contents: ($site_contents | str join ', ')(ansi reset)"
$issues
}
# Get file size in human readable format
def human_size [bytes: int] {
if $bytes < 1024 {
$"($bytes) B"
} else if $bytes < 1048576 {
$"($bytes / 1024 | math round) KB"
} else {
$"($bytes / 1048576 | math round) MB"
}
}