231 lines
No EOL
7.2 KiB
Text
231 lines
No EOL
7.2 KiB
Text
#!/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"
|
|
}
|
|
} |