agy-superpowers 5.0.8 → 5.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/template/agent/rules/superpowers.md +54 -0
- package/template/agent/skills/frontend-developer/SKILL.md +39 -0
- package/template/agent/skills/frontend-developer/references/react-nextjs.md +343 -0
- package/template/agent/skills/frontend-developer/references/react-rules/_sections.md +46 -0
- package/template/agent/skills/frontend-developer/references/react-rules/_template.md +28 -0
- package/template/agent/skills/frontend-developer/references/react-rules/advanced-event-handler-refs.md +55 -0
- package/template/agent/skills/frontend-developer/references/react-rules/advanced-init-once.md +42 -0
- package/template/agent/skills/frontend-developer/references/react-rules/advanced-use-latest.md +39 -0
- package/template/agent/skills/frontend-developer/references/react-rules/async-api-routes.md +38 -0
- package/template/agent/skills/frontend-developer/references/react-rules/async-defer-await.md +80 -0
- package/template/agent/skills/frontend-developer/references/react-rules/async-dependencies.md +51 -0
- package/template/agent/skills/frontend-developer/references/react-rules/async-parallel.md +28 -0
- package/template/agent/skills/frontend-developer/references/react-rules/async-suspense-boundaries.md +99 -0
- package/template/agent/skills/frontend-developer/references/react-rules/bundle-barrel-imports.md +59 -0
- package/template/agent/skills/frontend-developer/references/react-rules/bundle-conditional.md +31 -0
- package/template/agent/skills/frontend-developer/references/react-rules/bundle-defer-third-party.md +49 -0
- package/template/agent/skills/frontend-developer/references/react-rules/bundle-dynamic-imports.md +35 -0
- package/template/agent/skills/frontend-developer/references/react-rules/bundle-preload.md +50 -0
- package/template/agent/skills/frontend-developer/references/react-rules/client-event-listeners.md +74 -0
- package/template/agent/skills/frontend-developer/references/react-rules/client-localstorage-schema.md +71 -0
- package/template/agent/skills/frontend-developer/references/react-rules/client-passive-event-listeners.md +48 -0
- package/template/agent/skills/frontend-developer/references/react-rules/client-swr-dedup.md +56 -0
- package/template/agent/skills/frontend-developer/references/react-rules/js-batch-dom-css.md +107 -0
- package/template/agent/skills/frontend-developer/references/react-rules/js-cache-function-results.md +80 -0
- package/template/agent/skills/frontend-developer/references/react-rules/js-cache-property-access.md +28 -0
- package/template/agent/skills/frontend-developer/references/react-rules/js-cache-storage.md +70 -0
- package/template/agent/skills/frontend-developer/references/react-rules/js-combine-iterations.md +32 -0
- package/template/agent/skills/frontend-developer/references/react-rules/js-early-exit.md +50 -0
- package/template/agent/skills/frontend-developer/references/react-rules/js-flatmap-filter.md +60 -0
- package/template/agent/skills/frontend-developer/references/react-rules/js-hoist-regexp.md +45 -0
- package/template/agent/skills/frontend-developer/references/react-rules/js-index-maps.md +37 -0
- package/template/agent/skills/frontend-developer/references/react-rules/js-length-check-first.md +49 -0
- package/template/agent/skills/frontend-developer/references/react-rules/js-min-max-loop.md +82 -0
- package/template/agent/skills/frontend-developer/references/react-rules/js-set-map-lookups.md +24 -0
- package/template/agent/skills/frontend-developer/references/react-rules/js-tosorted-immutable.md +57 -0
- package/template/agent/skills/frontend-developer/references/react-rules/rendering-activity.md +26 -0
- package/template/agent/skills/frontend-developer/references/react-rules/rendering-animate-svg-wrapper.md +47 -0
- package/template/agent/skills/frontend-developer/references/react-rules/rendering-conditional-render.md +40 -0
- package/template/agent/skills/frontend-developer/references/react-rules/rendering-content-visibility.md +38 -0
- package/template/agent/skills/frontend-developer/references/react-rules/rendering-hoist-jsx.md +46 -0
- package/template/agent/skills/frontend-developer/references/react-rules/rendering-hydration-no-flicker.md +82 -0
- package/template/agent/skills/frontend-developer/references/react-rules/rendering-hydration-suppress-warning.md +30 -0
- package/template/agent/skills/frontend-developer/references/react-rules/rendering-resource-hints.md +85 -0
- package/template/agent/skills/frontend-developer/references/react-rules/rendering-script-defer-async.md +68 -0
- package/template/agent/skills/frontend-developer/references/react-rules/rendering-svg-precision.md +28 -0
- package/template/agent/skills/frontend-developer/references/react-rules/rendering-usetransition-loading.md +75 -0
- package/template/agent/skills/frontend-developer/references/react-rules/rerender-defer-reads.md +39 -0
- package/template/agent/skills/frontend-developer/references/react-rules/rerender-dependencies.md +45 -0
- package/template/agent/skills/frontend-developer/references/react-rules/rerender-derived-state-no-effect.md +40 -0
- package/template/agent/skills/frontend-developer/references/react-rules/rerender-derived-state.md +29 -0
- package/template/agent/skills/frontend-developer/references/react-rules/rerender-functional-setstate.md +74 -0
- package/template/agent/skills/frontend-developer/references/react-rules/rerender-lazy-state-init.md +58 -0
- package/template/agent/skills/frontend-developer/references/react-rules/rerender-memo-with-default-value.md +38 -0
- package/template/agent/skills/frontend-developer/references/react-rules/rerender-memo.md +44 -0
- package/template/agent/skills/frontend-developer/references/react-rules/rerender-move-effect-to-event.md +45 -0
- package/template/agent/skills/frontend-developer/references/react-rules/rerender-no-inline-components.md +82 -0
- package/template/agent/skills/frontend-developer/references/react-rules/rerender-simple-expression-in-memo.md +35 -0
- package/template/agent/skills/frontend-developer/references/react-rules/rerender-split-combined-hooks.md +64 -0
- package/template/agent/skills/frontend-developer/references/react-rules/rerender-transitions.md +40 -0
- package/template/agent/skills/frontend-developer/references/react-rules/rerender-use-deferred-value.md +59 -0
- package/template/agent/skills/frontend-developer/references/react-rules/rerender-use-ref-transient-values.md +73 -0
- package/template/agent/skills/frontend-developer/references/react-rules/server-after-nonblocking.md +73 -0
- package/template/agent/skills/frontend-developer/references/react-rules/server-auth-actions.md +96 -0
- package/template/agent/skills/frontend-developer/references/react-rules/server-cache-lru.md +41 -0
- package/template/agent/skills/frontend-developer/references/react-rules/server-cache-react.md +76 -0
- package/template/agent/skills/frontend-developer/references/react-rules/server-dedup-props.md +65 -0
- package/template/agent/skills/frontend-developer/references/react-rules/server-hoist-static-io.md +142 -0
- package/template/agent/skills/frontend-developer/references/react-rules/server-parallel-fetching.md +83 -0
- package/template/agent/skills/frontend-developer/references/react-rules/server-serialization.md +38 -0
- package/template/agent/skills/frontend-developer/references/svelte-sveltekit.md +220 -0
- package/template/agent/skills/frontend-developer/references/vanilla.md +275 -0
- package/template/agent/skills/frontend-developer/references/vue-nuxt.md +289 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/_index.md +154 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/animation-class-based-technique.md +254 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/animation-state-driven-technique.md +291 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/component-async.md +97 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/component-data-flow.md +307 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/component-fallthrough-attrs.md +174 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/component-keep-alive.md +137 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/component-slots.md +216 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/component-suspense.md +228 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/component-teleport.md +108 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/component-transition-group.md +128 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/component-transition.md +125 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/composables.md +290 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/directives.md +162 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/perf-avoid-component-abstraction-in-lists.md +159 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/perf-v-once-v-memo-directives.md +182 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/perf-virtualize-large-lists.md +187 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/plugins.md +166 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/reactivity.md +344 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/render-functions.md +201 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/sfc.md +310 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/state-management.md +135 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/updated-hook-performance.md +187 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/router/_index.md +23 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/router/router-beforeenter-no-param-trigger.md +167 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/router/router-beforerouteenter-no-this.md +176 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/router/router-guard-async-await-pattern.md +227 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/router/router-navigation-guard-infinite-loop.md +187 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/router/router-navigation-guard-next-deprecated.md +150 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/router/router-param-change-no-lifecycle.md +181 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/router/router-simple-routing-cleanup.md +209 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/router/router-use-vue-router-for-production.md +183 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/testing/_index.md +29 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/testing/async-component-testing.md +163 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/testing/teleport-testing-complexity.md +158 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/testing/testing-async-await-flushpromises.md +175 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/testing/testing-browser-vs-node-runners.md +208 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/testing/testing-component-blackbox-approach.md +144 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/testing/testing-composables-helper-wrapper.md +238 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/testing/testing-e2e-playwright-recommended.md +242 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/testing/testing-no-snapshot-only.md +197 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/testing/testing-pinia-store-setup.md +228 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/testing/testing-suspense-async-components.md +229 -0
- package/template/agent/skills/frontend-developer/references/vue-rules/testing/testing-vitest-recommended-for-vue.md +204 -0
- package/template/agent/skills/mobile-developer/SKILL.md +52 -0
- package/template/agent/skills/mobile-developer/references/android-native.md +396 -0
- package/template/agent/skills/mobile-developer/references/android-rules/android-accessibility.md +36 -0
- package/template/agent/skills/mobile-developer/references/android-rules/android-architecture.md +52 -0
- package/template/agent/skills/mobile-developer/references/android-rules/android-coroutines.md +139 -0
- package/template/agent/skills/mobile-developer/references/android-rules/android-data-layer.md +51 -0
- package/template/agent/skills/mobile-developer/references/android-rules/android-emulator-skill.md +108 -0
- package/template/agent/skills/mobile-developer/references/android-rules/android-gradle-logic.md +126 -0
- package/template/agent/skills/mobile-developer/references/android-rules/android-retrofit.md +142 -0
- package/template/agent/skills/mobile-developer/references/android-rules/android-testing.md +102 -0
- package/template/agent/skills/mobile-developer/references/android-rules/android-viewmodel.md +43 -0
- package/template/agent/skills/mobile-developer/references/android-rules/coil-compose.md +74 -0
- package/template/agent/skills/mobile-developer/references/android-rules/compose-navigation.md +422 -0
- package/template/agent/skills/mobile-developer/references/android-rules/compose-performance-audit.md +199 -0
- package/template/agent/skills/mobile-developer/references/android-rules/compose-ui.md +49 -0
- package/template/agent/skills/mobile-developer/references/android-rules/gradle-build-performance.md +346 -0
- package/template/agent/skills/mobile-developer/references/android-rules/kotlin-concurrency-expert.md +169 -0
- package/template/agent/skills/mobile-developer/references/android-rules/rxjava-to-coroutines-migration.md +101 -0
- package/template/agent/skills/mobile-developer/references/android-rules/xml-to-compose-migration.md +338 -0
- package/template/agent/skills/mobile-developer/references/flutter-rules/dart-best-practices.md +52 -0
- package/template/agent/skills/mobile-developer/references/flutter-rules/dart-checks-migration.md +134 -0
- package/template/agent/skills/mobile-developer/references/flutter-rules/dart-cli-app-best-practices.md +123 -0
- package/template/agent/skills/mobile-developer/references/flutter-rules/dart-doc-validation.md +45 -0
- package/template/agent/skills/mobile-developer/references/flutter-rules/dart-matcher-best-practices.md +106 -0
- package/template/agent/skills/mobile-developer/references/flutter-rules/dart-modern-features.md +241 -0
- package/template/agent/skills/mobile-developer/references/flutter-rules/dart-package-maintenance.md +75 -0
- package/template/agent/skills/mobile-developer/references/flutter-rules/dart-test-fundamentals.md +124 -0
- package/template/agent/skills/mobile-developer/references/flutter.md +291 -0
- package/template/agent/skills/mobile-developer/references/ios-native.md +358 -0
- package/template/agent/skills/mobile-developer/references/ios-rules/accessibility-patterns.md +215 -0
- package/template/agent/skills/mobile-developer/references/ios-rules/animation-advanced.md +403 -0
- package/template/agent/skills/mobile-developer/references/ios-rules/animation-basics.md +284 -0
- package/template/agent/skills/mobile-developer/references/ios-rules/animation-transitions.md +326 -0
- package/template/agent/skills/mobile-developer/references/ios-rules/charts-accessibility.md +135 -0
- package/template/agent/skills/mobile-developer/references/ios-rules/charts.md +602 -0
- package/template/agent/skills/mobile-developer/references/ios-rules/image-optimization.md +203 -0
- package/template/agent/skills/mobile-developer/references/ios-rules/latest-apis.md +464 -0
- package/template/agent/skills/mobile-developer/references/ios-rules/layout-best-practices.md +266 -0
- package/template/agent/skills/mobile-developer/references/ios-rules/liquid-glass.md +416 -0
- package/template/agent/skills/mobile-developer/references/ios-rules/list-patterns.md +394 -0
- package/template/agent/skills/mobile-developer/references/ios-rules/macos-scenes.md +318 -0
- package/template/agent/skills/mobile-developer/references/ios-rules/macos-views.md +357 -0
- package/template/agent/skills/mobile-developer/references/ios-rules/macos-window-styling.md +303 -0
- package/template/agent/skills/mobile-developer/references/ios-rules/performance-patterns.md +403 -0
- package/template/agent/skills/mobile-developer/references/ios-rules/scroll-patterns.md +293 -0
- package/template/agent/skills/mobile-developer/references/ios-rules/sheet-navigation-patterns.md +363 -0
- package/template/agent/skills/mobile-developer/references/ios-rules/state-management.md +417 -0
- package/template/agent/skills/mobile-developer/references/ios-rules/view-structure.md +389 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/_sections.md +86 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/_template.md +28 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/animation-derived-value.md +53 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/animation-gesture-detector-press.md +95 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/animation-gpu-properties.md +65 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/design-system-compound-components.md +66 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/fonts-config-plugin.md +71 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/imports-design-system-folder.md +68 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/js-hoist-intl.md +61 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/list-performance-callbacks.md +44 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/list-performance-function-references.md +132 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/list-performance-images.md +53 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/list-performance-inline-objects.md +97 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/list-performance-item-expensive.md +94 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/list-performance-item-memo.md +82 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/list-performance-item-types.md +104 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/list-performance-virtualize.md +67 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/monorepo-native-deps-in-app.md +46 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/monorepo-single-dependency-versions.md +63 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/navigation-native-navigators.md +188 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/react-compiler-destructure-functions.md +50 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/react-compiler-reanimated-shared-values.md +48 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/react-state-dispatcher.md +91 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/react-state-fallback.md +56 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/react-state-minimize.md +65 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/rendering-no-falsy-and.md +74 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/rendering-text-in-text-component.md +36 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/scroll-position-no-state.md +82 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/state-ground-truth.md +80 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/ui-expo-image.md +66 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/ui-image-gallery.md +104 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/ui-measure-views.md +78 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/ui-menus.md +174 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/ui-native-modals.md +77 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/ui-pressable.md +61 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/ui-safe-area-scroll.md +65 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/ui-scrollview-content-inset.md +45 -0
- package/template/agent/skills/mobile-developer/references/react-native-rules/ui-styling.md +87 -0
- package/template/agent/skills/mobile-developer/references/react-native.md +345 -0
package/template/agent/skills/frontend-developer/references/react-rules/server-parallel-fetching.md
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Parallel Data Fetching with Component Composition
|
|
3
|
+
impact: CRITICAL
|
|
4
|
+
impactDescription: eliminates server-side waterfalls
|
|
5
|
+
tags: server, rsc, parallel-fetching, composition
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Parallel Data Fetching with Component Composition
|
|
9
|
+
|
|
10
|
+
React Server Components execute sequentially within a tree. Restructure with composition to parallelize data fetching.
|
|
11
|
+
|
|
12
|
+
**Incorrect (Sidebar waits for Page's fetch to complete):**
|
|
13
|
+
|
|
14
|
+
```tsx
|
|
15
|
+
export default async function Page() {
|
|
16
|
+
const header = await fetchHeader()
|
|
17
|
+
return (
|
|
18
|
+
<div>
|
|
19
|
+
<div>{header}</div>
|
|
20
|
+
<Sidebar />
|
|
21
|
+
</div>
|
|
22
|
+
)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
async function Sidebar() {
|
|
26
|
+
const items = await fetchSidebarItems()
|
|
27
|
+
return <nav>{items.map(renderItem)}</nav>
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
**Correct (both fetch simultaneously):**
|
|
32
|
+
|
|
33
|
+
```tsx
|
|
34
|
+
async function Header() {
|
|
35
|
+
const data = await fetchHeader()
|
|
36
|
+
return <div>{data}</div>
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
async function Sidebar() {
|
|
40
|
+
const items = await fetchSidebarItems()
|
|
41
|
+
return <nav>{items.map(renderItem)}</nav>
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export default function Page() {
|
|
45
|
+
return (
|
|
46
|
+
<div>
|
|
47
|
+
<Header />
|
|
48
|
+
<Sidebar />
|
|
49
|
+
</div>
|
|
50
|
+
)
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
**Alternative with children prop:**
|
|
55
|
+
|
|
56
|
+
```tsx
|
|
57
|
+
async function Header() {
|
|
58
|
+
const data = await fetchHeader()
|
|
59
|
+
return <div>{data}</div>
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
async function Sidebar() {
|
|
63
|
+
const items = await fetchSidebarItems()
|
|
64
|
+
return <nav>{items.map(renderItem)}</nav>
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function Layout({ children }: { children: ReactNode }) {
|
|
68
|
+
return (
|
|
69
|
+
<div>
|
|
70
|
+
<Header />
|
|
71
|
+
{children}
|
|
72
|
+
</div>
|
|
73
|
+
)
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export default function Page() {
|
|
77
|
+
return (
|
|
78
|
+
<Layout>
|
|
79
|
+
<Sidebar />
|
|
80
|
+
</Layout>
|
|
81
|
+
)
|
|
82
|
+
}
|
|
83
|
+
```
|
package/template/agent/skills/frontend-developer/references/react-rules/server-serialization.md
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Minimize Serialization at RSC Boundaries
|
|
3
|
+
impact: HIGH
|
|
4
|
+
impactDescription: reduces data transfer size
|
|
5
|
+
tags: server, rsc, serialization, props
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Minimize Serialization at RSC Boundaries
|
|
9
|
+
|
|
10
|
+
The React Server/Client boundary serializes all object properties into strings and embeds them in the HTML response and subsequent RSC requests. This serialized data directly impacts page weight and load time, so **size matters a lot**. Only pass fields that the client actually uses.
|
|
11
|
+
|
|
12
|
+
**Incorrect (serializes all 50 fields):**
|
|
13
|
+
|
|
14
|
+
```tsx
|
|
15
|
+
async function Page() {
|
|
16
|
+
const user = await fetchUser() // 50 fields
|
|
17
|
+
return <Profile user={user} />
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
'use client'
|
|
21
|
+
function Profile({ user }: { user: User }) {
|
|
22
|
+
return <div>{user.name}</div> // uses 1 field
|
|
23
|
+
}
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
**Correct (serializes only 1 field):**
|
|
27
|
+
|
|
28
|
+
```tsx
|
|
29
|
+
async function Page() {
|
|
30
|
+
const user = await fetchUser()
|
|
31
|
+
return <Profile name={user.name} />
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
'use client'
|
|
35
|
+
function Profile({ name }: { name: string }) {
|
|
36
|
+
return <div>{name}</div>
|
|
37
|
+
}
|
|
38
|
+
```
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
# Svelte + SvelteKit Reference
|
|
2
|
+
|
|
3
|
+
> **Philosophy:** Write less code. No virtual DOM. Compiled framework.
|
|
4
|
+
> Reactivity is built into the language, not bolted on.
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Project Setup & Detection
|
|
9
|
+
|
|
10
|
+
**Stack indicators:** `svelte.config.js`, `package.json` with `svelte` or `@sveltejs/kit` dependency.
|
|
11
|
+
|
|
12
|
+
**Key config files:**
|
|
13
|
+
|
|
14
|
+
| File | Purpose |
|
|
15
|
+
|------|---------|
|
|
16
|
+
| `svelte.config.js` | SvelteKit configuration (adapter, preprocess) |
|
|
17
|
+
| `vite.config.ts` | Vite bundler configuration |
|
|
18
|
+
| `tsconfig.json` | TypeScript configuration |
|
|
19
|
+
| `.env` | Environment variables (prefixed `PUBLIC_` for client) |
|
|
20
|
+
|
|
21
|
+
**Recommended project structure (SvelteKit):**
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
src/
|
|
25
|
+
routes/
|
|
26
|
+
+layout.svelte # Root layout
|
|
27
|
+
+page.svelte # Home page
|
|
28
|
+
+error.svelte # Error page
|
|
29
|
+
about/
|
|
30
|
+
+page.svelte # /about
|
|
31
|
+
users/
|
|
32
|
+
[id]/
|
|
33
|
+
+page.svelte # /users/:id
|
|
34
|
+
+page.server.ts # Server load function
|
|
35
|
+
api/
|
|
36
|
+
posts/
|
|
37
|
+
+server.ts # API endpoint
|
|
38
|
+
lib/
|
|
39
|
+
components/ # Reusable components
|
|
40
|
+
stores/ # Svelte stores
|
|
41
|
+
server/ # Server-only code ($lib/server/)
|
|
42
|
+
utils.ts # Shared utilities
|
|
43
|
+
app.html # HTML template
|
|
44
|
+
app.css # Global styles
|
|
45
|
+
static/ # Static assets
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## Architecture Patterns
|
|
51
|
+
|
|
52
|
+
### Svelte 5 Runes (Default)
|
|
53
|
+
|
|
54
|
+
```svelte
|
|
55
|
+
<script lang="ts">
|
|
56
|
+
let count = $state(0)
|
|
57
|
+
let doubled = $derived(count * 2)
|
|
58
|
+
|
|
59
|
+
function increment() {
|
|
60
|
+
count++
|
|
61
|
+
}
|
|
62
|
+
</script>
|
|
63
|
+
|
|
64
|
+
<button onclick={increment}>{count} ({doubled})</button>
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
| Rune | Purpose |
|
|
68
|
+
|------|---------|
|
|
69
|
+
| `$state` | Reactive state declaration |
|
|
70
|
+
| `$derived` | Computed value (replaces `$:` reactive statements) |
|
|
71
|
+
| `$effect` | Side effect (replaces `$:` for effects) |
|
|
72
|
+
| `$props` | Component props |
|
|
73
|
+
| `$bindable` | Two-way binding capability |
|
|
74
|
+
|
|
75
|
+
### Data Loading (SvelteKit)
|
|
76
|
+
|
|
77
|
+
| Pattern | Use When |
|
|
78
|
+
|---------|----------|
|
|
79
|
+
| **`+page.server.ts` `load()`** | SSR data — runs on server only |
|
|
80
|
+
| **`+page.ts` `load()`** | Universal — runs on server AND client |
|
|
81
|
+
| **`+server.ts`** | API endpoints |
|
|
82
|
+
| **Form actions** | Mutations (POST/PUT/DELETE) |
|
|
83
|
+
|
|
84
|
+
```ts
|
|
85
|
+
// src/routes/posts/+page.server.ts
|
|
86
|
+
export async function load({ fetch }) {
|
|
87
|
+
const posts = await fetch('/api/posts').then(r => r.json())
|
|
88
|
+
return { posts }
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// src/routes/posts/+page.svelte
|
|
92
|
+
<script>
|
|
93
|
+
let { data } = $props()
|
|
94
|
+
</script>
|
|
95
|
+
|
|
96
|
+
{#each data.posts as post}
|
|
97
|
+
<article>{post.title}</article>
|
|
98
|
+
{/each}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### State Management
|
|
102
|
+
|
|
103
|
+
| Approach | Use When |
|
|
104
|
+
|----------|----------|
|
|
105
|
+
| **`$state` (rune)** | Component-local state |
|
|
106
|
+
| **Svelte stores (`writable`)** | Shared state across components |
|
|
107
|
+
| **`$page.url.searchParams`** | URL state (filters, pagination) |
|
|
108
|
+
| **Context API** | Scoped dependency injection |
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
## Performance Optimization
|
|
113
|
+
|
|
114
|
+
### Why Svelte is Fast by Default
|
|
115
|
+
|
|
116
|
+
- **No virtual DOM** — compiles to direct DOM manipulation
|
|
117
|
+
- **No runtime framework** — smaller bundle (Svelte ~2KB vs React ~40KB)
|
|
118
|
+
- **Granular reactivity** — only updates exactly what changed
|
|
119
|
+
- **Automatic code splitting** — SvelteKit splits by route
|
|
120
|
+
|
|
121
|
+
### Key Optimizations
|
|
122
|
+
|
|
123
|
+
1. **`{#key}`** — force re-create a component when key changes.
|
|
124
|
+
|
|
125
|
+
2. **`{#await}`** — built-in async rendering.
|
|
126
|
+
|
|
127
|
+
```svelte
|
|
128
|
+
{#await fetchData()}
|
|
129
|
+
<Spinner />
|
|
130
|
+
{:then data}
|
|
131
|
+
<DataView {data} />
|
|
132
|
+
{:catch error}
|
|
133
|
+
<ErrorMessage {error} />
|
|
134
|
+
{/await}
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
3. **Enhanced image** — `@sveltejs/enhanced-img` for automatic optimization.
|
|
138
|
+
|
|
139
|
+
4. **Streaming** — SvelteKit supports streaming SSR with nested `load` functions.
|
|
140
|
+
|
|
141
|
+
5. **Preloading** — `data-sveltekit-preload-data="hover"` preloads links on hover.
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## Common Libraries Ecosystem
|
|
146
|
+
|
|
147
|
+
| Category | Recommended | Alternative |
|
|
148
|
+
|----------|-------------|-------------|
|
|
149
|
+
| **UI** | `shadcn-svelte` | `skeleton`, `melt-ui` |
|
|
150
|
+
| **Styling** | `tailwindcss` | `unocss` |
|
|
151
|
+
| **Forms** | `superforms` + `zod` | `felte` |
|
|
152
|
+
| **Auth** | `lucia` | `authjs-sveltekit` |
|
|
153
|
+
| **Database** | `prisma` / `drizzle` | `kysely` |
|
|
154
|
+
| **Testing** | `vitest` + `@testing-library/svelte` | — |
|
|
155
|
+
| **E2E** | `playwright` | `cypress` |
|
|
156
|
+
| **Icons** | `lucide-svelte` | `svelte-icons` |
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
## Anti-Patterns & Gotchas
|
|
161
|
+
|
|
162
|
+
| ❌ Don't | Why | ✅ Do Instead |
|
|
163
|
+
|----------|-----|---------------|
|
|
164
|
+
| Svelte 4 `$:` reactive statements | Legacy (Svelte 5 uses runes) | `$derived`, `$effect` |
|
|
165
|
+
| `onMount` for data fetching | Runs only on client, no SSR | `load()` in `+page.server.ts` |
|
|
166
|
+
| Mutating `$state` arrays without reassignment | May not trigger reactivity | Push then reassign: `items = [...items, newItem]` |
|
|
167
|
+
| `$effect` for derived state | Extra update cycle | Use `$derived` |
|
|
168
|
+
| `PUBLIC_` prefix missing for client env | Variable not available in client | Prefix with `PUBLIC_` |
|
|
169
|
+
| Importing `$lib/server` in client code | Server secrets leak to bundle | Use `$lib/server/` only in `.server.ts` |
|
|
170
|
+
| Missing form `use:enhance` | Full page reload on submit | Add `use:enhance` for progressive enhancement |
|
|
171
|
+
|
|
172
|
+
---
|
|
173
|
+
|
|
174
|
+
## Testing
|
|
175
|
+
|
|
176
|
+
| Layer | Tool | Purpose |
|
|
177
|
+
|-------|------|---------|
|
|
178
|
+
| **Unit** | Vitest + `@testing-library/svelte` | Components, stores |
|
|
179
|
+
| **E2E** | Playwright | Full user flows |
|
|
180
|
+
|
|
181
|
+
```ts
|
|
182
|
+
import { render, screen } from '@testing-library/svelte'
|
|
183
|
+
import Counter from '$lib/components/Counter.svelte'
|
|
184
|
+
|
|
185
|
+
test('increments count', async () => {
|
|
186
|
+
render(Counter)
|
|
187
|
+
const button = screen.getByRole('button')
|
|
188
|
+
await button.click()
|
|
189
|
+
expect(button.textContent).toBe('1')
|
|
190
|
+
})
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
---
|
|
194
|
+
|
|
195
|
+
## Deployment & Distribution
|
|
196
|
+
|
|
197
|
+
### Adapters
|
|
198
|
+
|
|
199
|
+
SvelteKit uses adapters for different deployment targets:
|
|
200
|
+
|
|
201
|
+
```bash
|
|
202
|
+
npm run build
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
| Adapter | Platform |
|
|
206
|
+
|---------|----------|
|
|
207
|
+
| `@sveltejs/adapter-auto` | Auto-detect (Vercel, Netlify, Cloudflare) |
|
|
208
|
+
| `@sveltejs/adapter-vercel` | Vercel |
|
|
209
|
+
| `@sveltejs/adapter-node` | Node.js server |
|
|
210
|
+
| `@sveltejs/adapter-static` | Static site (SSG) |
|
|
211
|
+
| `@sveltejs/adapter-cloudflare` | Cloudflare Pages/Workers |
|
|
212
|
+
|
|
213
|
+
```js
|
|
214
|
+
// svelte.config.js
|
|
215
|
+
import adapter from '@sveltejs/adapter-auto'
|
|
216
|
+
|
|
217
|
+
export default {
|
|
218
|
+
kit: { adapter: adapter() }
|
|
219
|
+
}
|
|
220
|
+
```
|
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
# Vanilla JS/TS + Web Components Reference
|
|
2
|
+
|
|
3
|
+
> **Philosophy:** Zero dependencies. Platform APIs first.
|
|
4
|
+
> The best framework is the one you don't need.
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Project Setup & Detection
|
|
9
|
+
|
|
10
|
+
**Stack indicators:** No framework dependency in `package.json`. Plain `index.html` + `<script>` tags, or Vite with no framework plugin.
|
|
11
|
+
|
|
12
|
+
**Key config files:**
|
|
13
|
+
|
|
14
|
+
| File | Purpose |
|
|
15
|
+
|------|---------|
|
|
16
|
+
| `index.html` | Entry point |
|
|
17
|
+
| `vite.config.ts` | Build tool (if using Vite) |
|
|
18
|
+
| `tsconfig.json` | TypeScript configuration |
|
|
19
|
+
| `package.json` | Dependencies (minimal or none) |
|
|
20
|
+
|
|
21
|
+
**Recommended project structure:**
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
src/
|
|
25
|
+
components/
|
|
26
|
+
header.ts # Custom elements / component modules
|
|
27
|
+
modal.ts
|
|
28
|
+
services/
|
|
29
|
+
api.ts # Fetch wrapper
|
|
30
|
+
storage.ts # localStorage abstraction
|
|
31
|
+
utils/
|
|
32
|
+
dom.ts # DOM utility functions
|
|
33
|
+
events.ts # Event system
|
|
34
|
+
styles/
|
|
35
|
+
main.css # Global styles
|
|
36
|
+
components/ # Component-scoped CSS
|
|
37
|
+
main.ts # Entry point
|
|
38
|
+
router.ts # Client-side router (if SPA)
|
|
39
|
+
index.html
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## Architecture Patterns
|
|
45
|
+
|
|
46
|
+
### Web Components (Custom Elements)
|
|
47
|
+
|
|
48
|
+
```ts
|
|
49
|
+
class MyCounter extends HTMLElement {
|
|
50
|
+
#count = 0
|
|
51
|
+
#shadow: ShadowRoot
|
|
52
|
+
|
|
53
|
+
constructor() {
|
|
54
|
+
super()
|
|
55
|
+
this.#shadow = this.attachShadow({ mode: 'open' })
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
connectedCallback() {
|
|
59
|
+
this.render()
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
render() {
|
|
63
|
+
this.#shadow.innerHTML = `
|
|
64
|
+
<style>
|
|
65
|
+
button { font-size: 1rem; padding: 0.5rem 1rem; cursor: pointer; }
|
|
66
|
+
</style>
|
|
67
|
+
<button>${this.#count}</button>
|
|
68
|
+
`
|
|
69
|
+
this.#shadow.querySelector('button')!
|
|
70
|
+
.addEventListener('click', () => { this.#count++; this.render() })
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
customElements.define('my-counter', MyCounter)
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Module Pattern
|
|
78
|
+
|
|
79
|
+
```ts
|
|
80
|
+
// services/api.ts
|
|
81
|
+
const BASE_URL = '/api'
|
|
82
|
+
|
|
83
|
+
export async function get<T>(path: string): Promise<T> {
|
|
84
|
+
const res = await fetch(`${BASE_URL}${path}`)
|
|
85
|
+
if (!res.ok) throw new Error(`HTTP ${res.status}`)
|
|
86
|
+
return res.json()
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export async function post<T>(path: string, body: unknown): Promise<T> {
|
|
90
|
+
const res = await fetch(`${BASE_URL}${path}`, {
|
|
91
|
+
method: 'POST',
|
|
92
|
+
headers: { 'Content-Type': 'application/json' },
|
|
93
|
+
body: JSON.stringify(body),
|
|
94
|
+
})
|
|
95
|
+
if (!res.ok) throw new Error(`HTTP ${res.status}`)
|
|
96
|
+
return res.json()
|
|
97
|
+
}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### State Management
|
|
101
|
+
|
|
102
|
+
| Approach | Use When |
|
|
103
|
+
|----------|----------|
|
|
104
|
+
| **Module-level variables** | Simple state, single module access |
|
|
105
|
+
| **Custom EventTarget** | Pub/sub across modules |
|
|
106
|
+
| **Proxy-based reactivity** | Automatic DOM updates |
|
|
107
|
+
| **URL state** (`URLSearchParams`) | Shareable, bookmarkable state |
|
|
108
|
+
|
|
109
|
+
**Proxy-based reactivity:**
|
|
110
|
+
|
|
111
|
+
```ts
|
|
112
|
+
function createStore<T extends object>(initial: T, onChange: () => void): T {
|
|
113
|
+
return new Proxy(initial, {
|
|
114
|
+
set(target, prop, value) {
|
|
115
|
+
Reflect.set(target, prop, value)
|
|
116
|
+
onChange()
|
|
117
|
+
return true
|
|
118
|
+
}
|
|
119
|
+
})
|
|
120
|
+
}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## Performance Optimization
|
|
126
|
+
|
|
127
|
+
### Modern Browser APIs to Use
|
|
128
|
+
|
|
129
|
+
| API | Purpose |
|
|
130
|
+
|-----|---------|
|
|
131
|
+
| `fetch` | Network requests (replaces XMLHttpRequest) |
|
|
132
|
+
| `IntersectionObserver` | Lazy loading, infinite scroll |
|
|
133
|
+
| `ResizeObserver` | Responsive components |
|
|
134
|
+
| `MutationObserver` | DOM change detection |
|
|
135
|
+
| `requestIdleCallback` | Defer non-critical work |
|
|
136
|
+
| `requestAnimationFrame` | Smooth animations |
|
|
137
|
+
| `Web Workers` | Offload heavy computation |
|
|
138
|
+
| `AbortController` | Cancel fetch requests |
|
|
139
|
+
| `structuredClone` | Deep clone objects |
|
|
140
|
+
| `URLPattern` | URL matching/routing |
|
|
141
|
+
| `View Transitions API` | Page transition animations |
|
|
142
|
+
| `Popover API` | Native popovers (no JS library) |
|
|
143
|
+
| `<dialog>` | Native modal dialogs |
|
|
144
|
+
|
|
145
|
+
### Key Optimizations
|
|
146
|
+
|
|
147
|
+
1. **Event delegation** — one listener on parent, not N listeners on children.
|
|
148
|
+
|
|
149
|
+
```ts
|
|
150
|
+
// ❌ Bad: N listeners
|
|
151
|
+
items.forEach(item => item.addEventListener('click', handler))
|
|
152
|
+
|
|
153
|
+
// ✅ Good: 1 listener with delegation
|
|
154
|
+
list.addEventListener('click', (e) => {
|
|
155
|
+
const item = (e.target as HTMLElement).closest('[data-id]')
|
|
156
|
+
if (item) handleClick(item.dataset.id!)
|
|
157
|
+
})
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
2. **`DocumentFragment`** — batch DOM insertions.
|
|
161
|
+
|
|
162
|
+
```ts
|
|
163
|
+
const fragment = document.createDocumentFragment()
|
|
164
|
+
items.forEach(item => {
|
|
165
|
+
const li = document.createElement('li')
|
|
166
|
+
li.textContent = item.name
|
|
167
|
+
fragment.appendChild(li)
|
|
168
|
+
})
|
|
169
|
+
list.appendChild(fragment) // single reflow
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
3. **CSS `content-visibility: auto`** — skip rendering off-screen content.
|
|
173
|
+
|
|
174
|
+
4. **`<link rel="modulepreload">`** — preload ES modules.
|
|
175
|
+
|
|
176
|
+
5. **`loading="lazy"`** on images and iframes — native lazy loading.
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
## Common Libraries (Minimal Dependencies)
|
|
181
|
+
|
|
182
|
+
| Category | Lightweight Pick | Why Not Full Framework |
|
|
183
|
+
|----------|-----------------|----------------------|
|
|
184
|
+
| **Routing** | `navigo` / custom History API | 2KB vs router libraries |
|
|
185
|
+
| **HTTP** | `fetch` (built-in) | No library needed |
|
|
186
|
+
| **Templating** | `lit-html` | Tagged templates, 5KB |
|
|
187
|
+
| **State** | `nanostores` | Framework-agnostic, 1KB |
|
|
188
|
+
| **Build** | `vite` | Fast, ESM-native |
|
|
189
|
+
| **Testing** | `vitest` | Fast, compatible |
|
|
190
|
+
| **E2E** | `playwright` | Cross-browser |
|
|
191
|
+
| **CSS** | CSS custom properties | Native variables |
|
|
192
|
+
|
|
193
|
+
---
|
|
194
|
+
|
|
195
|
+
## Anti-Patterns & Gotchas
|
|
196
|
+
|
|
197
|
+
| ❌ Don't | Why | ✅ Do Instead |
|
|
198
|
+
|----------|-----|---------------|
|
|
199
|
+
| `innerHTML` with user input | XSS vulnerability | `textContent` or sanitize |
|
|
200
|
+
| `document.write()` | Blocks parsing, destroys page | DOM manipulation methods |
|
|
201
|
+
| jQuery for new projects | Unnecessary, browser APIs suffice | Native `querySelector`, `fetch` |
|
|
202
|
+
| Sync XHR | Blocks main thread | `fetch` with async/await |
|
|
203
|
+
| `var` declarations | Hoisting bugs, no block scope | `const` / `let` |
|
|
204
|
+
| `==` loose equality | Type coercion bugs | `===` strict equality |
|
|
205
|
+
| Missing `type="module"` on scripts | No ES module support | `<script type="module">` |
|
|
206
|
+
| Global variables | Namespace pollution | ES modules |
|
|
207
|
+
| Polling for DOM changes | Wasteful | `MutationObserver` |
|
|
208
|
+
| `setTimeout` for animations | Inconsistent frame rate | `requestAnimationFrame` |
|
|
209
|
+
|
|
210
|
+
---
|
|
211
|
+
|
|
212
|
+
## Testing
|
|
213
|
+
|
|
214
|
+
| Layer | Tool | Purpose |
|
|
215
|
+
|-------|------|---------|
|
|
216
|
+
| **Unit** | Vitest | Functions, modules |
|
|
217
|
+
| **DOM** | Vitest + `happy-dom` | Component rendering |
|
|
218
|
+
| **E2E** | Playwright | Full browser flows |
|
|
219
|
+
|
|
220
|
+
```ts
|
|
221
|
+
import { describe, it, expect } from 'vitest'
|
|
222
|
+
import { createStore } from '../src/store'
|
|
223
|
+
|
|
224
|
+
describe('Store', () => {
|
|
225
|
+
it('notifies on change', () => {
|
|
226
|
+
let called = false
|
|
227
|
+
const store = createStore({ count: 0 }, () => { called = true })
|
|
228
|
+
store.count = 1
|
|
229
|
+
expect(called).toBe(true)
|
|
230
|
+
})
|
|
231
|
+
})
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
---
|
|
235
|
+
|
|
236
|
+
## Deployment & Distribution
|
|
237
|
+
|
|
238
|
+
### Static Hosting (Most Common)
|
|
239
|
+
|
|
240
|
+
```bash
|
|
241
|
+
# Build (Vite)
|
|
242
|
+
vite build
|
|
243
|
+
|
|
244
|
+
# Output: dist/
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
Deploy `dist/` to any static host: Cloudflare Pages, Netlify, Vercel, GitHub Pages, S3 + CloudFront.
|
|
248
|
+
|
|
249
|
+
### No-Build Option
|
|
250
|
+
|
|
251
|
+
For simple projects, no build step needed:
|
|
252
|
+
|
|
253
|
+
```html
|
|
254
|
+
<!DOCTYPE html>
|
|
255
|
+
<html>
|
|
256
|
+
<head>
|
|
257
|
+
<link rel="stylesheet" href="styles/main.css">
|
|
258
|
+
</head>
|
|
259
|
+
<body>
|
|
260
|
+
<script type="module" src="src/main.ts"></script>
|
|
261
|
+
</body>
|
|
262
|
+
</html>
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
Modern browsers support ES modules natively. Use import maps for bare specifiers:
|
|
266
|
+
|
|
267
|
+
```html
|
|
268
|
+
<script type="importmap">
|
|
269
|
+
{
|
|
270
|
+
"imports": {
|
|
271
|
+
"lit-html": "https://esm.sh/lit-html"
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
</script>
|
|
275
|
+
```
|