<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Alfredo Bonilla</title>
    <description>The latest articles on Forem by Alfredo Bonilla (@brolag).</description>
    <link>https://forem.com/brolag</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F125411%2Fc887f545-793c-46b3-8a0c-a9c690465341.jpeg</url>
      <title>Forem: Alfredo Bonilla</title>
      <link>https://forem.com/brolag</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/brolag"/>
    <language>en</language>
    <item>
      <title>How to Deploy an Eliza AI Agent on Railway</title>
      <dc:creator>Alfredo Bonilla</dc:creator>
      <pubDate>Fri, 24 Jan 2025 04:51:27 +0000</pubDate>
      <link>https://forem.com/brolag/how-to-deploy-eliza-starter-on-railway-2pbn</link>
      <guid>https://forem.com/brolag/how-to-deploy-eliza-starter-on-railway-2pbn</guid>
      <description>&lt;p&gt;If you’re looking to quickly deploy Eliza Starter on Railway, this guide will walk you through the process step by step. Let’s get started!&lt;/p&gt;

&lt;h3&gt;
  
  
  What is Eliza Starter?
&lt;/h3&gt;

&lt;p&gt;Eliza Starter is a lightweight open-source framework designed to help developers build conversational AI agents quickly and efficiently. It provides all the necessary tools and structure to kickstart projects that integrate AI-driven dialogue systems, making it a great choice for AI enthusiasts and developers.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is Railway?
&lt;/h3&gt;

&lt;p&gt;Railway is a modern cloud platform that simplifies deploying and managing applications. It offers a seamless developer experience by automating much of the infrastructure setup, allowing you to focus on writing and deploying code with minimal hassle. With Railway, you can deploy projects directly from GitHub and manage environment variables effortlessly.&lt;/p&gt;

