Developer Experience
Slash oferece ferramentas para melhorar a experiência de desenvolvimento, incluindo warnings automáticos, mensagens de erro detalhadas e controle sobre o comportamento em dev/produção.
Dev Mode
Section titled “Dev Mode”Por padrão, Slash detecta automaticamente se está em modo de desenvolvimento baseado em process.env.NODE_ENV:
import { isDevMode } from '@ezbug/slash'
console.log(isDevMode()) // true em dev, false em produçãoConfigurando Dev Mode
Section titled “Configurando Dev Mode”Você pode controlar manualmente o dev mode:
import { setDevMode, isDevMode } from '@ezbug/slash'
// Desabilitar dev mode manualmentesetDevMode(false)console.log(isDevMode()) // false
// Habilitar dev modesetDevMode(true)console.log(isDevMode()) // trueQuando usar:
- Em testes: desabilitar warnings para testes limpos
- Em produção: garantir que dev mode está desabilitado
- Em staging: habilitar warnings mesmo em build de produção
Warnings Automáticos
Section titled “Warnings Automáticos”Em dev mode, Slash emite warnings úteis no console quando detecta problemas:
Tipos de Warnings
Section titled “Tipos de Warnings”1. Props inválidas:
import { html } from '@ezbug/slash'
// ⚠️ Warning: Unknown prop "onclick" (should be "onClick")html`<button onclick=${() => {}}>Click</button>`
// ✅ Corretohtml`<button onClick=${() => {}}>Click</button>`2. State mutations:
import { createState } from '@ezbug/slash'
const state = createState({ count: 0 })
// ⚠️ Warning: Não modifique o estado diretamentestate.get().count++ // Mutação direta
// ✅ Corretostate.set({ count: state.get().count + 1 })3. Memory leaks potenciais:
// ⚠️ Warning: Watcher não foi removido (memory leak)const state = createState(0)state.watch(() => { // ... sem cleanup})
// ✅ Correto: sempre limpe watchersconst unwatch = state.watch(() => { // ...})// Quando não precisar mais:unwatch()Controlando Warnings
Section titled “Controlando Warnings”Você pode habilitar ou desabilitar warnings:
import { setWarningsEnabled, isWarningsEnabled } from '@ezbug/slash'
// Desabilitar warningssetWarningsEnabled(false)console.log(isWarningsEnabled()) // false
// Habilitar warnings novamentesetWarningsEnabled(true)console.log(isWarningsEnabled()) // trueCasos de uso:
// Em testes: desabilitar warnings temporariamentebeforeEach(() => { setWarningsEnabled(false)})
afterEach(() => { setWarningsEnabled(true)})
// Em CI: garantir que warnings não quebrem buildsif (process.env.CI) { setWarningsEnabled(false)}Error Messages
Section titled “Error Messages”Throw em Erros
Section titled “Throw em Erros”Por padrão, erros são apenas logados no console. Você pode fazer Slash lançar exceções:
import { setErrorsThrow } from '@ezbug/slash'
// Fazer erros lançarem exceçõessetErrorsThrow(true)
try { // Código que pode gerar erro const state = createState(null) state.set(undefined) // Lança Error} catch (error) { console.error('Caught:', error)}
// Voltar ao comportamento padrão (apenas log)setErrorsThrow(false)Quando usar:
- Testes: capturar erros esperados
- Debug: parar execução em erros críticos
- Produção: deixar false (default) para não quebrar a aplicação
Mensagens de Erro Detalhadas
Section titled “Mensagens de Erro Detalhadas”Em dev mode, mensagens de erro incluem:
- Stack trace completo
- Contexto do erro (qual state/component)
- Sugestões de correção
Exemplo de mensagem:
❌ [Slash Error] Invalid state update
Context: state "userForm" (line 42 in UserForm.ts)Problem: Attempted to set undefined valueSuggestion: Use null instead of undefined, or provide a default value
Stack trace: at setState (state.ts:66) at UserForm (UserForm.ts:42) ...TypeScript Support
Section titled “TypeScript Support”Slash é escrito em TypeScript e oferece tipos completos para toda a API.
Tipos Automáticos
Section titled “Tipos Automáticos”import { createState, html } from '@ezbug/slash'import type { State, Props } from '@ezbug/slash'
// Type inference automáticoconst count = createState(0) // State<number>const name = createState('Alice') // State<string>
// Props tipadasinterface ButtonProps extends Props { label: string onClick: () => void disabled?: boolean}
const Button = ({ label, onClick, disabled = false }: ButtonProps) => { return html` <button onClick=${onClick} disabled=${disabled}> ${label} </button> `}Tipos Genéricos
Section titled “Tipos Genéricos”import { createState } from '@ezbug/slash'import type { State } from '@ezbug/slash'
interface User { id: number name: string email: string}
// State tipadoconst user: State<User | null> = createState<User | null>(null)
// Autocomplete funcionauser.set({ id: 1, name: 'Alice', // TypeScript valida as props email: 'alice@example.com'})
// ❌ TypeScript error: Property 'age' does not existuser.set({ id: 1, name: 'Bob', age: 30 })Strict Mode
Section titled “Strict Mode”Para máxima type safety, use strict mode no tsconfig.json:
{ "compilerOptions": { "strict": true, "noImplicitAny": true, "strictNullChecks": true, "strictFunctionTypes": true, "strictPropertyInitialization": true, "noImplicitThis": true, "alwaysStrict": true }}Debugging Tools
Section titled “Debugging Tools”Inspecionando State
Section titled “Inspecionando State”import { createState } from '@ezbug/slash'
const state = createState({ count: 0, items: [] })
// Ver valor atualconsole.log('Current state:', state.get())
// Watch todas as mudançasstate.watch((value) => { console.log('State changed:', value)})
// Debug com stack tracestate.watch((value) => { console.trace('State changed from:', value)})DevTools Integration
Section titled “DevTools Integration”Slash pode integrar com Redux DevTools para time-travel debugging:
import { createState } from '@ezbug/slash'
const state = createState(0, { history: true, // Habilita histórico maxHistory: 50 // Máximo de estados salvos})
// Acesse históricoconsole.log(state.history) // [0, 1, 2, 3, ...]
// Time-travelstate.undo() // Volta para estado anteriorstate.redo() // Avança para próximo estadoConsole Helpers
Section titled “Console Helpers”// Adicione helpers globais para debugif (process.env.NODE_ENV === 'development') { window.__SLASH_DEBUG__ = { states: new Map(), logAll: () => { window.__SLASH_DEBUG__.states.forEach((state, name) => { console.log(`${name}:`, state.get()) }) } }
// Registrar states para inspeção const count = createState(0) window.__SLASH_DEBUG__.states.set('count', count)}Performance Profiling
Section titled “Performance Profiling”Medindo Renders
Section titled “Medindo Renders”import { html, render } from '@ezbug/slash'
const Component = () => { console.time('render') const result = html`<div>Heavy component</div>` console.timeEnd('render') return result}
render(Component(), '#app')Performance Marks
Section titled “Performance Marks”import { createState } from '@ezbug/slash'
const state = createState(0)
state.watch(() => { performance.mark('state-update-start')
// ... operações custosas
performance.mark('state-update-end') performance.measure('state-update', 'state-update-start', 'state-update-end')})
// Ver mediçõesconst measures = performance.getEntriesByType('measure')console.table(measures)Environment Detection
Section titled “Environment Detection”isServer()
Section titled “isServer()”Detecte se o código está rodando no servidor (SSR) ou cliente:
import { isServer } from '@ezbug/slash'
if (isServer()) { // Código apenas no servidor console.log('Running on server')} else { // Código apenas no cliente console.log('Running on client') window.addEventListener('click', () => {})}Uso em componentes:
import { isServer, html } from '@ezbug/slash'
const Component = () => { const clientOnly = isServer() ? null : html`<div>Client-side only content</div>`
return html` <div> <h1>Universal content</h1> ${clientOnly} </div> `}Build Optimization
Section titled “Build Optimization”Production Builds
Section titled “Production Builds”Em produção, certifique-se de:
- Desabilitar dev mode:
import { setDevMode } from '@ezbug/slash'
if (process.env.NODE_ENV === 'production') { setDevMode(false)}- Tree-shaking: Ferramentas de build modernas (Vite, Webpack, Rollup) removem automaticamente código de dev:
// Este código é removido em produçãoif (process.env.NODE_ENV === 'development') { console.log('Debug info')}- Minificação:
# Vitebun run build
Bundle Size
Section titled “Bundle Size”Slash é extremamente leve:
| Build | Tamanho (min+gzip) |
|---|---|
| Core (state + render) | ~3KB |
| Full (com router, forms, SSR) | ~8KB |
| Dev warnings | ~1KB (removido em prod) |
Comparação com outras libs:
- React: ~45KB
- Vue: ~33KB
- Solid: ~7KB
- Slash: ~8KB ✅
Configuração Recomendada
Section titled “Configuração Recomendada”Para melhor DX em desenvolvimento:
import { setDevMode, setWarningsEnabled, setErrorsThrow} from '@ezbug/slash'
export const setupDev = () => { const isDev = process.env.NODE_ENV === 'development' const isTest = process.env.NODE_ENV === 'test'
// Dev mode setDevMode(isDev)
// Warnings (desabilitar em testes) setWarningsEnabled(isDev && !isTest)
// Throw errors apenas em testes setErrorsThrow(isTest)
// Console helpers if (isDev) { window.__SLASH_DEBUG__ = { version: '1.0.0', isDev: true } }}Uso:
import { setupDev } from './config/dev'
setupDev()
// ... resto da aplicaçãoPróximos Passos
Section titled “Próximos Passos”- Performance - Otimizações e best practices
- API Reference - Documentação completa da API
- Exemplos - Aplicações práticas