mirror of
https://github.com/cloud-shuttle/leptos-shadcn-ui.git
synced 2025-12-22 22:00:00 +00:00
🚀 New Features: - Add leptos-shadcn-ui-wasm package with minimal dependencies - 10 core components optimized for WebAssembly - Feature flags for granular bundle control - WASM-specific utilities and helpers 🔧 Technical Improvements: - Fix WASM compatibility issues in test-utils package - Add conditional compilation for native vs WASM targets - Update contract-testing package for WASM compatibility - Add comprehensive WASM demo application 📦 Bundle Optimization: - 70% reduction in dependencies (150+ → 25) - WASM-compatible only dependencies - Gzipped bundle size: ~813KB for full demo 📚 Documentation: - Complete README with examples and migration guide - Bundle size comparisons and performance metrics - Comprehensive remediation plan and design docs ✅ Testing: - All packages compile for wasm32-unknown-unknown - Feature flags work correctly - Demo builds and runs successfully - Backward compatibility maintained
12 KiB
12 KiB
WASM Compatibility Remediation Plan
leptos-shadcn-ui v0.9.0+ WASM Support Strategy
Document Version: 1.0
Date: 2025-01-27
Status: DRAFT - Implementation Ready
🎯 Executive Summary
This document outlines a comprehensive remediation plan to resolve WASM compatibility issues in leptos-shadcn-ui, specifically addressing dependency conflicts with mio, uuid, and rustc-serialize crates. The plan provides three strategic approaches to ensure full WASM support while maintaining backward compatibility.
🔍 Problem Analysis
Current Issues Identified
-
Dependency Conflicts:
packages/test-utils/Cargo.toml:uuidmissing"js"featureproptestandtempfiledependencies not WASM-compatible- Mixed WASM/non-WASM dependencies in utility packages
-
Architecture Gaps:
- No conditional compilation for WASM targets
- Testing utilities assume file system access
- Property-based testing framework incompatible with WASM
-
Existing WASM Support:
- ✅ Core components (button, card, input) are WASM-compatible
- ✅ Working WASM demos exist (
standalone-demo/,examples/leptos/) - ✅ Proper WASM dependencies in demo configurations
🚀 Strategic Approaches
Approach 1: Fix Existing test-utils Package (Recommended)
Priority: HIGH
Effort: MEDIUM
Risk: LOW
Implementation Strategy
# packages/test-utils/Cargo.toml - WASM-Compatible Version
[package]
name = "shadcn-ui-test-utils"
version = "0.2.0"
[dependencies]
# WASM-compatible core dependencies
wasm-bindgen-test = "0.3"
web-sys = { workspace = true, features = ["console", "Document", "Element", "HtmlElement", "Window", "Performance", "PerformanceTiming"] }
js-sys = "0.3"
console_error_panic_hook = { workspace = true }
serde = { workspace = true }
serde_json = { workspace = true }
# ✅ FIXED: Add "js" feature for WASM compatibility
uuid = { version = "1.0", features = ["v4", "js"] }
# Framework-specific testing
leptos = { workspace = true }
# ❌ REMOVED: Non-WASM compatible dependencies
# proptest = "1.4" # Not WASM-compatible
# tempfile = "3.0" # File system operations not available in WASM
# ✅ ADDED: WASM-compatible alternatives
getrandom = { version = "0.2", features = ["js"] }
[features]
default = ["wasm-testing"]
wasm-testing = []
native-testing = []
# Conditional dependencies for different targets
[target.'cfg(target_arch = "wasm32")'.dependencies]
# WASM-specific testing utilities
wasm-bindgen-futures = "0.4"
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
# Native-only testing utilities
proptest = "1.4"
tempfile = "3.0"
Code Changes Required
- Update
packages/test-utils/src/dom_testing.rs:
// Add conditional compilation for WASM vs native testing
#[cfg(target_arch = "wasm32")]
use wasm_bindgen_futures::JsFuture;
#[cfg(not(target_arch = "wasm32"))]
use std::fs::File;
use std::io::Write;
impl ComponentTestHarness {
#[cfg(target_arch = "wasm32")]
pub fn new() -> Self {
// WASM-compatible UUID generation
let mount_id = format!("test-mount-{}", uuid::Uuid::new_v4().to_string());
Self { mount_point: mount_id }
}
#[cfg(not(target_arch = "wasm32"))]
pub fn new() -> Self {
// Native UUID generation with additional features
let mount_id = format!("test-mount-{}", uuid::Uuid::new_v4().to_string());
Self { mount_point: mount_id }
}
}
- Create WASM-compatible property testing:
// packages/test-utils/src/wasm_property_testing.rs
#[cfg(target_arch = "wasm32")]
pub mod wasm_property_testing {
use wasm_bindgen_test::*;
/// WASM-compatible property testing using JavaScript
pub fn wasm_proptest<F>(test_fn: F)
where
F: Fn() + 'static,
{
wasm_bindgen_test_configure!(run_in_browser);
test_fn();
}
}
#[cfg(not(target_arch = "wasm32"))]
pub mod native_property_testing {
use proptest::prelude::*;
/// Native property testing using proptest
pub fn native_proptest<F>(test_fn: F)
where
F: Fn() + 'static,
{
proptest! {
test_fn();
}
}
}
Approach 2: Create WASM-Only Minimal Version
Priority: MEDIUM
Effort: HIGH
Risk: MEDIUM
Package Structure
packages/
├── leptos-shadcn-ui-wasm/ # New WASM-only package
│ ├── Cargo.toml # Minimal WASM dependencies
│ ├── src/
│ │ ├── lib.rs # Re-export core components
│ │ ├── components/ # WASM-compatible components only
│ │ └── utils/ # WASM-specific utilities
│ └── README.md
Cargo.toml Design
[package]
name = "leptos-shadcn-ui-wasm"
version = "0.9.0"
edition = "2021"
description = "WASM-only version of leptos-shadcn-ui with minimal dependencies"
[dependencies]
# Core Leptos (WASM-compatible)
leptos = { version = "0.8", features = ["csr"] }
leptos_router = "0.8"
leptos-node-ref = "0.2"
leptos-struct-component = "0.2"
leptos-style = "0.2"
# WASM-specific dependencies only
wasm-bindgen = "0.2"
web-sys = "0.3"
js-sys = "0.3"
console_error_panic_hook = "0.1"
getrandom = { version = "0.2", features = ["js"] }
uuid = { version = "1.0", features = ["v4", "js"] }
# Essential components only (no testing utilities)
leptos-shadcn-button = { version = "0.9.0", path = "../leptos/button" }
leptos-shadcn-input = { version = "0.9.0", path = "../leptos/input" }
leptos-shadcn-card = { version = "0.9.0", path = "../leptos/card" }
leptos-shadcn-label = { version = "0.9.0", path = "../leptos/label" }
# ... other core components
[features]
default = ["essential-components"]
essential-components = ["button", "input", "card", "label"]
extended-components = ["essential-components", "dialog", "popover", "tooltip"]
# No testing features - testing handled separately
Approach 3: Conditional Compilation Strategy
Priority: HIGH
Effort: HIGH
Risk: LOW
Workspace-Level Configuration
# Cargo.toml - Workspace level
[workspace]
resolver = "2"
members = [
# ... existing members
"packages/leptos-shadcn-ui-wasm", # New WASM package
]
[workspace.dependencies]
# WASM-compatible versions
uuid-wasm = { version = "1.0", features = ["v4", "js"] }
uuid-native = { version = "1.0", features = ["v4", "serde"] }
getrandom-wasm = { version = "0.2", features = ["js"] }
getrandom-native = { version = "0.2", features = ["std"] }
# Conditional testing dependencies
proptest = { version = "1.4", optional = true }
tempfile = { version = "3.0", optional = true }
Component-Level Conditional Compilation
// packages/leptos/button/src/lib.rs
use leptos::prelude::*;
// Conditional imports based on target
#[cfg(target_arch = "wasm32")]
use uuid::Uuid;
#[cfg(not(target_arch = "wasm32"))]
use uuid::Uuid;
#[component]
pub fn Button(
#[prop(into, optional)] class: MaybeProp<String>,
#[prop(into, optional)] id: MaybeProp<String>,
children: Children,
) -> impl IntoView {
// Component implementation works for both targets
view! {
<button class=class id=id>
{children()}
</button>
}
}
// Conditional testing modules
#[cfg(target_arch = "wasm32")]
#[cfg(test)]
mod wasm_tests {
use wasm_bindgen_test::*;
use super::*;
wasm_bindgen_test_configure!(run_in_browser);
#[wasm_bindgen_test]
fn test_button_wasm() {
// WASM-specific tests
}
}
#[cfg(not(target_arch = "wasm32"))]
#[cfg(test)]
mod native_tests {
use proptest::prelude::*;
use super::*;
proptest! {
#[test]
fn test_button_properties(props in any::<ButtonProps>()) {
// Native property-based tests
}
}
}
📋 Implementation Roadmap
Phase 1: Immediate Fixes (Week 1)
- Fix
packages/test-utils/Cargo.tomlUUID dependency - Add conditional compilation for WASM targets
- Update workspace dependencies
- Test WASM compilation
Phase 2: Enhanced WASM Support (Week 2-3)
- Create WASM-compatible property testing utilities
- Implement conditional testing modules
- Add WASM-specific documentation
- Create WASM-only package (Approach 2)
Phase 3: Full Integration (Week 4)
- Update CI/CD for WASM testing
- Create WASM-specific examples
- Performance optimization for WASM
- Documentation and release
🧪 Testing Strategy
WASM Testing Framework
// packages/test-utils/src/wasm_testing.rs
use wasm_bindgen_test::*;
use web_sys::*;
wasm_bindgen_test_configure!(run_in_browser);
pub struct WASMTestRunner {
test_results: Vec<TestResult>,
}
impl WASMTestRunner {
pub fn new() -> Self {
Self {
test_results: Vec::new(),
}
}
pub fn run_component_test<F>(&mut self, name: &str, test_fn: F)
where
F: FnOnce() -> bool,
{
let start = performance().unwrap().now();
let result = test_fn();
let duration = performance().unwrap().now() - start;
self.test_results.push(TestResult {
name: name.to_string(),
passed: result,
duration_ms: duration,
});
}
}
#[derive(Debug)]
struct TestResult {
name: String,
passed: bool,
duration_ms: f64,
}
CI/CD Integration
# .github/workflows/wasm-tests.yml
name: WASM Compatibility Tests
on: [push, pull_request]
jobs:
wasm-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Rust with WASM target
uses: actions-rs/toolchain@v1
with:
toolchain: stable
target: wasm32-unknown-unknown
- name: Install wasm-pack
run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
- name: Test WASM compilation
run: |
cargo check --target wasm32-unknown-unknown
wasm-pack test --headless --firefox
- name: Test WASM demos
run: |
cd standalone-demo
wasm-pack build --target web
📊 Success Metrics
Technical Metrics
- 100% WASM compilation success rate
- < 2MB total WASM bundle size
- < 100ms component initialization time
- 0 WASM-specific runtime errors
Quality Metrics
- All core components work in WASM
- WASM tests pass in all supported browsers
- Performance within 10% of native benchmarks
- Documentation coverage > 90%
🔧 Migration Guide
For Existing Users
- Update Dependencies:
# Before
leptos-shadcn-ui = "0.8.0"
# After (WASM-compatible)
leptos-shadcn-ui = "0.9.0"
# OR for WASM-only projects
leptos-shadcn-ui-wasm = "0.9.0"
- Update Cargo.toml:
[dependencies]
# Add WASM-compatible features
uuid = { version = "1.0", features = ["v4", "js"] }
getrandom = { version = "0.2", features = ["js"] }
- Update Test Configuration:
// Use conditional compilation in tests
#[cfg(target_arch = "wasm32")]
use wasm_bindgen_test::*;
#[cfg(not(target_arch = "wasm32"))]
use proptest::prelude::*;
🚨 Risk Assessment
High Risk
- Breaking Changes: Conditional compilation may require code changes
- Testing Coverage: WASM testing infrastructure needs validation
Medium Risk
- Performance: WASM bundle size optimization required
- Browser Compatibility: Need to test across all target browsers
Low Risk
- Dependency Conflicts: Well-understood and documented
- Backward Compatibility: Native functionality preserved
📚 References
Next Steps:
- Review and approve this remediation plan
- Begin Phase 1 implementation
- Set up WASM testing infrastructure
- Create migration documentation for users