&lt;h3&gt;
  
  
  What You Need
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;A GitHub account with access to the &lt;a href="https://github.com/elizaOS/eliza-starter" rel="noopener noreferrer"&gt;Eliza Starter repository&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;A Railway account (sign up for free at &lt;a href="https://railway.app/" rel="noopener noreferrer"&gt;Railway&lt;/a&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Steps to Deploy
&lt;/h3&gt;

&lt;h4&gt;
  
  
  1. Clone the Eliza Starter Repository
&lt;/h4&gt;

&lt;p&gt;Start by cloning the &lt;a href="https://github.com/elizaOS/eliza-starter" rel="noopener noreferrer"&gt;Eliza Starter repository&lt;/a&gt;. You’ll use this as the base for your project.&lt;/p&gt;

&lt;h4&gt;
  
  
  2. Create a New Railway Instance
&lt;/h4&gt;

&lt;p&gt;Go to &lt;a href="https://railway.app/" rel="noopener noreferrer"&gt;Railway&lt;/a&gt; and create a new instance:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Log in to your Railway account.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;New Project&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  3. Connect Your GitHub Repository
&lt;/h4&gt;

&lt;p&gt;Once you’ve created a new project:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Select &lt;strong&gt;Deploy from GitHub&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Choose your GitHub account and connect the Eliza Starter repository.&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  4. Configure Environment Variables
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Open your project in Railway.&lt;/li&gt;
&lt;li&gt;Navigate to the &lt;strong&gt;Variables&lt;/strong&gt; tab.&lt;/li&gt;
&lt;li&gt;Click on &lt;strong&gt;Raw Editor&lt;/strong&gt; to open the editor for environment variables.&lt;/li&gt;
&lt;li&gt;Copy the &lt;code&gt;.env&lt;/code&gt; file from the Eliza Starter repository into the Raw Editor.&lt;/li&gt;
&lt;li&gt;Add or modify the following key-value pair:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   DAEMON_PROCESS=true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;This disables the chat functionality in the terminal to prevent build errors.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  5. Deploy
&lt;/h4&gt;

&lt;p&gt;Once the variables are set:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Click &lt;strong&gt;Deploy&lt;/strong&gt; to build and deploy your project.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Why Set &lt;code&gt;DAEMON_PROCESS=true&lt;/code&gt;?
&lt;/h3&gt;

&lt;p&gt;Cloud platforms like Railway do not support interactive terminals. This means that any processes requiring user input or terminal interaction during runtime can cause the deployment to fail. Setting &lt;code&gt;DAEMON_PROCESS=true&lt;/code&gt; disables the interactive chat functionality in the terminal, ensuring a smooth and error-free build process.&lt;/p&gt;

&lt;h3&gt;
  
  
  That’s It!
&lt;/h3&gt;

&lt;p&gt;Your Eliza Starter project should now be live on Railway. If you encounter any issues, refer to the &lt;a href="https://github.com/elizaOS/eliza-starter" rel="noopener noreferrer"&gt;Eliza Starter GitHub repository&lt;/a&gt; for troubleshooting tips.&lt;/p&gt;

&lt;p&gt;Happy coding! 🚀&lt;/p&gt;

</description>
      <category>eliza</category>
      <category>ai</category>
      <category>aiagents</category>
      <category>elizaos</category>
    </item>
    <item>
      <title>TailwindCSS: A Game-Changer for AI-Driven Code Generation and Design Systems</title>
      <dc:creator>Alfredo Bonilla</dc:creator>
      <pubDate>Sun, 29 Sep 2024 01:34:00 +0000</pubDate>
      <link>https://forem.com/brolag/tailwindcss-a-game-changer-for-ai-driven-code-generation-and-design-systems-18m7</link>
      <guid>https://forem.com/brolag/tailwindcss-a-game-changer-for-ai-driven-code-generation-and-design-systems-18m7</guid>
      <description>&lt;p&gt;In today's fast-paced world of software development, AI is making waves by revolutionizing how we write and optimize code. Among the various tools at our disposal, TailwindCSS has emerged as a standout framework, particularly when it comes to AI-assisted coding and creating comprehensive design systems. Let's dive into why TailwindCSS is such a perfect fit for AI-driven development, how it's boosting product innovation and efficiency, and how AI agents can leverage it to create entire design systems from scratch.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why TailwindCSS and AI are a Match Made in Heaven
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Utility-First Approach: Keeping It Simple
&lt;/h3&gt;

&lt;p&gt;TailwindCSS's utility-first philosophy is like a playground for AI. Instead of crafting intricate CSS rules from scratch, AI can tap into Tailwind's vast library of pre-defined classes. This means AI can focus on the big picture of design logic rather than getting bogged down in styling minutiae. It's like giving AI a set of Lego blocks to build with, rather than asking it to mold each brick from clay.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Predictable Class Names: Speaking the Same Language
&lt;/h3&gt;

&lt;p&gt;The consistent and intuitive class naming in TailwindCSS is music to AI's ears. With predictable class names, AI models can quickly learn and apply styles accurately. It's like teaching AI a new language where every word makes logical sense – no more fumbling around with cryptic class names or extensive trial-and-error.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Readability and Maintainability: Keeping It Clean
&lt;/h3&gt;

&lt;p&gt;By embedding styles directly in HTML through class names, TailwindCSS creates code that's a breeze for AI to parse and understand. It's like having a clear, organized workspace – AI can see the layout and styling at a glance, leading to more coherent and maintainable code structures. The result? Code that's not just functional, but also easy on the eyes for human developers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Supercharging Product Development with TailwindCSS and AI
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Rapid Prototyping: From Idea to Interface in No Time
&lt;/h3&gt;

&lt;p&gt;Imagine being able to whip up responsive, good-looking interfaces in the blink of an eye. That's what you get when you combine TailwindCSS with AI. This dynamic duo allows for lightning-fast prototyping and iteration, helping products evolve quickly to meet changing market demands.&lt;/p&gt;

&lt;p&gt;Tools like &lt;a href="https://cursor.com" rel="noopener noreferrer"&gt;Cursor&lt;/a&gt; are taking this to the next level. Cursor is an AI-powered code editor that integrates seamlessly with frameworks like TailwindCSS, allowing developers to generate code snippets, refactor existing code, and even get explanations about complex codebases. When used in conjunction with TailwindCSS, Cursor can significantly speed up the development process, suggesting appropriate utility classes and even entire component structures.&lt;/p&gt;

&lt;h3&gt;
  
  
  Consistency is Key
&lt;/h3&gt;

&lt;p&gt;With TailwindCSS, you're essentially giving AI a unified design language to work with. The result? Products that look polished and cohesive across all components and pages. This consistency not only makes for a better user experience but also makes life easier for development teams working on different parts of a project.&lt;/p&gt;

&lt;h3&gt;
  
  
  Less Overhead, More Innovation
&lt;/h3&gt;

&lt;p&gt;By cutting down on the need for custom CSS, TailwindCSS frees up AI (and human developers) to focus on the bigger picture. Instead of getting tangled up in repetitive styling tasks, teams can channel their energy into the strategic aspects of product innovation. It's about working smarter, not harder.&lt;/p&gt;

&lt;h3&gt;
  
  
  Scaling Up with Ease
&lt;/h3&gt;

&lt;p&gt;Whether you're working on a small side project or a massive enterprise application, TailwindCSS has got you covered. Its scalability means AI can adapt to projects of all sizes, customizing utility classes as needed. It's like having a Swiss Army knife that can handle any job you throw at it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating Complete Design Systems with AI and TailwindCSS
&lt;/h2&gt;

&lt;p&gt;One of the most exciting developments in the intersection of AI and TailwindCSS is the ability to generate entire design systems directly in code. Here's how AI agents can leverage TailwindCSS to create comprehensive design systems:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Defining Design Tokens
&lt;/h3&gt;

&lt;p&gt;AI agents can start by defining design tokens - the fundamental building blocks of a design system. Using TailwindCSS's configuration file, AI can set up custom colors, typography, spacing, and other design variables. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;colors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;primary&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#0047AB&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;secondary&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#6CB4EE&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="c1"&gt;// ... more colors&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;fontFamily&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;sans&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Roboto&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;sans-serif&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="na"&gt;serif&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Merriweather&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;serif&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;spacing&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;sm&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;0.5rem&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;md&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1rem&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;lg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1.5rem&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="c1"&gt;// ... more spacing values&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Generating Component Libraries
&lt;/h3&gt;

&lt;p&gt;With design tokens in place, AI can then generate a library of reusable components. These could range from simple buttons and form elements to more complex components like navigation bars or card layouts. Each component would be created using TailwindCSS utility classes, ensuring consistency with the overall design system. For instance:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- AI-generated button component --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"bg-primary text-white font-sans py-sm px-md rounded hover:bg-secondary transition duration-300"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  Click me
&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is where tools like &lt;a href="https://v0.dev" rel="noopener noreferrer"&gt;v0.dev&lt;/a&gt; shine. v0.dev is an AI-powered design tool that can generate entire web components and pages using natural language prompts. It leverages the power of TailwindCSS to create visually appealing and responsive designs quickly. By integrating v0.dev into your workflow, you can rapidly prototype and iterate on your design system components, all while maintaining the consistency and efficiency that TailwindCSS provides.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Creating Layout Systems
&lt;/h3&gt;

&lt;p&gt;AI agents can develop flexible layout systems using TailwindCSS's grid and flexbox utilities. This could include creating responsive layouts that adapt to different screen sizes, as well as defining standard page templates and sections.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Documenting the Design System
&lt;/h3&gt;

&lt;p&gt;As the AI generates components and layouts, it can simultaneously create documentation. This could be in the form of markdown files or even a simple website built with TailwindCSS, showcasing each component, its usage, and any variants.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Generating Theme Variations
&lt;/h3&gt;

&lt;p&gt;AI can create multiple theme variations based on the initial design system. By adjusting the TailwindCSS configuration, it can quickly generate light/dark modes or even entirely different color schemes for different brand identities.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Ensuring Accessibility
&lt;/h3&gt;

&lt;p&gt;AI agents can be programmed to prioritize accessibility, using TailwindCSS classes that ensure proper color contrast, font sizes, and interactive element states that meet WCAG guidelines.&lt;/p&gt;

&lt;h3&gt;
  
  
  7. Optimizing for Performance
&lt;/h3&gt;

&lt;p&gt;Using TailwindCSS's built-in purge feature, AI can ensure that only the used utility classes are included in the final CSS, resulting in a lean and performant design system.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Power of AI-Generated Design Systems
&lt;/h2&gt;

&lt;p&gt;By leveraging AI to create design systems with TailwindCSS, development teams can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Save Time&lt;/strong&gt;: What might take weeks for a human team can be accomplished in hours by AI.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Maintain Consistency&lt;/strong&gt;: AI-generated systems ensure perfect consistency across all components and pages.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Iterate Quickly&lt;/strong&gt;: Need to update the entire system? AI can regenerate it with new parameters in minutes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scale Effortlessly&lt;/strong&gt;: As project requirements grow, AI can expand the design system accordingly.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Wrapping Up
&lt;/h2&gt;

&lt;p&gt;TailwindCSS is proving to be a powerhouse when it comes to AI-driven code generation and design system creation. Its utility-first approach, consistent naming conventions, and focus on readability play right into AI's strengths, leading to more efficient and accurate code production. As AI continues to reshape how we develop software, frameworks like TailwindCSS will be key players in driving innovation and delivering top-notch products.&lt;/p&gt;

&lt;p&gt;The ability to generate entire design systems using AI and TailwindCSS opens up exciting possibilities for rapid prototyping, consistent brand implementation, and scalable design across large projects. It's a glimpse into a future where the line between design and development becomes increasingly blurred, with AI acting as the bridge between creative vision and technical implementation.&lt;/p&gt;

&lt;p&gt;Tools like Cursor and v0.dev are at the forefront of this revolution, showcasing how AI can work hand-in-hand with frameworks like TailwindCSS to supercharge the development process. As these technologies continue to evolve, we can expect even more seamless integration between AI-driven coding assistants, design tools, and utility-first CSS frameworks.&lt;/p&gt;

&lt;p&gt;So, whether you're an AI enthusiast, a developer looking to streamline your workflow, or a product manager aiming for faster time-to-market, it might be time to give TailwindCSS and AI-driven design systems a closer look. Who knows? It could be the secret weapon your team needs to take your development process to the next level and stay ahead in the fast-paced world of digital product creation.&lt;/p&gt;

</description>
      <category>tailwindcss</category>
      <category>ai</category>
      <category>frontend</category>
    </item>
    <item>
      <title>7 things I learned from DevRel Engineers 🥑 at DevCon</title>
      <dc:creator>Alfredo Bonilla</dc:creator>
      <pubDate>Sat, 15 Oct 2022 18:10:17 +0000</pubDate>
      <link>https://forem.com/brolag/7-things-i-learned-from-devrel-engineers-at-devcon-31pf</link>
      <guid>https://forem.com/brolag/7-things-i-learned-from-devrel-engineers-at-devcon-31pf</guid>
      <description>&lt;p&gt;Web3 business model requires adoption which means it needs a constant flow of builders, new features, users and feedback. &lt;/p&gt;

&lt;p&gt;Builders is the key word and the best way to get builders aware of a project is through well designed resources such as exciting hackathons, tools, practical education materials, live events and community support. Here is where Developer Relationships comes into play.&lt;/p&gt;

&lt;p&gt;One of the most insightful moments for me during Dev Con VI at Bogotá was the full-of-alphas DevRel Workshop hosted by &lt;a href="https://twitter.com/sunnyjaycer" rel="noopener noreferrer"&gt;Sunny Jaycer&lt;/a&gt; (DevRel at &lt;a href="https://twitter.com/Superfluid_HQ" rel="noopener noreferrer"&gt;SuperFluid&lt;/a&gt;) and a panel formed by:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://twitter.com/sflamini5" rel="noopener noreferrer"&gt;Sam Flamini&lt;/a&gt; @ &lt;a href="https://twitter.com/Superfluid_HQ" rel="noopener noreferrer"&gt;Superfluid&lt;/a&gt;&lt;br&gt;
&lt;a href="https://twitter.com/thatguyintech" rel="noopener noreferrer"&gt;Albert Hu&lt;/a&gt; @ &lt;a href="https://twitter.com/AlchemyPlatform" rel="noopener noreferrer"&gt;Alchemy&lt;/a&gt;&lt;br&gt;
&lt;a href="https://twitter.com/emijlin" rel="noopener noreferrer"&gt;Emily Lin&lt;/a&gt; @ &lt;a href="https://twitter.com/trufflesuite" rel="noopener noreferrer"&gt;Truffle&lt;/a&gt;&lt;br&gt;
&lt;a href="https://twitter.com/Yazanator" rel="noopener noreferrer"&gt;Yaz Khouri&lt;/a&gt; @ &lt;a href="https://twitter.com/celestiaorg" rel="noopener noreferrer"&gt;Celestia&lt;/a&gt;&lt;br&gt;
&lt;a href="https://twitter.com/0ceans404" rel="noopener noreferrer"&gt;Steph Orpilla&lt;/a&gt; @ &lt;a href="https://twitter.com/0xpolygon" rel="noopener noreferrer"&gt;Polygon&lt;/a&gt;&lt;br&gt;
&lt;a href="https://twitter.com/francescoswiss" rel="noopener noreferrer"&gt;Francesco Andreoli&lt;/a&gt;  @ &lt;a href="https://twitter.com/Metamask" rel="noopener noreferrer"&gt;Metamask&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here is what I learned.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. What DevRel is not
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;DevRel is not sales.&lt;/li&gt;
&lt;li&gt;DevRel is not marketing.&lt;/li&gt;
&lt;li&gt;DevRel is not Engineering.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Where you put a DevRel will determine their success so it’s important to understand the role.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. DevRel main goal
&lt;/h2&gt;

&lt;p&gt;Your main goal as DevRel is the product success and you will achieve it having a lot of empathy with other developers and creating resources that are very accesible. &lt;/p&gt;

&lt;p&gt;The developer is the main character of the story and there are plenty of ways to support their journey.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. DevRel is actually an umbrella term
&lt;/h2&gt;

&lt;p&gt;There are different focus areas for DevRel Engineers including but not limited to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Evangelism&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Talk in public about the project, company or protocol.&lt;/li&gt;
&lt;li&gt;Create educational resources for users and builders.&lt;/li&gt;
&lt;li&gt;Engage the communities on-line and off-line.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Advocacy&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Support the community and get feedback from it.&lt;/li&gt;
&lt;li&gt;Serve as a bridge between the outside community and the internal team of the project.&lt;/li&gt;
&lt;li&gt;Encourage contributors and build tools and processes to effectively support them.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Documentation&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Create written documentation for the project.&lt;/li&gt;
&lt;li&gt;Maintain current documentation.&lt;/li&gt;
&lt;li&gt;Keep tack of new features or updates delivered by the internal team.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Community&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Moderate online community channels.&lt;/li&gt;
&lt;li&gt;Provide support at events such as hackathons.&lt;/li&gt;
&lt;li&gt;Keep track of high value members of the community and help the to succeed.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Content will play a key part of the role indistinctly of your focus area so you will need to develop a strategy effectively impact your community. &lt;/p&gt;

&lt;h2&gt;
  
  
  4. The DevRel Playbook
&lt;/h2&gt;

&lt;p&gt;Creating content for developers is tricky. Here are some useful ideas to figure out how to do it right.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create great content for your community and your product will thrive.&lt;/li&gt;
&lt;li&gt;Your personal brand is important but you are advocating for your platform and the brand. Your goal is help everyone to succeed.&lt;/li&gt;
&lt;li&gt;Think about developer first, product second. Make others feel they are not alone when using your product.&lt;/li&gt;
&lt;li&gt;Educate people about how to look for relevant material.&lt;/li&gt;
&lt;li&gt;Some content is more volatile than other. Things change fast in Web3.&lt;/li&gt;
&lt;li&gt;Written content is updatable but video is not. You’ll probably want to create videos about more ever-green general ideas and text for updates or release notes.&lt;/li&gt;
&lt;li&gt;Be creative! you can mix art with technical content. You could do a &lt;a href="https://youtu.be/mdvK0-A4ePo" rel="noopener noreferrer"&gt;web3 rap&lt;/a&gt; for example.&lt;/li&gt;
&lt;li&gt;Make useful stuff. Think about something you would love to have in the past but you didn’t.&lt;/li&gt;
&lt;li&gt;When creating content think about use cases. Don’t repeat the documentation but add value to it by exploring new use cases.&lt;/li&gt;
&lt;li&gt;Show how to integrate your product with other products. Web3 is about composability. Most of the time developers will need to use several tools or platforms. “Wagmi-fy” your content.&lt;/li&gt;
&lt;li&gt;Be transparent about your own developer journey. Build in public (your community will love it).&lt;/li&gt;
&lt;li&gt;Consistency is the key.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  5. Developer Personas and The Orbit Model
&lt;/h2&gt;

&lt;p&gt;As DevRel you should be clear about who you are talking to and when. The Orbit model (presented by &lt;a href="https://twitter.com/Yazanator" rel="noopener noreferrer"&gt;Yaz Khoury&lt;/a&gt;) is an awesome tool for defining Developer Personas. &lt;/p&gt;

&lt;p&gt;According to Khoury there are 4 community orbits around a project. Each of these orbits will require a different strategy. The closer the orbit is, the more mature the person is in their journey with your product. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The Casually Interested&lt;/strong&gt;: haven’t explored the project in depth but is curious about it. Requires help and motivation getting onboard and understanding the project better.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Builder:&lt;/strong&gt; knows the documentation and can build or integrate with your product with other products. Needs technical help around specific use cases when building. Hackathons are a common place for builders with this profile.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Community Member&lt;/strong&gt;: is involved in the community. Participates in communication channels even volunteers for activities. Needs support to get more visibility and remove blockers from their journey.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Biggest Fan&lt;/strong&gt;: is invested long term. Participates in grants. Bring value to the project and other members trough contributions, support and feedback. This is the most valuable member of the community and will need the best incentives from the internal team such as direct technical guidance, priority and why not? limited edition swags.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Depending on the project there will be more or less specific activities across the orbits. One particular case is being a DevRel for a Layer 1 project. &lt;/p&gt;

&lt;h2&gt;
  
  
  6. DevRel for Layer 1
&lt;/h2&gt;

&lt;p&gt;Being a DevRel for a Layer 1 instead of a project higher in the stack has its own particular activities and responsibilities like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Improve developer experience.&lt;/li&gt;
&lt;li&gt;Hardfork coordination&lt;/li&gt;
&lt;li&gt;Validator relations&lt;/li&gt;
&lt;li&gt;Governance relations&lt;/li&gt;
&lt;li&gt;Improve the proposals&lt;/li&gt;
&lt;li&gt;Host Core Dev calls&lt;/li&gt;
&lt;li&gt;Advocate smart contracts languages&lt;/li&gt;
&lt;li&gt;Technical writing&lt;/li&gt;
&lt;li&gt;Community calls and coordination&lt;/li&gt;
&lt;li&gt;Engineering activities&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This skills will help a lot in your journey as a Level 1 DevRel&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Basic practical knowledge about cloud computing&lt;/li&gt;
&lt;li&gt;Building Dapps for workshops or demos&lt;/li&gt;
&lt;li&gt;Being confortable with the command line (don’t be afraid of it, it’s really useful)&lt;/li&gt;
&lt;li&gt;Being confortable with Linux&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Making sure you understand your responsibilities and execute accordingly is important however you will also need to quantify your progress in order to communicate your achievements to the core team.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. How to measure DevRel success
&lt;/h2&gt;

&lt;p&gt;Measuring success in DevRel is quite challenging because not everything is quantifiable. However there are some strategies you can use to get a better understanding of the impact.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Here are some tips to define success metrics:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create interactive tutorials and measure the progress of your users&lt;/li&gt;
&lt;li&gt;Quantify how many hackathon projects get funded&lt;/li&gt;
&lt;li&gt;Track engagement on Discord and Github&lt;/li&gt;
&lt;li&gt;Look for repeated pieces of feedback&lt;/li&gt;
&lt;li&gt;Track attendance at workshops&lt;/li&gt;
&lt;li&gt;Use social media analytics&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;You can get better metrics doing these:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ask what is interesting for people and document it&lt;/li&gt;
&lt;li&gt;Go to every hackathon and get feedback&lt;/li&gt;
&lt;li&gt;Look for trends and move fast

&lt;ul&gt;
&lt;li&gt;Develop integrations with new products&lt;/li&gt;
&lt;li&gt;Provide feedback and ideas to the core team&lt;/li&gt;
&lt;li&gt;Develop documentation and examples for new use cases&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Hack with your community!&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;DevRel is a complex role extremely important for web3 projects and difficult to find by recruiters. In my opinion it will become hotter and hotter in the next few years. &lt;/p&gt;

&lt;p&gt;If you want to become a DevRel start by paying attention to what other DevRels do and learn from them. Finally here is a hack from the legendary &lt;a href="https://twitter.com/dabit3" rel="noopener noreferrer"&gt;Nader Dabit&lt;/a&gt;: target smaller projects instead of big famous protocols. There is more room for you to shine and a bigger probability of getting noticed.&lt;/p&gt;

&lt;p&gt;Enjoy the ride!&lt;/p&gt;

</description>
      <category>devrel</category>
      <category>web3</category>
      <category>devcon</category>
      <category>devconbogota</category>
    </item>
    <item>
      <title>Cómo crear una aplicación Full-Stack con React, NestJS y Nx</title>
      <dc:creator>Alfredo Bonilla</dc:creator>
      <pubDate>Thu, 15 Oct 2020 23:38:20 +0000</pubDate>
      <link>https://forem.com/brolag/como-crear-una-aplicacion-full-stack-con-react-nestjs-y-nx-3b3p</link>
      <guid>https://forem.com/brolag/como-crear-una-aplicacion-full-stack-con-react-nestjs-y-nx-3b3p</guid>
      <description>&lt;h2&gt;
  
  
  🏁 TL;DR
&lt;/h2&gt;

&lt;p&gt;Nx es un conjunto de herramientas que nos permiten construir aplicaciones full-stack de una manera más sencilla por medio de mono repositorios reforzando además las buenas prácticas de programación. Podemos generar aplicaciones full-stack con NestJS y React por medio de la ejecución de algunos sencillos comandos.&lt;/p&gt;




&lt;h3&gt;
  
  
  Pre requisitos:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;⚛️ Conceptos básicos de React.&lt;/li&gt;
&lt;li&gt;🐈 Conocimiento básico de NestJS.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  😮 ¿Por qué utilizar mono repos?
&lt;/h2&gt;

&lt;p&gt;Las organizaciones por lo general trabajan y dan mantenimiento a múltiples proyectos y no siempre es sencillo mantener estándares o reutilizar código entre ellas.&lt;/p&gt;

&lt;p&gt;Implementar una estrategia de mono repositorio nos va a permitir centralizar el código de nuestras diferentes aplicaciones un único repositorio permitiendo así compartir código entre nuestras aplicaciones.&lt;/p&gt;

&lt;p&gt;Entre las ventajas que nos ofrece esa estrategia podemos recalcar:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Facilidad para compartir código entre aplicaciones.&lt;/li&gt;
&lt;li&gt;Un mejor manejo de dependencias a lo largo de distintos proyectos así como la compatibilidad de sus versiones.&lt;/li&gt;
&lt;li&gt;Permite mayor fluidez en el trabajo entre distintos equipos.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Existen herramientas que nos permiten abstraer nuestro código en librerías e implementar mono repos como los paquetes &lt;a href="https://docs.npmjs.com/about-private-packages" rel="noopener noreferrer"&gt;privados de npm&lt;/a&gt;, &lt;a href="https://github.com/lerna/lerna" rel="noopener noreferrer"&gt;Lerna&lt;/a&gt; o &lt;a href="https://classic.yarnpkg.com/en/docs/workspaces/" rel="noopener noreferrer"&gt;Yarn Workspaces&lt;/a&gt;, sin embargo existen varios aspectos dónde podríamos vernos beneficiados con mejores herramientas.&lt;/p&gt;

&lt;p&gt;Con Nx tenemos a nuestro alcance una colección de herramientas que nos permitirán administrar nuestro mono repo de una mejor manera gracias Nx CLI: una herramienta de línea de comandos basada en &lt;a href="https://www.google.com/search?q=angular+schematics&amp;amp;oq=angular+schematics&amp;amp;aqs=chrome..69i57.1896j0j1&amp;amp;sourceid=chrome&amp;amp;ie=UTF-8" rel="noopener noreferrer"&gt;Angular Schematics&lt;/a&gt; con la cuál podremos generar código de manera consistente con solo ejecutar una serie de comandos. Nx además provee herramientas para optimizar nuestro proceso de pruebas automatizadas y despligue.&lt;/p&gt;

&lt;h2&gt;
  
  
  🙌🏽 Aplicaciones full-stack utilizando Nx
&lt;/h2&gt;

&lt;p&gt;Otro uso que podemos dar a los mono repositorios son las aplicaciones full-stack. Nx resulta poderosamente conveniente cuando hablamos específicamente de aplicaciones full-stack con TypeScript ya que nos permite mantener el código del front end y el back end en un mismo repositorio junto con librerías que facilitan la reutilización de código cómo interfaces y funciones utilitarias.&lt;/p&gt;

&lt;p&gt;Para este ejemplo vamos a utilizar NestJS, un framework dogmático de NodeJS que busca ser robusto y escalable por medio de la implementación de buenas prácticas y patrones de diseño. Esta fuertemente inspirado en la arquitectura de Angular. NestJS ha ganado bastante popularidad gracias a sus características.&lt;/p&gt;

&lt;p&gt;Es muy común ver implementaciones full-stack con Angular y NestJS debido a que comparten muchas características e implementan patrones similares, sin embargo es completamente posible utilizar React con TypeScript.&lt;/p&gt;

&lt;p&gt;Nx ofrece una serie de comandos para generar estructuras de aplicaciones full-stack, entre ellas podemos generar Angular + NestJS, o React + NodeJS con Express. De momento no existe una opción directa para combinar estas opciones sin embargo podemos hacerlo manualmente y así poder aprovechar el potencial tanto de NestJS en el backend como la flexibilidad y rapidez de desarrollo de React en el front end.&lt;/p&gt;

&lt;h2&gt;
  
  
  ⚙️ Configurando una aplicación React + NestJS
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Aplicación front end con React y TypeScript
&lt;/h3&gt;

&lt;p&gt;El primer paso que vamos a seguir es la creación de un espacio de trabajo junto con la aplicación de React. Para esto vamos a ejecutar el siguiente comando:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npx create-nx-workspace@latest&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Una vez hecho esto vamos a elegir un nombre para nuestra organización. La organización va a contener los distintos proyectos entre los cuales queramos compartir código.&lt;/p&gt;

&lt;p&gt;Después de esto vamos a seleccionar la opción "&lt;em&gt;a workspace with a single React application&lt;/em&gt;"&lt;/p&gt;

&lt;p&gt;Nx va a generar por nosotros toda la estructura del espacio de trabajo junto con una aplicación React funcional.&lt;/p&gt;

&lt;p&gt;Podemos ejecutar la aplicación con el siguiente comando&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npx nx serve &amp;lt;nombre_de_la_aplicacion&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  API con NestJS
&lt;/h3&gt;

&lt;p&gt;Seguidamente vamos a generar nuestro api NestJS.&lt;/p&gt;

&lt;p&gt;Si ejecutamos el comando &lt;code&gt;nx list&lt;/code&gt; podremos observar las distintas opciones que nos ofrece Nx para generar código.&lt;/p&gt;

&lt;p&gt;Vamos a ejecutar &lt;code&gt;yarn add --dev @nrwl/nest&lt;/code&gt; para añadir la capacidad de generar aplicaciones NestJS.&lt;/p&gt;

&lt;p&gt;Después de esto vamos a ejecutar el comando:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npx nx g @nrwl/nest:app api --frontendProject=&amp;lt;nombre_de_la_aplicacion_front_end&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Con este comando ya podremos ver nuestro espacio de trabajo conteniendo el código de un api NestJS.&lt;/p&gt;

&lt;p&gt;Además de esto tenemos una configuración de proxy creada automáticamente.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/api&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;target&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;http://localhost:3333&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;secure&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En este punto ya tenemos el front end y el back end. En el siguiente paso vamos a compartir código entre ambas aplicaciones.&lt;/p&gt;

&lt;h2&gt;
  
  
  🤝 Compartir código entre distintas aplicaciones
&lt;/h2&gt;

&lt;p&gt;Una de las ventajas de utilizar librerías de Nx para compartir código es que no necesitaremos procesos extra de despliegue como es el caso de los paquetes privados de NPM donde primero necesitamos desplegar el paquete y luego actualizar la versión en nuestra aplicación. Con Nx es tan sencillo como crear un nuevo pull request.&lt;/p&gt;

&lt;p&gt;Para generar una librería que podamos acceder desde los distintos proyectos vamos a ejecutar el siguiente comando.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npx nx g @nrwl/workspace:lib data&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Nx va a generar el código de nuestra librería, en la ruta &lt;code&gt;libs/data/src/lib&lt;/code&gt; podremos encontrar un archivo de TypeScript que eventualmente podremos importar en nuestras aplicaciones. Para probar podemos escribir un tipo de dato que vayamos a utilizar tanto en el front end como en el back end, esto nos permitirá evitar duplicar el código de nuestras interfaces de TypeScript.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Book&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;author&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;isbn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;cover&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Seguidamente vamos a actualizar un poco el código para poder probar la aplicación:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;En el API, vamos a actualizar el app.service.ts importando el nuevo tipo de dato por medio de la línea: &lt;code&gt;import { Book } from '@public-library/data';&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Injectable&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@nestjs/common&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Book&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@public-library/data&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Injectable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AppService&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;books&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Book&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Clean Code&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;author&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Robert C. Martin&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;isbn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;9780132350884&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;The Pragmatic Programmer&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;author&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Andy Hunt &amp;amp; Dave Thomas&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;isbn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;9780132119177&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Working Effectively with Legacy Code&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;author&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Michael C. Feathers&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;isbn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;9780131177055&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt;

  &lt;span class="nf"&gt;getData&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nx"&gt;Book&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;books&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Si estamos utilizando VS Code, es importante tomar en cuenta que cada vez que agregamos una nueva librería debemos reiniciar el servidor de TypeScript ya sea reiniciando el editor o ejecutando &lt;code&gt;Cmd + Shift + P&lt;/code&gt; y ejecutando el comando &lt;code&gt;TypeScript: Restart TS Server&lt;/code&gt;.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Vamos a crear una ruta personalizada en el controlador para poder manipular la petición al del front end al API
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Controller&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Get&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@nestjs/common&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;AppService&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./app.service&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Controller&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AppController&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kr"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;appService&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;AppService&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;books&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nf"&gt;getData&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;appService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getData&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;En la aplicación de React vamos a modificar el archivo app.tsx para poder obtener los datos del API y listarlos de la siguiente manera. Al igual que en el API vamos a importar nuestra librería con exactamente la misma interfaz.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Book&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@public-library/data&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;books&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setBooks&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Book&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;([]);&lt;/span&gt;

  &lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/api/books&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;setBooks&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
     &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Books&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;ul&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;books&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isbn&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;book&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;ul&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;¡Y listo! una vez finalizado este paso tendremos una estructura escalable lista para empezar a desarrollar nuestra aplicación full-stack TypeScript con React y NestJS.&lt;/p&gt;

&lt;h2&gt;
  
  
  🎯 Conclusion
&lt;/h2&gt;

&lt;p&gt;El uso de mono repos nos permite administrar nuestro código de una mejor manera tanto para agrupar y compartir código entre distintas aplicaciones de una organización así como para nuestras aplicaciones full-stack.&lt;/p&gt;

&lt;p&gt;Nx ofrece una serie de herramientas y buenas prácticas que facilitarán mucho la implementación de una estrategia de mono repos y de aplicaciones full-stack escritas en TypeScript.&lt;/p&gt;

&lt;p&gt;A pesar de que Nx no ofrece por defecto la opción de generar una aplicación full-stack combinando NestJs y React, es posible hacerlo manualmente mediante una serie de comandos.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fuentes y Documentación adicional
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://nx.dev/latest/react/tutorial/01-create-application" rel="noopener noreferrer"&gt;Nx&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://es.reactjs.org/" rel="noopener noreferrer"&gt;React&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.nestjs.com/" rel="noopener noreferrer"&gt;NestJS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/Monorepo" rel="noopener noreferrer"&gt;Monorepos&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;¿Utilizarías React con NestJS, tienes experiencia utilizando estas tecnologías juntas?&lt;/p&gt;

&lt;p&gt;Espero sus comentarios.&lt;/p&gt;

&lt;p&gt;¡Hasta la próxima! 😁&lt;/p&gt;

</description>
    </item>
    <item>
      <title>WeakRefs y Finalizers en JavaScript</title>
      <dc:creator>Alfredo Bonilla</dc:creator>
      <pubDate>Thu, 08 Oct 2020 23:21:08 +0000</pubDate>
      <link>https://forem.com/brolag/weakrefs-y-finalizers-en-javascript-4feb</link>
      <guid>https://forem.com/brolag/weakrefs-y-finalizers-en-javascript-4feb</guid>
      <description>&lt;p&gt;WeakRefs y Finalizers es una nueva característica de JavaScript añadida como parte de ES2021, su funcionamiento es bastante interesante pero puede ser complejo y no debe utilizarse si no es estrictamente necesario, a continuación veremos un poco más sobre esto.&lt;/p&gt;




&lt;h2&gt;
  
  
  🏁 &lt;strong&gt;TL;DR&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;En JavaScript las referencias a objetos son respetadas por el recolector de basura (o &lt;em&gt;garbage collector&lt;/em&gt;), es decir, si el algoritmo de recolección encuentra que un objeto es alcanzable desde un objeto raíz este no será recolectado, pero si el objeto es inalcanzable, este será recolectado.&lt;/p&gt;

&lt;p&gt;Se puede decir que este proceso es una aproximación ya que el algoritmo no puede saber a ciencia cierta si un objeto es necesario o no.&lt;/p&gt;

&lt;p&gt;Un objeto &lt;code&gt;weakRef&lt;/code&gt; permite mantener una referencia débil a otro objeto sin prevenir que este objeto sea eliminado de la memoria por el recolector de basura y &lt;code&gt;FinalizationRegistry&lt;/code&gt; nos permite hacer un &lt;em&gt;callback&lt;/em&gt; cuando este objeto ha sido debidamente recolectado.&lt;/p&gt;




&lt;h2&gt;
  
  
  📦 Gestión de la memoria en JavaScript
&lt;/h2&gt;

&lt;p&gt;El ciclo de vida de la memoria es muy parecido en todos los lenguajes de programación primero se reserva la memoria necesaria, se utiliza y luego se libera cuando ya no es necesaria.&lt;/p&gt;

&lt;p&gt;JavaScript asigna memoria de manera automática cada vez que se declara un valor al igual que la liberación de memoria no utilizada se realiza automáticamente por medio del Recolector de Basura o &lt;em&gt;Garbage Collector.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🔗 WeakRefs
&lt;/h2&gt;

&lt;p&gt;Una &lt;code&gt;weakRef&lt;/code&gt; es un objeto que tiene una referencia débil a un objeto llamado referente u objetivo, esta referencia permite que el objeto sea recolectado por el &lt;em&gt;garbage collector.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Cabe mencionar que se debe tener cuidado al utilizar las referencias débiles, de hecho es bueno evitarlas de ser posible. También debemos saber que el comportamiento del garbage collector puede cambiar de motor a motor y podría ser diferente para diferentes versiones del motor de JavaScript.&lt;/p&gt;

&lt;p&gt;En otras palabras, el momento y la manera en que la recolección sucede puede variar y eso puede afectar el resultado que esperamos, incluso podría suceder que el método &lt;code&gt;deref&lt;/code&gt; nunca retorne &lt;code&gt;undefined&lt;/code&gt; debido a que el recolector decidió nunca recolectar esa referencia.&lt;/p&gt;

&lt;h3&gt;
  
  
  📣 FinalizationRegistry
&lt;/h3&gt;

&lt;p&gt;FinalizationRegistry es un objeto que permite ejecutar un callback cuando un objeto es recolectado. Si el objetivo de un FinalizationRegistry es también un elemento con una WeakRef entonces la referencia se eliminará al mismo tiempo que la ejecución del callback por lo que no será posible obtener la referencia del objeto dentro del callback.&lt;/p&gt;

&lt;h3&gt;
  
  
  ⚙️ Ejemplo
&lt;/h3&gt;

&lt;p&gt;Este es un ejemplo simple donde vamos a definir una referencia débil para un objeto que va a contener una animación generada a partir de otros elementos del DOM que se adjuntan segundo a segundo durante 5 segundos.&lt;/p&gt;

&lt;p&gt;Una vez que el tiempo haya pasado, la referencia será recolectada y se disparará un callback indicando que el objeto fue recolectado.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CircleAnimation&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Define una referencia débil a un elemento del DOM.&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ref&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;WeakRef&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;// Define un callback que se ejecutara&lt;/span&gt;
    &lt;span class="c1"&gt;// cuando el elemento de referencia débil sea recolectado.&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;registry&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;FinalizationRegistry&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;hadValue&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Referencia recolectada: &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;hadValue&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;registry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;register&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Elemento de animación&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;start&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;start&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;timer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;addCircle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// Obtiene el elemento de la referencia.&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;referencedElement&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;deref&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;referencedElement&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;circle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;div&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nx"&gt;circle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;className&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;circle&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
        &lt;span class="nx"&gt;referencedElement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;circle&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// El elemento ya no existe.&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;El elemento ya no existe.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stop&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ref&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;addCircle&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;timer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;setInterval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;addCircle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;stop&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;timer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;clearInterval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;timer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;timer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;animation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;CircleAnimation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;app&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="nx"&gt;animation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;start&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;app&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;5000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;💻 El ejemplo completo se encuentra &lt;a href="https://stackblitz.com/edit/es2021-weak-reference" rel="noopener noreferrer"&gt;aquí&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;‼️ Para poder observar su funcionamiento correctamente es necesario recargar la página cada vez que se ejecuta la animación.&lt;/p&gt;

&lt;p&gt;¿Se les ocurre algún uso para esta característica? Dejen sus comentarios y opiniones sobre el tema.&lt;/p&gt;

&lt;p&gt;Puedes encontrar el artículo original en mi &lt;a href="https://alfredobonilla.dev/blog/weakrefs-y-finalizers-en-javascript" rel="noopener noreferrer"&gt;blog&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;¡Hasta la próxima! 😉&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>es2021</category>
      <category>espanol</category>
      <category>spanish</category>
    </item>
  </channel>
</rss>
