#!/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" } }