<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Webs on Commentary of Takao</title><link>https://takao.blog/es/web/</link><description>Recent content in Webs on Commentary of Takao</description><generator>Hugo -- gohugo.io</generator><language>es</language><copyright>Commentary of Takao</copyright><lastBuildDate>Sun, 12 Jul 2026 04:12:51 +0900</lastBuildDate><atom:link href="https://takao.blog/es/web/index.xml" rel="self" type="application/rss+xml"/><item><title>Herramientas de monitoreo de rendimiento web 2026</title><link>https://takao.blog/es/web/web-performance-monitoring-tools-2026/</link><pubDate>Wed, 08 Jul 2026 10:00:00 +0900</pubDate><guid>https://takao.blog/es/web/web-performance-monitoring-tools-2026/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/web-performance-monitoring-tools-2026-es.png" alt="Featured image of post Herramientas de monitoreo de rendimiento web 2026" /&gt;&lt;p&gt;El monitoreo de rendimiento web (RUM) captura datos reales de usuarios. Combinado con laboratorio (Lighthouse), da una visión completa del rendimiento.&lt;/p&gt;
&lt;h2 id="rum-real-user-monitoring"&gt;RUM (Real User Monitoring)
&lt;/h2&gt;&lt;p&gt;Mide usuarios reales. Captura Core Web Vitals (LCP, INP, CLS), TTFB, FCP, TBT. Library &lt;code&gt;web-vitals&lt;/code&gt; para envío a Analytics.&lt;/p&gt;
&lt;h2 id="herramientas"&gt;Herramientas
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;CrUX&lt;/strong&gt; (Chrome UX Report): datos de campo agregados. &lt;strong&gt;Lighthouse&lt;/strong&gt;: laboratorio. &lt;strong&gt;PageSpeed Insights&lt;/strong&gt;: combina ambos. &lt;strong&gt;WebPageTest&lt;/strong&gt;: análisis detallado.&lt;/p&gt;
&lt;h2 id="monitoreo-continuo"&gt;Monitoreo continuo
&lt;/h2&gt;&lt;p&gt;Alertas cuando las métricas superan umbrales. Dashboard con tendencias. Presupuesto de rendimiento en CI. Regresión = build fallido.&lt;/p&gt;</description></item><item><title>React 19: Novedades que los desarrolladores deben conocer</title><link>https://takao.blog/es/web/react-19-new-features/</link><pubDate>Wed, 08 Jul 2026 10:00:00 +0900</pubDate><guid>https://takao.blog/es/web/react-19-new-features/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/react-19-new-features-es.png" alt="Featured image of post React 19: Novedades que los desarrolladores deben conocer" /&gt;&lt;h2 id="qué-cambió-en-react-19"&gt;Qué cambió en React 19
&lt;/h2&gt;&lt;p&gt;React 19 no es una actualización menor sino un cambio de paradigma. Server Components estables, nuevos hooks y el React Compiler cambian fundamentalmente cómo se escriben las aplicaciones.&lt;/p&gt;
&lt;h2 id="server-components-estables"&gt;Server Components estables
&lt;/h2&gt;&lt;p&gt;Los React Server Components (RSC) ahora están listos para producción. Al renderizar en el servidor y enviar HTML al cliente, reducen significativamente el tamaño del bundle. Los componentes que usan useState o useEffect deben declarar &amp;ldquo;use client&amp;rdquo;.&lt;/p&gt;</description></item><item><title>Agentes de IA para refactorización de código</title><link>https://takao.blog/es/web/ai-agents-codebase-refactoring-future/</link><pubDate>Sun, 05 Jul 2026 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/ai-agents-codebase-refactoring-future/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/ai-agents-codebase-refactoring-future-es.png" alt="Featured image of post Agentes de IA para refactorización de código" /&gt;&lt;p&gt;Los agentes de IA como Cursor, Copilot Workspace y Claude pueden refactorizar código base de forma autónoma. El futuro del desarrollo incluye colaboración humano-agente.&lt;/p&gt;
&lt;h2 id="capacidades-actuales"&gt;Capacidades actuales
&lt;/h2&gt;&lt;p&gt;Refactorización de nombres, extracción de funciones, división de módulos, migración de APIs. Los agentes entienden el contexto del proyecto y aplican cambios.&lt;/p&gt;
&lt;h2 id="límites"&gt;Límites
&lt;/h2&gt;&lt;p&gt;Los agentes pueden introducir bugs sutiles. No entienden completamente la intención del negocio. La revisión humana sigue siendo necesaria.&lt;/p&gt;
&lt;h2 id="flujo-de-trabajo"&gt;Flujo de trabajo
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;Describe el refactor. 2. El agente analiza el código. 3. Propone cambios. 4. Revisas y apruebas. 5. El agente aplica. 6. Pruebas automáticas.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="futuro"&gt;Futuro
&lt;/h2&gt;&lt;p&gt;Agentes especializados por dominio, integración con CI/CD, aprendizaje del estilo del equipo, refactorizaciones multi-repositorio.&lt;/p&gt;</description></item><item><title>Alias de Git: Productividad en la línea de comandos</title><link>https://takao.blog/es/web/git-alias-setup-productivity/</link><pubDate>Sat, 20 Jun 2026 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/git-alias-setup-productivity/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/git-alias-setup-productivity-es.png" alt="Featured image of post Alias de Git: Productividad en la línea de comandos" /&gt;&lt;p&gt;Los alias de Git permiten abreviar comandos largos. Configurados en &lt;code&gt;.gitconfig&lt;/code&gt;, pueden incluir secuencias completas y flags.&lt;/p&gt;
&lt;h2 id="alias-básicos"&gt;Alias básicos
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;git config --global alias.co checkout&lt;/code&gt;, &lt;code&gt;alias.br branch&lt;/code&gt;, &lt;code&gt;alias.ci commit&lt;/code&gt;, &lt;code&gt;alias.st status&lt;/code&gt;. Los alias más comunes ahorran cientos de pulsaciones al día.&lt;/p&gt;
&lt;h2 id="alias-avanzados"&gt;Alias avanzados
&lt;/h2&gt;&lt;p&gt;Combinan múltiples comandos con &lt;code&gt;!&lt;/code&gt;: &lt;code&gt;alias.lg = !git log --graph --oneline --all&lt;/code&gt;. Ejecutan scripts shell arbitrarios.&lt;/p&gt;
&lt;h2 id="alias-con-parámetros"&gt;Alias con parámetros
&lt;/h2&gt;&lt;p&gt;Usando funciones shell en el alias: &lt;code&gt;!f() { git log --oneline --author=&amp;quot;$1&amp;quot;; }; f&lt;/code&gt;. Máximo control sin memorizar flags.&lt;/p&gt;</description></item><item><title>CSS Containment: Aislamiento de renderizado para rendimiento</title><link>https://takao.blog/es/web/performance-css-contain-property/</link><pubDate>Mon, 15 Jun 2026 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/performance-css-contain-property/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/performance-css-contain-property-es.png" alt="Featured image of post CSS Containment: Aislamiento de renderizado para rendimiento" /&gt;&lt;p&gt;La propiedad CSS &lt;code&gt;contain&lt;/code&gt; permite aislar subárboles del DOM para que el navegador pueda optimizar el renderizado independientemente del resto de la página.&lt;/p&gt;
&lt;h2 id="valores-de-contain"&gt;Valores de contain
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;layout&lt;/code&gt;: el layout interno no afecta al exterior. &lt;code&gt;style&lt;/code&gt;: los estilos no se escapan. &lt;code&gt;paint&lt;/code&gt;: el elemento pinta dentro de sus bounds. &lt;code&gt;size&lt;/code&gt;: el elemento necesita dimensiones explícitas.&lt;/p&gt;
&lt;h2 id="content-visibility"&gt;content-visibility
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;content-visibility: auto&lt;/code&gt; combina containment con lazy rendering. Los elementos fuera de pantalla no se renderizan hasta que se acercan al viewport. Mejora drásticamente LCP en páginas largas.&lt;/p&gt;</description></item><item><title>Tipos no mapeados y utilidades avanzadas de TypeScript</title><link>https://takao.blog/es/web/typescript-unmapped-types-utility/</link><pubDate>Wed, 10 Jun 2026 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/typescript-unmapped-types-utility/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/typescript-unmapped-types-utility-es.png" alt="Featured image of post Tipos no mapeados y utilidades avanzadas de TypeScript" /&gt;&lt;p&gt;Más allá de los mapped types, TypeScript ofrece patrones avanzados como tipos condicionales distributivos, tipos recursivos y operaciones sobre uniones y e intersecciones.&lt;/p&gt;
&lt;h2 id="tipos-condicionales-distributivos"&gt;Tipos condicionales distributivos
&lt;/h2&gt;&lt;p&gt;Cuando un tipo condicional recibe un tipo unión, la condición se aplica a cada miembro individualmente: &lt;code&gt;T extends U ? X : Y&lt;/code&gt; con T = A | B produce (A extends U ? X : Y) | (B extends U ? X : Y).&lt;/p&gt;</description></item><item><title>OWASP ZAP Avanzado 2026: Automatización y scripting</title><link>https://takao.blog/es/web/owasp-zap-advanced-2026/</link><pubDate>Tue, 09 Jun 2026 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/owasp-zap-advanced-2026/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/owasp-zap-advanced-2026-es.png" alt="Featured image of post OWASP ZAP Avanzado 2026: Automatización y scripting" /&gt;&lt;p&gt;OWASP ZAP ofrece capacidades avanzadas de automatización y scripting para equipos de seguridad y desarrollo.&lt;/p&gt;
&lt;h2 id="zap-automation-framework"&gt;ZAP Automation Framework
&lt;/h2&gt;&lt;p&gt;YAML para definir pipelines de seguridad: spider, active scan, alert filtering, report generation. Reemplaza scripts ad-hoc.&lt;/p&gt;
&lt;h2 id="scripting-con-zap"&gt;Scripting con ZAP
&lt;/h2&gt;&lt;p&gt;JavaScript, Python, Groovy para hooks personalizados. Scripts passive/active/extender. Automatización de autenticación y sesiones.&lt;/p&gt;
&lt;h2 id="api-de-zap"&gt;API de ZAP
&lt;/h2&gt;&lt;p&gt;REST API completa. Integración con Postman, curl, cualquier lenguaje. Control total de escaneos, contextos y alerts.&lt;/p&gt;
&lt;h2 id="contextos-y-autenticación"&gt;Contextos y autenticación
&lt;/h2&gt;&lt;p&gt;Define contextos de aplicación (URLs, include/exclude). Autenticación basada en formularios, JSON API, OAuth. Manejo de sesiones.&lt;/p&gt;</description></item><item><title>Hugo 2026: Mejores prácticas con CSP</title><link>https://takao.blog/es/web/hugo-latest-csp-best-practices-2026/</link><pubDate>Fri, 05 Jun 2026 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/hugo-latest-csp-best-practices-2026/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/hugo-latest-csp-best-practices-2026-es.png" alt="Featured image of post Hugo 2026: Mejores prácticas con CSP" /&gt;&lt;p&gt;Content Security Policy (CSP) es esencial para la seguridad. Hugo 2026 ofrece nuevas capacidades para integrar CSP sin sacrificar funcionalidad.&lt;/p&gt;
&lt;h2 id="csp-en-sitios-estáticos"&gt;CSP en sitios estáticos
&lt;/h2&gt;&lt;p&gt;Los sitios estáticos tienen menos vectores de ataque pero aún necesitan CSP para scripts de terceros, analytics y widgets embebidos.&lt;/p&gt;
&lt;h2 id="generación-de-nonces"&gt;Generación de nonces
&lt;/h2&gt;&lt;p&gt;Hugo puede generar nonces únicos por build para scripts inline. Configuración via template functions. Integración con partials.&lt;/p&gt;
&lt;h2 id="hash-para-scripts-estáticos"&gt;Hash para scripts estáticos
&lt;/h2&gt;&lt;p&gt;Calcula hashes SHA de scripts embebidos. Incluye en la cabecera CSP. Hugo puede automatizar esto con pipe functions.&lt;/p&gt;</description></item><item><title>Firmado de commits con claves SSH</title><link>https://takao.blog/es/web/git-signing-commits-ssh-keys/</link><pubDate>Mon, 25 May 2026 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/git-signing-commits-ssh-keys/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/git-signing-commits-ssh-keys-es.png" alt="Featured image of post Firmado de commits con claves SSH" /&gt;&lt;p&gt;Git 2.34+ permite firmar commits con claves SSH además de GPG. SSH es más familiar para desarrolladores que ya usan claves SSH para autenticación.&lt;/p&gt;
&lt;h2 id="configuración"&gt;Configuración
&lt;/h2&gt;&lt;p&gt;Usa tu clave SSH existente (&lt;code&gt;~/.ssh/id_ed25519.pub&lt;/code&gt;). Configura &lt;code&gt;git config --global gpg.format ssh&lt;/code&gt; y &lt;code&gt;user.signingkey ~/.ssh/id_ed25519.pub&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="firma-automática"&gt;Firma automática
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;git config --global commit.gpgsign true&lt;/code&gt; firma todos los commits. Git usa SSH agent para la frase de paso.&lt;/p&gt;
&lt;h2 id="registro-en-github"&gt;Registro en GitHub
&lt;/h2&gt;&lt;p&gt;Añade tu clave SSH pública en GitHub Settings con tipo &amp;ldquo;Signing Key&amp;rdquo; (no solo Authentication). Los commits firmados muestran &amp;ldquo;Verified&amp;rdquo;.&lt;/p&gt;</description></item><item><title>CSP Report-Only: Implementación segura de Content Security Policy</title><link>https://takao.blog/es/web/security-content-security-policy-csp-report-only/</link><pubDate>Fri, 15 May 2026 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/security-content-security-policy-csp-report-only/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/security-content-security-policy-csp-report-only-es.png" alt="Featured image of post CSP Report-Only: Implementación segura de Content Security Policy" /&gt;&lt;p&gt;Content-Security-Policy-Report-Only permite probar políticas de seguridad sin bloquear recursos. Ideal para implementación gradual.&lt;/p&gt;
&lt;h2 id="diferencia-con-csp"&gt;Diferencia con CSP
&lt;/h2&gt;&lt;p&gt;CSP normal bloquea violaciones. CSP-Report-Only solo reporta. Usa ambas en paralelo: una activa y otra para nuevas reglas.&lt;/p&gt;
&lt;h2 id="reportes"&gt;Reportes
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-http" data-lang="http"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;Content-Security-Policy-Report-Only: script-src &amp;#39;self&amp;#39;; report-uri /csp-endpoint
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Los reportes JSON contienen: document-uri, violated-directive, blocked-uri, source-file.&lt;/p&gt;
&lt;h2 id="endpoints-de-reporte"&gt;Endpoints de reporte
&lt;/h2&gt;&lt;p&gt;Servidor propio que captura POST. &lt;code&gt;report-to&lt;/code&gt; (nuevo) en lugar de &lt;code&gt;report-uri&lt;/code&gt; (obsoleto). Servicios como Report URI, Sentry.&lt;/p&gt;
&lt;h2 id="flujo-de-adopción"&gt;Flujo de adopción
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;Report-Only vigilando. 2. Identificar violaciones legítimas. 3. Ajustar política. 4. Migrar a CSP real. 5. Repetir hasta sin reportes.&lt;/li&gt;
&lt;/ol&gt;</description></item><item><title>Archivos de declaración .d.ts en TypeScript</title><link>https://takao.blog/es/web/typescript-declaration-files-dts/</link><pubDate>Sun, 10 May 2026 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/typescript-declaration-files-dts/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/typescript-declaration-files-dts-es.png" alt="Featured image of post Archivos de declaración .d.ts en TypeScript" /&gt;&lt;p&gt;Los archivos &lt;code&gt;.d.ts&lt;/code&gt; describen las formas de los tipos de bibliotecas JavaScript a TypeScript. Son la interfaz entre el ecosistema JS y el sistema de tipos de TS.&lt;/p&gt;
&lt;h2 id="anatomía-de-un-dts"&gt;Anatomía de un .d.ts
&lt;/h2&gt;&lt;p&gt;Declaran tipos, interfaces, funciones y clases sin implementación. &lt;code&gt;declare function&lt;/code&gt;, &lt;code&gt;declare class&lt;/code&gt;, &lt;code&gt;declare module&lt;/code&gt;. No generan código en el output.&lt;/p&gt;
&lt;h2 id="declaraciones-de-módulos"&gt;Declaraciones de módulos
&lt;/h2&gt;&lt;p&gt;Para bibliotecas sin tipos nativos: &lt;code&gt;declare module 'library-name' { ... }&lt;/code&gt;. TypeScript fusiona estas declaraciones con los imports.&lt;/p&gt;</description></item><item><title>Comparativa de generadores de sitios estáticos 2026</title><link>https://takao.blog/es/web/static-site-generators-2026-comparison/</link><pubDate>Tue, 05 May 2026 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/static-site-generators-2026-comparison/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/static-site-generators-2026-comparison-es.png" alt="Featured image of post Comparativa de generadores de sitios estáticos 2026" /&gt;&lt;p&gt;Los SSG han evolucionado. En 2026, las opciones principales ofrecen rendimiento, flexibilidad y DX mejorada.&lt;/p&gt;
&lt;h2 id="hugo"&gt;Hugo
&lt;/h2&gt;&lt;p&gt;Más rápido (&amp;lt;1ms por página). Go templates. Ideal para blogs y sitios de contenido. Ecosistema de temas maduro.&lt;/p&gt;
&lt;h2 id="astro"&gt;Astro
&lt;/h2&gt;&lt;p&gt;Islas de interactividad. Multi-framework (React, Vue, Svelte). Zero JS por defecto. Ideal para marketing sites y documentación.&lt;/p&gt;
&lt;h2 id="nextjs"&gt;Next.js
&lt;/h2&gt;&lt;p&gt;SSG + SSR + PPR. Más complejo pero más potente. Ideal para aplicaciones y e-commerce con contenido dinámico.&lt;/p&gt;</description></item><item><title>Recuperación de ramas eliminadas con git reflog</title><link>https://takao.blog/es/web/git-recovery-deleted-branch-reflog/</link><pubDate>Sat, 25 Apr 2026 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/git-recovery-deleted-branch-reflog/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/git-recovery-deleted-branch-reflog-es.png" alt="Featured image of post Recuperación de ramas eliminadas con git reflog" /&gt;&lt;p&gt;&lt;code&gt;git reflog&lt;/code&gt; registra todos los movimientos de HEAD. Es la herramienta de rescate cuando eliminas una rama por accidente.&lt;/p&gt;
&lt;h2 id="cómo-funciona-reflog"&gt;Cómo funciona reflog
&lt;/h2&gt;&lt;p&gt;Cada cambio de HEAD (commit, checkout, reset, merge) se registra. &lt;code&gt;git reflog&lt;/code&gt; muestra el historial de movimientos con sus hashes.&lt;/p&gt;
&lt;h2 id="recuperar-una-rama-eliminada"&gt;Recuperar una rama eliminada
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;Encuentra el último commit de la rama en reflog. 2. &lt;code&gt;git checkout -b rama-recuperada &amp;lt;hash&amp;gt;&lt;/code&gt;. La rama y sus commits están intactos.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="límites-de-reflog"&gt;Límites de reflog
&lt;/h2&gt;&lt;p&gt;Reflog es local y temporal. Los commits huérfanos son recolectados por GC tras 90 días (default). Recupera pronto.&lt;/p&gt;</description></item><item><title>Docker Compose: Mejores prácticas de producción</title><link>https://takao.blog/es/web/docker-compose-production-best-practice/</link><pubDate>Mon, 20 Apr 2026 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/docker-compose-production-best-practice/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/docker-compose-production-best-practice-es.png" alt="Featured image of post Docker Compose: Mejores prácticas de producción" /&gt;&lt;p&gt;Más allá del Docker Compose básico, existen patrones probados para entornos de producción robustos.&lt;/p&gt;
&lt;h2 id="multi-stage-builds"&gt;Multi-stage builds
&lt;/h2&gt;&lt;p&gt;Compila en una etapa, ejecuta en otra más ligera. Reduce significativamente el tamaño de la imagen final y la superficie de ataque.&lt;/p&gt;
&lt;h2 id="healthchecks"&gt;Healthchecks
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;healthcheck&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;test&lt;/span&gt;: [&lt;span style="color:#e6db74"&gt;&amp;#34;CMD&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;curl&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;-f&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;http://localhost&amp;#34;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;interval&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;30s&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;retries&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;3&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Docker reinicia servicios no saludables automáticamente.&lt;/p&gt;
&lt;h2 id="logging"&gt;Logging
&lt;/h2&gt;&lt;p&gt;Configura drivers de logging (&lt;code&gt;json-file&lt;/code&gt;, &lt;code&gt;fluentd&lt;/code&gt;, &lt;code&gt;awslogs&lt;/code&gt;). Rotación de logs: &lt;code&gt;max-size: 10m&lt;/code&gt;, &lt;code&gt;max-file: 3&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="seguridad-de-red"&gt;Seguridad de red
&lt;/h2&gt;&lt;p&gt;Redes separadas para frontend, backend y base de datos. Solo expone puertos al host cuando sea necesario. Usa redes externas para servicios compartidos.&lt;/p&gt;</description></item><item><title>DNS-prefetch y Preconnect: Optimización de conexiones de red</title><link>https://takao.blog/es/web/performance-dns-prefetch-preconnect/</link><pubDate>Wed, 15 Apr 2026 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/performance-dns-prefetch-preconnect/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/performance-dns-prefetch-preconnect-es.png" alt="Featured image of post DNS-prefetch y Preconnect: Optimización de conexiones de red" /&gt;&lt;p&gt;DNS-prefetch y preconnect reducen la latencia de conexiones a orígenes externos resolviendo DNS y estableciendo conexiones TCP/SSL antes de que se necesiten.&lt;/p&gt;
&lt;h2 id="dns-prefetch"&gt;DNS-prefetch
&lt;/h2&gt;&lt;p&gt;Resuelve DNS de dominios externos antes de que el navegador los solicite. Útil para recursos en CDNs, APIs y fuentes.&lt;/p&gt;
&lt;h2 id="preconnect"&gt;Preconnect
&lt;/h2&gt;&lt;p&gt;Además de DNS, establece la conexión TCP y el handshake TLS. Más costoso pero más efectivo. Usar solo para los orígenes más críticos (3-4 máximo).&lt;/p&gt;
&lt;h2 id="implementación"&gt;Implementación
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-html" data-lang="html"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;link&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;rel&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;dns-prefetch&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;href&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;https://fonts.googleapis.com&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;link&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;rel&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;preconnect&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;href&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;https://fonts.gstatic.com&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;crossorigin&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="cuándo-usar-cuál"&gt;Cuándo usar cuál
&lt;/h2&gt;&lt;p&gt;DNS-prefetch: recursos de terceros que no son críticos. Preconnect: orígenes que se usan en los primeros segundos de carga. Preconnect sin crossorigin puede filtrar datos.&lt;/p&gt;</description></item><item><title>Parsers a nivel de tipos con Template Literal Types</title><link>https://takao.blog/es/web/typescript-template-literal-type-level-parsers/</link><pubDate>Fri, 10 Apr 2026 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/typescript-template-literal-type-level-parsers/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/typescript-template-literal-type-level-parsers-es.png" alt="Featured image of post Parsers a nivel de tipos con Template Literal Types" /&gt;&lt;p&gt;Los template literal types combinados con inferencia condicional permiten construir parsers que operan exclusivamente en tiempo de compilación, analizando cadenas como rutas, formatos y DSLs.&lt;/p&gt;
&lt;h2 id="conceptos-básicos"&gt;Conceptos básicos
&lt;/h2&gt;&lt;p&gt;Usar &lt;code&gt;T extends &lt;/code&gt;${pattern}${infer Rest}&lt;code&gt; ? ... : never&lt;/code&gt; para extraer partes de una cadena recursivamente. Cada paso consume un token.&lt;/p&gt;
&lt;h2 id="parseo-de-rutas"&gt;Parseo de rutas
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;type&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;ParseRoute&lt;/span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;T&lt;/span&gt;&amp;gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;T&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;extends&lt;/span&gt; &lt;span style="color:#e6db74"&gt;`&lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;infer&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Segment&lt;/span&gt;&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;/&lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;infer&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Rest&lt;/span&gt;&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;?&lt;/span&gt; [&lt;span style="color:#a6e22e"&gt;Segment&lt;/span&gt;, ...&lt;span style="color:#a6e22e"&gt;ParseRoute&lt;/span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;Rest&lt;/span&gt;&amp;gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;:&lt;/span&gt; [&lt;span style="color:#a6e22e"&gt;T&lt;/span&gt;];
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="validación-de-formatos"&gt;Validación de formatos
&lt;/h2&gt;&lt;p&gt;Validar UUIDs, fechas ISO, versiones semver, rutas de archivos. Los errores se detectan en tiempo de compilación con mensajes claros.&lt;/p&gt;</description></item><item><title>WebGPU: Gráficos nativos en el navegador</title><link>https://takao.blog/es/web/webgpu-native-browser-graphics-generation/</link><pubDate>Sun, 05 Apr 2026 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/webgpu-native-browser-graphics-generation/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/webgpu-native-browser-graphics-generation-es.png" alt="Featured image of post WebGPU: Gráficos nativos en el navegador" /&gt;&lt;p&gt;WebGPU es la nueva API de gráficos y cómputo para la web. Sucesora de WebGL, ofrece acceso directo a GPUs modernas con rendimiento nativo.&lt;/p&gt;
&lt;h2 id="diferencias-con-webgl"&gt;Diferencias con WebGL
&lt;/h2&gt;&lt;p&gt;WebGPU usa una API más cercana a Vulkan/DX12/Metal. Menos overhead de driver. Compute shaders nativos. Soporte gráfico moderno.&lt;/p&gt;
&lt;h2 id="conceptos-clave"&gt;Conceptos clave
&lt;/h2&gt;&lt;p&gt;Adapter (GPU física), Device (contexto lógico), Queue (comandos), Pipeline (shaders), Buffer, Texture, BindGroup.&lt;/p&gt;
&lt;h2 id="shaders-con-wgsl"&gt;Shaders con WGSL
&lt;/h2&gt;&lt;p&gt;WGSL (WebGPU Shading Language) es el lenguaje de shaders. Tipado fuerte. Similar a SPIR-V. Compilado a código nativo de GPU.&lt;/p&gt;</description></item><item><title>Git checkout, restore y switch: Diferencias y cuándo usar cada uno</title><link>https://takao.blog/es/web/git-checkout-restore-switch-commands/</link><pubDate>Wed, 25 Mar 2026 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/git-checkout-restore-switch-commands/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/git-checkout-restore-switch-commands-es.png" alt="Featured image of post Git checkout, restore y switch: Diferencias y cuándo usar cada uno" /&gt;&lt;p&gt;Git 2.23 introdujo &lt;code&gt;git switch&lt;/code&gt; y &lt;code&gt;git restore&lt;/code&gt; para reemplazar los usos sobrecargados de &lt;code&gt;git checkout&lt;/code&gt;. Cada comando tiene una responsabilidad única.&lt;/p&gt;
&lt;h2 id="git-switch"&gt;git switch
&lt;/h2&gt;&lt;p&gt;Cambia de rama. Equivalente a &lt;code&gt;git checkout &amp;lt;rama&amp;gt;&lt;/code&gt;. &lt;code&gt;-c&lt;/code&gt; crea y cambia a una nueva rama. &lt;code&gt;-&lt;/code&gt; vuelve a la rama anterior.&lt;/p&gt;
&lt;h2 id="git-restore"&gt;git restore
&lt;/h2&gt;&lt;p&gt;Restaura archivos del working tree o staging. &lt;code&gt;git restore archivo&lt;/code&gt; descarta cambios locales. &lt;code&gt;--staged&lt;/code&gt; quita archivos del staging.&lt;/p&gt;
&lt;h2 id="git-checkout-legacy"&gt;git checkout (legacy)
&lt;/h2&gt;&lt;p&gt;Aún funciona pero es sobrecargado. Puede cambiar ramas o restaurar archivos. Para scripts y automatización, prefiere switch y restore.&lt;/p&gt;</description></item><item><title>JWT vs Autenticación por sesión: Cuál elegir</title><link>https://takao.blog/es/web/security-jwt-vs-session-auth/</link><pubDate>Fri, 20 Mar 2026 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/security-jwt-vs-session-auth/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/security-jwt-vs-session-auth-es.png" alt="Featured image of post JWT vs Autenticación por sesión: Cuál elegir" /&gt;&lt;p&gt;JWT (JSON Web Tokens) y sesiones basadas en cookies son los dos enfoques principales de autenticación. Cada uno tiene ventajas según el contexto.&lt;/p&gt;
&lt;h2 id="autenticación-por-sesión"&gt;Autenticación por sesión
&lt;/h2&gt;&lt;p&gt;Token de sesión almacenado en el servidor (memoria, Redis, DB). Cookie con session ID. Fácil invalidar (eliminar sesión del servidor). Estado server-side.&lt;/p&gt;
&lt;h2 id="jwt"&gt;JWT
&lt;/h2&gt;&lt;p&gt;Token autónomo firmado. Contiene claims (userId, rol, exp). Sin estado server-side. Válido hasta expirar. Difícil invalidar (revocación complicada).&lt;/p&gt;
&lt;h2 id="comparativa"&gt;Comparativa
&lt;/h2&gt;&lt;p&gt;Sesión: más fácil invalidar, seguro contra robos de token. JWT: escalable (sin almacenamiento), mejor para microservicios y APIs móviles.&lt;/p&gt;</description></item><item><title>Optimización de carga de fuentes web</title><link>https://takao.blog/es/web/performance-fonts-loading-optimization/</link><pubDate>Sun, 15 Mar 2026 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/performance-fonts-loading-optimization/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/performance-fonts-loading-optimization-es.png" alt="Featured image of post Optimización de carga de fuentes web" /&gt;&lt;p&gt;Las fuentes web pueden causar FOIT (Flash of Invisible Text) o FOUT (Flash of Unstyled Text). Optimizar su carga mejora LCP y la experiencia de lectura.&lt;/p&gt;
&lt;h2 id="font-display"&gt;font-display
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;font-display: swap&lt;/code&gt;: muestra texto con fuente del sistema mientras carga. &lt;code&gt;font-display: optional&lt;/code&gt;: no descarga si la red es lenta. &lt;code&gt;font-display: block&lt;/code&gt;: período de bloqueo corto.&lt;/p&gt;
&lt;h2 id="subset-de-fuentes"&gt;Subset de fuentes
&lt;/h2&gt;&lt;p&gt;Incluye solo los caracteres necesarios (latino básico, no todos los glifos). Herramientas: &lt;code&gt;glyphhanger&lt;/code&gt;, &lt;code&gt;fonttools&lt;/code&gt;. Reduce drásticamente el tamaño de archivos.&lt;/p&gt;</description></item><item><title>Recetas CSS creativas con el selector padre :has()</title><link>https://takao.blog/es/web/css-has-pseudo-selector-recipes/</link><pubDate>Tue, 10 Mar 2026 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/css-has-pseudo-selector-recipes/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/css-has-pseudo-selector-recipes-es.png" alt="Featured image of post Recetas CSS creativas con el selector padre :has()" /&gt;&lt;h2 id="cómo-funciona-has"&gt;Cómo funciona &lt;code&gt;:has()&lt;/code&gt;
&lt;/h2&gt;&lt;p&gt;La pseudo-clase &lt;code&gt;:has()&lt;/code&gt; toma una lista de selectores y selecciona un elemento si contiene cierto descendiente o hermano. Soportada en todos los navegadores principales desde 2026.&lt;/p&gt;
&lt;h2 id="receta-1-estilos-de-validación-de-formularios"&gt;Receta 1: Estilos de validación de formularios
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#a6e22e"&gt;form-group&lt;/span&gt;:&lt;span style="color:#a6e22e"&gt;has&lt;/span&gt;&lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#f92672"&gt;input&lt;/span&gt;:&lt;span style="color:#a6e22e"&gt;invalid&lt;/span&gt;&lt;span style="color:#f92672"&gt;)&lt;/span&gt; { &lt;span style="color:#66d9ef"&gt;border-left&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;3&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;px&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;solid&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;#e74c3c&lt;/span&gt;; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Muestra/oculta mensajes de error y colorea bordes según el estado del input, sin JavaScript.&lt;/p&gt;
&lt;h2 id="receta-2-layouts-dinámicos-de-tarjetas"&gt;Receta 2: Layouts dinámicos de tarjetas
&lt;/h2&gt;&lt;p&gt;Tarjetas con imagen ajustan su padding automáticamente: &lt;code&gt;.card:has(img) { padding: 0; }&lt;/code&gt;&lt;/p&gt;</description></item><item><title>Google Gemini API: Modelos y usos prácticos</title><link>https://takao.blog/es/web/gemini-api-pro-latest-utilization/</link><pubDate>Thu, 05 Mar 2026 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/gemini-api-pro-latest-utilization/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/gemini-api-pro-latest-utilization-es.png" alt="Featured image of post Google Gemini API: Modelos y usos prácticos" /&gt;&lt;p&gt;Gemini de Google ofrece modelos multimodales de última generación accesibles via API. Compite directamente con GPT-4o y Claude.&lt;/p&gt;
&lt;h2 id="modelos-disponibles"&gt;Modelos disponibles
&lt;/h2&gt;&lt;p&gt;Gemini 2.5 Pro: razonamiento avanzado, contexto de 1M tokens. Gemini 2.5 Flash: rápido y económico. Ambos soportan texto, imagen, audio y video.&lt;/p&gt;
&lt;h2 id="contexto-largo"&gt;Contexto largo
&lt;/h2&gt;&lt;p&gt;1M tokens de contexto permite procesar documentos completos, repositorios de código, logs extensos. Ideal para análisis de código base.&lt;/p&gt;
&lt;h2 id="api-features"&gt;API Features
&lt;/h2&gt;&lt;p&gt;Streaming, JSON mode, function calling, grounding (búsqueda web), caching. Precios competitivos con free tier generoso.&lt;/p&gt;</description></item><item><title>Git Merge vs Rebase: Mejores prácticas</title><link>https://takao.blog/es/web/git-merge-vs-rebase-best-practice/</link><pubDate>Wed, 25 Feb 2026 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/git-merge-vs-rebase-best-practice/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/git-merge-vs-rebase-best-practice-es.png" alt="Featured image of post Git Merge vs Rebase: Mejores prácticas" /&gt;&lt;p&gt;Merge y rebase son dos estrategias para integrar cambios. Cada una tiene ventajas según el contexto y la política del equipo.&lt;/p&gt;
&lt;h2 id="merge"&gt;Merge
&lt;/h2&gt;&lt;p&gt;Crea un commit de merge que preserva el historial exacto. Útil para ramas públicas y compartidas. Traza claramente cuándo y cómo se integraron los cambios.&lt;/p&gt;
&lt;h2 id="rebase"&gt;Rebase
&lt;/h2&gt;&lt;p&gt;Reescribe el historial aplicando commits de una rama sobre otra línea. Resulta en un historial lineal y limpio. No recomendado para ramas compartidas.&lt;/p&gt;</description></item><item><title>Reemplazando localStorage: localForage como wrapper de IndexedDB</title><link>https://takao.blog/es/web/js-indexeddb-localforage-localstorage/</link><pubDate>Fri, 20 Feb 2026 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/js-indexeddb-localforage-localstorage/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/js-indexeddb-localforage-localstorage-es.png" alt="Featured image of post Reemplazando localStorage: localForage como wrapper de IndexedDB" /&gt;&lt;h2 id="introducción"&gt;Introducción
&lt;/h2&gt;&lt;p&gt;El almacenamiento del lado del cliente es fundamental. localStorage tiene límites dolorosos: ~5 MB, API síncrona, solo strings.&lt;/p&gt;
&lt;h2 id="indexeddb-potente-pero-complejo"&gt;IndexedDB: Potente pero complejo
&lt;/h2&gt;&lt;p&gt;Ofrece almacenamiento virtualmente ilimitado, API asíncrona, datos estructurados y consultas indexadas. Pero es notoriamente verboso.&lt;/p&gt;
&lt;h2 id="localforage-lo-mejor-de-ambos-mundos"&gt;localForage: Lo mejor de ambos mundos
&lt;/h2&gt;&lt;p&gt;Wrapper ligero que envuelve IndexedDB (con WebSQL y localStorage como respaldo) tras una API simple basada en promesas, inspirada en localStorage.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;await&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;localforage&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;setItem&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;user&amp;#39;&lt;/span&gt;, { &lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;Alice&amp;#39;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;role&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;admin&amp;#39;&lt;/span&gt; });
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;user&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;await&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;localforage&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;getItem&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;user&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Detección del mejor driver disponible: 1. IndexedDB, 2. WebSQL, 3. localStorage. Para la mayoría de necesidades de almacenamiento, localForage es la elección pragmática.&lt;/p&gt;</description></item><item><title>Seguridad DNS: DNSSEC, SPF, DKIM y DMARC</title><link>https://takao.blog/es/web/web-security-dnssec-spf-dkim-dmarc/</link><pubDate>Sun, 15 Feb 2026 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/web-security-dnssec-spf-dkim-dmarc/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/web-security-dnssec-spf-dkim-dmarc-es.png" alt="Featured image of post Seguridad DNS: DNSSEC, SPF, DKIM y DMARC" /&gt;&lt;p&gt;La seguridad del correo electrónico y DNS se basa en cuatro tecnologías que previenen spoofing, phishing y suplantación de dominio.&lt;/p&gt;
&lt;h2 id="dnssec"&gt;DNSSEC
&lt;/h2&gt;&lt;p&gt;Firma digitalmente los registros DNS. Protege contra envenenamiento de caché DNS y ataques Man-in-the-Middle. El navegador verifica la firma.&lt;/p&gt;
&lt;h2 id="spf"&gt;SPF
&lt;/h2&gt;&lt;p&gt;Especifica qué servidores pueden enviar correo desde tu dominio. Registro TXT con IPs autorizadas. Previene falsificación de remitente.&lt;/p&gt;
&lt;h2 id="dkim"&gt;DKIM
&lt;/h2&gt;&lt;p&gt;Firma digitalmente los correos salientes. El receptor verifica la firma contra un registro DNS. Asegura que el correo no fue alterado.&lt;/p&gt;</description></item><item><title>Partial Prerendering (PPR) en Next.js</title><link>https://takao.blog/es/web/nextjs-partial-prerendering-ppr/</link><pubDate>Tue, 10 Feb 2026 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/nextjs-partial-prerendering-ppr/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/nextjs-partial-prerendering-ppr-es.png" alt="Featured image of post Partial Prerendering (PPR) en Next.js" /&gt;&lt;p&gt;Partial Prerendering (PPR) combina contenido estático prerenderizado con contenido dinámico transmitido vía streaming en una misma página.&lt;/p&gt;
&lt;h2 id="el-problema"&gt;El problema
&lt;/h2&gt;&lt;p&gt;SSG: rápido pero contenido obsoleto. SSR: contenido fresco pero más lento. PPR ofrece lo mejor de ambos: HTML estático inmediato + partes dinámicas en streaming.&lt;/p&gt;
&lt;h2 id="cómo-funciona"&gt;Cómo funciona
&lt;/h2&gt;&lt;p&gt;Next.js prerenderiza el shell estático de la página. Los componentes dinámicos (con &lt;code&gt;cookies()&lt;/code&gt;, &lt;code&gt;headers()&lt;/code&gt;, &lt;code&gt;searchParams&lt;/code&gt;) se renderizan bajo demanda.&lt;/p&gt;
&lt;h2 id="configuración"&gt;Configuración
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;experimental.ppr = 'incremental'&lt;/code&gt; en next.config.js. Los componentes dinámicos se envuelven en Suspense. PPR solo aplica donde se detectan datos dinámicos.&lt;/p&gt;</description></item><item><title>Tailwind CSS v4: Novedades y cambios</title><link>https://takao.blog/es/web/tailwind-css-v4-release-changes/</link><pubDate>Thu, 05 Feb 2026 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/tailwind-css-v4-release-changes/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/tailwind-css-v4-release-changes-es.png" alt="Featured image of post Tailwind CSS v4: Novedades y cambios" /&gt;&lt;p&gt;Tailwind CSS v4 es un rediseño completo. Usa el motor CSS nativo de Cascade Layers, configuración via CSS en lugar de JS, y nuevas utilidades.&lt;/p&gt;
&lt;h2 id="configuración-via-css"&gt;Configuración via CSS
&lt;/h2&gt;&lt;p&gt;Adiós a &lt;code&gt;tailwind.config.js&lt;/code&gt;. La configuración se hace en CSS con &lt;code&gt;@theme&lt;/code&gt;, &lt;code&gt;@utility&lt;/code&gt;, &lt;code&gt;@variant&lt;/code&gt;. &lt;code&gt;@import &amp;quot;tailwindcss&amp;quot;&lt;/code&gt; reemplaza las directivas anteriores.&lt;/p&gt;
&lt;h2 id="rendimiento"&gt;Rendimiento
&lt;/h2&gt;&lt;p&gt;Engine de CSS nativo sin PostCSS. Compilación 10x más rápida. Cero dependencias de JavaScript en tiempo de ejecución.&lt;/p&gt;
&lt;h2 id="nuevas-utilidades"&gt;Nuevas utilidades
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;inset-*&lt;/code&gt;, &lt;code&gt;field-sizing-*&lt;/code&gt;, &lt;code&gt;@starting-style&lt;/code&gt; para animaciones de entrada. &lt;code&gt;color-mix()&lt;/code&gt;, &lt;code&gt;light-dark()&lt;/code&gt;. Soporte mejorado para contenedores.&lt;/p&gt;</description></item><item><title>Commits semánticos: Estandarización de mensajes de commit</title><link>https://takao.blog/es/web/git-semantic-commit-messages-standard/</link><pubDate>Sun, 25 Jan 2026 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/git-semantic-commit-messages-standard/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/git-semantic-commit-messages-standard-es.png" alt="Featured image of post Commits semánticos: Estandarización de mensajes de commit" /&gt;&lt;p&gt;Los mensajes de commit semánticos siguen un formato estructurado que facilita la generación de changelogs y el versionado semántico automático.&lt;/p&gt;
&lt;h2 id="formato"&gt;Formato
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;tipo(alcance): descripción&lt;/code&gt; + cuerpo + footer. Tipos: &lt;code&gt;feat&lt;/code&gt;, &lt;code&gt;fix&lt;/code&gt;, &lt;code&gt;chore&lt;/code&gt;, &lt;code&gt;docs&lt;/code&gt;, &lt;code&gt;style&lt;/code&gt;, &lt;code&gt;refactor&lt;/code&gt;, &lt;code&gt;perf&lt;/code&gt;, &lt;code&gt;test&lt;/code&gt;, &lt;code&gt;ci&lt;/code&gt;, &lt;code&gt;build&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="beneficios"&gt;Beneficios
&lt;/h2&gt;&lt;p&gt;Generación automática de changelogs con herramientas como &lt;code&gt;standard-version&lt;/code&gt;. Versionado semántico: feat → minor, fix → patch, breaking changes → major.&lt;/p&gt;
&lt;h2 id="breaking-changes"&gt;Breaking changes
&lt;/h2&gt;&lt;p&gt;Añade &lt;code&gt;BREAKING CHANGE:&lt;/code&gt; en el footer o &lt;code&gt;!&lt;/code&gt; después del tipo/alcance: &lt;code&gt;feat(api)!: rediseñar autenticación&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>Error Boundaries y logging en frontend</title><link>https://takao.blog/es/web/frontend-error-boundaries-logging/</link><pubDate>Tue, 20 Jan 2026 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/frontend-error-boundaries-logging/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/frontend-error-boundaries-logging-es.png" alt="Featured image of post Error Boundaries y logging en frontend" /&gt;&lt;p&gt;Error Boundaries en React capturan errores de renderizado para mostrar una UI de fallback. Combinados con logging, permiten monitorear errores en producción.&lt;/p&gt;
&lt;h2 id="error-boundaries-en-react"&gt;Error Boundaries en React
&lt;/h2&gt;&lt;p&gt;Componentes que capturan errores en su subárbol con &lt;code&gt;componentDidCatch()&lt;/code&gt; o &lt;code&gt;static getDerivedStateFromError()&lt;/code&gt;. Reemplazan try/catch para errores de renderizado.&lt;/p&gt;
&lt;h2 id="logging-de-errores"&gt;Logging de errores
&lt;/h2&gt;&lt;p&gt;Captura errores en Error Boundaries y envíalos a un servicio: Sentry, LogRocket, Datadog. Incluye stack trace, props, y contexto del usuario.&lt;/p&gt;
&lt;h2 id="windowonerror-y-unhandledrejection"&gt;window.onerror y unhandledrejection
&lt;/h2&gt;&lt;p&gt;Captura errores no manejados globalmente. &lt;code&gt;window.onerror&lt;/code&gt; para errores síncronos. &lt;code&gt;unhandledrejection&lt;/code&gt; para promesas rechazadas.&lt;/p&gt;</description></item><item><title>HTTP Strict Transport Security (HSTS): Forzar HTTPS</title><link>https://takao.blog/es/web/web-security-http-strict-transport-hsts-hacks/</link><pubDate>Fri, 16 Jan 2026 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/web-security-http-strict-transport-hsts-hacks/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/web-security-http-strict-transport-hsts-hacks-es.png" alt="Featured image of post HTTP Strict Transport Security (HSTS): Forzar HTTPS" /&gt;&lt;p&gt;HSTS le indica al navegador que solo se conecte al sitio mediante HTTPS, incluso si el usuario escribe &lt;code&gt;http://&lt;/code&gt; o hace clic en un enlace HTTP.&lt;/p&gt;
&lt;h2 id="cabecera-hsts"&gt;Cabecera HSTS
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Strict&lt;span style="color:#f92672"&gt;-&lt;/span&gt;Transport&lt;span style="color:#f92672"&gt;-&lt;/span&gt;Security: max&lt;span style="color:#f92672"&gt;-&lt;/span&gt;age&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;31536000&lt;/span&gt;; includeSubDomains; preload
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;max-age&lt;/code&gt; en segundos (1 año recomendado). &lt;code&gt;includeSubDomains&lt;/code&gt; aplica a todos los subdominios.&lt;/p&gt;
&lt;h2 id="hsts-preload"&gt;HSTS Preload
&lt;/h2&gt;&lt;p&gt;Lista mantenida por Chrome (cargada en todos los navegadores). Los dominios en la lista tienen HSTS activo desde la primera visita, sin necesidad de cabecera.&lt;/p&gt;</description></item><item><title>Ramas en el sistema de tipos de TypeScript: Introducción a Conditional Types</title><link>https://takao.blog/es/web/typescript-conditional-types/</link><pubDate>Thu, 15 Jan 2026 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/typescript-conditional-types/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/typescript-conditional-types-es.png" alt="Featured image of post Ramas en el sistema de tipos de TypeScript: Introducción a Conditional Types" /&gt;&lt;h2 id="introducción"&gt;Introducción
&lt;/h2&gt;&lt;p&gt;Los conditional types permiten lógica a nivel de tipos: &lt;code&gt;T extends U ? X : Y&lt;/code&gt;. Esto permite resolución de tipos dinámica y consciente del contexto.&lt;/p&gt;
&lt;h2 id="sintaxis-básica"&gt;Sintaxis básica
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;type IsString&amp;lt;T&amp;gt; = T extends string ? true : false;&lt;/code&gt; La condición pregunta: &amp;ldquo;¿Es &lt;code&gt;T&lt;/code&gt; asignable a &lt;code&gt;U&lt;/code&gt;?&amp;rdquo;&lt;/p&gt;
&lt;h2 id="la-palabra-clave-infer"&gt;La palabra clave infer
&lt;/h2&gt;&lt;p&gt;Extrae un tipo desde dentro de una condición: &lt;code&gt;type ReturnType&amp;lt;T&amp;gt; = T extends (...args: any[]) =&amp;gt; infer R ? R : never;&lt;/code&gt;&lt;/p&gt;</description></item><item><title>React Compiler: Di adiós a la memoización manual</title><link>https://takao.blog/es/web/react-compiler-automated-memoization/</link><pubDate>Sat, 10 Jan 2026 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/react-compiler-automated-memoization/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/react-compiler-automated-memoization-es.png" alt="Featured image of post React Compiler: Di adiós a la memoización manual" /&gt;&lt;h2 id="introducción"&gt;Introducción
&lt;/h2&gt;&lt;p&gt;El React Compiler (antes React Forget) es una herramienta de compilación que memoiza automáticamente componentes, hooks y valores de React analizando dependencias reactivas en tiempo de compilación.&lt;/p&gt;
&lt;h2 id="el-problema-de-la-memoización-manual"&gt;El problema de la memoización manual
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;useMemo&lt;/code&gt;, &lt;code&gt;useCallback&lt;/code&gt;, &lt;code&gt;React.memo&lt;/code&gt; son verbosos, propensos a errores y fáciles de olvidar. Un &lt;code&gt;useMemo&lt;/code&gt; faltante causa re-renderizados innecesarios; un array de dependencias incorrecto causa closures obsoletas.&lt;/p&gt;
&lt;h2 id="cómo-funciona"&gt;Cómo funciona
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;Detección de valores reactivos (AST). 2. Construcción de grafo de dependencias. 3. Generación de código optimizado con caché integrada.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="lo-que-puedes-eliminar"&gt;Lo que puedes eliminar
&lt;/h2&gt;&lt;p&gt;Con el React Compiler activado ya no necesitas: &lt;code&gt;useMemo()&lt;/code&gt;, &lt;code&gt;useCallback()&lt;/code&gt;, &lt;code&gt;React.memo()&lt;/code&gt;, ni arrays de dependencias manuales.&lt;/p&gt;</description></item><item><title>Cloudflare Workers y WebAssembly en el Edge</title><link>https://takao.blog/es/web/cloudflare-workers-wasm-edge-developments/</link><pubDate>Mon, 05 Jan 2026 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/cloudflare-workers-wasm-edge-developments/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/cloudflare-workers-wasm-edge-developments-es.png" alt="Featured image of post Cloudflare Workers y WebAssembly en el Edge" /&gt;&lt;p&gt;Cloudflare Workers ejecuta código JavaScript, WASM y Python en el edge. Ofrece latencia ultrabaja al procesar solicitudes cerca del usuario.&lt;/p&gt;
&lt;h2 id="workers-runtime"&gt;Workers Runtime
&lt;/h2&gt;&lt;p&gt;Basado en V8. Aislado por contexto. Sin Node.js (API propia: Fetch, Cache, KV, D1, R2, Queues). Arranque en frío &amp;lt; 5ms.&lt;/p&gt;
&lt;h2 id="webassembly-en-workers"&gt;WebAssembly en Workers
&lt;/h2&gt;&lt;p&gt;Compila Rust, C/C++, Go, Zig a WASM. Workers carga módulos WASM estáticos. Procesamiento de imágenes, parsing, cálculos pesados en el edge.&lt;/p&gt;
&lt;h2 id="almacenamiento-en-el-edge"&gt;Almacenamiento en el edge
&lt;/h2&gt;&lt;p&gt;KV (clave-valor, baja latencia), D1 (SQLite), R2 (S3-compatible), Durable Objects (estado coordinado). Bases de datos geodistribuidas.&lt;/p&gt;</description></item><item><title>Limpieza de ramas remotas huérfanas con git prune</title><link>https://takao.blog/es/web/git-prune-clean-remote-branches/</link><pubDate>Thu, 25 Dec 2025 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/git-prune-clean-remote-branches/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/git-prune-clean-remote-branches-es.png" alt="Featured image of post Limpieza de ramas remotas huérfanas con git prune" /&gt;&lt;p&gt;Las ramas remotas eliminadas en el servidor pueden quedar como referencias locales obsoletas. &lt;code&gt;git remote prune&lt;/code&gt; y &lt;code&gt;git fetch --prune&lt;/code&gt; las eliminan.&lt;/p&gt;
&lt;h2 id="el-problema"&gt;El problema
&lt;/h2&gt;&lt;p&gt;Cuando un compañero elimina una rama remota, tu repositorio local aún conserva &lt;code&gt;origin/rama-eliminada&lt;/code&gt;. Con el tiempo se acumulan decenas de referencias muertas.&lt;/p&gt;
&lt;h2 id="soluciones"&gt;Soluciones
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;git fetch --prune origin&lt;/code&gt; limpia al hacer fetch. &lt;code&gt;git remote prune origin&lt;/code&gt; limpia sin fetch. Configura &lt;code&gt;fetch.prune = true&lt;/code&gt; globalmente.&lt;/p&gt;
&lt;h2 id="ramas-locales-huérfanas"&gt;Ramas locales huérfanas
&lt;/h2&gt;&lt;p&gt;Usa &lt;code&gt;git branch --merged&lt;/code&gt; para encontrar ramas locales ya mergeadas. Elimínalas con &lt;code&gt;git branch -d&lt;/code&gt;. Combina con prun para limpieza completa.&lt;/p&gt;</description></item><item><title>Optimizaciones del Critical Rendering Path</title><link>https://takao.blog/es/web/performance-critical-rendering-path-optimizations/</link><pubDate>Sat, 20 Dec 2025 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/performance-critical-rendering-path-optimizations/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/performance-critical-rendering-path-optimizations-es.png" alt="Featured image of post Optimizaciones del Critical Rendering Path" /&gt;&lt;p&gt;El Critical Rendering Path (CRP) es la secuencia de pasos que el navegador sigue para renderizar la página inicial. Optimizarlo mejora LCP y First Paint.&lt;/p&gt;
&lt;h2 id="bloqueo-de-renderizado"&gt;Bloqueo de renderizado
&lt;/h2&gt;&lt;p&gt;CSS bloquea el renderizado. JavaScript bloquea el parsing de HTML. Reduce el CSS crítico e inlinealo. Difiere JS no crítico con &lt;code&gt;defer&lt;/code&gt; o &lt;code&gt;async&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="css-crítico"&gt;CSS crítico
&lt;/h2&gt;&lt;p&gt;Extrae el CSS necesario para el contenido above-the-fold. Inlinealo en &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt;. Carga el resto asíncronamente. Herramientas: Critical, Penthouse.&lt;/p&gt;</description></item><item><title>HTTP Headers de seguridad y CORS</title><link>https://takao.blog/es/web/web-security-http-headers-cors/</link><pubDate>Mon, 15 Dec 2025 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/web-security-http-headers-cors/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/web-security-http-headers-cors-es.png" alt="Featured image of post HTTP Headers de seguridad y CORS" /&gt;&lt;p&gt;Las cabeceras HTTP de seguridad protegen contra ataques comunes. CORS controla qué dominios pueden acceder a tus recursos desde el navegador.&lt;/p&gt;
&lt;h2 id="cabeceras-de-seguridad-esenciales"&gt;Cabeceras de seguridad esenciales
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;X-Content-Type-Options: nosniff&lt;/code&gt;, &lt;code&gt;X-Frame-Options: DENY&lt;/code&gt;, &lt;code&gt;X-XSS-Protection: 0&lt;/code&gt; (obsoleto). &lt;code&gt;Referrer-Policy&lt;/code&gt;, &lt;code&gt;Permissions-Policy&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="cors-cross-origin-resource-sharing"&gt;CORS (Cross-Origin Resource Sharing)
&lt;/h2&gt;&lt;p&gt;Controla qué orígenes pueden leer respuestas de tu API. &lt;code&gt;Access-Control-Allow-Origin&lt;/code&gt;, &lt;code&gt;-Methods&lt;/code&gt;, &lt;code&gt;-Headers&lt;/code&gt;. Preflight con OPTIONS para solicitudes complejas.&lt;/p&gt;
&lt;h2 id="cors-en-apis"&gt;CORS en APIs
&lt;/h2&gt;&lt;p&gt;Para APIs públicas: &lt;code&gt;Access-Control-Allow-Origin: *&lt;/code&gt;. Para APIs privadas: lista blanca de orígenes. Credenciales requieren &lt;code&gt;Allow-Credentials: true&lt;/code&gt; y origen específico.&lt;/p&gt;</description></item><item><title>Previniendo el Cumulative Layout Shift con CSS aspect-ratio</title><link>https://takao.blog/es/web/css-aspect-ratio-cumulative-layout-shift/</link><pubDate>Wed, 10 Dec 2025 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/css-aspect-ratio-cumulative-layout-shift/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/css-aspect-ratio-cumulative-layout-shift-es.png" alt="Featured image of post Previniendo el Cumulative Layout Shift con CSS aspect-ratio" /&gt;&lt;h2 id="entendiendo-cumulative-layout-shift"&gt;Entendiendo Cumulative Layout Shift
&lt;/h2&gt;&lt;p&gt;CLS es una métrica de Core Web Vitals que mide la estabilidad visual. Un CLS alto daña la experiencia de usuario y el SEO. La causa principal son elementos multimedia que cargan sin espacio reservado.&lt;/p&gt;
&lt;h2 id="cómo-funciona-aspect-ratio"&gt;Cómo funciona aspect-ratio
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;aspect-ratio&lt;/code&gt; declara la proporción ancho/alto de un elemento. El navegador reserva espacio, evitando saltos de layout.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#a6e22e"&gt;responsive-video&lt;/span&gt; { &lt;span style="color:#66d9ef"&gt;aspect-ratio&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;16&lt;/span&gt; &lt;span style="color:#f92672"&gt;/&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;9&lt;/span&gt;; &lt;span style="color:#66d9ef"&gt;width&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;100&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;%&lt;/span&gt;; &lt;span style="color:#66d9ef"&gt;height&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;auto&lt;/span&gt;; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="uso-con-imágenes"&gt;Uso con imágenes
&lt;/h2&gt;&lt;p&gt;Reemplaza el viejo truco de padding-bottom. Combina con &lt;code&gt;max-width&lt;/code&gt; y &lt;code&gt;object-fit&lt;/code&gt; para resultados óptimos.&lt;/p&gt;</description></item><item><title>Cloudflare y Privacy Sandbox: El fin de las cookies de terceros</title><link>https://takao.blog/es/web/cloudflare-privacy-sandbox-thirdparty-cookie-deprecation/</link><pubDate>Fri, 05 Dec 2025 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/cloudflare-privacy-sandbox-thirdparty-cookie-deprecation/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/cloudflare-privacy-sandbox-thirdparty-cookie-deprecation-es.png" alt="Featured image of post Cloudflare y Privacy Sandbox: El fin de las cookies de terceros" /&gt;&lt;p&gt;Google está eliminando gradualmente las cookies de terceros. Cloudflare ofrece soluciones para mantener la funcionalidad del sitio sin depender de ellas.&lt;/p&gt;
&lt;h2 id="el-problema"&gt;El problema
&lt;/h2&gt;&lt;p&gt;Las cookies de terceros se usan para tracking, autenticación y personalización. Su desaparición afecta a analytics, ads y widgets sociales.&lt;/p&gt;
&lt;h2 id="privacy-sandbox"&gt;Privacy Sandbox
&lt;/h2&gt;&lt;p&gt;APIs de Google: Topics API (intereses), Protected Audience (remarketing), Attribution Reporting (conversiones), Shared Storage (datos entre contextos).&lt;/p&gt;
&lt;h2 id="alternativas-con-cloudflare"&gt;Alternativas con Cloudflare
&lt;/h2&gt;&lt;p&gt;Cookies propias (first-party) con Cloudflare Workers para tracking. Cloudflare Zaraz para analytics sin cookies. Turnstile para CAPTCHA sin tracking.&lt;/p&gt;</description></item><item><title>Revertir merges en Git de forma segura</title><link>https://takao.blog/es/web/git-revert-merge-commit-safe/</link><pubDate>Tue, 25 Nov 2025 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/git-revert-merge-commit-safe/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/git-revert-merge-commit-safe-es.png" alt="Featured image of post Revertir merges en Git de forma segura" /&gt;&lt;p&gt;Revertir un merge commit es diferente a revertir un commit normal. Git necesita saber de qué lado del merge se revierte para evitar conflictos futuros.&lt;/p&gt;
&lt;h2 id="el-problema"&gt;El problema
&lt;/h2&gt;&lt;p&gt;Revertir un merge con &lt;code&gt;git revert -m 1&lt;/code&gt; revierte contra la primera rama (main). Si luego reintentas mergear la rama original, los cambios revertidos no reaparecen.&lt;/p&gt;
&lt;h2 id="cómo-revertir-correctamente"&gt;Cómo revertir correctamente
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;git revert -m 1 &amp;lt;merge-commit-hash&amp;gt;&lt;/code&gt; para revertir contra main. Si necesitas reintroducir los cambios, revierte el revert: &lt;code&gt;git revert &amp;lt;revert-commit-hash&amp;gt;&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>Caché en GitHub Actions: Acelerar workflows</title><link>https://takao.blog/es/web/github-actions-caching-setup/</link><pubDate>Thu, 20 Nov 2025 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/github-actions-caching-setup/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/github-actions-caching-setup-es.png" alt="Featured image of post Caché en GitHub Actions: Acelerar workflows" /&gt;&lt;p&gt;El caché de GitHub Actions almacena dependencias y artefactos entre ejecuciones. Reduce drásticamente el tiempo de CI.&lt;/p&gt;
&lt;h2 id="actioncache"&gt;action/cache
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;- &lt;span style="color:#f92672"&gt;uses&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;actions/cache@v4&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;with&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;path&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;~/.npm&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;key&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;npm-${{ hashFiles(&amp;#39;package-lock.json&amp;#39;) }}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="estrategias-de-clave"&gt;Estrategias de clave
&lt;/h2&gt;&lt;p&gt;Usa hash de archivos lock como clave primaria. Restore keys para coincidencias parciales. Fallback a último cache válido si cambian las dependencias.&lt;/p&gt;
&lt;h2 id="límites"&gt;Límites
&lt;/h2&gt;&lt;p&gt;10GB por repositorio. 7 días de retención (último acceso). Limpieza manual con API de GitHub. Cache miss si la clave no coincide exactamente.&lt;/p&gt;</description></item><item><title>Vulnerabilidades en dependencias con npm audit</title><link>https://takao.blog/es/web/security-dependency-vulnerabilities-npm-audit/</link><pubDate>Sat, 15 Nov 2025 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/security-dependency-vulnerabilities-npm-audit/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/security-dependency-vulnerabilities-npm-audit-es.png" alt="Featured image of post Vulnerabilidades en dependencias con npm audit" /&gt;&lt;p&gt;&lt;code&gt;npm audit&lt;/code&gt; escanea las dependencias del proyecto en busca de vulnerabilidades conocidas. Es la primera línea de defensa contra paquetes comprometidos.&lt;/p&gt;
&lt;h2 id="uso-básico"&gt;Uso básico
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;npm audit&lt;/code&gt; lista vulnerabilidades por severidad (critical, high, moderate, low). Muestra ruta de dependencia, versión vulnerable y versión corregida.&lt;/p&gt;
&lt;h2 id="npm-audit-fix"&gt;npm audit fix
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;npm audit fix --force&lt;/code&gt; actualiza a la versión corregida. &lt;code&gt;--force&lt;/code&gt; puede cambiar versiones major (puede romper cosas).&lt;/p&gt;
&lt;h2 id="alternativas"&gt;Alternativas
&lt;/h2&gt;&lt;p&gt;Snyk: escaneo continuo, PRs automáticos de fix. Dependabot: PRs automáticos en GitHub. &lt;code&gt;socket.dev&lt;/code&gt;: análisis de comportamiento de paquetes.&lt;/p&gt;</description></item><item><title>Tipos mapeados en TypeScript: Transformación de tipos</title><link>https://takao.blog/es/web/typescript-mapped-types/</link><pubDate>Mon, 10 Nov 2025 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/typescript-mapped-types/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/typescript-mapped-types-es.png" alt="Featured image of post Tipos mapeados en TypeScript: Transformación de tipos" /&gt;&lt;p&gt;Los tipos mapeados transforman un tipo existente iterando sobre sus propiedades. Son la base de utilidades como &lt;code&gt;Partial&amp;lt;T&amp;gt;&lt;/code&gt;, &lt;code&gt;Readonly&amp;lt;T&amp;gt;&lt;/code&gt;, &lt;code&gt;Pick&amp;lt;T, K&amp;gt;&lt;/code&gt; y &lt;code&gt;Record&amp;lt;K, V&amp;gt;&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="sintaxis-básica"&gt;Sintaxis básica
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;type&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Nullable&lt;/span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;T&lt;/span&gt;&amp;gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; { [&lt;span style="color:#a6e22e"&gt;P&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;in&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;keyof&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;T&lt;/span&gt;]&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;T&lt;/span&gt;[&lt;span style="color:#a6e22e"&gt;P&lt;/span&gt;] &lt;span style="color:#f92672"&gt;|&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;null&lt;/span&gt; };
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Itera sobre &lt;code&gt;keyof T&lt;/code&gt; y aplica una transformación a cada propiedad.&lt;/p&gt;
&lt;h2 id="modificadores"&gt;Modificadores
&lt;/h2&gt;&lt;p&gt;Añadir o remover &lt;code&gt;readonly&lt;/code&gt; y &lt;code&gt;?&lt;/code&gt; con prefijos &lt;code&gt;+&lt;/code&gt; y &lt;code&gt;-&lt;/code&gt;: &lt;code&gt;{ -readonly [P in keyof T]-?: T[P] }&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="reasignación-de-claves-ts-41"&gt;Reasignación de claves (TS 4.1+)
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;as&lt;/code&gt; clause para renombrar propiedades: &lt;code&gt;{ [P in keyof T as &lt;/code&gt;get${Capitalize&amp;lt;string &amp;amp; P&amp;gt;}&lt;code&gt;]: () =&amp;gt; T[P] }&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>ESM estable en Node.js: Soporte de require</title><link>https://takao.blog/es/web/node-esm-require-support-stable/</link><pubDate>Wed, 05 Nov 2025 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/node-esm-require-support-stable/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/node-esm-require-support-stable-es.png" alt="Featured image of post ESM estable en Node.js: Soporte de require" /&gt;&lt;p&gt;Node.js ha estabilizado el soporte de ES Modules. La función &lt;code&gt;require(esm)&lt;/code&gt; permite cargar módulos ESM desde CJS de forma síncrona, simplificando la migración.&lt;/p&gt;
&lt;h2 id="requireesm-en-nodejs-22"&gt;require(esm) en Node.js 22+
&lt;/h2&gt;&lt;p&gt;Node.js 22+ permite &lt;code&gt;require()&lt;/code&gt; de módulos ESM sincrónicamente si no tienen top-level await. Facilita la adopción híbrida.&lt;/p&gt;
&lt;h2 id="configuración"&gt;Configuración
&lt;/h2&gt;&lt;p&gt;No requiere flags de línea de comandos. Los paquetes ESM deben declararse con &lt;code&gt;&amp;quot;type&amp;quot;: &amp;quot;module&amp;quot;&lt;/code&gt; o &lt;code&gt;.mjs&lt;/code&gt;. &lt;code&gt;require()&lt;/code&gt; resuelve automáticamente.&lt;/p&gt;
&lt;h2 id="limitaciones"&gt;Limitaciones
&lt;/h2&gt;&lt;p&gt;Top-level await deshabilita require(esm). Paquetes ESM con solo named exports pueden necesitar ajustes. Los loaders personalizados afectan el comportamiento.&lt;/p&gt;</description></item><item><title>Git Bisect: Depuración de regresiones binaria</title><link>https://takao.blog/es/web/git-bisect-debug-regression/</link><pubDate>Mon, 20 Oct 2025 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/git-bisect-debug-regression/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/git-bisect-debug-regression-es.png" alt="Featured image of post Git Bisect: Depuración de regresiones binaria" /&gt;&lt;p&gt;&lt;code&gt;git bisect&lt;/code&gt; realiza una búsqueda binaria para encontrar el commit que introdujo un bug. Es la herramienta más eficiente para depurar regresiones.&lt;/p&gt;
&lt;h2 id="uso-básico"&gt;Uso básico
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;git bisect start&lt;/code&gt;, marca el commit bueno (&lt;code&gt;git bisect good&lt;/code&gt;) y el malo (&lt;code&gt;git bisect bad&lt;/code&gt;). Git checkout commits intermedios para probar.&lt;/p&gt;
&lt;h2 id="automatización"&gt;Automatización
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;git bisect run &amp;lt;script&amp;gt;&lt;/code&gt; ejecuta un script que devuelve 0 (bueno) o distinto de 0 (malo). El proceso es completamente automático.&lt;/p&gt;
&lt;h2 id="estrategias"&gt;Estrategias
&lt;/h2&gt;&lt;p&gt;Bisect sobre un rango específico de commits. Usa &lt;code&gt;--first-parent&lt;/code&gt; para ignorar merges. Prueba en una rama limpia para evitar falsos positivos.&lt;/p&gt;</description></item><item><title>Potenciando tus expresiones regulares con el flag v</title><link>https://takao.blog/es/web/js-regex-v-flag/</link><pubDate>Wed, 15 Oct 2025 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/js-regex-v-flag/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/js-regex-v-flag-es.png" alt="Featured image of post Potenciando tus expresiones regulares con el flag v" /&gt;&lt;h2 id="introducción"&gt;Introducción
&lt;/h2&gt;&lt;p&gt;ES2024 introduce el flag &lt;code&gt;v&lt;/code&gt;, un superconjunto del flag &lt;code&gt;u&lt;/code&gt; que permite notación de conjuntos, resta de clases, intersección y coincidencia de emojis Unicode.&lt;/p&gt;
&lt;h2 id="resta-de-clases---"&gt;Resta de clases (&lt;code&gt;--&lt;/code&gt;)
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;re&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;/[\p{Letter}--[aeiouAEIOU]]/v; // letras excepto vocales&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="intersección-"&gt;Intersección (&lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt;)
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;re&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;/[\p{Letter}&amp;amp;&amp;amp;\p{Script=Greek}]/v; // solo letras griegas&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="clases-anidadas"&gt;Clases anidadas
&lt;/h2&gt;&lt;p&gt;El flag &lt;code&gt;v&lt;/code&gt; permite anidar clases con corchetes, eliminando secuencias de escape confusas.&lt;/p&gt;
&lt;h2 id="coincidencia-de-emojis"&gt;Coincidencia de emojis
&lt;/h2&gt;&lt;p&gt;Nuevas propiedades: &lt;code&gt;\p{RGI_Emoji}&lt;/code&gt;, &lt;code&gt;\p{Basic_Emoji}&lt;/code&gt;, &lt;code&gt;\p{Emoji_Keycap_Sequence}&lt;/code&gt;, etc.&lt;/p&gt;
&lt;h2 id="migración-desde-flag-u"&gt;Migración desde flag u
&lt;/h2&gt;&lt;p&gt;El flag &lt;code&gt;v&lt;/code&gt; es estrictamente un superconjunto pero tiene cambios disruptivos: &lt;code&gt;\d&lt;/code&gt; dentro de clase no está permitido, &lt;code&gt;--&lt;/code&gt; y &lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt; son operadores.&lt;/p&gt;</description></item><item><title>Implementando modo oscuro simple con CSS light-dark()</title><link>https://takao.blog/es/web/css-light-dark-color-scheme/</link><pubDate>Fri, 10 Oct 2025 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/css-light-dark-color-scheme/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/css-light-dark-color-scheme-es.png" alt="Featured image of post Implementando modo oscuro simple con CSS light-dark()" /&gt;&lt;h2 id="el-problema-del-modo-oscuro-tradicional"&gt;El problema del modo oscuro tradicional
&lt;/h2&gt;&lt;p&gt;Tradicionalmente requería reglas CSS duplicadas en &lt;code&gt;@media (prefers-color-scheme: dark)&lt;/code&gt;. &lt;code&gt;light-dark()&lt;/code&gt; elimina esta duplicación.&lt;/p&gt;
&lt;h2 id="la-función-light-dark"&gt;La función light-dark()
&lt;/h2&gt;&lt;p&gt;Acepta dos colores y retorna el que coincide con el esquema actual del usuario: &lt;code&gt;color: light-dark(black, white)&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="configuración-de-color-scheme"&gt;Configuración de color-scheme
&lt;/h2&gt;&lt;p&gt;Requiere declarar los esquemas soportados: &lt;code&gt;color-scheme: light dark;&lt;/code&gt; en &lt;code&gt;:root&lt;/code&gt; o mediante &lt;code&gt;&amp;lt;meta name=&amp;quot;color-scheme&amp;quot;&amp;gt;&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="variables-de-tema-simplificadas"&gt;Variables de tema simplificadas
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;:&lt;span style="color:#a6e22e"&gt;root&lt;/span&gt; { --bg: &lt;span style="color:#a6e22e"&gt;light-dark&lt;/span&gt;(&lt;span style="color:#ae81ff"&gt;#ffffff&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;#1a1a2e&lt;/span&gt;); --text: &lt;span style="color:#a6e22e"&gt;light-dark&lt;/span&gt;(&lt;span style="color:#ae81ff"&gt;#111111&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;#e0e0e0&lt;/span&gt;); }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Sin media queries. El navegador maneja el cambio automáticamente.&lt;/p&gt;</description></item><item><title>Next.js 15 Stable: Mejores prácticas en producción</title><link>https://takao.blog/es/web/nextjs-15-stable-features-overview/</link><pubDate>Sun, 05 Oct 2025 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/nextjs-15-stable-features-overview/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/nextjs-15-stable-features-overview-es.png" alt="Featured image of post Next.js 15 Stable: Mejores prácticas en producción" /&gt;&lt;h2 id="introducción"&gt;Introducción
&lt;/h2&gt;&lt;p&gt;Next.js 15 llega con soporte para React 19, un modelo de caché rediseñado y mejoras importantes en APIs asíncronas. Por defecto, las solicitudes fetch NO se cachean, simplificando la previsibilidad del comportamiento.&lt;/p&gt;
&lt;h2 id="react-19-estable"&gt;React 19 estable
&lt;/h2&gt;&lt;p&gt;Next.js 15 se empareja con React 19 estable, permitiendo el React Compiler para memoización automática. Soporte completo para &lt;code&gt;use()&lt;/code&gt; y Server Actions.&lt;/p&gt;
&lt;h2 id="cambios-en-caché-por-defecto"&gt;Cambios en caché por defecto
&lt;/h2&gt;&lt;p&gt;En Next.js 14, fetch se cacheaba por defecto. En Next.js 15 NO se cachea — debes optar explícitamente con &lt;code&gt;cache: 'force-cache'&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>Firmado de commits con GPG en Git</title><link>https://takao.blog/es/web/git-commit-signing-gpg/</link><pubDate>Thu, 25 Sep 2025 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/git-commit-signing-gpg/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/git-commit-signing-gpg-es.png" alt="Featured image of post Firmado de commits con GPG en Git" /&gt;&lt;p&gt;Firmar commits con GPG verifica la identidad del autor. GitHub/GitLab muestran una insignia &amp;ldquo;Verified&amp;rdquo; en los commits firmados.&lt;/p&gt;
&lt;h2 id="configuración"&gt;Configuración
&lt;/h2&gt;&lt;p&gt;Genera una clave GPG: &lt;code&gt;gpg --full-generate-key&lt;/code&gt;. Configura &lt;code&gt;git config --global user.signingkey &amp;lt;KEY&amp;gt;&lt;/code&gt;. Firma commits con &lt;code&gt;-S&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="firma-automática"&gt;Firma automática
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;git config --global commit.gpgsign true&lt;/code&gt; firma todos los commits. &lt;code&gt;git config --global tag.gpgsign true&lt;/code&gt; para etiquetas.&lt;/p&gt;
&lt;h2 id="registro-en-github"&gt;Registro en GitHub
&lt;/h2&gt;&lt;p&gt;Añade la clave GPG pública en GitHub Settings → SSH and GPG keys. Verifica que los commits muestren &amp;ldquo;Verified&amp;rdquo;.&lt;/p&gt;</description></item><item><title>Caché de build en Docker: Acelerar compilaciones</title><link>https://takao.blog/es/web/docker-build-caches-speedup/</link><pubDate>Sat, 20 Sep 2025 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/docker-build-caches-speedup/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/docker-build-caches-speedup-es.png" alt="Featured image of post Caché de build en Docker: Acelerar compilaciones" /&gt;&lt;p&gt;Docker aprovecha la caché de capas para acelerar builds. Entender el orden de las capas y la invalidación de caché es clave para builds rápidos.&lt;/p&gt;
&lt;h2 id="orden-de-capas"&gt;Orden de capas
&lt;/h2&gt;&lt;p&gt;Coloca las capas que cambian con menos frecuencia al inicio: dependencias del sistema, luego dependencias de la aplicación, luego código fuente.&lt;/p&gt;
&lt;h2 id="copy-vs-add"&gt;COPY vs ADD
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;COPY&lt;/code&gt; invalida la caché si el contenido del archivo fuente cambia. Usa &lt;code&gt;.dockerignore&lt;/code&gt; para excluir archivos innecesarios (node_modules, .git).&lt;/p&gt;</description></item><item><title>Accesibilidad web: Fundamentos de ARIA</title><link>https://takao.blog/es/web/web-accessibility-aria-basics/</link><pubDate>Mon, 15 Sep 2025 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/web-accessibility-aria-basics/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/web-accessibility-aria-basics-es.png" alt="Featured image of post Accesibilidad web: Fundamentos de ARIA" /&gt;&lt;p&gt;ARIA (Accessible Rich Internet Applications) proporciona atributos HTML para mejorar la accesibilidad de contenido dinámico y componentes personalizados.&lt;/p&gt;
&lt;h2 id="principios-aria"&gt;Principios ARIA
&lt;/h2&gt;&lt;p&gt;No uses ARIA cuando los elementos HTML nativos funcionan. ARIA modifica el árbol de accesibilidad pero no el comportamiento. Primera regla: usa HTML semántico.&lt;/p&gt;
&lt;h2 id="roles-y-propiedades"&gt;Roles y propiedades
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;role=&amp;quot;button&amp;quot;&lt;/code&gt;, &lt;code&gt;aria-label&lt;/code&gt;, &lt;code&gt;aria-expanded&lt;/code&gt;, &lt;code&gt;aria-hidden&lt;/code&gt;, &lt;code&gt;aria-live&lt;/code&gt;. Roles de landmarks (&lt;code&gt;navigation&lt;/code&gt;, &lt;code&gt;main&lt;/code&gt;, &lt;code&gt;complementary&lt;/code&gt;).&lt;/p&gt;
&lt;h2 id="componentes-dinámicos"&gt;Componentes dinámicos
&lt;/h2&gt;&lt;p&gt;Tabs, modales, acordeones, sliders necesitan roles y estados ARIA. &lt;code&gt;aria-controls&lt;/code&gt;, &lt;code&gt;aria-selected&lt;/code&gt;, &lt;code&gt;aria-current&lt;/code&gt;, &lt;code&gt;aria-valuenow&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>Uniones discriminadas en TypeScript: Patrón switch exhaustivo</title><link>https://takao.blog/es/web/typescript-discriminated-unions/</link><pubDate>Wed, 10 Sep 2025 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/typescript-discriminated-unions/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/typescript-discriminated-unions-es.png" alt="Featured image of post Uniones discriminadas en TypeScript: Patrón switch exhaustivo" /&gt;&lt;p&gt;Las uniones discriminadas (tagged unions) son la forma principal de modelar datos que pueden ser una de varias variantes. Usan una propiedad literal común (discriminante) para diferenciar los miembros.&lt;/p&gt;
&lt;h2 id="sintaxis-básica"&gt;Sintaxis básica
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;type&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Shape&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;|&lt;/span&gt; { &lt;span style="color:#a6e22e"&gt;kind&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;circle&amp;#39;&lt;/span&gt;; &lt;span style="color:#a6e22e"&gt;radius&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;number&lt;/span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;|&lt;/span&gt; { &lt;span style="color:#a6e22e"&gt;kind&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;square&amp;#39;&lt;/span&gt;; &lt;span style="color:#a6e22e"&gt;side&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;number&lt;/span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;|&lt;/span&gt; { &lt;span style="color:#a6e22e"&gt;kind&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;triangle&amp;#39;&lt;/span&gt;; &lt;span style="color:#a6e22e"&gt;base&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;number&lt;/span&gt;; &lt;span style="color:#a6e22e"&gt;height&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;number&lt;/span&gt; };
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="estrechamiento-narrowing"&gt;Estrechamiento (narrowing)
&lt;/h2&gt;&lt;p&gt;TypeScript reduce automáticamente el tipo basado en el discriminante. Usar &lt;code&gt;switch&lt;/code&gt; con discriminante para manejar cada variante con seguridad de tipos.&lt;/p&gt;
&lt;h2 id="exhaustividad"&gt;Exhaustividad
&lt;/h2&gt;&lt;p&gt;Combinar con &lt;code&gt;never&lt;/code&gt; para garantizar que todos los casos se manejan: &lt;code&gt;default: const _exhaustive: never = value;&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>GitHub Copilot Workspace: El agente desarrollador</title><link>https://takao.blog/es/web/github-copilot-workspace-developer-agent/</link><pubDate>Fri, 05 Sep 2025 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/github-copilot-workspace-developer-agent/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/github-copilot-workspace-developer-agent-es.png" alt="Featured image of post GitHub Copilot Workspace: El agente desarrollador" /&gt;&lt;p&gt;GitHub Copilot Workspace es un agente de IA que ayuda a planificar, implementar y probar características completas directamente desde issues de GitHub.&lt;/p&gt;
&lt;h2 id="flujo-de-trabajo"&gt;Flujo de trabajo
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;Crea un issue. 2. Copilot Workspace analiza el código base. 3. Propone un plan de implementación. 4. Genera cambios. 5. Abre un PR con los cambios.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="contexto-completo"&gt;Contexto completo
&lt;/h2&gt;&lt;p&gt;El agente entiende el repositorio completo, no solo el archivo actual. Analiza estructura, dependencias y patrones del proyecto.&lt;/p&gt;</description></item><item><title>Protección CSRF: Tokens y SameSite Cookies</title><link>https://takao.blog/es/web/security-csrf-tokens-samesite-cookies/</link><pubDate>Mon, 25 Aug 2025 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/security-csrf-tokens-samesite-cookies/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/security-csrf-tokens-samesite-cookies-es.png" alt="Featured image of post Protección CSRF: Tokens y SameSite Cookies" /&gt;&lt;p&gt;Cross-Site Request Forgery (CSRF) engaña al navegador para ejecutar acciones no deseadas en un sitio donde el usuario está autenticado.&lt;/p&gt;
&lt;h2 id="cómo-funciona-csrf"&gt;Cómo funciona CSRF
&lt;/h2&gt;&lt;p&gt;El atacante crea un formulario o enlace en su sitio que apunta a una acción en tu sitio (cambiar email, transferir dinero). Las cookies se envían automáticamente.&lt;/p&gt;
&lt;h2 id="tokens-csrf"&gt;Tokens CSRF
&lt;/h2&gt;&lt;p&gt;Token único por sesión o formulario. Incluido como campo oculto en formularios o header en requests AJAX. El servidor valida el token en cada mutación.&lt;/p&gt;</description></item><item><title>Técnicas avanzadas de Git Stash</title><link>https://takao.blog/es/web/git-stash-advanced-techniques/</link><pubDate>Wed, 20 Aug 2025 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/git-stash-advanced-techniques/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/git-stash-advanced-techniques-es.png" alt="Featured image of post Técnicas avanzadas de Git Stash" /&gt;&lt;p&gt;&lt;code&gt;git stash&lt;/code&gt; guarda cambios temporales sin commitearlos. Más allá del uso básico, stash ofrece opciones avanzadas para flujos complejos.&lt;/p&gt;
&lt;h2 id="stash-parcial"&gt;Stash parcial
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;git stash -p&lt;/code&gt; selecciona interactivamente qué cambios guardar. Útil cuando solo quieres stash una parte de los cambios.&lt;/p&gt;
&lt;h2 id="stash-con-archivos-no-rastreados"&gt;Stash con archivos no rastreados
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;git stash -u&lt;/code&gt; (o &lt;code&gt;--include-untracked&lt;/code&gt;) guarda también archivos nuevos. &lt;code&gt;-a&lt;/code&gt; guarda incluso archivos ignorados.&lt;/p&gt;
&lt;h2 id="stash-nombrado"&gt;Stash nombrado
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;git stash push -m &amp;quot;mensaje descriptivo&amp;quot;&lt;/code&gt; crea un stash con nombre. Listarlos con &lt;code&gt;git stash list&lt;/code&gt; y buscar con &lt;code&gt;git stash show -p &amp;lt;stash&amp;gt;&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>Sintaxis estándar de anidamiento CSS sin preprocesadores</title><link>https://takao.blog/es/web/css-nesting-standard-syntax/</link><pubDate>Fri, 15 Aug 2025 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/css-nesting-standard-syntax/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/css-nesting-standard-syntax-es.png" alt="Featured image of post Sintaxis estándar de anidamiento CSS sin preprocesadores" /&gt;&lt;h2 id="introducción"&gt;Introducción
&lt;/h2&gt;&lt;p&gt;El anidamiento CSS ahora es nativo en todos los navegadores modernos, sin necesidad de Sass, Less o PostCSS.&lt;/p&gt;
&lt;h2 id="sintaxis-básica"&gt;Sintaxis básica
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#a6e22e"&gt;card&lt;/span&gt; { &lt;span style="color:#66d9ef"&gt;background-color&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;#fff&lt;/span&gt;; &lt;span style="color:#960050;background-color:#1e0010"&gt;.card-title&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;{&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;font-size&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;1.5&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;rem&lt;/span&gt;; } &lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt;:&lt;span style="color:#a6e22e"&gt;hover&lt;/span&gt; { &lt;span style="color:#66d9ef"&gt;box-shadow&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;4&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;px&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;8&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;px&lt;/span&gt; rgba(&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;,&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;,&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;,&lt;span style="color:#ae81ff"&gt;0.1&lt;/span&gt;); } &lt;span style="color:#960050;background-color:#1e0010"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Ya no se requiere el prefijo &lt;code&gt;&amp;amp;&lt;/code&gt; para anidar selectores de clase o elemento.&lt;/p&gt;
&lt;h2 id="diferencia-clave-con-sass"&gt;Diferencia clave con Sass
&lt;/h2&gt;&lt;p&gt;CSS nativo NO soporta concatenación de sufijos tipo BEM (&lt;code&gt;&amp;amp;--large&lt;/code&gt; es inválido). En su lugar, escribe la clase completa: &lt;code&gt;&amp;amp;.button--large&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="posicionamiento-del-"&gt;Posicionamiento del &amp;amp;
&lt;/h2&gt;&lt;p&gt;Puedes usar &lt;code&gt;&amp;amp;&lt;/code&gt; al final o en medio de un selector para estilos contextuales: &lt;code&gt;.dark-mode &amp;amp; { color: #fff; }&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>Reglas para crear hooks personalizados en React</title><link>https://takao.blog/es/web/react-custom-hooks-rules/</link><pubDate>Sun, 10 Aug 2025 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/react-custom-hooks-rules/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/react-custom-hooks-rules-es.png" alt="Featured image of post Reglas para crear hooks personalizados en React" /&gt;&lt;p&gt;Los hooks personalizados son la forma principal de extraer lógica con estado en React. Deben seguir las mismas reglas que los hooks integrados.&lt;/p&gt;
&lt;h2 id="reglas-fundamentales"&gt;Reglas fundamentales
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;Solo llama hooks en el nivel superior (no en condicionales, bucles o funciones anidadas).&lt;/li&gt;
&lt;li&gt;Solo llama hooks desde componentes React o desde otros hooks.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="patrones-de-hooks-personalizados"&gt;Patrones de hooks personalizados
&lt;/h2&gt;&lt;p&gt;Un hook debe comenzar con &lt;code&gt;use&lt;/code&gt;. Debe devolver un objeto o array con valores y funciones. La lógica de efecto debe limpiarse en el cleanup.&lt;/p&gt;</description></item><item><title>Vite 6 vs Rspack: Velocidades de bundler en 2026</title><link>https://takao.blog/es/web/vite-6-rspack-bundler-speeds/</link><pubDate>Tue, 05 Aug 2025 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/vite-6-rspack-bundler-speeds/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/vite-6-rspack-bundler-speeds-es.png" alt="Featured image of post Vite 6 vs Rspack: Velocidades de bundler en 2026" /&gt;&lt;p&gt;Vite y Rspack son los bundlers más rápidos del ecosistema. Ambos usan Rust para tareas críticas pero con filosofías diferentes.&lt;/p&gt;
&lt;h2 id="vite-6"&gt;Vite 6
&lt;/h2&gt;&lt;p&gt;Usa esbuild para desarrollo (bundling nativo en Go) y Rollup para producción (con rolldown en desarrollo para unificar). HMR instantáneo. Ecosistema maduro de plugins.&lt;/p&gt;
&lt;h2 id="rspack"&gt;Rspack
&lt;/h2&gt;&lt;p&gt;Bundler escrito en Rust, compatible con webpack API y plugins. Ofrece migración directa desde webpack con 5-10x mejora en tiempo de build.&lt;/p&gt;
&lt;h2 id="comparativa"&gt;Comparativa
&lt;/h2&gt;&lt;p&gt;Rspack: mejor para migraciones desde webpack, SSR complejo, monorepos. Vite: mejor para proyectos nuevos, SPA, desarrollo con HMR. Ambos superan webpack 4/5 significativamente.&lt;/p&gt;</description></item><item><title>Interoperabilidad ESM y CJS en Node.js</title><link>https://takao.blog/es/web/node-esm-cjs-interoperability/</link><pubDate>Fri, 25 Jul 2025 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/node-esm-cjs-interoperability/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/node-esm-cjs-interoperability-es.png" alt="Featured image of post Interoperabilidad ESM y CJS en Node.js" /&gt;&lt;p&gt;Node.js soporta dos sistemas de módulos: CommonJS (require) y ES Modules (import). La interoperabilidad entre ambos tiene reglas específicas.&lt;/p&gt;
&lt;h2 id="detección-del-tipo-de-módulo"&gt;Detección del tipo de módulo
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;.mjs&lt;/code&gt; siempre ESM. &lt;code&gt;.cjs&lt;/code&gt; siempre CJS. &lt;code&gt;.js&lt;/code&gt; depende del &lt;code&gt;package.json&lt;/code&gt; más cercano: &lt;code&gt;&amp;quot;type&amp;quot;: &amp;quot;module&amp;quot;&lt;/code&gt; para ESM, &lt;code&gt;&amp;quot;type&amp;quot;: &amp;quot;commonjs&amp;quot;&lt;/code&gt; o sin campo para CJS.&lt;/p&gt;
&lt;h2 id="importar-cjs-desde-esm"&gt;Importar CJS desde ESM
&lt;/h2&gt;&lt;p&gt;Los módulos CJS se importan con &lt;code&gt;import&lt;/code&gt; desde ESM. Node.js envuelve &lt;code&gt;module.exports&lt;/code&gt; como default export. Named exports requieren análisis estático limitado.&lt;/p&gt;</description></item><item><title>Optimizaciones con requestIdleCallback</title><link>https://takao.blog/es/web/web-performance-requestidlecallback-optimizations/</link><pubDate>Fri, 25 Jul 2025 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/web-performance-requestidlecallback-optimizations/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/web-performance-requestidlecallback-optimizations-es.png" alt="Featured image of post Optimizaciones con requestIdleCallback" /&gt;&lt;p&gt;&lt;code&gt;requestIdleCallback&lt;/code&gt; programa tareas no urgentes para cuando el navegador está inactivo. Mejora la capacidad de respuesta de la página.&lt;/p&gt;
&lt;h2 id="cómo-funciona"&gt;Cómo funciona
&lt;/h2&gt;&lt;p&gt;El navegador ejecuta callbacks en los tiempos muertos entre frames. &lt;code&gt;requestIdleCallback(callback, { timeout: 2000 })&lt;/code&gt;. &lt;code&gt;IdleDeadline.timeRemaining()&lt;/code&gt; indica el tiempo disponible.&lt;/p&gt;
&lt;h2 id="casos-de-uso"&gt;Casos de uso
&lt;/h2&gt;&lt;p&gt;Análisis (analytics), logging, precarga de datos no críticos, cleanups, procesamiento diferido, renderizado de contenido secundario.&lt;/p&gt;
&lt;h2 id="alternativas"&gt;Alternativas
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;setTimeout&lt;/code&gt; con 0: menos eficiente. &lt;code&gt;Scheduler.postTask&lt;/code&gt; (experimental) con prioridades. &lt;code&gt;requestAnimationFrame&lt;/code&gt; para animaciones. Elige según la urgencia.&lt;/p&gt;</description></item><item><title>Git Blame: Ignorando cambios de formato con .git-blame-ignore-revs</title><link>https://takao.blog/es/web/git-blame-ignore-revs/</link><pubDate>Sun, 20 Jul 2025 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/git-blame-ignore-revs/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/git-blame-ignore-revs-es.png" alt="Featured image of post Git Blame: Ignorando cambios de formato con .git-blame-ignore-revs" /&gt;&lt;p&gt;&lt;code&gt;git blame&lt;/code&gt; es útil para encontrar quién cambió cada línea, pero los commits de formateo (Prettier, ESLint) contaminan los resultados. &lt;code&gt;.git-blame-ignore-revs&lt;/code&gt; resuelve esto.&lt;/p&gt;
&lt;h2 id="cómo-funciona"&gt;Cómo funciona
&lt;/h2&gt;&lt;p&gt;Crea un archivo &lt;code&gt;.git-blame-ignore-revs&lt;/code&gt; con los hashes de commits de formateo. Configura &lt;code&gt;git config blame.ignoreRevsFile .git-blame-ignore-revs&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="uso-directo"&gt;Uso directo
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;git blame --ignore-revs-file .git-blame-ignore-revs archivo.ts&lt;/code&gt;. Muestra la autoría real ignorando los commits listados.&lt;/p&gt;
&lt;h2 id="soporte-en-github"&gt;Soporte en GitHub
&lt;/h2&gt;&lt;p&gt;GitHub respeta el archivo &lt;code&gt;.git-blame-ignore-revs&lt;/code&gt; automáticamente en la interfaz web. Añade también los commits de refactors grandes.&lt;/p&gt;</description></item><item><title>Lazy loading de iframes para rendimiento web</title><link>https://takao.blog/es/web/web-performance-lazyloading-iframe/</link><pubDate>Sun, 20 Jul 2025 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/web-performance-lazyloading-iframe/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/web-performance-lazyloading-iframe-es.png" alt="Featured image of post Lazy loading de iframes para rendimiento web" /&gt;&lt;p&gt;Los iframes cargan documentos completos (HTML, CSS, JS) que pueden pesar varios MB. El lazy loading nativo y técnicas avanzadas mejoran el rendimiento.&lt;/p&gt;
&lt;h2 id="loadinglazy-nativo"&gt;loading=lazy nativo
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;&amp;lt;iframe loading=&amp;quot;lazy&amp;quot; src=&amp;quot;...&amp;quot;&amp;gt;&lt;/code&gt; difiere la carga hasta que el iframe está cerca del viewport. Soporte universal en navegadores modernos.&lt;/p&gt;
&lt;h2 id="intersection-observer"&gt;Intersection Observer
&lt;/h2&gt;&lt;p&gt;Carga el iframe solo cuando es visible. Control granular: margen de precarga, umbral de visibilidad. Ideal para integraciones complejas.&lt;/p&gt;
&lt;h2 id="alternativas-a-iframes"&gt;Alternativas a iframes
&lt;/h2&gt;&lt;p&gt;Embed con JavaScript ligero (widget API). Web Components. Contenido precargado y mostrado bajo demanda. Prefiere APIs sobre iframes.&lt;/p&gt;</description></item><item><title>Optimización de imágenes para rendimiento web</title><link>https://takao.blog/es/web/web-performance-image-optimizations/</link><pubDate>Tue, 15 Jul 2025 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/web-performance-image-optimizations/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/web-performance-image-optimizations-es.png" alt="Featured image of post Optimización de imágenes para rendimiento web" /&gt;&lt;p&gt;Las imágenes son el recurso más pesado y común en la web. Optimizarlas correctamente mejora LCP, CLS y la experiencia general.&lt;/p&gt;
&lt;h2 id="formatos-modernos"&gt;Formatos modernos
&lt;/h2&gt;&lt;p&gt;AVIF: mejor compresión pero codificación lenta. WebP: equilibrio calidad/velocidad. JPEG XL: prometedor pero soporte limitado. Proporciona múltiples formatos con &lt;code&gt;&amp;lt;picture&amp;gt;&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="carga-responsive"&gt;Carga responsive
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;srcset&lt;/code&gt; con diferentes tamaños. &lt;code&gt;sizes&lt;/code&gt; para indicar el espacio que ocupa la imagen. El navegador selecciona la imagen óptima.&lt;/p&gt;
&lt;h2 id="lazy-loading"&gt;Lazy loading
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;loading=&amp;quot;lazy&amp;quot;&lt;/code&gt; nativo para imágenes fuera del viewport. &lt;code&gt;fetchpriority=&amp;quot;high&amp;quot;&lt;/code&gt; para la LCP image. Intersection Observer para control granular.&lt;/p&gt;</description></item><item><title>Diseñando layouts modulares con CSS Container Queries</title><link>https://takao.blog/es/web/css-container-queries-vs-media-queries/</link><pubDate>Thu, 10 Jul 2025 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/css-container-queries-vs-media-queries/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/css-container-queries-vs-media-queries-es.png" alt="Featured image of post Diseñando layouts modulares con CSS Container Queries" /&gt;&lt;h2 id="introducción"&gt;Introducción
&lt;/h2&gt;&lt;p&gt;Las Media Queries (&lt;code&gt;@media&lt;/code&gt;) cambian estilos según el viewport. CSS Container Queries (&lt;code&gt;@container&lt;/code&gt;) permiten estilar componentes según el ancho de su contenedor padre, ideal para componentes reutilizables.&lt;/p&gt;
&lt;h2 id="viewport-vs-container"&gt;Viewport vs Container
&lt;/h2&gt;&lt;p&gt;Media queries dependen del ancho de la ventana. Container queries dependen del contenedor padre inmediato, permitiendo que un mismo componente se adapte a diferentes contextos.&lt;/p&gt;
&lt;h2 id="configuración-básica"&gt;Configuración básica
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;Registrar el padre con &lt;code&gt;container-type: inline-size&lt;/code&gt; 2. Escribir reglas con &lt;code&gt;@container (min-width: 400px)&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#a6e22e"&gt;card-wrapper&lt;/span&gt; { &lt;span style="color:#66d9ef"&gt;container-type&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;inline&lt;/span&gt;&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;size&lt;/span&gt;; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;@&lt;span style="color:#66d9ef"&gt;container&lt;/span&gt; &lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#f92672"&gt;min-width&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#f92672"&gt;400px&lt;/span&gt;&lt;span style="color:#f92672"&gt;)&lt;/span&gt; { .&lt;span style="color:#a6e22e"&gt;my-card&lt;/span&gt; { &lt;span style="color:#66d9ef"&gt;flex-direction&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;row&lt;/span&gt;; } }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="unidades-de-container-query"&gt;Unidades de container query
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;cqw&lt;/code&gt; (1% del ancho), &lt;code&gt;cqh&lt;/code&gt; (1% del alto), &lt;code&gt;cqmin&lt;/code&gt;, &lt;code&gt;cqmax&lt;/code&gt;. Útiles para tipografía dinámica: &lt;code&gt;font-size: clamp(1rem, 5cqw, 2rem)&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>Cómo usar decoradores estándar en TypeScript</title><link>https://takao.blog/es/web/typescript-5-decorations-adoption/</link><pubDate>Sat, 05 Jul 2025 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/typescript-5-decorations-adoption/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/typescript-5-decorations-adoption-es.png" alt="Featured image of post Cómo usar decoradores estándar en TypeScript" /&gt;&lt;h2 id="introducción"&gt;Introducción
&lt;/h2&gt;&lt;p&gt;TypeScript 5.0 introdujo soporte oficial para decoradores ECMAScript estándar (Stage 3/4), reemplazando los experimentales.&lt;/p&gt;
&lt;h2 id="decoradores-experimentales-vs-estándar"&gt;Decoradores experimentales vs estándar
&lt;/h2&gt;&lt;p&gt;Los experimentales requerían &lt;code&gt;experimentalDecorators: true&lt;/code&gt;. Los estándar funcionan por defecto y reciben un objeto &lt;code&gt;context&lt;/code&gt; con metadatos tipados.&lt;/p&gt;
&lt;h2 id="escribir-un-decorador-de-método-estándar"&gt;Escribir un decorador de método estándar
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;logMethod&lt;/span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;This&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;Args&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;extends&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;any&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;[]&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;Return&lt;/span&gt;&amp;gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;target&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;This&lt;/span&gt;, ...&lt;span style="color:#a6e22e"&gt;args&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;Args&lt;/span&gt;) &lt;span style="color:#f92672"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Return&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;context&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;ClassMethodDecoratorContext&lt;/span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;This&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;...&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;) { &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;This&lt;/span&gt;, ...&lt;span style="color:#a6e22e"&gt;args&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;Args&lt;/span&gt;)&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Return&lt;/span&gt; { ... }; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="consideraciones-de-migración"&gt;Consideraciones de migración
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;Verifica compatibilidad con reflect-metadata antes de deshabilitar flags experimentales.&lt;/li&gt;
&lt;li&gt;Los decoradores de parámetros fueron excluidos del estándar final. Solo pueden targetizar clases, métodos, campos y accessors.&lt;/li&gt;
&lt;/ol&gt;</description></item><item><title>Comandos de terminal Linux para desarrolladores web</title><link>https://takao.blog/es/web/linux-shell-commands-for-webdevelopers/</link><pubDate>Wed, 25 Jun 2025 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/linux-shell-commands-for-webdevelopers/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/linux-shell-commands-for-webdevelopers-es.png" alt="Featured image of post Comandos de terminal Linux para desarrolladores web" /&gt;&lt;p&gt;La línea de comandos es esencial para el desarrollo web moderno. Estos comandos aumentan la productividad diaria.&lt;/p&gt;
&lt;h2 id="navegación-y-archivos"&gt;Navegación y archivos
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;ls -la&lt;/code&gt;, &lt;code&gt;cd&lt;/code&gt;, &lt;code&gt;pwd&lt;/code&gt;, &lt;code&gt;find . -name &amp;quot;*.ts&amp;quot;&lt;/code&gt;, &lt;code&gt;grep -r &amp;quot;patrón&amp;quot; .&lt;/code&gt;, &lt;code&gt;tree&lt;/code&gt;, &lt;code&gt;du -sh *&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="procesos-y-red"&gt;Procesos y red
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;ps aux&lt;/code&gt;, &lt;code&gt;kill&lt;/code&gt;, &lt;code&gt;htop&lt;/code&gt;. &lt;code&gt;curl&lt;/code&gt;, &lt;code&gt;wget&lt;/code&gt;, &lt;code&gt;ping&lt;/code&gt;, &lt;code&gt;netstat -tulpn&lt;/code&gt;. &lt;code&gt;lsof -i :3000&lt;/code&gt; para ver qué ocupa un puerto.&lt;/p&gt;
&lt;h2 id="git-avanzado-en-terminal"&gt;Git avanzado en terminal
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;tig&lt;/code&gt; (navegador de git). &lt;code&gt;diff-so-fancy&lt;/code&gt; (diff bonito). &lt;code&gt;git lg&lt;/code&gt; (alias para log gráfico). &lt;code&gt;gh&lt;/code&gt; (GitHub CLI).&lt;/p&gt;</description></item><item><title>useMemo y useCallback: Optimización de rendimiento en React</title><link>https://takao.blog/es/web/react-hooks-usememo-usecallback/</link><pubDate>Fri, 20 Jun 2025 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/react-hooks-usememo-usecallback/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/react-hooks-usememo-usecallback-es.png" alt="Featured image of post useMemo y useCallback: Optimización de rendimiento en React" /&gt;&lt;p&gt;&lt;code&gt;useMemo&lt;/code&gt; memoiza valores calculados, &lt;code&gt;useCallback&lt;/code&gt; memoiza funciones. Ambos evitan trabajo innecesario en re-renderizados.&lt;/p&gt;
&lt;h2 id="usememo"&gt;useMemo
&lt;/h2&gt;&lt;p&gt;Solo recalcula el valor cuando cambian sus dependencias. Útil para cálculos costosos o para mantener referencias estables entre renderizados.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-jsx" data-lang="jsx"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;sorted&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;useMemo&lt;/span&gt;(() =&amp;gt; &lt;span style="color:#a6e22e"&gt;items&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;sort&lt;/span&gt;(), [&lt;span style="color:#a6e22e"&gt;items&lt;/span&gt;]);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="usecallback"&gt;useCallback
&lt;/h2&gt;&lt;p&gt;Devuelve la misma función a menos que cambien las dependencias. Esencial para pasar callbacks a componentes hijos memoizados.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-jsx" data-lang="jsx"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;handleClick&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;useCallback&lt;/span&gt;(() =&amp;gt; &lt;span style="color:#a6e22e"&gt;doSomething&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;id&lt;/span&gt;), [&lt;span style="color:#a6e22e"&gt;id&lt;/span&gt;]);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="cuándo-usarlos"&gt;Cuándo usarlos
&lt;/h2&gt;&lt;p&gt;No optimices prematuramente. Solo usa estos hooks cuando perfiles muestren un problema real. Con el React Compiler, estos hooks serán innecesarios.&lt;/p&gt;</description></item><item><title>CSP strict-dynamic: La mejor defensa contra XSS</title><link>https://takao.blog/es/web/security-csp-strict-dynamic-implementation/</link><pubDate>Sun, 15 Jun 2025 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/security-csp-strict-dynamic-implementation/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/security-csp-strict-dynamic-implementation-es.png" alt="Featured image of post CSP strict-dynamic: La mejor defensa contra XSS" /&gt;&lt;p&gt;La directiva &lt;code&gt;strict-dynamic&lt;/code&gt; de CSP cambia la forma de aplicar políticas de seguridad. En lugar de listar dominios permitidos, confía en scripts que fueron cargados por scripts legítimos.&lt;/p&gt;
&lt;h2 id="problema-con-listas-blancas"&gt;Problema con listas blancas
&lt;/h2&gt;&lt;p&gt;Las listas de URLs permitidas son difíciles de mantener y pueden incluir CDNs comprometidas o bibliotecas con vulnerabilidades.&lt;/p&gt;
&lt;h2 id="cómo-funciona-strict-dynamic"&gt;Cómo funciona strict-dynamic
&lt;/h2&gt;&lt;p&gt;Si un script tiene un nonce o hash válido, puede cargar otros scripts del mismo origen. La confianza se propaga del script inicial a sus dependencias.&lt;/p&gt;</description></item><item><title>Template Literal Types en TypeScript: Manipulación de tipos de cadenas</title><link>https://takao.blog/es/web/typescript-template-literal-types/</link><pubDate>Tue, 10 Jun 2025 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/typescript-template-literal-types/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/typescript-template-literal-types-es.png" alt="Featured image of post Template Literal Types en TypeScript: Manipulación de tipos de cadenas" /&gt;&lt;p&gt;Los Template Literal Types (TS 4.1+) permiten manipular tipos de cadenas en tiempo de compilación. Usan la misma sintaxis que los template literals de JavaScript pero con tipos.&lt;/p&gt;
&lt;h2 id="sintaxis"&gt;Sintaxis
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;type&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;EventName&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;`on&lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;Capitalize&lt;/span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;string&lt;/span&gt;&amp;gt;&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;`&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// &amp;#39;onChange&amp;#39; | &amp;#39;onClick&amp;#39; | &amp;#39;onSubmit&amp;#39; ...
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="tipos-de-manipulación-de-cadenas"&gt;Tipos de manipulación de cadenas
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;Uppercase&amp;lt;T&amp;gt;&lt;/code&gt;, &lt;code&gt;Lowercase&amp;lt;T&amp;gt;&lt;/code&gt;, &lt;code&gt;Capitalize&amp;lt;T&amp;gt;&lt;/code&gt;, &lt;code&gt;Uncapitalize&amp;lt;T&amp;gt;&lt;/code&gt;. Combinables para crear patrones de nomenclatura.&lt;/p&gt;
&lt;h2 id="inferencia-en-template-literals"&gt;Inferencia en template literals
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;type&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;ExtractRoute&lt;/span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;T&lt;/span&gt;&amp;gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;T&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;extends&lt;/span&gt; &lt;span style="color:#e6db74"&gt;`/api/&lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;infer&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;R&lt;/span&gt;&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;`&lt;/span&gt; &lt;span style="color:#f92672"&gt;?&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;R&lt;/span&gt; : &lt;span style="color:#66d9ef"&gt;never&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;type&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;R&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;ExtractRoute&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;/api/users&amp;#39;&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt;; &lt;span style="color:#75715e"&gt;// &amp;#39;users&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="casos-de-uso-avanzados"&gt;Casos de uso avanzados
&lt;/h2&gt;&lt;p&gt;Mapeo evento-manejador, tipado de rutas de API, traducciones tipadas, CSS-in-JS con props de tema, generación de tipos a partir de recursos.&lt;/p&gt;</description></item><item><title>WWDC 2025: Novedades de Safari</title><link>https://takao.blog/es/web/apple-wwdc-2025-safari-updates/</link><pubDate>Thu, 05 Jun 2025 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/apple-wwdc-2025-safari-updates/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/apple-wwdc-2025-safari-updates-es.png" alt="Featured image of post WWDC 2025: Novedades de Safari" /&gt;&lt;p&gt;Apple anunció importantes actualizaciones para Safari en WWDC 2025, incluyendo nuevas APIs web, mejoras de rendimiento y compatibilidad con estándares.&lt;/p&gt;
&lt;h2 id="nuevas-apis"&gt;Nuevas APIs
&lt;/h2&gt;&lt;p&gt;Soporte completo de WebGPU, CSS Anchor Positioning, View Transitions API. Mejoras en Service Workers y Push Notifications en iOS.&lt;/p&gt;
&lt;h2 id="rendimiento"&gt;Rendimiento
&lt;/h2&gt;&lt;p&gt;Mejoras en JavaScript Core (JIT más rápido). Reducción de uso de memoria. Perfilado de rendimiento mejorado en Safari Web Inspector.&lt;/p&gt;
&lt;h2 id="css-y-diseño"&gt;CSS y diseño
&lt;/h2&gt;&lt;p&gt;Soporte de &lt;code&gt;@scope&lt;/code&gt;, &lt;code&gt;@starting-style&lt;/code&gt;, &lt;code&gt;scroll-driven-animations&lt;/code&gt;. Mejoras en Subgrid y Container Queries. Propiedades de texto avanzadas.&lt;/p&gt;</description></item><item><title>Indexación de bases de datos: Fundamentos para desarrolladores</title><link>https://takao.blog/es/web/backend-database-indexing-basics/</link><pubDate>Sun, 25 May 2025 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/backend-database-indexing-basics/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/backend-database-indexing-basics-es.png" alt="Featured image of post Indexación de bases de datos: Fundamentos para desarrolladores" /&gt;&lt;p&gt;Los índices de base de datos aceleran las consultas a costa de espacio y rendimiento de escritura. Entenderlos es esencial para aplicaciones escalables.&lt;/p&gt;
&lt;h2 id="cómo-funcionan"&gt;Cómo funcionan
&lt;/h2&gt;&lt;p&gt;Estructura de datos (B-tree, Hash, GiST) que mapea valores a ubicaciones. Sin índice: full table scan (O(n)). Con índice: búsqueda logarítmica (O(log n)).&lt;/p&gt;
&lt;h2 id="tipos-de-índices"&gt;Tipos de índices
&lt;/h2&gt;&lt;p&gt;Índice primario (clave primaria). Índice único (valores únicos). Índice compuesto (múltiples columnas). Índice parcial (WHERE). Índice de texto completo.&lt;/p&gt;</description></item><item><title>Git Worktree: Trabajar en múltiples ramas simultáneamente</title><link>https://takao.blog/es/web/git-worktree-multi-branches/</link><pubDate>Tue, 20 May 2025 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/git-worktree-multi-branches/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/git-worktree-multi-branches-es.png" alt="Featured image of post Git Worktree: Trabajar en múltiples ramas simultáneamente" /&gt;&lt;p&gt;&lt;code&gt;git worktree&lt;/code&gt; permite tener múltiples copias del repositorio en diferentes directorios, cada una en una rama distinta. Sin cambiar de rama ni stash.&lt;/p&gt;
&lt;h2 id="uso-básico"&gt;Uso básico
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;git worktree add ../rama-feature feature-branch&lt;/code&gt; crea un directorio &lt;code&gt;../rama-feature&lt;/code&gt; con la rama activa. Puedes trabajar en ambas simultáneamente.&lt;/p&gt;
&lt;h2 id="casos-de-uso"&gt;Casos de uso
&lt;/h2&gt;&lt;p&gt;Revisar un PR mientras trabajas en otra rama. Ejecutar tests en paralelo. Mantener una rama de producción abierta para hotfixes rápidos.&lt;/p&gt;
&lt;h2 id="gestión"&gt;Gestión
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;git worktree list&lt;/code&gt; muestra todos los worktrees. &lt;code&gt;git worktree prune&lt;/code&gt; elimina referencias a directorios eliminados. Cada worktree comparte objetos pero tiene su propio index y HEAD.&lt;/p&gt;</description></item><item><title>Novedades emocionantes en ECMAScript 2025 (ES16)</title><link>https://takao.blog/es/web/js-es2025-new-features/</link><pubDate>Thu, 15 May 2025 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/js-es2025-new-features/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/js-es2025-new-features-es.png" alt="Featured image of post Novedades emocionantes en ECMAScript 2025 (ES16)" /&gt;&lt;h2 id="introducción"&gt;Introducción
&lt;/h2&gt;&lt;p&gt;Cada año, el comité TC39 actualiza las especificaciones ECMAScript. Para ECMAScript 2025 (ES16), varias propuestas han alcanzado Stage 3 o 4.&lt;/p&gt;
&lt;h2 id="promisetry"&gt;Promise.try
&lt;/h2&gt;&lt;p&gt;Unifica el manejo de errores síncronos y asíncronos. Si el callback lanza una excepción síncrona, &lt;code&gt;Promise.try()&lt;/code&gt; la captura y retorna una Promise rechazada, permitiendo un solo &lt;code&gt;.catch()&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="iterator-helpers"&gt;Iterator Helpers
&lt;/h2&gt;&lt;p&gt;Añade &lt;code&gt;.map()&lt;/code&gt; y &lt;code&gt;.filter()&lt;/code&gt; a todos los objetos iterables (Set, Map, etc.). Evaluación perezosa: los elementos se procesan solo cuando se solicitan.&lt;/p&gt;</description></item><item><title>Alineación perfecta con CSS Grid Subgrid</title><link>https://takao.blog/es/web/css-subgrid-grid-nesting/</link><pubDate>Sat, 10 May 2025 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/css-subgrid-grid-nesting/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/css-subgrid-grid-nesting-es.png" alt="Featured image of post Alineación perfecta con CSS Grid Subgrid" /&gt;&lt;h2 id="introducción"&gt;Introducción
&lt;/h2&gt;&lt;p&gt;Alinear componentes anidados entre columnas en layouts de tarjetas es un desafío común. CSS Grid subgrid resuelve esta limitación permitiendo que grids anidados hereden los tracks del padre.&lt;/p&gt;
&lt;h2 id="la-limitación-de-los-grids-anidados"&gt;La limitación de los grids anidados
&lt;/h2&gt;&lt;p&gt;Con Flexbox, los contenedores de tarjetas se alinean en altura pero los elementos internos (títulos, descripciones, botones) no se alinean entre tarjetas hermanas.&lt;/p&gt;
&lt;h2 id="solución-con-subgrid"&gt;Solución con subgrid
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#a6e22e"&gt;card&lt;/span&gt; { &lt;span style="color:#66d9ef"&gt;display&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;grid&lt;/span&gt;; &lt;span style="color:#66d9ef"&gt;grid-template-rows&lt;/span&gt;: subgrid; &lt;span style="color:#66d9ef"&gt;grid-row&lt;/span&gt;: span &lt;span style="color:#ae81ff"&gt;3&lt;/span&gt;; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#a6e22e"&gt;card-title&lt;/span&gt; { &lt;span style="color:#66d9ef"&gt;grid-row&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;; } .&lt;span style="color:#a6e22e"&gt;card-desc&lt;/span&gt; { &lt;span style="color:#66d9ef"&gt;grid-row&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;; } .&lt;span style="color:#a6e22e"&gt;card-btn&lt;/span&gt; { &lt;span style="color:#66d9ef"&gt;grid-row&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;3&lt;/span&gt;; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Los títulos, descripciones y botones se alinean perfectamente entre tarjetas, independientemente de la longitud del contenido.&lt;/p&gt;</description></item><item><title>Google I/O 2025: Novedades para la web</title><link>https://takao.blog/es/web/google-io-2025-web-updates/</link><pubDate>Mon, 05 May 2025 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/google-io-2025-web-updates/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/google-io-2025-web-updates-es.png" alt="Featured image of post Google I/O 2025: Novedades para la web" /&gt;&lt;p&gt;Google I/O 2025 trajo actualizaciones importantes para desarrolladores web: Chrome, Web Platform, Angular, y herramientas de desarrollo.&lt;/p&gt;
&lt;h2 id="chrome-y-web-platform"&gt;Chrome y Web Platform
&lt;/h2&gt;&lt;p&gt;WebGPU estable, View Transitions API, Scroll-Driven Animations. Mejoras en Core Web Vitals. INP como métrica oficial.&lt;/p&gt;
&lt;h2 id="angular"&gt;Angular
&lt;/h2&gt;&lt;p&gt;Angular v20 con nuevas características. Hydration mejorada. Signal components. Rendimiento optimizado con Vite como bundler por defecto.&lt;/p&gt;
&lt;h2 id="herramientas-de-desarrollo"&gt;Herramientas de desarrollo
&lt;/h2&gt;&lt;p&gt;Lighthouse 12 con nuevas auditorías. Chrome DevTools mejoradas para debugging de WebGPU y animaciones. Performance Insights panel.&lt;/p&gt;</description></item><item><title>Diseño de APIs REST: Mejores prácticas</title><link>https://takao.blog/es/web/web-api-design-rest-best-practices/</link><pubDate>Fri, 25 Apr 2025 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/web-api-design-rest-best-practices/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/web-api-design-rest-best-practices-es.png" alt="Featured image of post Diseño de APIs REST: Mejores prácticas" /&gt;&lt;p&gt;Una API REST bien diseñada es intuitiva, consistente y fácil de mantener. Estas prácticas aplican a cualquier lenguaje y framework.&lt;/p&gt;
&lt;h2 id="nombres-de-recursos"&gt;Nombres de recursos
&lt;/h2&gt;&lt;p&gt;Sustantivos en plural: &lt;code&gt;/users&lt;/code&gt;, &lt;code&gt;/articles&lt;/code&gt;. Jerarquía: &lt;code&gt;/users/123/posts&lt;/code&gt;. URLs limpias, sin verbos. Versionado: &lt;code&gt;/v1/users&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="métodos-http"&gt;Métodos HTTP
&lt;/h2&gt;&lt;p&gt;GET (leer), POST (crear), PUT (reemplazar), PATCH (actualizar parcial), DELETE (eliminar). Siempre respeta la semántica HTTP.&lt;/p&gt;
&lt;h2 id="respuestas-consistentes"&gt;Respuestas consistentes
&lt;/h2&gt;&lt;p&gt;Estructura JSON unificada. Códigos HTTP correctos: 200, 201, 204, 400, 401, 403, 404, 409, 422, 500. Mensajes de error descriptivos.&lt;/p&gt;</description></item><item><title>Husky y Git Hooks: Previniendo bugs antes del commit</title><link>https://takao.blog/es/web/git-hooks-husky-prevent-bugs/</link><pubDate>Sun, 20 Apr 2025 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/git-hooks-husky-prevent-bugs/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/git-hooks-husky-prevent-bugs-es.png" alt="Featured image of post Husky y Git Hooks: Previniendo bugs antes del commit" /&gt;&lt;p&gt;Husky facilita la configuración de hooks de Git para equipos de JavaScript/TypeScript. Previene commits con código roto o no formateado.&lt;/p&gt;
&lt;h2 id="instalación"&gt;Instalación
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;npx husky init&lt;/code&gt;. Crea un directorio &lt;code&gt;.husky/&lt;/code&gt; con scripts ejecutables. Husky 9 es la versión moderna, más ligera y simple.&lt;/p&gt;
&lt;h2 id="pre-commit-con-lint-staged"&gt;Pre-commit con lint-staged
&lt;/h2&gt;&lt;p&gt;Combina Husky con &lt;code&gt;lint-staged&lt;/code&gt; para ejecutar linters solo en los archivos modificados. Rápido y escalable incluso en proyectos grandes.&lt;/p&gt;
&lt;h2 id="pre-push-con-pruebas"&gt;Pre-push con pruebas
&lt;/h2&gt;&lt;p&gt;Ejecuta la suite de tests completa antes de permitir el push. Previene integraciones rotas en ramas compartidas.&lt;/p&gt;</description></item><item><title>npm, pnpm y yarn: Comparativa de gestores de paquetes</title><link>https://takao.blog/es/web/npm-pnpm-yarn-package-managers/</link><pubDate>Tue, 15 Apr 2025 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/npm-pnpm-yarn-package-managers/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/npm-pnpm-yarn-package-managers-es.png" alt="Featured image of post npm, pnpm y yarn: Comparativa de gestores de paquetes" /&gt;&lt;p&gt;Los gestores de paquetes de JavaScript han evolucionado. Cada uno ofrece ventajas en velocidad, almacenamiento y seguridad.&lt;/p&gt;
&lt;h2 id="npm"&gt;npm
&lt;/h2&gt;&lt;p&gt;El gestor oficial. npm 10+ es más rápido que versiones anteriores. &lt;code&gt;package-lock.json&lt;/code&gt;. Workspaces para monorepos. Audit de seguridad integrado.&lt;/p&gt;
&lt;h2 id="pnpm"&gt;pnpm
&lt;/h2&gt;&lt;p&gt;Usa un almacenamiento global con enlaces duros. Los paquetes se almacenan una vez, ahorrando espacio en disco. Instalación más rápida y estricta.&lt;/p&gt;
&lt;h2 id="yarn"&gt;Yarn
&lt;/h2&gt;&lt;p&gt;Yarn Berry (v4+) con Plug&amp;rsquo;n&amp;rsquo;Play: sin node_modules, genera un solo archivo &lt;code&gt;.pnp.cjs&lt;/code&gt;. Resuelve dependencias más rápido. Zero-installs.&lt;/p&gt;</description></item><item><title>Descifrando los mecanismos de caché del App Router de Next.js</title><link>https://takao.blog/es/web/nextjs-app-router-caching/</link><pubDate>Thu, 10 Apr 2025 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/nextjs-app-router-caching/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/nextjs-app-router-caching-es.png" alt="Featured image of post Descifrando los mecanismos de caché del App Router de Next.js" /&gt;&lt;h2 id="introducción"&gt;Introducción
&lt;/h2&gt;&lt;p&gt;El App Router de Next.js tiene cuatro capas de caché que pueden causar confusión. Este artículo explica cada una y cómo configurarlas.&lt;/p&gt;
&lt;h2 id="las-cuatro-capas"&gt;Las cuatro capas
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Router Cache&lt;/strong&gt; (cliente): Cache de navegación en el navegador, basada en sesión.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Request Memoization&lt;/strong&gt; (servidor): Desduplica fetch dentro de un mismo ciclo de renderizado.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Data Cache&lt;/strong&gt; (servidor): Persiste respuestas de API entre solicitudes y usuarios.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Full Route Cache&lt;/strong&gt; (servidor): HTML estático y payloads RSC en tiempo de build.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="request-memoization"&gt;Request Memoization
&lt;/h2&gt;&lt;p&gt;Si la misma URL se fetch múltiples veces en el mismo árbol de componentes, solo la primera ejecuta la llamada API. Las siguientes leen de la caché de memoización.&lt;/p&gt;</description></item><item><title>Transiciones de página suaves con View Transitions API</title><link>https://takao.blog/es/web/css-view-transitions-single-page-api/</link><pubDate>Sat, 05 Apr 2025 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/css-view-transitions-single-page-api/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/css-view-transitions-single-page-api-es.png" alt="Featured image of post Transiciones de página suaves con View Transitions API" /&gt;&lt;h2 id="introducción"&gt;Introducción
&lt;/h2&gt;&lt;p&gt;La View Transitions API permite al navegador capturar estados de la página antes y después de una modificación del DOM, ejecutando una transición acelerada por hardware.&lt;/p&gt;
&lt;h2 id="configuración-básica-spa"&gt;Configuración básica (SPA)
&lt;/h2&gt;&lt;p&gt;Envuelve tu función de actualización DOM en &lt;code&gt;document.startViewTransition()&lt;/code&gt;. El navegador captura los estados saliente y entrante, ejecutando un crossfade de 0.25 segundos por defecto.&lt;/p&gt;
&lt;h2 id="personalización-css"&gt;Personalización CSS
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;::&lt;span style="color:#a6e22e"&gt;view-transition-old&lt;/span&gt;&lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#f92672"&gt;root&lt;/span&gt;&lt;span style="color:#f92672"&gt;)&lt;/span&gt; { &lt;span style="color:#66d9ef"&gt;animation&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;0.3&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;s&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;ease-out&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;both&lt;/span&gt; slide-out; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;::&lt;span style="color:#a6e22e"&gt;view-transition-new&lt;/span&gt;&lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#f92672"&gt;root&lt;/span&gt;&lt;span style="color:#f92672"&gt;)&lt;/span&gt; { &lt;span style="color:#66d9ef"&gt;animation&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;0.3&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;s&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;ease-out&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;both&lt;/span&gt; slide-in; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Crea transiciones de deslizamiento, fundido, o cualquier animación personalizada.&lt;/p&gt;</description></item><item><title>Git Cherry-Pick: Casos de uso prácticos</title><link>https://takao.blog/es/web/git-cherry-pick-usecases/</link><pubDate>Tue, 25 Mar 2025 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/git-cherry-pick-usecases/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/git-cherry-pick-usecases-es.png" alt="Featured image of post Git Cherry-Pick: Casos de uso prácticos" /&gt;&lt;p&gt;&lt;code&gt;git cherry-pick&lt;/code&gt; aplica commits específicos de una rama a otra. Esencial para hotfixes y selección selectiva de cambios.&lt;/p&gt;
&lt;h2 id="hotfixes-en-producción"&gt;Hotfixes en producción
&lt;/h2&gt;&lt;p&gt;Corrige un bug en main, luego cherry-pick el commit a release branches. Evita mergear toda la rama main con características incompletas.&lt;/p&gt;
&lt;h2 id="backport-de-cambios"&gt;Backport de cambios
&lt;/h2&gt;&lt;p&gt;Aplica parches seleccionados de una versión reciente a versiones anteriores mantenidas. Común en proyectos con LTS.&lt;/p&gt;
&lt;h2 id="reordenar-commits"&gt;Reordenar commits
&lt;/h2&gt;&lt;p&gt;Extrae commits de una rama de características y aplícalos en orden diferente. Útil cuando commits interdependientes se mezclan.&lt;/p&gt;</description></item><item><title>Multi-stage builds de Docker: Imágenes más ligeras</title><link>https://takao.blog/es/web/docker-multi-stage-build-reduction/</link><pubDate>Thu, 20 Mar 2025 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/docker-multi-stage-build-reduction/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/docker-multi-stage-build-reduction-es.png" alt="Featured image of post Multi-stage builds de Docker: Imágenes más ligeras" /&gt;&lt;p&gt;Multi-stage builds usan múltiples instrucciones FROM en un solo Dockerfile. Cada etapa puede usar una base diferente, copiando solo los artefactos necesarios a la etapa final.&lt;/p&gt;
&lt;h2 id="ejemplo-nodejs"&gt;Ejemplo Node.js
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-dockerfile" data-lang="dockerfile"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;FROM&lt;/span&gt; &lt;span style="color:#e6db74"&gt;node:20&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;AS&lt;/span&gt; &lt;span style="color:#e6db74"&gt;build&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;WORKDIR&lt;/span&gt; &lt;span style="color:#e6db74"&gt;/app&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;COPY&lt;/span&gt; package*.json .&lt;span style="color:#960050;background-color:#1e0010"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;RUN&lt;/span&gt; npm ci&lt;span style="color:#960050;background-color:#1e0010"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;COPY&lt;/span&gt; . .&lt;span style="color:#960050;background-color:#1e0010"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;RUN&lt;/span&gt; npm run build&lt;span style="color:#960050;background-color:#1e0010"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;FROM&lt;/span&gt; &lt;span style="color:#e6db74"&gt;node:20-slim&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;COPY&lt;/span&gt; --from&lt;span style="color:#f92672"&gt;=&lt;/span&gt;build /app/dist ./dist&lt;span style="color:#960050;background-color:#1e0010"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;CMD&lt;/span&gt; [&lt;span style="color:#e6db74"&gt;&amp;#34;node&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;dist/index.js&amp;#34;&lt;/span&gt;]&lt;span style="color:#960050;background-color:#1e0010"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="beneficios"&gt;Beneficios
&lt;/h2&gt;&lt;p&gt;Reduce la imagen final de ~1GB a ~150MB. Elimina herramientas de compilación, dependencias de desarrollo y archivos temporales.&lt;/p&gt;</description></item><item><title>INP: Interaction to Next Paint - La nueva métrica de interactividad</title><link>https://takao.blog/es/web/performance-web-vitals-inp/</link><pubDate>Sat, 15 Mar 2025 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/performance-web-vitals-inp/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/performance-web-vitals-inp-es.png" alt="Featured image of post INP: Interaction to Next Paint - La nueva métrica de interactividad" /&gt;&lt;p&gt;Interaction to Next Paint (INP) reemplaza First Input Delay (FID) como métrica de interactividad en Core Web Vitals. Mide la latencia de todas las interacciones, no solo la primera.&lt;/p&gt;
&lt;h2 id="cómo-se-mide-inp"&gt;Cómo se mide INP
&lt;/h2&gt;&lt;p&gt;Registra el tiempo desde que el usuario interactúa (click, tap, teclado) hasta el siguiente frame pintado. Considera las interacciones más lentas. Objetivo: &amp;lt; 200ms (bueno), &amp;lt; 500ms (mejorable).&lt;/p&gt;
&lt;h2 id="causas-de-inp-alto"&gt;Causas de INP alto
&lt;/h2&gt;&lt;p&gt;JavaScript síncrono pesado, re-renderizados grandes sin optimizar, tareas largas en el hilo principal (&amp;gt; 50ms), listeners complejos en eventos frecuentes.&lt;/p&gt;</description></item><item><title>El operador satisfies en TypeScript: Tipado flexible y seguro</title><link>https://takao.blog/es/web/typescript-satisfies-operator/</link><pubDate>Mon, 10 Mar 2025 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/typescript-satisfies-operator/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/typescript-satisfies-operator-es.png" alt="Featured image of post El operador satisfies en TypeScript: Tipado flexible y seguro" /&gt;&lt;p&gt;El operador &lt;code&gt;satisfies&lt;/code&gt; (TS 4.9+) verifica que una expresión cumple un tipo sin cambiar su tipo inferido. Permite tipado estricto en valores complejos como records y tuplas.&lt;/p&gt;
&lt;h2 id="el-problema"&gt;El problema
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;const x: Record&amp;lt;string, number&amp;gt; = { a: 1, b: 2 }&lt;/code&gt; pierde las claves específicas al acceder. Sin anotación, el tipo es demasiado amplio.&lt;/p&gt;
&lt;h2 id="solución-con-satisfies"&gt;Solución con satisfies
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;palette&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;red&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; [&lt;span style="color:#ae81ff"&gt;255&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;green&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;#00ff00&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;} &lt;span style="color:#a6e22e"&gt;satisfies&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Record&lt;/span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;string&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;string&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;|&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;number&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;[]&lt;/span&gt;&amp;gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;El tipo inferido conserva las propiedades específicas, pero se valida contra el constraint.&lt;/p&gt;</description></item><item><title>Lanzamiento oficial de React 19 y guía de funcionalidades prácticas</title><link>https://takao.blog/es/web/react-19-new-features-practical/</link><pubDate>Wed, 05 Mar 2025 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/react-19-new-features-practical/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/react-19-new-features-practical-es.png" alt="Featured image of post Lanzamiento oficial de React 19 y guía de funcionalidades prácticas" /&gt;&lt;h2 id="introducción"&gt;Introducción
&lt;/h2&gt;&lt;p&gt;React 19 representa un cambio de paradigma importante. Funciones antes restringidas a meta-frameworks como Next.js ahora están integradas en el núcleo estable de React.&lt;/p&gt;
&lt;h2 id="actions-api-y-useactionstate"&gt;Actions API y useActionState
&lt;/h2&gt;&lt;p&gt;Simplifica la gestión de mutaciones asíncronas. &lt;code&gt;useActionState&lt;/code&gt; enlaza manejadores asíncronos directamente a atributos de formulario nativos, manejando automáticamente indicadores de carga.&lt;/p&gt;
&lt;h2 id="useoptimistic"&gt;useOptimistic
&lt;/h2&gt;&lt;p&gt;Para acciones interactivas como &amp;ldquo;me gusta&amp;rdquo; o envío de chats. Actualiza la IU instantáneamente antes de que la solicitud al servidor se complete, con capacidad de rollback integrada.&lt;/p&gt;</description></item><item><title>Seguridad web: Prevención de XSS</title><link>https://takao.blog/es/web/security-basics-xss-prevention/</link><pubDate>Tue, 25 Feb 2025 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/security-basics-xss-prevention/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/security-basics-xss-prevention-es.png" alt="Featured image of post Seguridad web: Prevención de XSS" /&gt;&lt;p&gt;Cross-Site Scripting (XSS) es una vulnerabilidad donde un atacante inyecta scripts maliciosos en páginas web vistas por otros usuarios.&lt;/p&gt;
&lt;h2 id="tipos-de-xss"&gt;Tipos de XSS
&lt;/h2&gt;&lt;p&gt;Reflejado: el script viene en la URL o formulario. Almacenado: el script se guarda en la base de datos. DOM-based: el script se ejecuta mediante manipulación del DOM.&lt;/p&gt;
&lt;h2 id="prevención"&gt;Prevención
&lt;/h2&gt;&lt;p&gt;Escapa toda salida de HTML (React lo hace por defecto con JSX). Usa Content-Security-Policy (CSP). Sanitiza entradas con DOMPurify. HttpOnly y Secure en cookies.&lt;/p&gt;</description></item><item><title>Git Rebase Interactivo: Flujo de trabajo avanzado</title><link>https://takao.blog/es/web/git-rebase-interactive-flow/</link><pubDate>Thu, 20 Feb 2025 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/git-rebase-interactive-flow/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/git-rebase-interactive-flow-es.png" alt="Featured image of post Git Rebase Interactivo: Flujo de trabajo avanzado" /&gt;&lt;p&gt;&lt;code&gt;git rebase -i&lt;/code&gt; permite editar, reordenar, combinar y eliminar commits antes de integrarlos. Esencial para mantener un historial limpio.&lt;/p&gt;
&lt;h2 id="comandos-del-rebase-interactivo"&gt;Comandos del rebase interactivo
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;pick&lt;/code&gt;: mantener commit. &lt;code&gt;reword&lt;/code&gt;: cambiar mensaje. &lt;code&gt;edit&lt;/code&gt;: modificar contenido. &lt;code&gt;squash&lt;/code&gt;: combinar con anterior. &lt;code&gt;fixup&lt;/code&gt;: combinar sin mensaje. &lt;code&gt;drop&lt;/code&gt;: eliminar.&lt;/p&gt;
&lt;h2 id="flujo-típico"&gt;Flujo típico
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;&lt;code&gt;git rebase -i HEAD~3&lt;/code&gt; para últimos 3 commits. 2. Reordenar para agrupar cambios relacionados. 3. Squash commits de WIP. 4. Reword mensajes.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="resolución-de-conflictos"&gt;Resolución de conflictos
&lt;/h2&gt;&lt;p&gt;Git se detiene en cada conflicto. Resuelve, &lt;code&gt;git add&lt;/code&gt;, &lt;code&gt;git rebase --continue&lt;/code&gt;. Usa &lt;code&gt;--skip&lt;/code&gt; para omitir un commit, &lt;code&gt;--abort&lt;/code&gt; para cancelar todo.&lt;/p&gt;</description></item><item><title>Patrones a evitar con async/await en JavaScript</title><link>https://takao.blog/es/web/javascript-async-await-tips/</link><pubDate>Sat, 15 Feb 2025 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/javascript-async-await-tips/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/javascript-async-await-tips-es.png" alt="Featured image of post Patrones a evitar con async/await en JavaScript" /&gt;&lt;h2 id="introducción"&gt;Introducción
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;async/await&lt;/code&gt; hizo la programación asíncrona más intuitiva, pero puede ocultar problemas de rendimiento y errores.&lt;/p&gt;
&lt;h2 id="antipatrón-1-serialización-innecesaria"&gt;Antipatrón 1: Serialización innecesaria
&lt;/h2&gt;&lt;p&gt;No uses &lt;code&gt;await&lt;/code&gt; secuencial para tareas independientes. Usa &lt;code&gt;Promise.all&lt;/code&gt; para ejecución en paralelo.&lt;/p&gt;
&lt;h2 id="antipatrón-2-bloques-try-catch-anidados"&gt;Antipatrón 2: Bloques try-catch anidados
&lt;/h2&gt;&lt;p&gt;El anidamiento profundo derrota el propósito de async/await. Usa un solo bloque try-catch al más alto nivel.&lt;/p&gt;
&lt;h2 id="antipatrón-3-async-callbacks-en-foreach"&gt;Antipatrón 3: async callbacks en forEach
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;forEach&lt;/code&gt; con async callback ejecuta los callbacks síncronamente. Usa &lt;code&gt;for...of&lt;/code&gt; para secuencial o &lt;code&gt;Promise.all&lt;/code&gt; con &lt;code&gt;map&lt;/code&gt; para paralelo.&lt;/p&gt;</description></item><item><title>Introducción al posicionamiento con anclajes CSS</title><link>https://takao.blog/es/web/css-anchor-positioning-guide/</link><pubDate>Mon, 10 Feb 2025 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/css-anchor-positioning-guide/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/css-anchor-positioning-guide-es.png" alt="Featured image of post Introducción al posicionamiento con anclajes CSS" /&gt;&lt;h2 id="introducción"&gt;Introducción
&lt;/h2&gt;&lt;p&gt;Posicionar elementos flotantes (tooltips, popovers, menús) respecto a un elemento de referencia ha sido un desafío complejo. Tradicionalmente se requería JavaScript con cálculos continuos de coordenadas usando &lt;code&gt;getBoundingClientRect()&lt;/code&gt;. La &lt;strong&gt;API de Posicionamiento con Anclajes CSS&lt;/strong&gt; resuelve esto manejando coordenadas flotantes de forma nativa en el navegador.&lt;/p&gt;
&lt;h2 id="qué-es-css-anchor-positioning"&gt;¿Qué es CSS Anchor Positioning?
&lt;/h2&gt;&lt;p&gt;Es un estándar que permite anclar un elemento con posición absoluta o fija directamente a otro elemento usando solo CSS. Beneficios: cero JavaScript, rendimiento superior (compositor thread), y aislamiento de diseño evitando restricciones de recorte del padre.&lt;/p&gt;</description></item><item><title>Modelos de razonamiento de OpenAI</title><link>https://takao.blog/es/web/ai-reasoning-models-openai/</link><pubDate>Wed, 05 Feb 2025 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/ai-reasoning-models-openai/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/ai-reasoning-models-openai-es.png" alt="Featured image of post Modelos de razonamiento de OpenAI" /&gt;&lt;p&gt;Los modelos de razonamiento (o-series) de OpenAI resuelven problemas complejos mediante pensamiento encadenado (chain-of-thought). Son ideales para programación y matemáticas.&lt;/p&gt;
&lt;h2 id="o3-y-o4-mini"&gt;o3 y o4-mini
&lt;/h2&gt;&lt;p&gt;Modelos de razonamiento profundo. o4-mini es más rápido y económico. Usan &amp;ldquo;thinking tokens&amp;rdquo; internos para razonar antes de responder.&lt;/p&gt;
&lt;h2 id="cuándo-usarlos"&gt;Cuándo usarlos
&lt;/h2&gt;&lt;p&gt;Problemas de programación complejos, debugging, análisis de seguridad, optimización. No para tareas simples (mejor GPT-4o o Claude Sonnet).&lt;/p&gt;
&lt;h2 id="uso-práctico"&gt;Uso práctico
&lt;/h2&gt;&lt;p&gt;API con &lt;code&gt;reasoning_effort&lt;/code&gt; (low, medium, high). Mayor effort = mejor calidad pero más lento y costoso. Cache de thinking tokens.&lt;/p&gt;</description></item><item><title>Proxmox Backup Server: Recuperación ante desastres</title><link>https://takao.blog/es/web/proxmox-backup-disaster-recovery/</link><pubDate>Mon, 20 Jan 2025 00:00:00 +0000</pubDate><guid>https://takao.blog/es/web/proxmox-backup-disaster-recovery/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/proxmox-backup-disaster-recovery-es.png" alt="Featured image of post Proxmox Backup Server: Recuperación ante desastres" /&gt;&lt;p&gt;Proxmox Backup Server (PBS) es una solución de backup dedicada para entornos Proxmox. Ofrece deduplicación, compresión y cifrado.&lt;/p&gt;
&lt;h2 id="instalación-de-pbs"&gt;Instalación de PBS
&lt;/h2&gt;&lt;p&gt;Servidor independiente (Debian + PBS). Almacenamiento dedicado (preferiblemente ZFS). Acceso via web en &lt;code&gt;https://IP:8007&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="deduplicación-y-compresión"&gt;Deduplicación y compresión
&lt;/h2&gt;&lt;p&gt;Deduplicación por bloques. Sólo se almacenan bloques únicos entre todos los backups. Compresión zstd. Ahorra 80-95% de espacio.&lt;/p&gt;
&lt;h2 id="cifrado"&gt;Cifrado
&lt;/h2&gt;&lt;p&gt;Cifrado del lado del cliente. Las claves nunca salen del entorno Proxmox. Backups seguros incluso en almacenamiento no confiable.&lt;/p&gt;</description></item><item><title>Gestión de tareas para desarrolladores</title><link>https://takao.blog/es/web/task-managenemt/</link><pubDate>Tue, 14 Jan 2025 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/task-managenemt/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/task-management-es.png" alt="Featured image of post Gestión de tareas para desarrolladores" /&gt;&lt;p&gt;La gestión eficiente de tareas es crucial para la productividad del desarrollador. Sistemas como GTD, Kanban y timeboxing ayudan a organizar el trabajo.&lt;/p&gt;
&lt;h2 id="kanban"&gt;Kanban
&lt;/h2&gt;&lt;p&gt;Tablero visual: To Do, In Progress, Done. Limita el WIP (Work In Progress). Herramientas: GitHub Projects, Linear, Trello, Notion.&lt;/p&gt;
&lt;h2 id="gtd-getting-things-done"&gt;GTD (Getting Things Done)
&lt;/h2&gt;&lt;p&gt;Capturar, clarificar, organizar, reflexionar, ejecutar. Ideal para desarrolladores con muchas tareas interrumpidas.&lt;/p&gt;
&lt;h2 id="timeboxing"&gt;Timeboxing
&lt;/h2&gt;&lt;p&gt;Asigna bloques de tiempo fijos a tareas. Técnica Pomodoro (25 min trabajo, 5 min descanso). Evita el perfectionismo y la procrastinación.&lt;/p&gt;</description></item><item><title>Estrategias de caché en CDN</title><link>https://takao.blog/es/web/cdn-caching-strategies/</link><pubDate>Mon, 30 Dec 2024 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/cdn-caching-strategies/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/cdn-caching-strategies-es.png" alt="Featured image of post Estrategias de caché en CDN" /&gt;&lt;p&gt;Las CDN almacenan contenido en servidores edge cercanos al usuario. Las estrategias de caché determinan qué, cuándo y cómo se almacena.&lt;/p&gt;
&lt;h2 id="cache-control"&gt;Cache-Control
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;public, max-age=31536000, immutable&lt;/code&gt; para recursos versionados. &lt;code&gt;no-cache&lt;/code&gt; para validar con el origen. &lt;code&gt;no-store&lt;/code&gt; para datos sensibles.&lt;/p&gt;
&lt;h2 id="invalidación-de-caché"&gt;Invalidación de caché
&lt;/h2&gt;&lt;p&gt;Por URL (nuevo hash en nombre de archivo). Por purga (API de CDN). Por TTL (cacheo por tiempo). Por tags (purga por etiqueta).&lt;/p&gt;
&lt;h2 id="estrategias-híbridas"&gt;Estrategias híbridas
&lt;/h2&gt;&lt;p&gt;Assets estáticos: caché larga con versionado. HTML: TTL corto o sin caché. APIs: caché por URL con stale-while-revalidate.&lt;/p&gt;</description></item><item><title>File System Access API: Acceso a archivos en el navegador</title><link>https://takao.blog/es/web/file-system-access-api/</link><pubDate>Sat, 28 Dec 2024 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/file-system-access-api/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/file-system-access-api-es.png" alt="Featured image of post File System Access API: Acceso a archivos en el navegador" /&gt;&lt;p&gt;La File System Access API permite a las aplicaciones web leer, escribir y gestionar archivos y directorios en el sistema local del usuario.&lt;/p&gt;
&lt;h2 id="lectura-de-archivos"&gt;Lectura de archivos
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;window.showOpenFilePicker()&lt;/code&gt; devuelve un FileSystemFileHandle. Lee con &lt;code&gt;getFile()&lt;/code&gt; y &lt;code&gt;file.text()&lt;/code&gt; o &lt;code&gt;file.stream()&lt;/code&gt;. Múltiples archivos con &lt;code&gt;multiple: true&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="escritura-de-archivos"&gt;Escritura de archivos
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;window.showSaveFilePicker()&lt;/code&gt; permite guardar archivos. &lt;code&gt;handle.createWritable()&lt;/code&gt; devuelve un writable stream. Escritura segura con permisos del usuario.&lt;/p&gt;
&lt;h2 id="directorios"&gt;Directorios
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;window.showDirectoryPicker()&lt;/code&gt; permite seleccionar directorios. Iteración con &lt;code&gt;dir.entries()&lt;/code&gt;. Creación de archivos y subdirectorios.&lt;/p&gt;</description></item><item><title>Rendimiento móvil: Optimización para dispositivos con recursos limitados</title><link>https://takao.blog/es/web/mobile-performance/</link><pubDate>Thu, 26 Dec 2024 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/mobile-performance/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/mobile-performance-es.png" alt="Featured image of post Rendimiento móvil: Optimización para dispositivos con recursos limitados" /&gt;&lt;p&gt;Los dispositivos móviles tienen CPUs más lentas, menos memoria y redes más lentas. La optimización móvil requiere estrategias específicas.&lt;/p&gt;
&lt;h2 id="redes-lentas"&gt;Redes lentas
&lt;/h2&gt;&lt;p&gt;Minimiza el peso total de la página (&amp;lt; 1MB ideal). Usa la API Network Information para detectar conexiones lentas. Prioriza contenido crítico con lazy loading para el resto.&lt;/p&gt;
&lt;h2 id="memoria-limitada"&gt;Memoria limitada
&lt;/h2&gt;&lt;p&gt;Evita fugas de memoria con correcta limpieza de event listeners y observadores. Libera referencias a grandes buffers. Usa &lt;code&gt;performance.memory&lt;/code&gt; para monitoreo.&lt;/p&gt;</description></item><item><title>Git Hooks: Automatización del flujo de trabajo</title><link>https://takao.blog/es/web/git-hooks-automation/</link><pubDate>Tue, 24 Dec 2024 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/git-hooks-automation/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/git-hooks-automation-es.png" alt="Featured image of post Git Hooks: Automatización del flujo de trabajo" /&gt;&lt;p&gt;Los hooks de Git son scripts que se ejecutan en eventos específicos del ciclo de vida de Git. Automatizan validaciones, pruebas y despliegues.&lt;/p&gt;
&lt;h2 id="hooks-del-lado-cliente"&gt;Hooks del lado cliente
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;pre-commit&lt;/code&gt;: antes del mensaje de commit. &lt;code&gt;pre-push&lt;/code&gt;: antes del push. &lt;code&gt;post-commit&lt;/code&gt;: después del commit. &lt;code&gt;pre-rebase&lt;/code&gt;: antes del rebase.&lt;/p&gt;
&lt;h2 id="hooks-del-lado-servidor"&gt;Hooks del lado servidor
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;pre-receive&lt;/code&gt;, &lt;code&gt;update&lt;/code&gt;, &lt;code&gt;post-receive&lt;/code&gt;. Se ejecutan en el repositorio remoto. Ideales para CI/CD y políticas de equipo.&lt;/p&gt;
&lt;h2 id="ejemplos-prácticos"&gt;Ejemplos prácticos
&lt;/h2&gt;&lt;p&gt;pre-commit: lint, formateo, pruebas rápidas. pre-push: tests completos, verificación de builds. post-commit: notificaciones, actualización de issues.&lt;/p&gt;</description></item><item><title>Alias de rutas en TypeScript: Mejora tus imports</title><link>https://takao.blog/es/web/typescript-path-aliases/</link><pubDate>Sun, 22 Dec 2024 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/typescript-path-aliases/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/typescript-path-aliases-es.png" alt="Featured image of post Alias de rutas en TypeScript: Mejora tus imports" /&gt;&lt;p&gt;Los alias de rutas reemplazan imports relativos profundos (&lt;code&gt;../../components/Button&lt;/code&gt;) con alias limpios (&lt;code&gt;@/components/Button&lt;/code&gt;). Mejoran la legibilidad y facilitan la reestructuración.&lt;/p&gt;
&lt;h2 id="configuración-en-tsconfigjson"&gt;Configuración en tsconfig.json
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;compilerOptions&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;baseUrl&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;.&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;paths&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;@/*&amp;#34;&lt;/span&gt;: [&lt;span style="color:#e6db74"&gt;&amp;#34;src/*&amp;#34;&lt;/span&gt;],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;@components/*&amp;#34;&lt;/span&gt;: [&lt;span style="color:#e6db74"&gt;&amp;#34;src/components/*&amp;#34;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="integración-con-bundlers"&gt;Integración con bundlers
&lt;/h2&gt;&lt;p&gt;Vite: resuelve alias de tsconfig automáticamente con &lt;code&gt;vite-tsconfig-paths&lt;/code&gt;. Webpack: &lt;code&gt;resolve.alias&lt;/code&gt;. Next.js: &lt;code&gt;tsconfig.json paths&lt;/code&gt; soportado nativamente.&lt;/p&gt;
&lt;h2 id="eslint-y-editores"&gt;ESLint y editores
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;eslint-plugin-import&lt;/code&gt; necesita &lt;code&gt;import/resolver&lt;/code&gt; configurado para seguir alias. VS Code usa tsconfig para autocompletado y navegación.&lt;/p&gt;</description></item><item><title>Subresource Integrity (SRI): Garantizando integridad de recursos</title><link>https://takao.blog/es/web/subresource-integrity/</link><pubDate>Fri, 20 Dec 2024 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/subresource-integrity/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/subresource-integrity-es.png" alt="Featured image of post Subresource Integrity (SRI): Garantizando integridad de recursos" /&gt;&lt;p&gt;Subresource Integrity (SRI) permite verificar que un archivo cargado desde un CDN no ha sido manipulado, comparando su hash criptográfico.&lt;/p&gt;
&lt;h2 id="cómo-funciona"&gt;Cómo funciona
&lt;/h2&gt;&lt;p&gt;El atributo &lt;code&gt;integrity&lt;/code&gt; contiene un hash (SHA-256, SHA-384, SHA-512) del contenido esperado. El navegador calcula el hash y lo compara. Si no coincide, bloquea el recurso.&lt;/p&gt;
&lt;h2 id="ejemplo"&gt;Ejemplo
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-html" data-lang="html"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;script&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;src&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;https://cdn.example.com/lib.js&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;integrity&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;sha384-...&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;crossorigin&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;anonymous&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;El crossorigin es obligatorio para recursos CORS.&lt;/p&gt;
&lt;h2 id="generación-de-hashes"&gt;Generación de hashes
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;openssl dgst -sha384 -binary archivo.js | openssl base64 -A&lt;/code&gt;. O usando herramientas online de SRI. Automatiza en el build process.&lt;/p&gt;</description></item><item><title>Rendimiento en Node.js: Optimización y profiling</title><link>https://takao.blog/es/web/nodejs-performance/</link><pubDate>Wed, 18 Dec 2024 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/nodejs-performance/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/nodejs-performance-es.png" alt="Featured image of post Rendimiento en Node.js: Optimización y profiling" /&gt;&lt;p&gt;Node.js puede manejar alto rendimiento si se optimizan correctamente el bucle de eventos, la memoria y las operaciones asíncronas.&lt;/p&gt;
&lt;h2 id="bucle-de-eventos"&gt;Bucle de eventos
&lt;/h2&gt;&lt;p&gt;No bloquees el event loop con operaciones síncronas pesadas. Usa &lt;code&gt;setImmediate()&lt;/code&gt;, &lt;code&gt;nextTick()&lt;/code&gt; y &lt;code&gt;Worker Threads&lt;/code&gt; para descargar trabajo.&lt;/p&gt;
&lt;h2 id="profiling"&gt;Profiling
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;--inspect&lt;/code&gt; + Chrome DevTools para CPU profiling. &lt;code&gt;--prof&lt;/code&gt; para logs de V8. &lt;code&gt;clinic.js&lt;/code&gt; (Doctor, Bubbleprof, Flame) para diagnóstico visual.&lt;/p&gt;
&lt;h2 id="gestión-de-memoria"&gt;Gestión de memoria
&lt;/h2&gt;&lt;p&gt;Evita fugas con correcta limpieza de listeners y referencias. Usa &lt;code&gt;heapdump&lt;/code&gt; o &lt;code&gt;v8.writeHeapSnapshot()&lt;/code&gt;. Monitorea con &lt;code&gt;process.memoryUsage()&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>Estilos con alcance CSS: @scope y estrategias de encapsulación</title><link>https://takao.blog/es/web/css-scoped-styles/</link><pubDate>Sun, 15 Dec 2024 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/css-scoped-styles/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/css-scoped-styles-es.png" alt="Featured image of post Estilos con alcance CSS: @scope y estrategias de encapsulación" /&gt;&lt;p&gt;El alcance de CSS ha sido un desafío constante. &lt;code&gt;@scope&lt;/code&gt; introduce control de cascada basado en proximidad, aplicado por el navegador.&lt;/p&gt;
&lt;h2 id="la-regla-scope"&gt;La regla @scope
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;@scope (.card) { .title { font-size: 1.25rem; } }&lt;/code&gt; limita estilos a un elemento raíz y sus descendientes. La novedad clave es la &lt;strong&gt;proximidad de alcance&lt;/strong&gt;: estilos más cercanos al elemento tienen prioridad. Puedes definir límites con &lt;code&gt;to (.card__footer)&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="shadow-dom"&gt;Shadow DOM
&lt;/h2&gt;&lt;p&gt;Aislamiento total de estilos, marcado y comportamiento. Esencial para bibliotecas de widgets distribuidos, pero añade sobrecarga de ejecución.&lt;/p&gt;</description></item><item><title>Métodos de arrays JavaScript: De básicos a patrones avanzados</title><link>https://takao.blog/es/web/js-array-methods/</link><pubDate>Thu, 12 Dec 2024 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/js-array-methods/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/js-array-methods-es.png" alt="Featured image of post Métodos de arrays JavaScript: De básicos a patrones avanzados" /&gt;&lt;p&gt;Los arrays de JavaScript son el pilar de la manipulación de datos en el desarrollo web moderno. Con ES2023 introduciendo alternativas inmutables a métodos mutantes, es momento de revisar cómo trabajamos con arrays.&lt;/p&gt;
&lt;h2 id="panorama-de-métodos-de-array"&gt;Panorama de métodos de array
&lt;/h2&gt;&lt;p&gt;Los métodos se dividen en mutantes y no mutantes. ES2023 introdujo cuatro métodos inmutables: &lt;code&gt;toSorted()&lt;/code&gt;, &lt;code&gt;toReversed()&lt;/code&gt;, &lt;code&gt;toSpliced()&lt;/code&gt;, &lt;code&gt;with()&lt;/code&gt;. Estos crean nuevos arrays sin modificar el original, ideal para React o Redux.&lt;/p&gt;
&lt;h2 id="map-filter-y-reduce-en-profundidad"&gt;Map, Filter y Reduce en profundidad
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;map&lt;/code&gt; transforma cada elemento, &lt;code&gt;filter&lt;/code&gt; selecciona elementos, &lt;code&gt;reduce&lt;/code&gt; es el más versátil. Una anti-patrón común es encadenar &lt;code&gt;map&lt;/code&gt; seguido de &lt;code&gt;filter&lt;/code&gt; cuando un solo &lt;code&gt;flatMap&lt;/code&gt; sería suficiente.&lt;/p&gt;</description></item><item><title>Cookies seguras: HttpOnly, Secure, SameSite</title><link>https://takao.blog/es/web/secure-cookies/</link><pubDate>Mon, 09 Dec 2024 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/secure-cookies/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/secure-cookies-es.png" alt="Featured image of post Cookies seguras: HttpOnly, Secure, SameSite" /&gt;&lt;p&gt;Las cookies tienen atributos de seguridad que protegen contra XSS, CSRF y escuchas no autorizadas. Configurarlos correctamente es esencial.&lt;/p&gt;
&lt;h2 id="httponly"&gt;HttpOnly
&lt;/h2&gt;&lt;p&gt;Previene el acceso a la cookie desde JavaScript (&lt;code&gt;document.cookie&lt;/code&gt;). Bloquea robo de cookies via XSS. Esencial para cookies de sesión.&lt;/p&gt;
&lt;h2 id="secure"&gt;Secure
&lt;/h2&gt;&lt;p&gt;La cookie solo se envía en conexiones HTTPS. Nunca en HTTP. Protege contra ataques Man-in-the-Middle. Siempre activar.&lt;/p&gt;
&lt;h2 id="samesite"&gt;SameSite
&lt;/h2&gt;&lt;p&gt;Strict: máxima protección CSRF. Lax: balance seguridad/usabilidad. None + Secure: cookies de terceros (menos seguro).&lt;/p&gt;</description></item><item><title>React Concurrent: Guía de renderizado concurrente</title><link>https://takao.blog/es/web/react-concurrent/</link><pubDate>Fri, 06 Dec 2024 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/react-concurrent/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/react-concurrent-es.png" alt="Featured image of post React Concurrent: Guía de renderizado concurrente" /&gt;&lt;p&gt;El renderizado concurrente de React permite que React interrumpa el trabajo de renderizado para manejar eventos de mayor prioridad. Con React 18+, &lt;code&gt;startTransition&lt;/code&gt; y &lt;code&gt;useDeferredValue&lt;/code&gt; permiten actualizaciones no urgentes sin bloquear la UI.&lt;/p&gt;
&lt;h2 id="starttransition"&gt;startTransition
&lt;/h2&gt;&lt;p&gt;Marca una actualización de estado como transición. React puede interrumpirla para manejar eventos urgentes como entrada de teclado.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-jsx" data-lang="jsx"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;startTransition&lt;/span&gt;(() =&amp;gt; { &lt;span style="color:#a6e22e"&gt;setSearchQuery&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;input&lt;/span&gt;); });
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="usedeferredvalue"&gt;useDeferredValue
&lt;/h2&gt;&lt;p&gt;Aplaza un valor para que React pueda mostrar contenido antiguo mientras carga el nuevo. Útil para búsquedas en listas grandes.&lt;/p&gt;</description></item><item><title>GraphQL vs REST en 2024: Cuál elegir</title><link>https://takao.blog/es/web/graphql-vs-rest-2024/</link><pubDate>Tue, 03 Dec 2024 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/graphql-vs-rest-2024/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/graphql-vs-rest-2024-es.png" alt="Featured image of post GraphQL vs REST en 2024: Cuál elegir" /&gt;&lt;p&gt;REST y GraphQL son enfoques diferentes para diseñar APIs. La elección depende del caso de uso, no de la moda.&lt;/p&gt;
&lt;h2 id="rest"&gt;REST
&lt;/h2&gt;&lt;p&gt;Recursos como URLs. Métodos HTTP (GET, POST, PUT, DELETE). Cacheable por naturaleza. Familiar y probado. Overfetching y underfetching son desventajas.&lt;/p&gt;
&lt;h2 id="graphql"&gt;GraphQL
&lt;/h2&gt;&lt;p&gt;Un solo endpoint. El cliente solicita exactamente los campos que necesita. Tipado fuerte (schema). Resolvers. Suscripciones para tiempo real.&lt;/p&gt;
&lt;h2 id="ventajas-de-graphql"&gt;Ventajas de GraphQL
&lt;/h2&gt;&lt;p&gt;Sin over/under fetching. Documentación interactiva (GraphiQL). Tipos fuertes. Ideal para dashboards y apps con datos complejos.&lt;/p&gt;</description></item><item><title>WebAssembly (WASM): Aplicaciones nativas en el navegador</title><link>https://takao.blog/es/web/wasm-browser-apps/</link><pubDate>Sat, 30 Nov 2024 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/wasm-browser-apps/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/wasm-browser-apps-es.png" alt="Featured image of post WebAssembly (WASM): Aplicaciones nativas en el navegador" /&gt;&lt;p&gt;WebAssembly (WASM) ejecuta código compilado (C, C++, Rust, Go) en el navegador a velocidad casi nativa. Abre nuevas posibilidades para aplicaciones web.&lt;/p&gt;
&lt;h2 id="rendimiento"&gt;Rendimiento
&lt;/h2&gt;&lt;p&gt;WASM es 10-40% más lento que código nativo pero mucho más rápido que JavaScript para cálculos intensivos. Compilado a binario, parseado en microsegundos.&lt;/p&gt;
&lt;h2 id="ecosistema"&gt;Ecosistema
&lt;/h2&gt;&lt;p&gt;Rust + wasm-pack: el más popular. C/C++ con Emscripten. Go, Zig, Kotlin también compilan a WASM. WASI para WASM fuera del navegador.&lt;/p&gt;
&lt;h2 id="casos-de-uso"&gt;Casos de uso
&lt;/h2&gt;&lt;p&gt;Procesamiento de imagen/video, juegos, simulaciones, compiladores, ofimática, cifrado. Figma, AutoCAD, Google Earth usan WASM.&lt;/p&gt;</description></item><item><title>Git LFS: Gestión de archivos grandes</title><link>https://takao.blog/es/web/git-lfs/</link><pubDate>Tue, 26 Nov 2024 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/git-lfs/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/git-lfs-es.png" alt="Featured image of post Git LFS: Gestión de archivos grandes" /&gt;&lt;p&gt;Git LFS (Large File Storage) reemplaza archivos grandes con punteros de texto en el repositorio, mientras almacena el contenido real en un servidor remoto.&lt;/p&gt;
&lt;h2 id="instalación"&gt;Instalación
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;git lfs install&lt;/code&gt; configura Git para usar LFS. Luego &lt;code&gt;git lfs track &amp;quot;*.psd&amp;quot;&lt;/code&gt; para rastrear archivos grandes por patrón.&lt;/p&gt;
&lt;h2 id="flujo-de-trabajo"&gt;Flujo de trabajo
&lt;/h2&gt;&lt;p&gt;Los archivos LFS se usan como archivos normales. Git LFS maneja automáticamente la descarga/subida. El diff muestra el puntero, no el binario.&lt;/p&gt;
&lt;h2 id="límites-y-costos"&gt;Límites y costos
&lt;/h2&gt;&lt;p&gt;GitHub: 1GB gratis, luego pago por ancho de banda. Bitbucket y GitLab tienen políticas similares. Bandwidth se consume en push y pull.&lt;/p&gt;</description></item><item><title>Scripts de terceros: Impacto en rendimiento y privacidad</title><link>https://takao.blog/es/web/third-party-scripts/</link><pubDate>Tue, 19 Nov 2024 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/third-party-scripts/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/third-party-scripts-es.png" alt="Featured image of post Scripts de terceros: Impacto en rendimiento y privacidad" /&gt;&lt;p&gt;Los scripts de terceros (analytics, ads, widgets, chatbots) afectan el rendimiento y la privacidad. Gestionarlos correctamente es esencial para Core Web Vitals.&lt;/p&gt;
&lt;h2 id="impacto-en-rendimiento"&gt;Impacto en rendimiento
&lt;/h2&gt;&lt;p&gt;Los scripts de terceros bloquean el renderizado, añaden requests, y ejecutan código no optimizado. Pueden añadir segundos al tiempo de carga.&lt;/p&gt;
&lt;h2 id="carga-diferida"&gt;Carga diferida
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;async&lt;/code&gt; o &lt;code&gt;defer&lt;/code&gt; para scripts no críticos. Carga bajo demanda (interacción del usuario). Posterga analytics con &lt;code&gt;requestIdleCallback&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="privacidad"&gt;Privacidad
&lt;/h2&gt;&lt;p&gt;Los scripts de terceros pueden rastrear usuarios. Consent Mode (GDPR). Alternativas: Cloudflare Zaraz, Plausible, Fathom (sin cookies).&lt;/p&gt;</description></item><item><title>Docker Compose en producción</title><link>https://takao.blog/es/web/docker-compose-production/</link><pubDate>Tue, 12 Nov 2024 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/docker-compose-production/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/docker-compose-production-es.png" alt="Featured image of post Docker Compose en producción" /&gt;&lt;p&gt;Docker Compose no es solo para desarrollo. Con configuraciones adecuadas puede orquestar servicios en producción para despliegues pequeños y medianos.&lt;/p&gt;
&lt;h2 id="diferencias-desarrollo-vs-producción"&gt;Diferencias desarrollo vs producción
&lt;/h2&gt;&lt;p&gt;Usa múltiples archivos: &lt;code&gt;docker-compose.yml&lt;/code&gt; base, &lt;code&gt;docker-compose.override.yml&lt;/code&gt; para desarrollo, &lt;code&gt;docker-compose.prod.yml&lt;/code&gt; para producción.&lt;/p&gt;
&lt;h2 id="seguridad"&gt;Seguridad
&lt;/h2&gt;&lt;p&gt;No expongas puertos innecesarios. Usa redes internas para servicios. Variables de entorno via archivos &lt;code&gt;.env&lt;/code&gt; o secretos de Docker.&lt;/p&gt;
&lt;h2 id="persistencia-de-datos"&gt;Persistencia de datos
&lt;/h2&gt;&lt;p&gt;Volúmenes nombrados en lugar de bind mounts. Backups periódicos. Políticas de reinicio: &lt;code&gt;restart: unless-stopped&lt;/code&gt; o &lt;code&gt;restart: always&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>Funciones trigonométricas CSS: Matemáticas en tus hojas de estilo</title><link>https://takao.blog/es/web/css-trig-functions/</link><pubDate>Tue, 05 Nov 2024 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/css-trig-functions/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/css-trig-functions-es.png" alt="Featured image of post Funciones trigonométricas CSS: Matemáticas en tus hojas de estilo" /&gt;&lt;p&gt;CSS ha evolucionado para incluir funciones trigonométricas: &lt;code&gt;sin()&lt;/code&gt;, &lt;code&gt;cos()&lt;/code&gt;, &lt;code&gt;tan()&lt;/code&gt;, &lt;code&gt;atan2()&lt;/code&gt;, &lt;code&gt;asin()&lt;/code&gt;, &lt;code&gt;acos()&lt;/code&gt;. Soportadas en Chrome 111+, Firefox 108+, Safari 15.4+.&lt;/p&gt;
&lt;h2 id="patrones-de-onda-y-oscilaciones"&gt;Patrones de onda y oscilaciones
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#a6e22e"&gt;wave&lt;/span&gt; { &lt;span style="color:#66d9ef"&gt;transform&lt;/span&gt;: translateY(calc(&lt;span style="color:#a6e22e"&gt;sin&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;var&lt;/span&gt;(&lt;span style="color:#f92672"&gt;--&lt;/span&gt;phase)) &lt;span style="color:#f92672"&gt;*&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;20&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;px&lt;/span&gt;)); }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Crea efectos de onda puramente CSS. Combinado con &lt;code&gt;@property&lt;/code&gt; para iterar ángulos.&lt;/p&gt;
&lt;h2 id="layouts-circulares"&gt;Layouts circulares
&lt;/h2&gt;&lt;p&gt;Las fórmulas &lt;code&gt;x = cx + r * cos(angle)&lt;/code&gt; y &lt;code&gt;y = cy + r * sin(angle)&lt;/code&gt; permiten layouts circulares sin JavaScript. Power menús radiales, gráficos de donut, órbitas.&lt;/p&gt;</description></item><item><title>Generación de contenido con IA para desarrolladores</title><link>https://takao.blog/es/web/ai-content-generation/</link><pubDate>Tue, 29 Oct 2024 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/ai-content-generation/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/ai-content-generation-es.png" alt="Featured image of post Generación de contenido con IA para desarrolladores" /&gt;&lt;p&gt;La IA generativa puede crear documentación, entradas de blog, descripciones de commits y mensajes de PR. Ahorra tiempo en tareas de comunicación.&lt;/p&gt;
&lt;h2 id="documentación-técnica"&gt;Documentación técnica
&lt;/h2&gt;&lt;p&gt;Genera READMEs, guías de inicio rápido, documentación de API. La IA puede analizar el código fuente y describir su funcionalidad.&lt;/p&gt;
&lt;h2 id="blogging-técnico"&gt;Blogging técnico
&lt;/h2&gt;&lt;p&gt;Tutoriales, guías, comparativas. La IA estructura el contenido, sugiere ejemplos y mantiene un tono consistente.&lt;/p&gt;
&lt;h2 id="limitaciones"&gt;Limitaciones
&lt;/h2&gt;&lt;p&gt;La IA puede alucinar APIs que no existen. Verifica todo contenido generado. Usa la IA como borrador inicial, no como producto final.&lt;/p&gt;</description></item><item><title>Optimización del tamaño del bundle en aplicaciones web</title><link>https://takao.blog/es/web/bundle-size-optimization/</link><pubDate>Tue, 22 Oct 2024 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/bundle-size-optimization/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/bundle-size-optimization-es.png" alt="Featured image of post Optimización del tamaño del bundle en aplicaciones web" /&gt;&lt;p&gt;Reducir el tamaño del bundle mejora los tiempos de carga y la experiencia del usuario. Las técnicas van desde análisis hasta code splitting y tree shaking.&lt;/p&gt;
&lt;h2 id="análisis-del-bundle"&gt;Análisis del bundle
&lt;/h2&gt;&lt;p&gt;Usa &lt;code&gt;vite-bundle-visualizer&lt;/code&gt; o &lt;code&gt;webpack-bundle-analyzer&lt;/code&gt; para identificar módulos grandes. Busca bibliotecas duplicadas, importaciones completas de lo que solo necesita partes, y dependencias sobredimensionadas.&lt;/p&gt;
&lt;h2 id="tree-shaking"&gt;Tree Shaking
&lt;/h2&gt;&lt;p&gt;Asegura imports específicos en lugar de namespace imports: &lt;code&gt;import { map } from 'lodash-es'&lt;/code&gt; en vez de &lt;code&gt;import _ from 'lodash'&lt;/code&gt;. Usa librerías tree-shakeable (ESM).&lt;/p&gt;</description></item><item><title>TypeScript Branded Types: Validación de tipos en tiempo de compilación</title><link>https://takao.blog/es/web/typescript-branded-types/</link><pubDate>Tue, 15 Oct 2024 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/typescript-branded-types/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/typescript-branded-types-es.png" alt="Featured image of post TypeScript Branded Types: Validación de tipos en tiempo de compilación" /&gt;&lt;p&gt;Los tipos marcados (branded types) son una técnica para crear tipos nominales en TypeScript. Añaden una marca única a tipos estructuralmente compatibles para prevenir confusiones entre valores del mismo tipo subyacente.&lt;/p&gt;
&lt;h2 id="el-problema-de-los-tipos-estructurales"&gt;El problema de los tipos estructurales
&lt;/h2&gt;&lt;p&gt;TypeScript usa tipado estructural. Una cadena de ID de usuario y una cadena de ID de producto son compatibles aunque representen conceptos distintos. Las branded types resuelven esto.&lt;/p&gt;
&lt;h2 id="patrones-de-branded-types"&gt;Patrones de branded types
&lt;/h2&gt;&lt;p&gt;Intersección con una marca literal: &lt;code&gt;type UserID = string &amp;amp; { readonly __brand: 'UserID' }&lt;/code&gt;. Funciones constructoras con aserciones de tipo garantizan la seguridad.&lt;/p&gt;</description></item><item><title>Routing i18n en Next.js App Router</title><link>https://takao.blog/es/web/nextjs-i18n-routing/</link><pubDate>Tue, 08 Oct 2024 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/nextjs-i18n-routing/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/nextjs-i18n-routing-es.png" alt="Featured image of post Routing i18n en Next.js App Router" /&gt;&lt;p&gt;Next.js App Router ofrece routing internacionalizado con detección de idioma, redirecciones y Middleware. Soporta subpath y dominio.&lt;/p&gt;
&lt;h2 id="configuración"&gt;Configuración
&lt;/h2&gt;&lt;p&gt;Define &lt;code&gt;locales&lt;/code&gt; en next.config.js. &lt;code&gt;defaultLocale&lt;/code&gt;. Middleware detecta el idioma preferido del navegador y redirige. El path incluye &lt;code&gt;/es&lt;/code&gt;, &lt;code&gt;/ja&lt;/code&gt;, etc.&lt;/p&gt;
&lt;h2 id="estrategias-de-routing"&gt;Estrategias de routing
&lt;/h2&gt;&lt;p&gt;Subpath: &lt;code&gt;/es/about&lt;/code&gt;, &lt;code&gt;/ja/about&lt;/code&gt;. Dominio: &lt;code&gt;es.example.com&lt;/code&gt;, &lt;code&gt;ja.example.com&lt;/code&gt;. Subdominio. El Middleware maneja la detección y redirección.&lt;/p&gt;
&lt;h2 id="next-intl"&gt;next-intl
&lt;/h2&gt;&lt;p&gt;Biblioteca recomendada para internacionalización en Next.js. Mensajes en JSON, formateo de fechas/números, plurales. Integración con App Router.&lt;/p&gt;</description></item><item><title>Prevención de SQL Injection</title><link>https://takao.blog/es/web/sql-injection-prevention/</link><pubDate>Tue, 01 Oct 2024 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/sql-injection-prevention/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/sql-injection-prevention-es.png" alt="Featured image of post Prevención de SQL Injection" /&gt;&lt;p&gt;SQL Injection es una vulnerabilidad donde el atacante manipula consultas SQL insertando código malicioso en las entradas de usuario.&lt;/p&gt;
&lt;h2 id="cómo-ocurre"&gt;Cómo ocurre
&lt;/h2&gt;&lt;p&gt;Concatenar cadenas en SQL: &lt;code&gt;SELECT * FROM users WHERE id = '&lt;/code&gt; + id + &lt;code&gt;'&lt;/code&gt; permite al atacante inyectar &lt;code&gt;' OR '1'='1&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="prevención-consultas-parametrizadas"&gt;Prevención: Consultas parametrizadas
&lt;/h2&gt;&lt;p&gt;Usa placeholders: &lt;code&gt;SELECT * FROM users WHERE id = ?&lt;/code&gt;. La base de datos escapa los valores automáticamente. Nunca concatenes entradas en SQL.&lt;/p&gt;</description></item><item><title>Monorepos con Turborepo: Gestión eficiente de proyectos</title><link>https://takao.blog/es/web/monorepo-turborepo/</link><pubDate>Tue, 24 Sep 2024 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/monorepo-turborepo/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/monorepo-turborepo-es.png" alt="Featured image of post Monorepos con Turborepo: Gestión eficiente de proyectos" /&gt;&lt;p&gt;Turborepo es una herramienta de construcción de alto rendimiento para monorepos JavaScript/TypeScript. Acelera builds con caché y paralelización.&lt;/p&gt;
&lt;h2 id="por-qué-monorepo"&gt;Por qué monorepo
&lt;/h2&gt;&lt;p&gt;Código compartido entre proyectos, dependencias únicas, cambios atómicos, CI unificada. Ideal para equipos que mantienen múltiples paquetes.&lt;/p&gt;
&lt;h2 id="turborepo-vs-nx"&gt;Turborepo vs Nx
&lt;/h2&gt;&lt;p&gt;Turborepo: más simple, configuración mínima, caché remota integrada con Vercel. Nx: más características, generadores, migraciones automáticas.&lt;/p&gt;
&lt;h2 id="configuración"&gt;Configuración
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;turbo.json&lt;/code&gt; define pipeline de tareas. &lt;code&gt;dependsOn&lt;/code&gt; para orden de ejecución. &lt;code&gt;cache&lt;/code&gt; para outputs. &lt;code&gt;outputs&lt;/code&gt; para artefactos cacheados.&lt;/p&gt;</description></item><item><title>Patrones Serverless: Arquitecturas modernas</title><link>https://takao.blog/es/web/serverless-patterns/</link><pubDate>Tue, 17 Sep 2024 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/serverless-patterns/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/serverless-patterns-es.png" alt="Featured image of post Patrones Serverless: Arquitecturas modernas" /&gt;&lt;p&gt;Serverless abstrae la infraestructura. El código se ejecuta en respuesta a eventos sin gestionar servidores. Escala automáticamente.&lt;/p&gt;
&lt;h2 id="funciones-como-unidad"&gt;Funciones como unidad
&lt;/h2&gt;&lt;p&gt;AWS Lambda, Cloudflare Functions, Vercel Functions, Deno Deploy. Una función por endpoint. Stateless por defecto. Límites de duración (15min Lambda, 30s Workers).&lt;/p&gt;
&lt;h2 id="bases-de-datos-serverless"&gt;Bases de datos serverless
&lt;/h2&gt;&lt;p&gt;PlanetScale, Neon, Supabase (SQL). DynamoDB, Firestore (NoSQL). Conexiones pooling automático. Escalado a cero cuando no se usa.&lt;/p&gt;
&lt;h2 id="patrón-api-gateway--funciones"&gt;Patrón: API Gateway + Funciones
&lt;/h2&gt;&lt;p&gt;API Gateway recibe solicitudes, enruta a funciones. Autenticación, rate limiting, validación en el gateway. Las funciones solo manejan lógica de negocio.&lt;/p&gt;</description></item><item><title>Typed Arrays en JavaScript: Procesamiento de datos binarios en el navegador</title><link>https://takao.blog/es/web/js-typed-arrays/</link><pubDate>Tue, 10 Sep 2024 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/js-typed-arrays/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/js-typed-arrays-es.png" alt="Featured image of post Typed Arrays en JavaScript: Procesamiento de datos binarios en el navegador" /&gt;&lt;p&gt;El tipo &lt;code&gt;Number&lt;/code&gt; nativo de JavaScript es ineficiente para datos binarios. Los Typed Arrays (ES2015) traen gestión de memoria tipo C al navegador.&lt;/p&gt;
&lt;h2 id="arraybuffer"&gt;ArrayBuffer
&lt;/h2&gt;&lt;p&gt;Buffer binario raw de longitud fija. No se puede leer/escribir directamente — debe usarse una vista.&lt;/p&gt;
&lt;h2 id="vistas-typedarray"&gt;Vistas TypedArray
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;Int8Array&lt;/code&gt;, &lt;code&gt;Uint8Array&lt;/code&gt;, &lt;code&gt;Float32Array&lt;/code&gt;, etc. Cada vista interpreta los bytes como un tipo numérico específico. &lt;code&gt;subarray()&lt;/code&gt; crea una subvista sin copia.&lt;/p&gt;
&lt;h2 id="dataview-para-estructuras-complejas"&gt;DataView para estructuras complejas
&lt;/h2&gt;&lt;p&gt;Permite lectura/escritura en offsets arbitrarios con tipo y endianness explícitos. Ideal para formatos binarios como BMP, PNG, WAV.&lt;/p&gt;</description></item><item><title>Patrones de Portal en React: Renderizado fuera del árbol padre</title><link>https://takao.blog/es/web/react-portal-patterns/</link><pubDate>Tue, 03 Sep 2024 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/react-portal-patterns/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/react-portal-patterns-es.png" alt="Featured image of post Patrones de Portal en React: Renderizado fuera del árbol padre" /&gt;&lt;p&gt;ReactDOM.createPortal renderiza un componente fuera del árbol DOM del padre, útil para modales, tooltips y dropdowns que necesitan evitar overflow: hidden o z-index del padre.&lt;/p&gt;
&lt;h2 id="uso-básico"&gt;Uso básico
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-jsx" data-lang="jsx"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;createPortal&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;children&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;domNode&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;El portal se renderiza en &lt;code&gt;domNode&lt;/code&gt; pero conserva el contexto React (props, estado, context API).&lt;/p&gt;
&lt;h2 id="casos-de-uso-comunes"&gt;Casos de uso comunes
&lt;/h2&gt;&lt;p&gt;Modales, notificaciones toast, tooltips, menús contextuales, paneles laterales. Todos necesitan salir del flujo de layout del padre.&lt;/p&gt;
&lt;h2 id="accesibilidad"&gt;Accesibilidad
&lt;/h2&gt;&lt;p&gt;Los portales deben manejar el foco correctamente: atrapar foco dentro del modal, cerrar con Escape, restaurar foco al cerrar. Combinar con la Popover API nativa cuando sea posible.&lt;/p&gt;</description></item><item><title>Redes en Docker: Comunicación entre contenedores</title><link>https://takao.blog/es/web/docker-networking/</link><pubDate>Tue, 27 Aug 2024 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/docker-networking/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/docker-networking-es.png" alt="Featured image of post Redes en Docker: Comunicación entre contenedores" /&gt;&lt;p&gt;Docker proporciona varios modos de red para la comunicación entre contenedores y con el exterior. Elegir el correcto es fundamental para la seguridad y el rendimiento.&lt;/p&gt;
&lt;h2 id="tipos-de-red"&gt;Tipos de red
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;bridge&lt;/code&gt; (default): red privada por host, comunicación entre contenedores via IP/nombre. &lt;code&gt;host&lt;/code&gt;: comparte la red del host. &lt;code&gt;overlay&lt;/code&gt;: múltiples hosts (Swarm). &lt;code&gt;none&lt;/code&gt;: sin red.&lt;/p&gt;
&lt;h2 id="dns-interno"&gt;DNS interno
&lt;/h2&gt;&lt;p&gt;Docker tiene DNS interno. Los contenedores en la misma red bridge personalizada se resuelven por nombre de contenedor. No es necesario conocer IPs.&lt;/p&gt;</description></item><item><title>CSS Popover API: Superposiciones nativas sin JavaScript</title><link>https://takao.blog/es/web/css-popover-api/</link><pubDate>Tue, 20 Aug 2024 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/css-popover-api/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/css-popover-api-es.png" alt="Featured image of post CSS Popover API: Superposiciones nativas sin JavaScript" /&gt;&lt;h2 id="introducción"&gt;Introducción
&lt;/h2&gt;&lt;p&gt;Construir tooltips, menús y modales requería JavaScript. La CSS Popover API proporciona una forma declarativa nativa con manejo de posición, toggle, foco y cierre.&lt;/p&gt;
&lt;h2 id="atributos-básicos"&gt;Atributos básicos
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;popover&lt;/code&gt; marca un elemento como superposición. &lt;code&gt;popovertarget&lt;/code&gt; vincula un botón al popover. Modos: &lt;code&gt;auto&lt;/code&gt; (cierre al hacer clic fuera o Escape) y &lt;code&gt;manual&lt;/code&gt; (cierre programático).&lt;/p&gt;
&lt;h2 id="api-toggle"&gt;API Toggle
&lt;/h2&gt;&lt;p&gt;Métodos: &lt;code&gt;showPopover()&lt;/code&gt;, &lt;code&gt;hidePopover()&lt;/code&gt;, &lt;code&gt;togglePopover()&lt;/code&gt;. Eventos: &lt;code&gt;beforetoggle&lt;/code&gt; y &lt;code&gt;toggle&lt;/code&gt; con &lt;code&gt;oldState&lt;/code&gt; y &lt;code&gt;newState&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="light-dismiss"&gt;Light dismiss
&lt;/h2&gt;&lt;p&gt;Los popovers auto se cierran al hacer clic fuera, presionar Escape o abrir otro popover.&lt;/p&gt;</description></item><item><title>Almacenamiento ZFS en Proxmox</title><link>https://takao.blog/es/web/proxmox-zfs-storage/</link><pubDate>Wed, 14 Aug 2024 00:00:00 +0000</pubDate><guid>https://takao.blog/es/web/proxmox-zfs-storage/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/proxmox-zfs-storage-es.png" alt="Featured image of post Almacenamiento ZFS en Proxmox" /&gt;&lt;p&gt;ZFS es el sistema de archivos recomendado para Proxmox. Ofrece integridad de datos, compresión, snapshots y facilidad de gestión.&lt;/p&gt;
&lt;h2 id="ventajas-de-zfs"&gt;Ventajas de ZFS
&lt;/h2&gt;&lt;p&gt;Checksums en todos los datos. Auto-reparación de errores. Compresión (lz4, zstd). Snapshots instantáneos. Deduplicación. Caché ARC/L2ARC.&lt;/p&gt;
&lt;h2 id="pools-y-datasets"&gt;Pools y datasets
&lt;/h2&gt;&lt;p&gt;Pool: grupo de discos con RAID-Z1, Z2, mirror. Dataset: unidad de almacenamiento con atributos independientes (compresión, cuota).&lt;/p&gt;
&lt;h2 id="rendimiento"&gt;Rendimiento
&lt;/h2&gt;&lt;p&gt;ARC (caché en RAM) mejora rendimiento de lectura. SLOG para escritura síncrona. L2ARC para caché SSD. Ajuste de recordsize.&lt;/p&gt;</description></item><item><title>Referencias de proyecto en TypeScript: Código base a escala</title><link>https://takao.blog/es/web/typescript-project-references/</link><pubDate>Tue, 13 Aug 2024 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/typescript-project-references/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/typescript-project-references-es.png" alt="Featured image of post Referencias de proyecto en TypeScript: Código base a escala" /&gt;&lt;p&gt;Project References permiten dividir un código base grande en proyectos más pequeños que dependen entre sí. Mejoran tiempos de compilación y habilitan compilación incremental.&lt;/p&gt;
&lt;h2 id="configuración"&gt;Configuración
&lt;/h2&gt;&lt;p&gt;Cada subproyecto tiene su &lt;code&gt;tsconfig.json&lt;/code&gt; con &lt;code&gt;composite: true&lt;/code&gt;. El proyecto raíz usa &lt;code&gt;references&lt;/code&gt; para apuntar a cada subproyecto.&lt;/p&gt;
&lt;h2 id="modo-build"&gt;Modo build
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;tsc --build&lt;/code&gt; compila proyectos en orden topológico. Solo recompila los que cambiaron. &lt;code&gt;tsc --build --force&lt;/code&gt; para reconstrucción completa.&lt;/p&gt;
&lt;h2 id="patrones-de-estructura"&gt;Patrones de estructura
&lt;/h2&gt;&lt;p&gt;Monolito modular: &lt;code&gt;packages/*/tsconfig.json&lt;/code&gt;. Separación cliente/servidor. Bibliotecas compartidas con sus propias referencias.&lt;/p&gt;</description></item><item><title>Logging en Node.js: Prácticas y herramientas</title><link>https://takao.blog/es/web/nodejs-logging/</link><pubDate>Tue, 06 Aug 2024 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/nodejs-logging/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/nodejs-logging-es.png" alt="Featured image of post Logging en Node.js: Prácticas y herramientas" /&gt;&lt;p&gt;El logging es esencial para depuración, monitoreo y análisis. Node.js ofrece &lt;code&gt;console.log&lt;/code&gt; pero las aplicaciones en producción necesitan más.&lt;/p&gt;
&lt;h2 id="niveles-de-log"&gt;Niveles de log
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;error&lt;/code&gt;, &lt;code&gt;warn&lt;/code&gt;, &lt;code&gt;info&lt;/code&gt;, &lt;code&gt;debug&lt;/code&gt;, &lt;code&gt;trace&lt;/code&gt;. Configura el nivel mínimo: en producción solo &lt;code&gt;info&lt;/code&gt; y superiores, en desarrollo también &lt;code&gt;debug&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="bibliotecas-populares"&gt;Bibliotecas populares
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;Pino&lt;/strong&gt;: rápido, JSON nativo, niveles, child loggers. &lt;strong&gt;Winston&lt;/strong&gt;: flexible, transports múltiples (archivo, consola, remoto). &lt;strong&gt;Bunyan&lt;/strong&gt;: JSON con soporte de streams.&lt;/p&gt;
&lt;h2 id="formato-json"&gt;Formato JSON
&lt;/h2&gt;&lt;p&gt;Los logs en JSON son parseables por herramientas de análisis (ELK, Datadog, Grafana). Incluye timestamp, nivel, mensaje, contexto y correlation ID.&lt;/p&gt;</description></item><item><title>Machine Learning en el navegador con TensorFlow.js y ONNX</title><link>https://takao.blog/es/web/ml-in-browser/</link><pubDate>Tue, 30 Jul 2024 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/ml-in-browser/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/ml-in-browser-es.png" alt="Featured image of post Machine Learning en el navegador con TensorFlow.js y ONNX" /&gt;&lt;p&gt;El ML en el navegador permite ejecutar modelos directamente en el cliente sin enviar datos al servidor. Privacidad, baja latencia y sin costos de infraestructura.&lt;/p&gt;
&lt;h2 id="tensorflowjs"&gt;TensorFlow.js
&lt;/h2&gt;&lt;p&gt;Ejecuta modelos TF en el navegador via WebGL o WebGPU. Soporta modelos pre-entrenados (MobileNet, COCO-SSD) y transfer learning.&lt;/p&gt;
&lt;h2 id="onnx-runtime-web"&gt;ONNX Runtime Web
&lt;/h2&gt;&lt;p&gt;Ejecuta modelos en formato ONNX en navegadores y Node.js. Soporta modelos PyTorch, TensorFlow, Scikit-learn exportados a ONNX.&lt;/p&gt;
&lt;h2 id="webgpu-y-wasm"&gt;WebGPU y WASM
&lt;/h2&gt;&lt;p&gt;WebGPU acelera inferencia con GPU. WASM para CPUs (WASM SIMD). Transformers.js para NLP (BERT, T5) directamente en el navegador.&lt;/p&gt;</description></item><item><title>Web Bluetooth API: Conexión con dispositivos BLE</title><link>https://takao.blog/es/web/web-bluetooth-api/</link><pubDate>Tue, 23 Jul 2024 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/web-bluetooth-api/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/web-bluetooth-api-es.png" alt="Featured image of post Web Bluetooth API: Conexión con dispositivos BLE" /&gt;&lt;p&gt;La Web Bluetooth API permite que aplicaciones web se comuniquen con dispositivos Bluetooth Low Energy (BLE) cercanos.&lt;/p&gt;
&lt;h2 id="cómo-funciona"&gt;Cómo funciona
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;navigator.bluetooth.requestDevice()&lt;/code&gt; muestra un selector de dispositivos. Requiere interacción del usuario (click). Solo HTTPS.&lt;/p&gt;
&lt;h2 id="servicios-y-características"&gt;Servicios y características
&lt;/h2&gt;&lt;p&gt;Los dispositivos BLE exponen servicios (UUIDs) con características (lectura, escritura, notificaciones). &lt;code&gt;getPrimaryService()&lt;/code&gt;, &lt;code&gt;getCharacteristic()&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="casos-de-uso"&gt;Casos de uso
&lt;/h2&gt;&lt;p&gt;Monitoreo de sensores (temperatura, ritmo cardíaco), IoT, balizas, dispositivos de fitness, impresoras, controles remotos.&lt;/p&gt;
&lt;h2 id="limitaciones"&gt;Limitaciones
&lt;/h2&gt;&lt;p&gt;Solo Chrome/Edge (Chromium). El usuario debe seleccionar el dispositivo manualmente. No hay escaneo en segundo plano. Desconexión al cerrar la página.&lt;/p&gt;</description></item><item><title>Seguridad en contenedores: Mejores prácticas</title><link>https://takao.blog/es/web/container-security/</link><pubDate>Tue, 16 Jul 2024 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/container-security/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/container-security-es.png" alt="Featured image of post Seguridad en contenedores: Mejores prácticas" /&gt;&lt;p&gt;La seguridad en contenedores abarca desde la imagen base hasta la configuración de runtime. Un contenedor inseguro compromete todo el host.&lt;/p&gt;
&lt;h2 id="imágenes-base"&gt;Imágenes base
&lt;/h2&gt;&lt;p&gt;Usa imágenes oficiales y actualizadas. Prefiere &lt;code&gt;-slim&lt;/code&gt;, &lt;code&gt;-alpine&lt;/code&gt; o distroless. Escanea vulnerabilidades con &lt;code&gt;docker scout&lt;/code&gt; o &lt;code&gt;trivy&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="principio-de-mínimos-privilegios"&gt;Principio de mínimos privilegios
&lt;/h2&gt;&lt;p&gt;No ejecutes como root: &lt;code&gt;USER nobody&lt;/code&gt; en Dockerfile. Capacidades de Linux mínimas: &lt;code&gt;--cap-drop ALL --cap-add NEEDED&lt;/code&gt;. Modo de solo lectura: &lt;code&gt;--read-only&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="secrets-y-variables"&gt;Secrets y variables
&lt;/h2&gt;&lt;p&gt;Nunca incluyas secretos en la imagen. Usa &lt;code&gt;--secret&lt;/code&gt; de BuildKit para construir, y variables de entorno o montajes de secretos para ejecutar.&lt;/p&gt;</description></item><item><title>Module Federation: Micro-frontends con Webpack 5</title><link>https://takao.blog/es/web/module-federation/</link><pubDate>Tue, 09 Jul 2024 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/module-federation/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/module-federation-es.png" alt="Featured image of post Module Federation: Micro-frontends con Webpack 5" /&gt;&lt;p&gt;Module Federation permite cargar código JavaScript desde otra aplicación en tiempo de ejecución. Es la base de los micro-frontends modernos.&lt;/p&gt;
&lt;h2 id="cómo-funciona"&gt;Cómo funciona
&lt;/h2&gt;&lt;p&gt;Una aplicación expone módulos via &lt;code&gt;ModuleFederationPlugin&lt;/code&gt;. Otra aplicación los consume como si fueran locales. Los módulos compartidos se cargan una sola vez.&lt;/p&gt;
&lt;h2 id="configuración-expósitor"&gt;Configuración expósitor
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;ModuleFederationPlugin&lt;/span&gt;({
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;app1&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;exposes&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; { &lt;span style="color:#e6db74"&gt;&amp;#39;./Button&amp;#39;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;./src/Button&amp;#39;&lt;/span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;shared&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; { &lt;span style="color:#a6e22e"&gt;react&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; { &lt;span style="color:#a6e22e"&gt;singleton&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt; } }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;})
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="configuración-consumidor"&gt;Configuración consumidor
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;remotes: { app1: 'app1@http://...' }&lt;/code&gt;. Importa &lt;code&gt;import('app1/Button')&lt;/code&gt;. React y otras librerías compartidas como singletons.&lt;/p&gt;</description></item><item><title>Optimización de imágenes en 2024: Formatos, carga y mejores prácticas</title><link>https://takao.blog/es/web/image-optimization-2024/</link><pubDate>Tue, 02 Jul 2024 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/image-optimization-2024/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/image-optimization-2024-es.png" alt="Featured image of post Optimización de imágenes en 2024: Formatos, carga y mejores prácticas" /&gt;&lt;p&gt;Las imágenes son el recurso más pesado en la mayoría de sitios web. Optimizarlas mejora drásticamente LCP y la experiencia general.&lt;/p&gt;
&lt;h2 id="formatos-modernos"&gt;Formatos modernos
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;WebP&lt;/strong&gt;: soporte universal, compresión 30% mejor que JPEG. &lt;strong&gt;AVIF&lt;/strong&gt;: hasta 50% mejor que JPEG, pero mayor coste de codificación. &lt;strong&gt;JPEG XL&lt;/strong&gt;: prometedor pero soporte limitado.&lt;/p&gt;
&lt;h2 id="imágenes-responsive"&gt;Imágenes responsive
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;&amp;lt;picture&amp;gt;&lt;/code&gt; con &lt;code&gt;&amp;lt;source&amp;gt;&lt;/code&gt; para formatos múltiples. &lt;code&gt;srcset&lt;/code&gt; y &lt;code&gt;sizes&lt;/code&gt; para diferentes resoluciones. El navegador selecciona la imagen óptima según la pantalla.&lt;/p&gt;</description></item><item><title>Animaciones CSS basadas en scroll: El futuro de los efectos de desplazamiento</title><link>https://takao.blog/es/web/css-scroll-driven-animations/</link><pubDate>Tue, 25 Jun 2024 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/css-scroll-driven-animations/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/css-scroll-driven-animations-es.png" alt="Featured image of post Animaciones CSS basadas en scroll: El futuro de los efectos de desplazamiento" /&gt;&lt;h2 id="el-problema-de-los-eventos-scroll-en-javascript"&gt;El problema de los eventos scroll en JavaScript
&lt;/h2&gt;&lt;p&gt;Los efectos basados en scroll tradicionalmente usaban listeners de JavaScript en el hilo principal, causando jank y mala experiencia. CSS Scroll-Driven Animations mueven el tracking al compositor thread.&lt;/p&gt;
&lt;h2 id="conceptos-clave"&gt;Conceptos clave
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;scroll-timeline&lt;/code&gt; vincula una animación a la posición de scroll. &lt;code&gt;view-timeline&lt;/code&gt; la vincula a la visibilidad de un elemento. &lt;code&gt;animation-timeline&lt;/code&gt; asigna una animación a un timeline.&lt;/p&gt;
&lt;h2 id="scroll-progress-timelines"&gt;Scroll Progress Timelines
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#a6e22e"&gt;progress-bar&lt;/span&gt; { &lt;span style="color:#66d9ef"&gt;animation&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;fill&lt;/span&gt;&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;progress&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;linear&lt;/span&gt;; &lt;span style="color:#66d9ef"&gt;animation-timeline&lt;/span&gt;: &lt;span style="color:#a6e22e"&gt;scroll&lt;/span&gt;(); }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;La función &lt;code&gt;scroll()&lt;/code&gt; crea un timeline anónimo en el contenedor de scroll más cercano.&lt;/p&gt;</description></item><item><title>Vaultwarden y claves SSH</title><link>https://takao.blog/es/web/vaultwarden-ssh-key/</link><pubDate>Thu, 20 Jun 2024 00:00:00 +0000</pubDate><guid>https://takao.blog/es/web/vaultwarden-ssh-key/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/vaultwarden-ssh-key-es.png" alt="Featured image of post Vaultwarden y claves SSH" /&gt;&lt;p&gt;Vaultwarden puede almacenar claves SSH de forma segura. Con la extensión SSH Agent de Bitwarden, las claves se cargan bajo demanda.&lt;/p&gt;
&lt;h2 id="almacenamiento-de-claves"&gt;Almacenamiento de claves
&lt;/h2&gt;&lt;p&gt;Las claves SSH se guardan como notas seguras en Vaultwarden. Cifradas con AES-256. Acceso protegido con Master Password y 2FA.&lt;/p&gt;
&lt;h2 id="ssh-agent-browser-extension"&gt;SSH Agent (browser extension)
&lt;/h2&gt;&lt;p&gt;La extensión Bitwarden ofrece SSH Agent. Carga claves privadas en el agente SSH del sistema. Las claves no se almacenan en disco.&lt;/p&gt;</description></item><item><title>Middleware en Next.js: Redirects, rewrites y protección</title><link>https://takao.blog/es/web/nextjs-middleware/</link><pubDate>Tue, 18 Jun 2024 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/nextjs-middleware/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/nextjs-middleware-es.png" alt="Featured image of post Middleware en Next.js: Redirects, rewrites y protección" /&gt;&lt;p&gt;El Middleware de Next.js se ejecuta antes de cada solicitud, permitiendo redirecciones, reescrituras, autenticación y geolocalización en el edge.&lt;/p&gt;
&lt;h2 id="creación"&gt;Creación
&lt;/h2&gt;&lt;p&gt;Archivo &lt;code&gt;middleware.ts&lt;/code&gt; en la raíz del proyecto. Exporta &lt;code&gt;middleware(request)&lt;/code&gt; que retorna &lt;code&gt;NextResponse.next()&lt;/code&gt;, &lt;code&gt;redirect()&lt;/code&gt; o &lt;code&gt;rewrite()&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="matcher"&gt;Matcher
&lt;/h2&gt;&lt;p&gt;Configura las rutas donde se ejecuta el middleware: &lt;code&gt;export const config = { matcher: ['/dashboard/:path*'] }&lt;/code&gt;. Optimizado para ejecución en edge.&lt;/p&gt;
&lt;h2 id="casos-de-uso"&gt;Casos de uso
&lt;/h2&gt;&lt;p&gt;Autenticación (redirigir a login), localización (detectar idioma), A/B testing (cookies), geobloqueo, mantenimiento (rewrite a página de mantenimiento).&lt;/p&gt;</description></item><item><title>CSS @layer: Gestión de la cascada con arquitectura de capas</title><link>https://takao.blog/es/web/css-layer-architecture/</link><pubDate>Tue, 11 Jun 2024 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/css-layer-architecture/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/css-layer-architecture-es.png" alt="Featured image of post CSS @layer: Gestión de la cascada con arquitectura de capas" /&gt;&lt;p&gt;&lt;code&gt;@layer&lt;/code&gt; da control explícito sobre el orden de la cascada, independientemente de la especificidad o el orden de las fuentes.&lt;/p&gt;
&lt;h2 id="el-problema-de-la-cascada-antes-de-layer"&gt;El problema de la cascada antes de @layer
&lt;/h2&gt;&lt;p&gt;Antes, la gestión de la cascada se basaba en convenciones (BEM, SMACSS, ITCSS) que no eran aplicadas por el navegador.&lt;/p&gt;
&lt;h2 id="cómo-funciona-layer"&gt;Cómo funciona @layer
&lt;/h2&gt;&lt;p&gt;Agrupa estilos en capas con nombre y define su precedencia. Las capas posteriores sobrescriben a las anteriores, sin importar la especificidad.&lt;/p&gt;</description></item><item><title>API Proxy y Reflect de JavaScript: Patrones de metaprogramación</title><link>https://takao.blog/es/web/js-proxy-reflect/</link><pubDate>Tue, 04 Jun 2024 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/js-proxy-reflect/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/js-proxy-reflect-es.png" alt="Featured image of post API Proxy y Reflect de JavaScript: Patrones de metaprogramación" /&gt;&lt;p&gt;&lt;code&gt;Proxy&lt;/code&gt; y &lt;code&gt;Reflect&lt;/code&gt; permiten interceptar y personalizar operaciones fundamentales en objetos: acceso a propiedades, asignación, enumeración, invocación de funciones y llamadas a constructores.&lt;/p&gt;
&lt;h2 id="los-13-traps-de-proxy"&gt;Los 13 traps de Proxy
&lt;/h2&gt;&lt;p&gt;Desde &lt;code&gt;get&lt;/code&gt;/&lt;code&gt;set&lt;/code&gt; (lectura/escritura) hasta &lt;code&gt;apply&lt;/code&gt;/&lt;code&gt;construct&lt;/code&gt; (llamadas de función/constructor). Cada trap debe cumplir invariantes.&lt;/p&gt;
&lt;h2 id="api-reflect"&gt;API Reflect
&lt;/h2&gt;&lt;p&gt;Los métodos de &lt;code&gt;Reflect&lt;/code&gt; reflejan cada trap de Proxy. Usar &lt;code&gt;Reflect&lt;/code&gt; dentro de traps asegura propagación correcta del argumento &lt;code&gt;receiver&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="validación-e-integridad"&gt;Validación e integridad
&lt;/h2&gt;&lt;p&gt;El trap &lt;code&gt;set&lt;/code&gt; puede imponer restricciones de esquema. Proxy de solo lectura bloquea todos los traps de mutación.&lt;/p&gt;</description></item><item><title>Herramientas de revisión de código con IA</title><link>https://takao.blog/es/web/ai-code-review-tools/</link><pubDate>Tue, 28 May 2024 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/ai-code-review-tools/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/ai-code-review-tools-es.png" alt="Featured image of post Herramientas de revisión de código con IA" /&gt;&lt;p&gt;Las herramientas de IA para code review automatizan la detección de bugs, problemas de seguridad y malas prácticas antes de la revisión humana.&lt;/p&gt;
&lt;h2 id="coderabbit"&gt;CodeRabbit
&lt;/h2&gt;&lt;p&gt;Revisa PRs automáticamente. Comentarios contextuales en línea. Detecta bugs, vulnerabilidades y mejoras de rendimiento.&lt;/p&gt;
&lt;h2 id="github-copilot-code-review"&gt;GitHub Copilot Code Review
&lt;/h2&gt;&lt;p&gt;Integrado en GitHub. Revisión de PRs con sugerencias. Detecta problemas de calidad y seguridad.&lt;/p&gt;
&lt;h2 id="códacy-sonarcloud"&gt;Códacy, SonarCloud
&lt;/h2&gt;&lt;p&gt;Análisis estático con IA. Mantienen calidad del código. Gatekeeping en CI: no mergear si baja la calidad.&lt;/p&gt;</description></item><item><title>Contenedores LXC en Proxmox</title><link>https://takao.blog/es/web/proxmox-lxc-containers/</link><pubDate>Wed, 22 May 2024 00:00:00 +0000</pubDate><guid>https://takao.blog/es/web/proxmox-lxc-containers/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/proxmox-lxc-containers-es.png" alt="Featured image of post Contenedores LXC en Proxmox" /&gt;&lt;p&gt;Los contenedores LXC en Proxmox ofrecen virtualización a nivel de SO con menor overhead que KVM. Ideales para servicios ligeros.&lt;/p&gt;
&lt;h2 id="diferencias-con-vms"&gt;Diferencias con VMs
&lt;/h2&gt;&lt;p&gt;LXC comparte el kernel del host. Sin hypervisor. Arranque en segundos. Menor uso de memoria. Limitado a sistemas Linux.&lt;/p&gt;
&lt;h2 id="templates"&gt;Templates
&lt;/h2&gt;&lt;p&gt;Descarga templates desde repositorio Proxmox. Alpine, Ubuntu, CentOS, Debian. Creación de templates personalizados.&lt;/p&gt;
&lt;h2 id="configuración"&gt;Configuración
&lt;/h2&gt;&lt;p&gt;CPU, memoria, swap, discos (montaje directo o ZFS). Privilegiados vs no privilegiados. Mapeo de UID/GID para seguridad.&lt;/p&gt;</description></item><item><title>Squash Merge: Limpieza de historial en GitHub</title><link>https://takao.blog/es/web/git-squash-merge/</link><pubDate>Tue, 21 May 2024 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/git-squash-merge/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/git-squash-merge-es.png" alt="Featured image of post Squash Merge: Limpieza de historial en GitHub" /&gt;&lt;p&gt;Squash merge combina todos los commits de una rama en un solo commit al mergear. Produce un historial limpio sin commits de WIP ni experimentales.&lt;/p&gt;
&lt;h2 id="cómo-funciona"&gt;Cómo funciona
&lt;/h2&gt;&lt;p&gt;GitHub (y GitLab) ofrecen squash merge como opción al fusionar PRs. Todos los commits de la rama se comprimen en uno con un mensaje nuevo.&lt;/p&gt;
&lt;h2 id="beneficios"&gt;Beneficios
&lt;/h2&gt;&lt;p&gt;Historial lineal y legible. Cada commit en main representa una característica completa. Fácil revertir características enteras con un solo revert.&lt;/p&gt;</description></item><item><title>WebSockets: Comunicación en tiempo real</title><link>https://takao.blog/es/web/websocket-applications/</link><pubDate>Tue, 14 May 2024 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/websocket-applications/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/websocket-applications-es.png" alt="Featured image of post WebSockets: Comunicación en tiempo real" /&gt;&lt;p&gt;WebSocket proporciona un canal de comunicación bidireccional full-duplex sobre una sola conexión TCP. Ideal para aplicaciones en tiempo real.&lt;/p&gt;
&lt;h2 id="diferencias-con-http"&gt;Diferencias con HTTP
&lt;/h2&gt;&lt;p&gt;HTTP es request-response. WebSocket es persistente y bidireccional. Menos overhead (sin headers en cada mensaje). Latencia reducida.&lt;/p&gt;
&lt;h2 id="api-javascript"&gt;API JavaScript
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;ws&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;WebSocket&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;wss://server.com&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;ws&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;onmessage&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;event&lt;/span&gt;) =&amp;gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;event&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;data&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;ws&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;send&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;JSON&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;stringify&lt;/span&gt;({ &lt;span style="color:#a6e22e"&gt;type&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;chat&amp;#39;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;text&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;Hola&amp;#39;&lt;/span&gt; }));
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="casos-de-uso"&gt;Casos de uso
&lt;/h2&gt;&lt;p&gt;Chat, notificaciones en vivo, colaboración en tiempo real (Google Docs), juegos multijugador, datos financieros, paneles de monitoreo.&lt;/p&gt;
&lt;h2 id="consideraciones"&gt;Consideraciones
&lt;/h2&gt;&lt;p&gt;Reconexión automática. Heartbeats/pings para mantener conexión. Escalado: sticky sessions o pub/sub (Redis). Seguridad: WSS (WebSocket Secure).&lt;/p&gt;</description></item><item><title>Rate Limiting en APIs: Estrategias y mejores prácticas</title><link>https://takao.blog/es/web/api-rate-limiting/</link><pubDate>Tue, 07 May 2024 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/api-rate-limiting/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/api-rate-limiting-es.png" alt="Featured image of post Rate Limiting en APIs: Estrategias y mejores prácticas" /&gt;&lt;p&gt;Rate limiting protege las APIs contra abusos limitando el número de solicitudes en un período de tiempo. Esencial para seguridad y estabilidad.&lt;/p&gt;
&lt;h2 id="estrategias-comunes"&gt;Estrategias comunes
&lt;/h2&gt;&lt;p&gt;Fixed Window: cuenta en ventanas de tiempo fijas. Sliding Window: ventana deslizante más precisa. Token Bucket: tokens que se regeneran. Leaky Bucket: cola de velocidad fija.&lt;/p&gt;
&lt;h2 id="cabeceras-de-respuesta"&gt;Cabeceras de respuesta
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;X-RateLimit-Limit&lt;/code&gt;, &lt;code&gt;X-RateLimit-Remaining&lt;/code&gt;, &lt;code&gt;X-RateLimit-Reset&lt;/code&gt;. El cliente puede ajustar su comportamiento. HTTP 429 Too Many Requests con &lt;code&gt;Retry-After&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="implementación"&gt;Implementación
&lt;/h2&gt;&lt;p&gt;Redis para rate limiting distribuido. Almacenamiento en memoria para single-server. Middleware en Express, FastAPI, Cloudflare Workers.&lt;/p&gt;</description></item><item><title>Ingeniería de prompts para LLMs</title><link>https://takao.blog/es/web/llm-prompt-engineering/</link><pubDate>Tue, 30 Apr 2024 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/llm-prompt-engineering/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/llm-prompt-engineering-es.png" alt="Featured image of post Ingeniería de prompts para LLMs" /&gt;&lt;p&gt;La ingeniería de prompts es el arte de diseñar instrucciones efectivas para modelos de lenguaje. Un buen prompt obtiene respuestas precisas y útiles.&lt;/p&gt;
&lt;h2 id="principios-básicos"&gt;Principios básicos
&lt;/h2&gt;&lt;p&gt;Sé específico. Proporciona contexto. Define el formato de salida. Usa ejemplos (few-shot). Divide tareas complejas en pasos (chain-of-thought).&lt;/p&gt;
&lt;h2 id="técnicas-avanzadas"&gt;Técnicas avanzadas
&lt;/h2&gt;&lt;p&gt;Role prompting: &amp;ldquo;Eres un experto en React&amp;rdquo;. System prompts para definir comportamiento. Output formatting: JSON, markdown, código.&lt;/p&gt;
&lt;h2 id="iteración"&gt;Iteración
&lt;/h2&gt;&lt;p&gt;Prueba, evalúa, refina. Ajusta temperatura (0 para determinista, &amp;gt;0 para creativo). Mide la calidad con tests automatizados.&lt;/p&gt;</description></item><item><title>Worker Threads en Node.js: Paralelismo real</title><link>https://takao.blog/es/web/nodejs-worker-threads/</link><pubDate>Tue, 23 Apr 2024 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/nodejs-worker-threads/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/nodejs-worker-threads-es.png" alt="Featured image of post Worker Threads en Node.js: Paralelismo real" /&gt;&lt;p&gt;Worker Threads permite ejecutar JavaScript en múltiples hilos, descargando tareas CPU-intensive del event loop principal.&lt;/p&gt;
&lt;h2 id="cuándo-usar-workers"&gt;Cuándo usar workers
&lt;/h2&gt;&lt;p&gt;Cálculos matemáticos pesados, procesamiento de imágenes, parsing de archivos grandes, compresión, cifrado. No para operaciones I/O (ya son asíncronas).&lt;/p&gt;
&lt;h2 id="api-básica"&gt;API básica
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; { &lt;span style="color:#a6e22e"&gt;Worker&lt;/span&gt; } &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;worker_threads&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;worker&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Worker&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;./worker.js&amp;#39;&lt;/span&gt;, { &lt;span style="color:#a6e22e"&gt;workerData&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;data&lt;/span&gt; });
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;worker&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;on&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;message&amp;#39;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;result&lt;/span&gt; =&amp;gt; {});
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="comunicación"&gt;Comunicación
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;postMessage&lt;/code&gt;: copia estructurada (serializable). SharedArrayBuffer: memoria compartida. &lt;code&gt;parentPort.postMessage&lt;/code&gt; desde el worker. Atomics para sincronización.&lt;/p&gt;
&lt;h2 id="pool-de-workers"&gt;Pool de workers
&lt;/h2&gt;&lt;p&gt;Crear workers por tarea tiene overhead. Usa &lt;code&gt;workerpool&lt;/code&gt; o &lt;code&gt;piscina&lt;/code&gt; para pooling. Mantén un número fijo de workers (CPU cores - 1).&lt;/p&gt;</description></item><item><title>GitHub Actions: Técnicas avanzadas</title><link>https://takao.blog/es/web/github-actions-advanced/</link><pubDate>Tue, 16 Apr 2024 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/github-actions-advanced/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/github-actions-advanced-es.png" alt="Featured image of post GitHub Actions: Técnicas avanzadas" /&gt;&lt;p&gt;Más allá de los workflows básicos, GitHub Actions ofrece matrices, reutilización, entornos y despliegues avanzados.&lt;/p&gt;
&lt;h2 id="build-matrix"&gt;Build Matrix
&lt;/h2&gt;&lt;p&gt;Ejecuta el mismo job en múltiples configuraciones: SO, versión de Node, dependencias. Acelera la retroalimentación de compatibilidad.&lt;/p&gt;
&lt;h2 id="reusable-workflows"&gt;Reusable Workflows
&lt;/h2&gt;&lt;p&gt;Define un workflow en &lt;code&gt;.github/workflows/reusable.yml&lt;/code&gt; con &lt;code&gt;workflow_call&lt;/code&gt;. Reutiliza en otros workflows con &lt;code&gt;uses: ./&lt;/code&gt;. Reduce duplicación.&lt;/p&gt;
&lt;h2 id="entornos-y-approval-gates"&gt;Entornos y approval gates
&lt;/h2&gt;&lt;p&gt;Entornos con reviewers requeridos antes de desplegar a producción. Variables de entorno y secretos por ambiente. Protección de ramas.&lt;/p&gt;</description></item><item><title>Propiedades personalizadas CSS: Patrones estratégicos para estilos escalables</title><link>https://takao.blog/es/web/css-custom-properties/</link><pubDate>Tue, 09 Apr 2024 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/css-custom-properties/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/css-custom-properties-es.png" alt="Featured image of post Propiedades personalizadas CSS: Patrones estratégicos para estilos escalables" /&gt;&lt;p&gt;CSS Custom Properties (variables CSS) han cambiado fundamentalmente cómo escribimos y mantenemos hojas de estilo. A diferencia de las variables de preprocesadores, son dinámicas, participan en la cascada y la herencia.&lt;/p&gt;
&lt;h2 id="gestión-de-design-tokens"&gt;Gestión de design tokens
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;:&lt;span style="color:#a6e22e"&gt;root&lt;/span&gt; { --color-primary-500: &lt;span style="color:#ae81ff"&gt;#3b82f6&lt;/span&gt;; --space-md: &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;rem&lt;/span&gt;; --font-sans: &lt;span style="color:#e6db74"&gt;&amp;#34;Inter&amp;#34;&lt;/span&gt;, system-ui, &lt;span style="color:#66d9ef"&gt;sans-serif&lt;/span&gt;; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Usa nomenclatura BEM-inspirada: &lt;code&gt;--bloque__elemento--modificador&lt;/code&gt; para tokens de componente y &lt;code&gt;--categoria-propiedad-variante&lt;/code&gt; para globales.&lt;/p&gt;
&lt;h2 id="cambio-de-tema"&gt;Cambio de tema
&lt;/h2&gt;&lt;p&gt;Define tema claro en &lt;code&gt;:root&lt;/code&gt; y sobreescribe en &lt;code&gt;[data-theme=&amp;quot;dark&amp;quot;]&lt;/code&gt;. Añade &lt;code&gt;prefers-color-scheme&lt;/code&gt; para respetar la preferencia del sistema.&lt;/p&gt;</description></item><item><title>WebAuthn y Passkeys: Autenticación sin contraseñas</title><link>https://takao.blog/es/web/webauthn-passkeys/</link><pubDate>Tue, 02 Apr 2024 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/webauthn-passkeys/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/webauthn-passkeys-es.png" alt="Featured image of post WebAuthn y Passkeys: Autenticación sin contraseñas" /&gt;&lt;p&gt;WebAuthn es un estándar del W3C para autenticación sin contraseñas usando criptografía de clave pública. Passkeys son la implementación práctica.&lt;/p&gt;
&lt;h2 id="cómo-funciona"&gt;Cómo funciona
&lt;/h2&gt;&lt;p&gt;El navegador genera un par de claves (pública/privada). La clave privada nunca sale del dispositivo. La autenticación usa desafíos firmados.&lt;/p&gt;
&lt;h2 id="passkeys"&gt;Passkeys
&lt;/h2&gt;&lt;p&gt;Sincronización entre dispositivos via iCloud Keychain, Google Password Manager, 1Password. Reemplazan contraseñas tradicionales. Soporte en iOS, Android, Windows, macOS.&lt;/p&gt;
&lt;h2 id="registro-y-autenticación"&gt;Registro y autenticación
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;navigator.credentials.create()&lt;/code&gt; para registro. &lt;code&gt;navigator.credentials.get()&lt;/code&gt; para autenticación. Biometría (TouchID, FaceID) o PIN como verificación local.&lt;/p&gt;</description></item><item><title>Optimización de imágenes con Next.js Image</title><link>https://takao.blog/es/web/nextjs-image-optimization/</link><pubDate>Tue, 26 Mar 2024 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/nextjs-image-optimization/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/nextjs-image-optimization-es.png" alt="Featured image of post Optimización de imágenes con Next.js Image" /&gt;&lt;p&gt;Next.js Image component optimiza imágenes automáticamente: formatos modernos (WebP, AVIF), lazy loading, y dimensiones responsive.&lt;/p&gt;
&lt;h2 id="nextimage"&gt;next/image
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-jsx" data-lang="jsx"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Image&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;from&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;next/image&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;Image&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;src&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;/hero.jpg&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;width&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;{&lt;span style="color:#ae81ff"&gt;1200&lt;/span&gt;} &lt;span style="color:#a6e22e"&gt;height&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;{&lt;span style="color:#ae81ff"&gt;600&lt;/span&gt;} &lt;span style="color:#a6e22e"&gt;alt&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;Hero&amp;#34;&lt;/span&gt; /&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Optimización en tiempo de build o bajo demanda (servidor de optimización).&lt;/p&gt;
&lt;h2 id="formatos-y-calidad"&gt;Formatos y calidad
&lt;/h2&gt;&lt;p&gt;Next.js sirve WebP o AVIF si el navegador lo soporta. &lt;code&gt;quality&lt;/code&gt; (1-100, default 75). &lt;code&gt;sizes&lt;/code&gt; para imágenes responsive. &lt;code&gt;priority&lt;/code&gt; para LCP.&lt;/p&gt;
&lt;h2 id="remote-patterns"&gt;Remote patterns
&lt;/h2&gt;&lt;p&gt;Configura &lt;code&gt;remotePatterns&lt;/code&gt; en next.config.js para permitir imágenes de dominios externos. Protege contra abusos del optimizador.&lt;/p&gt;</description></item><item><title>Gestión de estado en React 2024: Context, Zustand, Jotai y más</title><link>https://takao.blog/es/web/react-state-management-2024/</link><pubDate>Tue, 19 Mar 2024 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/react-state-management-2024/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/react-state-management-2024-es.png" alt="Featured image of post Gestión de estado en React 2024: Context, Zustand, Jotai y más" /&gt;&lt;p&gt;La gestión de estado en React ha evolucionado. Además de useState/useReducer, existen soluciones para estado global, servidor y URL.&lt;/p&gt;
&lt;h2 id="estado-local-usestate-y-usereducer"&gt;Estado local: useState y useReducer
&lt;/h2&gt;&lt;p&gt;useState para estado simple. useReducer para lógica compleja con múltiples transiciones de estado. Para la mayoría de componentes, useState es suficiente.&lt;/p&gt;
&lt;h2 id="estado-global-context-api"&gt;Estado global: Context API
&lt;/h2&gt;&lt;p&gt;React.createContext + useContext permite estado compartido sin prop drilling. Limitado a árbol de componentes. No ideal para estado que cambia frecuentemente (causa re-renderizados masivos).&lt;/p&gt;</description></item><item><title>Instalación de Vaultwarden para gestión de contraseñas</title><link>https://takao.blog/es/web/vaultwarden-install/</link><pubDate>Fri, 15 Mar 2024 00:00:00 +0000</pubDate><guid>https://takao.blog/es/web/vaultwarden-install/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/vaultwarden-install-es.png" alt="Featured image of post Instalación de Vaultwarden para gestión de contraseñas" /&gt;&lt;p&gt;Vaultwarden es una implementación ligera del servidor Bitwarden en Rust. Auto-hospeda tu gestor de contraseñas con mínimos recursos.&lt;/p&gt;
&lt;h2 id="instalación-con-docker"&gt;Instalación con Docker
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;docker run -d --name vaultwarden &lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; -v /vw-data/:/data/ &lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; -p 80:80 &lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; vaultwarden/server:latest
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="configuración"&gt;Configuración
&lt;/h2&gt;&lt;p&gt;Variables: &lt;code&gt;DOMAIN&lt;/code&gt;, &lt;code&gt;SIGNUPS_ALLOWED&lt;/code&gt;, &lt;code&gt;SMTP_*&lt;/code&gt;. Cifrado de base de datos con &lt;code&gt;DATABASE_URL&lt;/code&gt;. Admin token para panel de administración.&lt;/p&gt;
&lt;h2 id="respaldo"&gt;Respaldo
&lt;/h2&gt;&lt;p&gt;Backup periódico del directorio &lt;code&gt;/data/&lt;/code&gt;. Contiene la base de datos SQLite, archivos adjuntos y claves. Restauración simple reemplazando el directorio.&lt;/p&gt;</description></item><item><title>Novedades de ES2024 en JavaScript</title><link>https://takao.blog/es/web/es2024-new-features/</link><pubDate>Tue, 12 Mar 2024 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/es2024-new-features/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/es2024-new-features-es.png" alt="Featured image of post Novedades de ES2024 en JavaScript" /&gt;&lt;p&gt;ES2024 (ES15) introduce nuevas funcionalidades al lenguaje, centradas en async, arrays y gestión de datos.&lt;/p&gt;
&lt;h2 id="promisewithresolvers"&gt;Promise.withResolvers()
&lt;/h2&gt;&lt;p&gt;Crea una promesa con sus funciones resolve y reject expuestas externamente. Útil para promisificar APIs callback sin anidar constructores.&lt;/p&gt;
&lt;h2 id="array-grouping"&gt;Array Grouping
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;Object.groupBy()&lt;/code&gt; y &lt;code&gt;Map.groupBy()&lt;/code&gt; agrupan elementos de un array según una función callback. Reemplaza implementaciones manuales con reduce.&lt;/p&gt;
&lt;h2 id="well-formed-unicode-strings"&gt;Well-formed Unicode Strings
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;String.prototype.isWellFormed()&lt;/code&gt; y &lt;code&gt;toWellFormed()&lt;/code&gt; para manejar cadenas Unicode mal formadas. Previene errores en APIs que requieren Unicode válido.&lt;/p&gt;</description></item><item><title>Restricciones genéricas en TypeScript: Construyendo APIs type-safe</title><link>https://takao.blog/es/web/typescript-generic-constraints/</link><pubDate>Tue, 05 Mar 2024 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/typescript-generic-constraints/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/typescript-generic-constraints-es.png" alt="Featured image of post Restricciones genéricas en TypeScript: Construyendo APIs type-safe" /&gt;&lt;p&gt;Los genéricos permiten código reutilizable type-safe. La palabra clave &lt;code&gt;extends&lt;/code&gt; restringe parámetros de tipo a formas con propiedades específicas.&lt;/p&gt;
&lt;h2 id="la-restricción-extends"&gt;La restricción extends
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;function getProperty&amp;lt;T, K extends keyof T&amp;gt;(obj: T, key: K): T[K]&lt;/code&gt; garantiza que &lt;code&gt;key&lt;/code&gt; sea una propiedad válida de &lt;code&gt;obj&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="conditional-types"&gt;Conditional Types
&lt;/h2&gt;&lt;p&gt;Usan &lt;code&gt;extends&lt;/code&gt; para verificar relaciones de tipo: &lt;code&gt;type IsString&amp;lt;T&amp;gt; = T extends string ? true : false;&lt;/code&gt;&lt;/p&gt;
&lt;h2 id="mapped-types-con-keyof"&gt;Mapped Types con keyof
&lt;/h2&gt;&lt;p&gt;Transforman cada propiedad de un tipo existente. &lt;code&gt;Partial&amp;lt;T&amp;gt;&lt;/code&gt;, &lt;code&gt;Required&amp;lt;T&amp;gt;&lt;/code&gt;, &lt;code&gt;Readonly&amp;lt;T&amp;gt;&lt;/code&gt;, &lt;code&gt;Pick&amp;lt;T, K&amp;gt;&lt;/code&gt;. Desde TS 4.1, remapeo de claves con template literal types.&lt;/p&gt;</description></item><item><title>ESLint Flat Config: La nueva configuración</title><link>https://takao.blog/es/web/eslint-flat-config/</link><pubDate>Mon, 26 Feb 2024 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/eslint-flat-config/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/eslint-flat-config-es.png" alt="Featured image of post ESLint Flat Config: La nueva configuración" /&gt;&lt;p&gt;ESLint Flat Config (v9+) reemplaza el formato jerárquico .eslintrc con un sistema de configuración plano basado en arrays de objetos.&lt;/p&gt;
&lt;h2 id="diferencias-clave"&gt;Diferencias clave
&lt;/h2&gt;&lt;p&gt;Un solo archivo &lt;code&gt;eslint.config.js&lt;/code&gt;. Sin herencia de configuraciones anidadas. Las reglas se evalúan en orden. Adiós a &lt;code&gt;.eslintrc&lt;/code&gt;, &lt;code&gt;extends&lt;/code&gt;, &lt;code&gt;overrides&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="sintaxis"&gt;Sintaxis
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;export&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;default&lt;/span&gt; [
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; { &lt;span style="color:#a6e22e"&gt;rules&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; { &lt;span style="color:#e6db74"&gt;&amp;#39;no-unused-vars&amp;#39;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;error&amp;#39;&lt;/span&gt; } },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; { &lt;span style="color:#a6e22e"&gt;files&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; [&lt;span style="color:#e6db74"&gt;&amp;#39;**/*.ts&amp;#39;&lt;/span&gt;], &lt;span style="color:#a6e22e"&gt;rules&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; { &lt;span style="color:#e6db74"&gt;&amp;#39;@typescript-eslint/no-explicit-any&amp;#39;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;error&amp;#39;&lt;/span&gt; } }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;];
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="migración"&gt;Migración
&lt;/h2&gt;&lt;p&gt;Usa &lt;code&gt;eslint --flag unstable_flat_config&lt;/code&gt; para probar. &lt;code&gt;@eslint/migrate-config&lt;/code&gt; convierte .eslintrc. Las configuraciones populares (typescript-eslint, eslint-plugin-react) ya soportan flat config.&lt;/p&gt;</description></item><item><title>Profundizando en el Event Loop de JavaScript: Microtasks, Macrotasks y más</title><link>https://takao.blog/es/web/js-event-loop/</link><pubDate>Mon, 19 Feb 2024 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/js-event-loop/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/js-event-loop-es.png" alt="Featured image of post Profundizando en el Event Loop de JavaScript: Microtasks, Macrotasks y más" /&gt;&lt;p&gt;El event loop de JavaScript es uno de los conceptos más importantes y menos entendidos. A pesar de ser single-threaded, su event loop permite concurrencia no bloqueante mediante un sistema de colas.&lt;/p&gt;
&lt;h2 id="call-stack"&gt;Call Stack
&lt;/h2&gt;&lt;p&gt;Estructura LIFO. Principio de run-to-completion: cada función se ejecuta hasta completarse antes de que otro código la interrumpa.&lt;/p&gt;
&lt;h2 id="cola-de-macrotasks"&gt;Cola de Macrotasks
&lt;/h2&gt;&lt;p&gt;Origen: &lt;code&gt;setTimeout&lt;/code&gt;, &lt;code&gt;setInterval&lt;/code&gt;, I/O, eventos UI. El event loop toma UNA macrotask por iteración, la ejecuta, luego procesa la cola de microtasks.&lt;/p&gt;</description></item><item><title>Gestión de máquinas virtuales en Proxmox</title><link>https://takao.blog/es/web/proxmox-vm-management/</link><pubDate>Sun, 18 Feb 2024 00:00:00 +0000</pubDate><guid>https://takao.blog/es/web/proxmox-vm-management/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/proxmox-vm-management-es.png" alt="Featured image of post Gestión de máquinas virtuales en Proxmox" /&gt;&lt;p&gt;Proxmox gestiona VMs KVM/QEMU con interfaz web, CLI y API REST. Soporta snapshots, clones y migración en vivo.&lt;/p&gt;
&lt;h2 id="creación-de-vms"&gt;Creación de VMs
&lt;/h2&gt;&lt;p&gt;ISO local o desde URL. Configura CPU, memoria, disco, red. Soporta BIOS y UEFI. VirtIO drivers para rendimiento óptimo.&lt;/p&gt;
&lt;h2 id="snapshots-y-clones"&gt;Snapshots y clones
&lt;/h2&gt;&lt;p&gt;Snapshots: punto de restauración instantáneo. Clones completos (independientes) o enlazados (comparten disco base). Templates para despliegue rápido.&lt;/p&gt;
&lt;h2 id="migración-en-vivo"&gt;Migración en vivo
&lt;/h2&gt;&lt;p&gt;Mueve VMs entre nodos sin downtime. Almacenamiento compartido requerido. Reequilibrio de carga automático con HA.&lt;/p&gt;</description></item><item><title>Service Workers: Experiencia offline y caché avanzada</title><link>https://takao.blog/es/web/service-workers-offline/</link><pubDate>Mon, 12 Feb 2024 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/service-workers-offline/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/service-workers-offline-es.png" alt="Featured image of post Service Workers: Experiencia offline y caché avanzada" /&gt;&lt;p&gt;Los Service Workers actúan como proxy entre el navegador y la red. Permiten experiencias offline, sincronización en segundo plano y push notifications.&lt;/p&gt;
&lt;h2 id="ciclo-de-vida"&gt;Ciclo de vida
&lt;/h2&gt;&lt;p&gt;Instalación → Activación → Fetch. &lt;code&gt;self.addEventListener('install')&lt;/code&gt; para precargar recursos. &lt;code&gt;activate&lt;/code&gt; para limpiar cachés antiguas.&lt;/p&gt;
&lt;h2 id="estrategias-de-caché"&gt;Estrategias de caché
&lt;/h2&gt;&lt;p&gt;Cache First: para assets estáticos. Network First: para APIs. Stale While Revalidate: balance. Network Only: datos sensibles. Cache Only: recursos offline.&lt;/p&gt;
&lt;h2 id="offline-primero"&gt;Offline primero
&lt;/h2&gt;&lt;p&gt;Precarga recursos en &lt;code&gt;install&lt;/code&gt;. Sirve desde caché en &lt;code&gt;fetch&lt;/code&gt;. Actualiza en segundo plano. Sincroniza cambios cuando vuelve la conexión (Background Sync).&lt;/p&gt;</description></item><item><title>Desarrollo de plugins para Vite</title><link>https://takao.blog/es/web/vite-plugin-dev/</link><pubDate>Mon, 05 Feb 2024 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/vite-plugin-dev/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/vite-plugin-dev-es.png" alt="Featured image of post Desarrollo de plugins para Vite" /&gt;&lt;p&gt;Los plugins de Vite transforman código en tiempo de build y desarrollo. Siguen la interfaz de Rollup con hooks específicos de Vite.&lt;/p&gt;
&lt;h2 id="hooks-básicos"&gt;Hooks básicos
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;resolveId&lt;/code&gt;, &lt;code&gt;load&lt;/code&gt;, &lt;code&gt;transform&lt;/code&gt; son los hooks universales. &lt;code&gt;handleHotUpdate&lt;/code&gt; para HMR personalizado. &lt;code&gt;config&lt;/code&gt; para modificar la configuración de Vite.&lt;/p&gt;
&lt;h2 id="ejemplo-de-plugin"&gt;Ejemplo de plugin
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;export&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;myPlugin&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;my-plugin&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;transform&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;code&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;id&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;id&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;endsWith&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;.special&amp;#39;&lt;/span&gt;)) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;transformSpecial&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;code&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; };
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="hooks-de-vite"&gt;Hooks de Vite
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;configResolved&lt;/code&gt;, &lt;code&gt;configureServer&lt;/code&gt;, &lt;code&gt;transformIndexHtml&lt;/code&gt;, &lt;code&gt;closeBundle&lt;/code&gt;. Cada hook se ejecuta en una fase específica del pipeline.&lt;/p&gt;</description></item><item><title>OAuth 2.0 y OpenID Connect: Autenticación y autorización modernas</title><link>https://takao.blog/es/web/oauth-oidc/</link><pubDate>Mon, 29 Jan 2024 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/oauth-oidc/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/oauth-oidc-es.png" alt="Featured image of post OAuth 2.0 y OpenID Connect: Autenticación y autorización modernas" /&gt;&lt;p&gt;OAuth 2.0 es un protocolo de autorización delegada. OpenID Connect (OIDC) añade una capa de autenticación sobre OAuth 2.0.&lt;/p&gt;
&lt;h2 id="roles-en-oauth-20"&gt;Roles en OAuth 2.0
&lt;/h2&gt;&lt;p&gt;Resource Owner (usuario), Client (app), Authorization Server (Auth0, Cognito), Resource Server (API). Flujo: consentimiento → token → acceso.&lt;/p&gt;
&lt;h2 id="grant-types"&gt;Grant Types
&lt;/h2&gt;&lt;p&gt;Authorization Code: el más seguro, con PKCE. Client Credentials: servidor a servidor. Implicit: obsoleto. Device Code: dispositivos sin navegador.&lt;/p&gt;
&lt;h2 id="openid-connect"&gt;OpenID Connect
&lt;/h2&gt;&lt;p&gt;Añade &lt;code&gt;id_token&lt;/code&gt; (JWT) con información del usuario. &lt;code&gt;/userinfo&lt;/code&gt; endpoint. Scope &lt;code&gt;openid&lt;/code&gt;. Claims: sub, name, email, picture.&lt;/p&gt;</description></item><item><title>Git Submodules: Dependencias anidadas</title><link>https://takao.blog/es/web/git-submodules/</link><pubDate>Mon, 22 Jan 2024 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/git-submodules/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/git-submodules-es.png" alt="Featured image of post Git Submodules: Dependencias anidadas" /&gt;&lt;p&gt;Los submódulos de Git permiten incluir un repositorio dentro de otro como una referencia versionada. Mantienen independencia de historial.&lt;/p&gt;
&lt;h2 id="añadir-un-submódulo"&gt;Añadir un submódulo
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;git submodule add &amp;lt;url&amp;gt; &amp;lt;path&amp;gt;&lt;/code&gt; clona el repositorio y crea un archivo &lt;code&gt;.gitmodules&lt;/code&gt;. El commit padre registra el hash exacto del submódulo.&lt;/p&gt;
&lt;h2 id="clonar-con-submódulos"&gt;Clonar con submódulos
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;git clone --recurse-submodules &amp;lt;url&amp;gt;&lt;/code&gt; clona el proyecto y todos los submódulos. Para repos existentes: &lt;code&gt;git submodule update --init --recursive&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="actualizar-submódulos"&gt;Actualizar submódulos
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;git submodule update --remote&lt;/code&gt; actualiza al último commit de la rama configurada. Luego commitear el cambio de hash en el repositorio padre.&lt;/p&gt;</description></item><item><title>Core Web Vitals: Métricas esenciales de rendimiento web</title><link>https://takao.blog/es/web/core-web-vitals/</link><pubDate>Mon, 15 Jan 2024 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/core-web-vitals/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/core-web-vitals-es.png" alt="Featured image of post Core Web Vitals: Métricas esenciales de rendimiento web" /&gt;&lt;p&gt;Core Web Vitals son tres métricas que Google usa para evaluar la experiencia de usuario. Impactan directamente en SEO y ranking de búsqueda.&lt;/p&gt;
&lt;h2 id="lcp-largest-contentful-paint"&gt;LCP (Largest Contentful Paint)
&lt;/h2&gt;&lt;p&gt;Mide el tiempo de renderizado del elemento visible más grande. Objetivo: menos de 2.5s. Estrategias: optimizar imágenes, precargar recursos críticos, minimizar bloqueo de renderizado.&lt;/p&gt;
&lt;h2 id="inp-interaction-to-next-paint"&gt;INP (Interaction to Next Paint)
&lt;/h2&gt;&lt;p&gt;Reemplaza FID como métrica de interactividad. Mide la latencia desde la interacción del usuario hasta el siguiente pintado. Objetivo: menos de 200ms.&lt;/p&gt;</description></item><item><title>React Server Components: El futuro del renderizado web</title><link>https://takao.blog/es/web/react-server-components/</link><pubDate>Mon, 08 Jan 2024 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/react-server-components/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/react-server-components-es.png" alt="Featured image of post React Server Components: El futuro del renderizado web" /&gt;&lt;p&gt;React Server Components (RSC) representan un cambio de paradigma. Los componentes se ejecutan exclusivamente en el servidor, enviando cero JavaScript al cliente. A diferencia del SSR tradicional, RSC produce un formato serializado especial (payload RSC) que el reconcilidor de React en el cliente usa para reconstruir el árbol de componentes sin ejecutar el código.&lt;/p&gt;
&lt;h2 id="límites-servidorcliente"&gt;Límites servidor/cliente
&lt;/h2&gt;&lt;p&gt;Las directivas &amp;ldquo;use client&amp;rdquo; y &amp;ldquo;use server&amp;rdquo; definen el límite. Componentes sin directiva son server components por defecto. Los server components no pueden usar estado, efectos o APIs del navegador.&lt;/p&gt;</description></item><item><title>Health Checks en Docker: Monitoreo de servicios</title><link>https://takao.blog/es/web/docker-health-checks/</link><pubDate>Mon, 25 Dec 2023 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/docker-health-checks/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/docker-health-checks-es.png" alt="Featured image of post Health Checks en Docker: Monitoreo de servicios" /&gt;&lt;p&gt;Los health checks de Docker permiten que el engine monitoree el estado de los contenedores y tome acciones automáticas (reinicios, notificaciones).&lt;/p&gt;
&lt;h2 id="sintaxis"&gt;Sintaxis
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;HEALTHCHECK --interval=30s --timeout=3s --retries=3 CMD curl -f http://localhost || exit 1&lt;/code&gt; en Dockerfile, o &lt;code&gt;healthcheck&lt;/code&gt; en docker-compose.yml.&lt;/p&gt;
&lt;h2 id="protocolos"&gt;Protocolos
&lt;/h2&gt;&lt;p&gt;HTTP: &lt;code&gt;curl -f http://localhost/health&lt;/code&gt;. TCP: &lt;code&gt;nc -z localhost 3306&lt;/code&gt;. Script personalizado para lógica compleja.&lt;/p&gt;
&lt;h2 id="integración-con-orquestadores"&gt;Integración con orquestadores
&lt;/h2&gt;&lt;p&gt;Docker Compose reinicia contenedores no saludables. Swarm y Kubernetes usan health checks para reemplazar instancias fallidas.&lt;/p&gt;</description></item><item><title>Streams en Node.js: Procesamiento eficiente de datos</title><link>https://takao.blog/es/web/nodejs-streams/</link><pubDate>Wed, 20 Dec 2023 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/nodejs-streams/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/nodejs-streams-es.png" alt="Featured image of post Streams en Node.js: Procesamiento eficiente de datos" /&gt;&lt;p&gt;Los streams de Node.js permiten procesar datos en fragmentos (chunks) sin cargar todo en memoria. Esencial para archivos grandes y redes.&lt;/p&gt;
&lt;h2 id="tipos-de-streams"&gt;Tipos de streams
&lt;/h2&gt;&lt;p&gt;Readable: fuente de datos. Writable: destino de datos. Transform: transforma datos (compress, encrypt). Duplex: ambos (net socket).&lt;/p&gt;
&lt;h2 id="pipe-y-pipeline"&gt;Pipe y pipeline
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;readable.pipe(writable)&lt;/code&gt; encadena streams. &lt;code&gt;pipeline&lt;/code&gt; (recomendada) maneja errores y limpia correctamente: &lt;code&gt;pipeline(readable, transform, writable, callback)&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="backpressure"&gt;Backpressure
&lt;/h2&gt;&lt;p&gt;Cuando el writable es más lento que el readable, se aplica backpressure. &lt;code&gt;highWaterMark&lt;/code&gt; controla el buffer interno. El stream pause automáticamente.&lt;/p&gt;</description></item><item><title>Patrones avanzados de CSS Grid: Layouts complejos simplificados</title><link>https://takao.blog/es/web/css-grid-advanced/</link><pubDate>Fri, 15 Dec 2023 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/css-grid-advanced/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/css-grid-advanced-es.png" alt="Featured image of post Patrones avanzados de CSS Grid: Layouts complejos simplificados" /&gt;&lt;p&gt;CSS Grid ha transformado el diseño de layouts web. Más allá de &lt;code&gt;grid-template-columns: 1fr 1fr 1fr&lt;/code&gt; hay un potente conjunto de características.&lt;/p&gt;
&lt;h2 id="named-grid-areas"&gt;Named Grid Areas
&lt;/h2&gt;&lt;p&gt;Define layouts que se leen como un wireframe directamente en CSS. El reordenamiento responsivo es trivial cambiando &lt;code&gt;grid-template-areas&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="auto-fill-vs-auto-fit"&gt;Auto-Fill vs Auto-Fit
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;auto-fill&lt;/code&gt; preserva tracks vacíos como espacio; &lt;code&gt;auto-fit&lt;/code&gt; los colapsa a cero. Usa &lt;code&gt;auto-fill&lt;/code&gt; para columnas predecibles y &lt;code&gt;auto-fit&lt;/code&gt; para layouts fluidos.&lt;/p&gt;
&lt;h2 id="dense-packing"&gt;Dense Packing
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;grid-auto-flow: dense&lt;/code&gt; rellena huecos moviendo elementos a filas anteriores. Cuidado con el orden de lectura para accesibilidad.&lt;/p&gt;</description></item><item><title>Utility Types de TypeScript: Tu caja de herramientas de tipos</title><link>https://takao.blog/es/web/typescript-utility-types/</link><pubDate>Sun, 10 Dec 2023 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/typescript-utility-types/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/typescript-utility-types-es.png" alt="Featured image of post Utility Types de TypeScript: Tu caja de herramientas de tipos" /&gt;&lt;p&gt;TypeScript incluye utility types globales para transformaciones comunes de tipos. Conocerlos evita reinventar la rueda y hace el código más legible.&lt;/p&gt;
&lt;h2 id="básicos"&gt;Básicos
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;Partial&amp;lt;T&amp;gt;&lt;/code&gt;: todas las propiedades opcionales. &lt;code&gt;Required&amp;lt;T&amp;gt;&lt;/code&gt;: todas obligatorias. &lt;code&gt;Readonly&amp;lt;T&amp;gt;&lt;/code&gt;: todas de solo lectura. &lt;code&gt;Record&amp;lt;K, V&amp;gt;&lt;/code&gt;: objeto con claves K y valores V.&lt;/p&gt;
&lt;h2 id="para-unión-e-intersección"&gt;Para unión e intersección
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;Pick&amp;lt;T, K&amp;gt;&lt;/code&gt;: seleccionar propiedades. &lt;code&gt;Omit&amp;lt;T, K&amp;gt;&lt;/code&gt;: excluir propiedades. &lt;code&gt;Extract&amp;lt;T, U&amp;gt;&lt;/code&gt;: extraer miembros de unión. &lt;code&gt;Exclude&amp;lt;T, U&amp;gt;&lt;/code&gt;: excluir miembros de unión.&lt;/p&gt;
&lt;h2 id="para-funciones"&gt;Para funciones
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;Parameters&amp;lt;T&amp;gt;&lt;/code&gt;: tipos de parámetros. &lt;code&gt;ReturnType&amp;lt;T&amp;gt;&lt;/code&gt;: tipo de retorno. &lt;code&gt;ConstructorParameters&amp;lt;T&amp;gt;&lt;/code&gt;: parámetros de constructor. &lt;code&gt;InstanceType&amp;lt;T&amp;gt;&lt;/code&gt;: tipo de instancia.&lt;/p&gt;</description></item><item><title>Patrones avanzados de Promises en JavaScript: Dominio del flujo asíncrono</title><link>https://takao.blog/es/web/js-promise-patterns/</link><pubDate>Tue, 05 Dec 2023 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/js-promise-patterns/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/js-promise-patterns-es.png" alt="Featured image of post Patrones avanzados de Promises en JavaScript: Dominio del flujo asíncrono" /&gt;&lt;p&gt;Las Promises son fundamentales en JavaScript moderno. Más allá de cadenas básicas &lt;code&gt;.then()&lt;/code&gt;, existen patrones avanzados para control de concurrencia, manejo de errores y cancelación.&lt;/p&gt;
&lt;h2 id="combinadores-de-promises"&gt;Combinadores de Promises
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;Promise.all&lt;/code&gt; resuelve cuando todas resuelven. &lt;code&gt;Promise.allSettled&lt;/code&gt; cuando todas se settling (nunca rechaza). &lt;code&gt;Promise.race&lt;/code&gt; con la primera que se settling. &lt;code&gt;Promise.any&lt;/code&gt; con la primera que resuelve.&lt;/p&gt;
&lt;h2 id="control-de-concurrencia"&gt;Control de concurrencia
&lt;/h2&gt;&lt;p&gt;Un limitador de concurrencia encola tareas y asegura que solo un número específico se ejecute simultáneamente. El patrón &lt;code&gt;pMap&lt;/code&gt; con &lt;code&gt;Promise.race&lt;/code&gt; soporta contrapresión.&lt;/p&gt;</description></item><item><title>Cloudflare Pages: Despliegue de sitios estáticos</title><link>https://takao.blog/es/web/cloudflare-pages/</link><pubDate>Tue, 28 Nov 2023 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/cloudflare-pages/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/how-to-cloudflare-pages-es.png" alt="Featured image of post Cloudflare Pages: Despliegue de sitios estáticos" /&gt;&lt;p&gt;Cloudflare Pages aloja sitios estáticos y aplicaciones Jamstack con integración directa desde repositorios de Git.&lt;/p&gt;
&lt;h2 id="configuración-inicial"&gt;Configuración inicial
&lt;/h2&gt;&lt;p&gt;Conecta tu repositorio (GitHub/GitLab). Selecciona la rama, framework (Hugo, Next, React) y comandos de build. Despliegue automático en cada push.&lt;/p&gt;
&lt;h2 id="funciones-serverless"&gt;Funciones serverless
&lt;/h2&gt;&lt;p&gt;Cloudflare Functions ejecutan código en el edge. Basadas en Workers. Formularios, autenticación, APIs ligeras.&lt;/p&gt;
&lt;h2 id="ramas-y-previsualizaciones"&gt;Ramas y previsualizaciones
&lt;/h2&gt;&lt;p&gt;Deploy preview por PR. Ramas de producción y staging. URLs únicas por preview. Ideal para revisión de cambios.&lt;/p&gt;</description></item><item><title>Guía de Cloudflare para desarrolladores web</title><link>https://takao.blog/es/web/cloudflare/</link><pubDate>Tue, 28 Nov 2023 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/cloudflare/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/how-to-cloudflare-es.png" alt="Featured image of post Guía de Cloudflare para desarrolladores web" /&gt;&lt;p&gt;Cloudflare ofrece CDN, seguridad, DNS y optimización de rendimiento para sitios web. Configurarlo correctamente mejora velocidad y protección.&lt;/p&gt;
&lt;h2 id="configuración-dns"&gt;Configuración DNS
&lt;/h2&gt;&lt;p&gt;Añade tu dominio, configura registros DNS (A, CNAME, MX). Activa el proxy naranja (proxy) para proteger IPs de origen y activar optimizaciones.&lt;/p&gt;
&lt;h2 id="ssltls"&gt;SSL/TLS
&lt;/h2&gt;&lt;p&gt;Modos: Off, Flexible, Full, Full (strict). Recomendado: Full (strict) con certificado de origen. HSTS para forzar HTTPS.&lt;/p&gt;
&lt;h2 id="reglas-de-page-rules-y-waf"&gt;Reglas de Page Rules y WAF
&lt;/h2&gt;&lt;p&gt;Reglas de caché, redirecciones, seguridad por ruta. Firewall con reglas custom, rate limiting y protección DDoS.&lt;/p&gt;</description></item><item><title>Instalación y configuración de Proxmox VE</title><link>https://takao.blog/es/web/proxmox-install-setup/</link><pubDate>Wed, 15 Nov 2023 00:00:00 +0000</pubDate><guid>https://takao.blog/es/web/proxmox-install-setup/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/proxmox-install-setup-es.png" alt="Featured image of post Instalación y configuración de Proxmox VE" /&gt;&lt;p&gt;Proxmox VE es una plataforma de virtualización open source basada en Debian. Combina KVM para máquinas virtuales y LXC para contenedores.&lt;/p&gt;
&lt;h2 id="instalación"&gt;Instalación
&lt;/h2&gt;&lt;p&gt;Descarga la ISO desde proxmox.com. Instala en hardware bare-metal. Configura red: IP estática, bridge vmbr0, DNS, gateway.&lt;/p&gt;
&lt;h2 id="post-instalación"&gt;Post-instalación
&lt;/h2&gt;&lt;p&gt;Accede via web: &lt;code&gt;https://IP:8006&lt;/code&gt;. Repositorio Enterprise (requiere suscripción) o repositorio gratuito No-Subscription. Actualiza el sistema.&lt;/p&gt;
&lt;h2 id="almacenamiento"&gt;Almacenamiento
&lt;/h2&gt;&lt;p&gt;ZFS (recomendado), LVM, EXT4, NFS. Creación de piscinas de almacenamiento. Deduplicación y compresión ZFS. Backups integrados.&lt;/p&gt;</description></item><item><title>Google Analytics para desarrolladores</title><link>https://takao.blog/es/web/google-analytics/</link><pubDate>Fri, 20 Oct 2023 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/google-analytics/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/how-to-google-analytics-es.png" alt="Featured image of post Google Analytics para desarrolladores" /&gt;&lt;p&gt;Google Analytics 4 (GA4) es la plataforma de análisis de Google. Los desarrolladores deben implementarlo correctamente para obtener datos precisos.&lt;/p&gt;
&lt;h2 id="implementación"&gt;Implementación
&lt;/h2&gt;&lt;p&gt;GTag: &lt;code&gt;gtag('config', 'G-XXXXXXXXXX')&lt;/code&gt;. GA4 Measurement ID. Eventos recomendados: &lt;code&gt;page_view&lt;/code&gt;, &lt;code&gt;scroll&lt;/code&gt;, &lt;code&gt;click&lt;/code&gt;, &lt;code&gt;view_item&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="eventos-personalizados"&gt;Eventos personalizados
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;gtag('event', 'tutorial_completed', { name: 'React Guide' })&lt;/code&gt;. Hasta 25 parámetros por evento. Eventos únicos para acciones clave del negocio.&lt;/p&gt;
&lt;h2 id="privacidad-y-gdpr"&gt;Privacidad y GDPR
&lt;/h2&gt;&lt;p&gt;Anonimización de IP (automática en GA4). Consent Mode para cumplir con regulaciones. Sin cookies de terceros para mediciones básicas.&lt;/p&gt;</description></item><item><title>Guía de OWASP ZAP para pruebas de seguridad</title><link>https://takao.blog/es/web/owasp-zap/</link><pubDate>Fri, 20 Oct 2023 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/owasp-zap/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/how-to-owasp-zap-es.png" alt="Featured image of post Guía de OWASP ZAP para pruebas de seguridad" /&gt;&lt;p&gt;OWASP ZAP (Zed Attack Proxy) es una herramienta de seguridad open source para encontrar vulnerabilidades en aplicaciones web.&lt;/p&gt;
&lt;h2 id="instalación"&gt;Instalación
&lt;/h2&gt;&lt;p&gt;Descarga desde zaproxy.org. Versión con JRE incluida. O via Docker: &lt;code&gt;docker pull softwaresecurityproject/zap-stable&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="escaneo-automático"&gt;Escaneo automático
&lt;/h2&gt;&lt;p&gt;Spider: rastrea URLs. Active Scan: inyecta payloads de seguridad. Modo automático: &lt;code&gt;zap -quickurl https://target.com&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="integración-cicd"&gt;Integración CI/CD
&lt;/h2&gt;&lt;p&gt;ZAP API para automatización. &lt;code&gt;zap-full-scan.py&lt;/code&gt; para escaneo completo. &lt;code&gt;zap-api-scan.py&lt;/code&gt; para APIs. Reports en JSON/HTML.&lt;/p&gt;
&lt;h2 id="principales-hallazgos"&gt;Principales hallazgos
&lt;/h2&gt;&lt;p&gt;XSS, SQL Injection, CSRF, missing headers (CSP, HSTS), authentication bypass, directory traversal, información sensible expuesta.&lt;/p&gt;</description></item><item><title>Wayback Machine: Archivo de la web para desarrolladores</title><link>https://takao.blog/es/web/waybackmachine/</link><pubDate>Mon, 11 Sep 2023 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/waybackmachine/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/wayback-machine-es.png" alt="Featured image of post Wayback Machine: Archivo de la web para desarrolladores" /&gt;&lt;p&gt;The Wayback Machine (archive.org) archiva páginas web desde 1996. Útil para desarrolladores para debugging, análisis y referencia histórica.&lt;/p&gt;
&lt;h2 id="casos-de-uso"&gt;Casos de uso
&lt;/h2&gt;&lt;p&gt;Recuperar código perdido, analizar cambios de diseño/SEO de competidores, verificar contenido histórico, debugging de cambios que rompieron algo.&lt;/p&gt;
&lt;h2 id="api"&gt;API
&lt;/h2&gt;&lt;p&gt;Disponible en &lt;code&gt;https://archive.org/help/wayback_api_usage.html&lt;/code&gt;. Búsqueda por URL y rango de fechas. Save Page Now para archivar páginas.&lt;/p&gt;
&lt;h2 id="integración-con-desarrollo"&gt;Integración con desarrollo
&lt;/h2&gt;&lt;p&gt;Ver cómo cambiaron las APIs de terceros. Recuperar documentación eliminada. Analizar la evolución de estándares web.&lt;/p&gt;</description></item><item><title>Guía completa de Git para desarrolladores web</title><link>https://takao.blog/es/web/how-to-git/</link><pubDate>Sun, 10 Sep 2023 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/how-to-git/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/how-to-git-es.png" alt="Featured image of post Guía completa de Git para desarrolladores web" /&gt;&lt;p&gt;Git es el sistema de control de versiones esencial para el desarrollo web moderno. Esta guía cubre desde la configuración inicial hasta flujos de equipo.&lt;/p&gt;
&lt;h2 id="configuración-inicial"&gt;Configuración inicial
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git config --global user.name &lt;span style="color:#e6db74"&gt;&amp;#34;Tu Nombre&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git config --global user.email &lt;span style="color:#e6db74"&gt;&amp;#34;email@ejemplo.com&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git config --global init.defaultBranch main
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="flujo-diario"&gt;Flujo diario
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;git pull&lt;/code&gt; → &lt;code&gt;git checkout -b feature/nombre&lt;/code&gt; → trabajo → &lt;code&gt;git add&lt;/code&gt; → &lt;code&gt;git commit&lt;/code&gt; → &lt;code&gt;git push -u origin feature/nombre&lt;/code&gt; → abrir PR.&lt;/p&gt;
&lt;h2 id="resolución-de-conflictos"&gt;Resolución de conflictos
&lt;/h2&gt;&lt;p&gt;Los conflictos ocurren cuando dos ramas modifican las mismas líneas. Márcalos: &lt;code&gt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&lt;/code&gt;, &lt;code&gt;=======&lt;/code&gt;, &lt;code&gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&lt;/code&gt;. Resuelve, &lt;code&gt;git add&lt;/code&gt;, &lt;code&gt;git commit&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>Guía de GitHub para desarrolladores</title><link>https://takao.blog/es/web/how-to-github/</link><pubDate>Sun, 10 Sep 2023 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/how-to-github/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/how-to-github-es.png" alt="Featured image of post Guía de GitHub para desarrolladores" /&gt;&lt;p&gt;GitHub es la plataforma de colaboración de código más grande. Más allá de git push/pull, ofrece herramientas de gestión de proyectos y CI/CD.&lt;/p&gt;
&lt;h2 id="pull-requests"&gt;Pull Requests
&lt;/h2&gt;&lt;p&gt;Los PRs son el corazón de la colaboración. Incluye descripción, contexto, capturas y enlaces a issues. Revisión de código con comentarios en línea.&lt;/p&gt;
&lt;h2 id="issues-y-projects"&gt;Issues y Projects
&lt;/h2&gt;&lt;p&gt;Issues para bugs y características. Projects (tableros Kanban) para gestión visual. Labels, milestones, assignees y templates.&lt;/p&gt;
&lt;h2 id="github-actions"&gt;GitHub Actions
&lt;/h2&gt;&lt;p&gt;CI/CD integrado. Workflows YAML para tests, lint, despliegues. Actions del Marketplace para integraciones comunes.&lt;/p&gt;</description></item><item><title>Instalación y configuración de Hugo</title><link>https://takao.blog/es/web/hugo-setup/</link><pubDate>Wed, 23 Aug 2023 00:00:00 +0900</pubDate><guid>https://takao.blog/es/web/hugo-setup/</guid><description>&lt;img src="https://takao.blog/img/thumbnail/hugo-setup-es.png" alt="Featured image of post Instalación y configuración de Hugo" /&gt;&lt;p&gt;Hugo es el generador de sitios estáticos más rápido. Escrito en Go, genera sitios completos en milisegundos.&lt;/p&gt;
&lt;h2 id="instalación"&gt;Instalación
&lt;/h2&gt;&lt;p&gt;Windows: &lt;code&gt;choco install hugo-extended&lt;/code&gt; o descargar binario. macOS: &lt;code&gt;brew install hugo&lt;/code&gt;. Linux: &lt;code&gt;snap install hugo&lt;/code&gt;. Verifica con &lt;code&gt;hugo version&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="crear-un-sitio-nuevo"&gt;Crear un sitio nuevo
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;hugo new site mysite&lt;/code&gt; crea la estructura. Añade un tema: &lt;code&gt;git submodule add &amp;lt;tema-url&amp;gt; themes/mi-tema&lt;/code&gt;. Configura en &lt;code&gt;hugo.toml&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="modo-desarrollo"&gt;Modo desarrollo
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;hugo server -D&lt;/code&gt; inicia el servidor con livereload. &lt;code&gt;-D&lt;/code&gt; incluye drafts. &lt;code&gt;--navigateToChanged&lt;/code&gt; navega automáticamente al archivo editado.&lt;/p&gt;</description></item></channel></rss>