feat: Complete fleet — 94 skills across 10+ domains

Pulled ALL skills from 15 source repositories:
- anthropics/skills: 16 (docs, design, MCP, testing)
- obra/superpowers: 14 (TDD, debugging, agents, planning)
- coreyhaines31/marketingskills: 25 (marketing, CRO, SEO, growth)
- better-auth/skills: 5 (auth patterns)
- vercel-labs/agent-skills: 5 (React, design, Vercel)
- antfu/skills: 16 (Vue, Vite, Vitest, pnpm, Turborepo)
- Plus 13 individual skills from various repos

Mosaic Stack is not limited to coding — the Orchestrator and
subagents serve coding, business, design, marketing, writing,
logistics, analysis, and more.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Jason Woltje
2026-02-16 16:27:42 -06:00
parent 861b28b965
commit f5792c40be
1262 changed files with 212048 additions and 61 deletions

View File

@@ -0,0 +1,225 @@
---
title: Colocate Template, Script, and Style in SFCs for Maintainability
impact: MEDIUM
impactDescription: Separating template, logic, and styles into different files reduces component cohesion and maintainability
type: best-practice
tags: [vue3, sfc, architecture, separation-of-concerns, maintainability]
---
# Colocate Template, Script, and Style in SFCs for Maintainability
**Impact: MEDIUM** - Vue SFCs are designed to colocate template, logic, and styles because these concerns are inherently coupled within a component. Separating them into different files based on file type (not concern) makes components harder to understand and maintain.
## Task Checklist
- [ ] Keep template, script, and style in the same `.vue` file by default
- [ ] Only use `src` imports when files become extremely large (500+ lines)
- [ ] Group related components in folders rather than separating by file type
- [ ] Use component composition to manage complexity instead of file splitting
**Not Recommended:**
```
components/
├── UserCard.vue # Just template
├── UserCard.js # Logic
├── UserCard.css # Styles
```
**Recommended:**
```vue
<!-- components/UserCard.vue - Everything in one file -->
<script setup>
import { computed } from 'vue'
import { useUserStatus } from '@/composables/useUserStatus'
const props = defineProps({
user: { type: Object, required: true }
})
const { isOnline } = useUserStatus(props.user.id)
const displayName = computed(() =>
`${props.user.firstName} ${props.user.lastName}`
)
</script>
<template>
<div class="user-card">
<img :src="user.avatar" :alt="displayName" class="avatar" />
<div class="info">
<h3 class="name">{{ displayName }}</h3>
<span :class="['status', { online: isOnline }]">
{{ isOnline ? 'Online' : 'Offline' }}
</span>
</div>
</div>
</template>
<style scoped>
.user-card {
display: flex;
padding: 1rem;
border: 1px solid #e0e0e0;
border-radius: 8px;
}
.avatar {
width: 48px;
height: 48px;
border-radius: 50%;
}
.info {
margin-left: 1rem;
}
.name {
margin: 0 0 0.25rem;
}
.status {
font-size: 0.875rem;
color: #666;
}
.status.online {
color: #22c55e;
}
</style>
```
## Why Colocation is Preferred
### 1. Coupled Concerns Should Stay Together
Template, logic, and styles within a component are inherently coupled:
- Template references reactive data from the script
- Styles target classes used in the template
- Changes in one often require changes in others
```vue
<!-- Everything references each other -->
<script setup>
const isExpanded = ref(false) // Used by template and affects styling
</script>
<template>
<!-- Uses isExpanded from script, applies class for styling -->
<div :class="{ expanded: isExpanded }">...</div>
</template>
<style scoped>
/* Targets class from template, shows visual state from script */
.expanded { max-height: 500px; }
</style>
```
### 2. Easier Navigation and Understanding
Single file = single place to look:
```vue
<!-- Open one file, understand the whole component -->
<script setup>
// All logic here
</script>
<template>
<!-- All markup here -->
</template>
<style scoped>
/* All styles here */
</style>
```
### 3. Better Refactoring Experience
Renaming a class? Everything is in one file:
```vue
<!-- Before: .card-title used in both template and style -->
<!-- After: Rename to .user-title in one file, one commit -->
```
## When Src Imports Are Acceptable
For genuinely large components (rare), use src imports:
```vue
<!-- LargeDataTable.vue -->
<script src="./LargeDataTable.ts" lang="ts"></script>
<template src="./LargeDataTable.html"></template>
<style src="./LargeDataTable.scss" scoped lang="scss"></style>
```
But first, consider if the component should be split into smaller components.
## Managing Complexity Without File Splitting
### Extract Logic to Composables
```typescript
// composables/useDataTable.ts
export function useDataTable(initialData: Ref<Item[]>) {
const sortColumn = ref<string | null>(null)
const sortDirection = ref<'asc' | 'desc'>('asc')
const currentPage = ref(1)
const sortedData = computed(() => { ... })
const paginatedData = computed(() => { ... })
function sort(column: string) { ... }
function goToPage(page: number) { ... }
return {
sortColumn,
sortDirection,
currentPage,
sortedData,
paginatedData,
sort,
goToPage
}
}
```
```vue
<!-- DataTable.vue - Component stays focused -->
<script setup>
import { useDataTable } from '@/composables/useDataTable'
const props = defineProps(['items'])
const { sortedData, sort, goToPage } = useDataTable(toRef(props, 'items'))
</script>
```
### Break Into Smaller Components
```vue
<!-- Instead of one 500-line component -->
<template>
<div class="data-table">
<DataTableHeader @sort="handleSort" />
<DataTableBody :rows="visibleRows" />
<DataTablePagination
:total="total"
:current="currentPage"
@change="handlePageChange"
/>
</div>
</template>
```
## The Real Separation of Concerns
True separation of concerns in Vue means:
- **Components** handle their own template/logic/style (coupled by nature)
- **Composables** handle reusable stateful logic
- **Utilities** handle pure functions
- **Stores** handle global state
This is more maintainable than separating HTML/CSS/JS into different files.
## Reference
- [Vue.js SFC Introduction](https://vuejs.org/guide/scaling-up/sfc.html#what-about-separation-of-concerns)
- [Vue.js SFC Src Imports](https://vuejs.org/api/sfc-spec.html#src-imports)