<?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: phukon</title>
    <description>The latest articles on Forem by phukon (@phukon).</description>
    <link>https://forem.com/phukon</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%2F1247663%2Ff83c4edd-83fe-4eaf-abc4-b21f8330667c.jpeg</url>
      <title>Forem: phukon</title>
      <link>https://forem.com/phukon</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/phukon"/>
    <language>en</language>
    <item>
      <title>Babel and Sourcemaps, Part-1</title>
      <dc:creator>phukon</dc:creator>
      <pubDate>Sun, 13 Oct 2024 13:37:32 +0000</pubDate>
      <link>https://forem.com/phukon/babel-and-sourcemaps-part-1-2cn</link>
      <guid>https://forem.com/phukon/babel-and-sourcemaps-part-1-2cn</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Repurposing source-maps with a Babel codemod.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I began working with sourcemaps a while ago and was fascinated by their ingenuity. This sparked an idea: what if sourcemaps could be used for other purposes? Specifically, I thought of applying them to documentation — comments, README files, and so on.&lt;/p&gt;

&lt;p&gt;That’s how ‘&lt;a href="https://github.com/phukon/docmap" rel="noopener noreferrer"&gt;DOCMAP&lt;/a&gt;’ was born! The process works by adding comments in the source code with a specific prefix. Then, Babel is run on the source code, stripping out the comments from the original files without modifying the JavaScript/TypeScript/JSX/TSX code itself. These comments are compiled into a single README file, and a sourcemap is generated for the comments!&lt;/p&gt;

&lt;p&gt;This will keep all the juicy comments right where they belong, pinpointing them to the relevant code without cluttering up the original source&lt;/p&gt;

&lt;h2&gt;
  
  
  A Primer
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Babel
&lt;/h3&gt;

&lt;p&gt;JavaScript is an evolving language, with new features and syntax being introduced regularly. However, not all browsers and environments immediately support the latest JavaScript features. This can create compatibility issues for developers who want to use modern language features while ensuring their code runs smoothly across all platforms. This is where transpiling comes in.&lt;/p&gt;

&lt;p&gt;Transpilers help bridge this gap by converting modern JavaScript code into older versions that are widely supported across different browsers. One popular transpiler is Babel, which not only allows developers to transpile code but also to create and run code mods—automated transformations of code.&lt;/p&gt;

&lt;h3&gt;
  
  
  Sourcemaps
&lt;/h3&gt;

&lt;p&gt;Now that we understand what Babel is and what it can do, let's address a common issue.&lt;/p&gt;

&lt;p&gt;When debugging compiled code in the browser’s debugger, problems can arise. The code running in the browser isn’t the code you originally wrote, making it difficult to follow and debug.&lt;/p&gt;

&lt;p&gt;Source maps offer a solution to this. They map the compiled code back to your original source code, allowing the debugger to display the code you wrote while still running the compiled version behind the scenes.&lt;/p&gt;

&lt;h3&gt;
  
  
  But what does a sourcemap look like?
&lt;/h3&gt;

&lt;p&gt;If we compile this ES 2015 code with Babel:&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;square&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&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;x&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It is transformed into this:&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;use strict&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;square&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;square&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&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="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;//# sourceMappingURL=test.js.map&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And this is the source map content inside “test.js.map”:&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="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;version&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;sources&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;test.es6.js&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;names&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;mappings&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;;;AAAA,IAAM,MAAM,GAAG,SAAT,MAAM,CAAI,CAAC;SAAK,CAAC,GAAG,CAAC;CAAA,CAAC&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;file&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;test.js&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;sourcesContent&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;const square = (x) =&amp;gt; x * x;&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What are those weird alphabets in the mappings key?&lt;/strong&gt;&lt;br&gt;
These are called Base 64 VLQ. VLQ stands for &lt;a href="https://en.wikipedia.org/wiki/Variable-length_quantity" rel="noopener noreferrer"&gt;variable-length quantity&lt;/a&gt;, and it’s used to store a number in a more space-efficient way than storing its digits as a string.&lt;/p&gt;

&lt;p&gt;The individual mapping entries, such as "AAAA" and "GAAG," are known as "segments." Each segment represents an array of numbers.&lt;/p&gt;

&lt;p&gt;In the sourcemap world. Everything is zero indexed (lines and columns)&lt;br&gt;
 A semicolon (;) means skip to next line in the output file.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;[0]&lt;/em&gt;: Column index in the compiled file&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;[1]&lt;/em&gt;: What original source file the location in the compiled source maps to&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;[2]&lt;/em&gt;: Row index in the original source file (i.e. the number of lines to move from the current position)&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;[3]&lt;/em&gt;: Column index in the original source file&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Source maps do not represent the position of every character; instead, they use relative values to indicate the proximity of source code locations.&lt;/p&gt;

&lt;p&gt;For example, if a column value is decoded to 8 and the next segment's column value is 10, the mapping indicates a change of +10 (rather than an absolute position of 10). We have to move 10 lines from the previous segment's decoded position in the original code. Therefore, each segment's current VLQ value depends on and is derived from its predecessors.&lt;/p&gt;

&lt;p&gt;This relative approach is especially useful when working with large codebases, as it keeps the source map concise while still enabling accurate debugging.&lt;/p&gt;

&lt;h2&gt;
  
  
  The code mod
&lt;/h2&gt;

&lt;p&gt;How does the codemod script work?&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Parse Code to AST&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The source code is tokenized and analyzed to create an &lt;strong&gt;Abstract Syntax Tree (AST)&lt;/strong&gt;, a structured representation of the code.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Transform AST to Another AST&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The AST is optimized or transformed through semantic analysis (e.g., type checking, optimizations like dead code elimination) to improve efficiency. But in our case, we are removing comment nodes from the code.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Generate Code from AST&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The optimized AST is translated into the target code (e.g., machine code or bytecode) that can be executed. In our case, we are translate the AST without the comment nodes into code.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In short: &lt;strong&gt;Parse → Transform → Generate&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;When working with Babel, you generally &lt;strong&gt;add nodes to paths&lt;/strong&gt; rather than directly to nodes. What’s a node and a path in the Babel AST you might ask?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Nodes:&lt;/strong&gt; These represent the actual elements of the Abstract Syntax Tree (AST). For example, a variable declaration, function call, or any other part of the code is a node. However, nodes are just data structures; they don’t know their position or context within the AST.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Paths:&lt;/strong&gt; A &lt;code&gt;NodePath&lt;/code&gt; is a wrapper around a node that includes information about its position in the AST and the scope it belongs to. Paths provide methods for navigating and manipulating the AST, such as &lt;code&gt;insertBefore&lt;/code&gt;, &lt;code&gt;insertAfter&lt;/code&gt;, &lt;code&gt;replaceWith&lt;/code&gt;, and more.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6v09majyz9sprsyiwx09.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6v09majyz9sprsyiwx09.png" alt="Image description" width="482" height="388"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Note
&lt;/h3&gt;

&lt;p&gt;We use the &lt;strong&gt;visitor pattern&lt;/strong&gt; while using babel for transformations. A visitor matches a node in the AST and returns a &lt;strong&gt;path!&lt;/strong&gt; This path wraps the node (ex: &lt;code&gt;CallExpression&lt;/code&gt;) and provides methods to interact with it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What the Path Object Provides:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Node Access&lt;/strong&gt;: You can access the actual AST node via &lt;code&gt;path.node&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Parent Node&lt;/strong&gt;: Access the parent node via &lt;code&gt;path.parent&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sibling Nodes&lt;/strong&gt;: Navigate to sibling nodes via methods like &lt;code&gt;path.getSibling(index)&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Node Replacement&lt;/strong&gt;: Replace the current node with &lt;code&gt;path.replaceWith(newNode)&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Traversal&lt;/strong&gt;: Traverse into child nodes using &lt;code&gt;path.traverse()&lt;/code&gt; with another visitor.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Contextual Information&lt;/strong&gt;: The path includes context about the scope, which can be important for variable declarations, function parameters, etc.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So, that wraps up &lt;strong&gt;Part 1&lt;/strong&gt;! We’ve explored how &lt;strong&gt;Babel&lt;/strong&gt; lets us use modern JavaScript features while making sure our code runs smoothly across different browsers. We also talked about &lt;strong&gt;sourcemaps&lt;/strong&gt; and how they help us debug by linking the compiled code back to the original source, which is super handy.&lt;/p&gt;

&lt;p&gt;Plus, we introduced the idea of &lt;strong&gt;DOCMAP&lt;/strong&gt;, a cool way to repurpose sourcemaps for documentation. It keeps those juicy comments tied to the right code without cluttering things up.&lt;/p&gt;

&lt;p&gt;In &lt;strong&gt;Part 2&lt;/strong&gt;, we’ll dive into how DOCMAP works, showing you the steps for extracting comments and generating a neat README. Can’t wait to get into it!&lt;/p&gt;




&lt;h3&gt;
  
  
  Resources
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;About sourcemaps: &lt;a href="https://pvdz.ee/weblog/281" rel="noopener noreferrer"&gt;https://pvdz.ee/weblog/281&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Base64 VLQ decoder: &lt;a href="http://www.murzwin.com/base64vlq.html" rel="noopener noreferrer"&gt;http://www.murzwin.com/base64vlq.html&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Good read: &lt;a href="https://www.linkedin.com/pulse/reconstructing-javascript-source-code-from-maps-schaffner-bofill/" rel="noopener noreferrer"&gt;https://www.linkedin.com/pulse/reconstructing-javascript-source-code-from-maps-schaffner-bofill/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Generating source maps: &lt;a href="https://www.mattzeunert.com/2016/02/14/how-do-source-maps-work.html" rel="noopener noreferrer"&gt;https://www.mattzeunert.com/2016/02/14/how-do-source-maps-work.html&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;VLQ npm package documentation: &lt;a href="https://www.npmjs.com/package/vlq" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/vlq&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Sentry’s Video on sourcemaps: &lt;a href="https://www.youtube.com/watch?v=6LI0BJIiamg" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=6LI0BJIiamg&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;AST Explorer: &lt;a href="https://astexplorer.net" rel="noopener noreferrer"&gt;https://astexplorer.net&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>babel</category>
      <category>sourcemaps</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Be a Better UI Engineer: Selectively Exclude CSS Styles</title>
      <dc:creator>phukon</dc:creator>
      <pubDate>Sun, 21 Apr 2024 06:06:50 +0000</pubDate>
      <link>https://forem.com/phukon/be-a-better-ui-engineer-selectively-exclude-css-styles-2720</link>
      <guid>https://forem.com/phukon/be-a-better-ui-engineer-selectively-exclude-css-styles-2720</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Fine grained control over your styles in 3 steps&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1s94d87nn5heekawonri.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1s94d87nn5heekawonri.png" alt="1" width="800" height="449"&gt;&lt;/a&gt;Correcting the styles. Before and after.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;I wanted to increase the sizes of the images in my personal site’s projects page. So I wrote some styles in &lt;code&gt;globals.css&lt;/code&gt;, and applied it to the parent node that contains the content.&lt;/p&gt;

&lt;p&gt;This style applies to all images within elements with the classes &lt;code&gt;.prose&lt;/code&gt; and &lt;code&gt;.project&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.prose.project&lt;/span&gt; &lt;span class="nt"&gt;img&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="err"&gt;@apply&lt;/span&gt; &lt;span class="err"&gt;max-w-none&lt;/span&gt; &lt;span class="err"&gt;rounded-md&lt;/span&gt; &lt;span class="err"&gt;border&lt;/span&gt; &lt;span class="err"&gt;border-secondary&lt;/span&gt; &lt;span class="err"&gt;bg-tertiary&lt;/span&gt; &lt;span class="py"&gt;md&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;rounded-lg&lt;/span&gt; &lt;span class="n"&gt;lg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;-ml-16&lt;/span&gt; &lt;span class="n"&gt;lg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;w-&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;calc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="err"&gt;+&lt;/span&gt;&lt;span class="m"&gt;128px&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;The problem arises with this dynamic classlg:w-[calc(100%+128px)]. It adds 128 pixels to 100% of the parent element’s width. This is a common technique in CSS for achieving responsive and dynamic layouts.&lt;/p&gt;

&lt;p&gt;This made the images in one of my custom MDX components to blow out of proportions.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgisj8mbwbppdwo4vcuer.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgisj8mbwbppdwo4vcuer.png" alt="2" width="800" height="645"&gt;&lt;/a&gt;See the &lt;strong&gt;red NPM logo&lt;/strong&gt; image that’s out of proportion.&lt;/p&gt;

&lt;p&gt;I don’t want this global style to be applied. How do I go about excluding it?&lt;/p&gt;

&lt;h2&gt;
  
  
  The Solution
&lt;/h2&gt;

&lt;p&gt;The key to solving this problem lies in understanding how CSS selectors work and how to leverage them to target specific elements. In our case, we want to exclude the global style from one specific element.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Add a Custom Class to the component
&lt;/h2&gt;

&lt;p&gt;First, add a custom class to the element/component where you don’t want the global style to be applied. For example, you can add a class named &lt;code&gt;.no-prose-style&lt;/code&gt;.&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;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;
 &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"project prose animate-in no-prose-style"&lt;/span&gt;
 &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&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;--index&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;CSSProperties&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 2: Define the Override Styles in CSS
&lt;/h2&gt;

&lt;p&gt;Next, define the styles you want to override or reset for the &lt;code&gt;.no-prose-style&lt;/code&gt; class in your CSS. You can reset the properties to their default values or set them to something else as needed.&lt;/p&gt;

&lt;p&gt;In my case, the problem revolved around images blowing out of proportions in my custom component. Hence, I set the width on large screens to be 100% with a Tailwind utility class.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo3u73v8mb1lxgushqioj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo3u73v8mb1lxgushqioj.png" alt="Image description" width="800" height="282"&gt;&lt;/a&gt;The the class to override the prose project style&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.no-prose-style&lt;/span&gt; &lt;span class="nt"&gt;img&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="err"&gt;@apply&lt;/span&gt; &lt;span class="py"&gt;lg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;w-full&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;h2&gt;
  
  
  The result:
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdbcbu8stkke69toriz1v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdbcbu8stkke69toriz1v.png" alt="4" width="800" height="602"&gt;&lt;/a&gt;The red &lt;strong&gt;NPM logo&lt;/strong&gt; looks great now!&lt;/p&gt;

&lt;p&gt;In conclusion, by understanding CSS selectors and utilizing targeted overrides, we can maintain fine-grained control over our styles in Tailwind CSS. With just a few simple steps, we can exclude global styles from specific elements, ensuring a more tailored and cohesive design across our projects.&lt;/p&gt;




&lt;p&gt;Footnotes:&lt;br&gt;
GitHub: &lt;a href="https://github.com/phukon"&gt;https://github.com/phukon&lt;/a&gt;&lt;br&gt;
Socials: &lt;a href="https://rkph.me"&gt;https://rkph.me&lt;/a&gt;&lt;/p&gt;

</description>
      <category>css</category>
      <category>webdev</category>
      <category>frontend</category>
    </item>
    <item>
      <title>How I test React components in isolation</title>
      <dc:creator>phukon</dc:creator>
      <pubDate>Sun, 14 Apr 2024 15:08:12 +0000</pubDate>
      <link>https://forem.com/phukon/how-i-test-react-components-in-isolation-24if</link>
      <guid>https://forem.com/phukon/how-i-test-react-components-in-isolation-24if</guid>
      <description>&lt;p&gt;&lt;em&gt;Are you even a frontend engineer if you don’t develop/test your components in isolation?&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;In modern frontend development, testing components in isolation is crucial for ensuring code quality and efficiency. Storybook is a powerful tool that facilitates this practice, allowing developers to develop and showcase UI components independently.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnqc41xotputl4d8g0zz8.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnqc41xotputl4d8g0zz8.jpg" alt="StoryBook dashboard" width="800" height="370"&gt;&lt;/a&gt;&lt;/p&gt;
Testing components in Storybook. For more &lt;a class="mentioned-user" href="https://dev.to/see"&gt;@see&lt;/a&gt; [BinaryDreams](https://bndr.rkph.me)



&lt;h2&gt;
  
  
  Step 1
&lt;/h2&gt;

&lt;p&gt;We need to initialize it in our project. Go to the root directory and do:&lt;br&gt;
&lt;code&gt;npx storybook@latest init&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Good! If you’re utilizing ESLint in your project, you’ll receive a prompt asking if you’d like to install the necessary dependencies that align with Storybook. Simply respond with “y” and proceed.&lt;/p&gt;

&lt;p&gt;Excellent! Upon inspection of your project, you’ll notice that Storybook has generated a &lt;code&gt;.storybook&lt;/code&gt; folder and a &lt;code&gt;stories&lt;/code&gt; folder.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;.storybook&lt;/code&gt;directory houses configuration files, while the &lt;code&gt;stories&lt;/code&gt; folder contains example Stories.&lt;/p&gt;

&lt;p&gt;Chances are, installing Storybook in your project also started the Storybook development server at &lt;a href="http://localhost:6006/"&gt;http://localhost:6006/&lt;/a&gt;, if not, try npm run storybook in your project using the terminal.&lt;/p&gt;
&lt;h2&gt;
  
  
  What do we see?
&lt;/h2&gt;

&lt;p&gt;We see a beautiful✨ dashboard with all the Stories defined in your project! (these are examples stories that come with the installation)&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhp028ztuq6wonodkra93.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhp028ztuq6wonodkra93.jpg" alt="dash" width="800" height="514"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click on a Story and you get a good overview of the component along with it’s description, the props it takes, etc.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwehsfn0ewovemvry6k00.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwehsfn0ewovemvry6k00.png" alt="Image description" width="800" height="433"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Congrats! You’ve just setup &lt;strong&gt;Storybook&lt;/strong&gt; for your project. &lt;strong&gt;BUT&lt;/strong&gt; you need to jazz it up by properly plugging in TailwindCSS. (cuz who doesn’t TailwindCSS?)&lt;/p&gt;
&lt;h2&gt;
  
  
  Setup Absolute Imports
&lt;/h2&gt;

&lt;p&gt;Storybook doesn’t support absolute imports out of the box. For this we have to do a minor change in the config. Open .storybook/main.ts and add this snippet in the config object.&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;webpackFinal&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;config&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;alias&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="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;alias&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;__dirname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../&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="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;config&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;h2&gt;
  
  
  Setup Tailwind!
&lt;/h2&gt;

&lt;p&gt;Unless you’ve been living in a cave (or under a rock, if you prefer), you probably know how crucial TailwindCSS is in the modern web dev scene. But the TailwindCSS utility classes won’t work with &lt;strong&gt;Storybook&lt;/strong&gt; out of the box.&lt;/p&gt;

&lt;p&gt;So here’s what you have to do&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;open the file preview.ts in the .storybook folder&lt;/li&gt;
&lt;li&gt;import your main CSS file, or in my case &lt;code&gt;globals.css&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1ikurkgurzv72x57gdun.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1ikurkgurzv72x57gdun.png" alt="Image description" width="756" height="602"&gt;&lt;/a&gt;&lt;/p&gt;
Import globals.css



&lt;h3&gt;
  
  
  &lt;em&gt;You’re doing great!&lt;/em&gt;
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Stories are a declarative syntax for supplying props and mock data to simulate component variations. Each component can have multiple stories. Each story allows you to demonstrate a specific variation of that component to verify appearance and behavior.&lt;br&gt;
You write stories for granular UI component variation and then use those stories in development, testing, and documentation.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is very simple, don’t worry if you can’t get a hold of it in the beginning. We write a story by importing a component we made in to a file ending with .stories&lt;/p&gt;

&lt;p&gt;If you are making a Story for &lt;strong&gt;LoginForm.tsx&lt;/strong&gt;, make a file called &lt;strong&gt;LoginForm.stories.tsx&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkat5121059vq06xzxjvj.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkat5121059vq06xzxjvj.jpg" alt="Image description" width="708" height="533"&gt;&lt;/a&gt;&lt;/p&gt;
A Story



&lt;ul&gt;
&lt;li&gt;We’ve imported some types from Storybook since we’re using Typescript in this project.&lt;/li&gt;
&lt;li&gt;We then import the component that we want test/develop in isolation and define write meta data for the component.&lt;/li&gt;
&lt;li&gt;Add the name of our component with the category under which it should be grouped. Here, the title is “Auth/LoginForm”. ‘Auth’ is the category. Think of it as a directory structure.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7ryx4nhruqx4ojk2nv51.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7ryx4nhruqx4ojk2nv51.jpg" alt="Image description" width="553" height="455"&gt;&lt;/a&gt;&lt;/p&gt;
We have currently defined to categories. Auth and Onboard



&lt;ul&gt;
&lt;li&gt;Don’t worry about this part. You can just copy this meta object in every component. But do change the name and define the imported component for which you’re setting the Story for!&lt;/li&gt;
&lt;li&gt;These lines imports types Meta and StoryObj from the @storybook/react package.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;satisfies&lt;/span&gt; &lt;span class="nx"&gt;Meta&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;LoginForm&lt;/span&gt;&lt;span class="o"&gt;&amp;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;meta&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Story&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;StoryObj&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;meta&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;These types are used to define the structure of stories and their metadata within Storybook.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Meta&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;StoryObj&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;@storybook/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="nx"&gt;LoginForm&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;./LoginForm&lt;/span&gt;&lt;span class="dl"&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;meta&lt;/span&gt; &lt;span class="o"&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="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;Auth/LoginForm&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;, // category/unique_name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;LoginForm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// the imported component&lt;/span&gt;

  &lt;span class="na"&gt;tags&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;autodocs&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;parameters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;layout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fullscreen&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="nx"&gt;satisfies&lt;/span&gt; &lt;span class="nx"&gt;Meta&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;LoginForm&lt;/span&gt;&lt;span class="o"&gt;&amp;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;meta&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Story&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;StoryObj&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;meta&lt;/span&gt;&lt;span class="o"&gt;&amp;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;LoginFormLight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Story&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;We define stories according to the Component Story Format (CSF), an ES6 module-based standard that is easy to write and portable between tools.&lt;/p&gt;

&lt;p&gt;The key ingredients are the default export that describes the component, and named exports that describe the stories.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Voila! You now know how to use StoryBook!
&lt;/h2&gt;

&lt;h2&gt;
  
  
  &lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbfhxsnc7bsliq26q68hf.png" alt="Image description" width="800" height="634"&gt;
&lt;/h2&gt;

&lt;p&gt;Do note that I’ve not touched upon powerful features like decorators, adding contexts to stories etc. That’s for another day.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Keep building, keep learning. After all, there’s nothing that teaches like a project!&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Footnotes:
&lt;/h2&gt;

&lt;p&gt;Checkout my repo to see how I’ve used Storybook : &lt;a href="https://github.com/phukon/binary-dreams?tab=readme-ov-file#binary-dreams"&gt;BinaryDreams&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>react</category>
      <category>nextjs</category>
      <category>javascript</category>
    </item>
    <item>
      <title>How I write Commits like a pro</title>
      <dc:creator>phukon</dc:creator>
      <pubDate>Mon, 08 Apr 2024 12:40:11 +0000</pubDate>
      <link>https://forem.com/phukon/how-i-write-commits-like-a-pro-340l</link>
      <guid>https://forem.com/phukon/how-i-write-commits-like-a-pro-340l</guid>
      <description>&lt;p&gt;Crafting effective commit messages is a hallmark of experienced developers. Embracing the Conventional Commits specification stands as a beacon for structuring commit messages. It’s not just a guideline; it’s a pathway to a clearer commit history that harmonizes with &lt;strong&gt;Semantic Versioning (SemVer)&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What are Conventional Commits?
&lt;/h2&gt;

&lt;p&gt;Conventional Commits offer a lightweight yet powerful framework for organizing commit messages. By categorizing changes into distinct types like features, fixes, and breaking changes, it sets a gold standard for clarity and consistency and aligns with Semantic Versioning (SemVer) by categorizing changes into features, fixes, and breaking changes.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Anatomy of a Great Commit Message
&lt;/h2&gt;

&lt;p&gt;When making commits, please use the conventional commit format, which typically follows the pattern of &lt;code&gt;&amp;lt;type&amp;gt;: &amp;lt;description&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;A commit message should follow this structure:&lt;/p&gt;

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

&amp;lt;type&amp;gt;[optional scope]: &amp;lt;description&amp;gt;
[optional body]
[optional footer(s)]


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;p&gt;&lt;code&gt;type&lt;/code&gt;: type of commit&lt;/p&gt;

&lt;p&gt;&lt;code&gt;scope&lt;/code&gt;: Short description of a section of the codebase enclosed in parenthesis followed by a colon and a space. &lt;strong&gt;Messages tend to be in the present and imperative.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;description&lt;/code&gt;: Short description of the code changes&lt;/p&gt;

&lt;p&gt;&lt;code&gt;body&lt;/code&gt;: A longer description of the commit, providing additional context about the changes.&lt;br&gt;
Must be placed one empty line after the description.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;footer&lt;/code&gt;: Fixes issue #3 //example&lt;br&gt;
The footer should only contain additional issue references about the changes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Examples:
&lt;/h2&gt;

&lt;p&gt;A commit I made to solve an issue.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdjvxxhgpgoo5tz5plt4f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdjvxxhgpgoo5tz5plt4f.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

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

feat(homepage): Add carousel feature to showcase testimonials

Implemented a carousel component on the homepage
Added client testimonials section for improved user engagement

Fixes #12


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;More examples:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;feat: Add new rating component&lt;/li&gt;
&lt;li&gt;fix: Resolve issue with city search feature&lt;/li&gt;
&lt;li&gt;docs: Update README with new contribution guidelines&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Types of Commits
&lt;/h2&gt;

&lt;p&gt;In addition to the classic &lt;code&gt;fix&lt;/code&gt;and &lt;code&gt;feat&lt;/code&gt;, we've got a whole buffet of commit types. It's like choosing toppings for your commit pizza:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;build&lt;/code&gt;: Changes related to build processes or tools.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;chore&lt;/code&gt;: Regular maintenance or administrative tasks.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ci&lt;/code&gt;: Updates to the continuous integration setup.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;docs&lt;/code&gt;: Documentation-related changes.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;style&lt;/code&gt;: Changes that do not affect the code’s functionality (e.g., formatting).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;refactor&lt;/code&gt;: Code modifications without changing its behavior.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;perf&lt;/code&gt;: Performance improvements.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;test&lt;/code&gt;: Adding or modifying tests.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can use these types to categorize your commits according to their nature. This helps maintain consistency in commit messages and aids in better organization of changes in the project history.&lt;/p&gt;

&lt;h2&gt;
  
  
  Footnote
&lt;/h2&gt;

&lt;p&gt;For more information on Conventional Commits, visit &lt;a href="https://www.conventionalcommits.org/en/v1.0.0/" rel="noopener noreferrer"&gt;Conventional Commits Specification&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>git</category>
      <category>github</category>
      <category>softwaredevelopment</category>
      <category>fullstack</category>
    </item>
    <item>
      <title>How I Structure my React Projects</title>
      <dc:creator>phukon</dc:creator>
      <pubDate>Sat, 06 Apr 2024 16:36:43 +0000</pubDate>
      <link>https://forem.com/phukon/how-i-structure-my-react-projects-1lk</link>
      <guid>https://forem.com/phukon/how-i-structure-my-react-projects-1lk</guid>
      <description>&lt;p&gt;Ever dreamt of a React app that chuckles at bugs and scoffs at spaghetti code? Let’s embark on a journey to create a React app so robust it could survive an apocalypse of bad coding practices.&lt;/p&gt;

&lt;p&gt;In those novice days, my code resembled a wild creature — functional, yet utterly chaotic. The project structure, if you could call it that, was a disorganized mess. It sufficed for my humble beginnings, &lt;strong&gt;but as the project grew, so did the complexity, and chaos ensued.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Inexperienced dev ⤵&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frzh6wcfl8e0ihwc65e69.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frzh6wcfl8e0ihwc65e69.png" alt="Image description" width="720" height="413"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Experienced dev ⤵&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9yw73s2xo7dxg75wgn66.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9yw73s2xo7dxg75wgn66.png" alt="Image description" width="640" height="511"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With each expansion of the project, finding a specific piece of code became a quest akin to searching for a needle in a haystack, only to realize that the needle was a variable aptly named ‘needle’ buried somewhere deep in the code.&lt;/p&gt;

&lt;p&gt;Take the time to learn how to &lt;strong&gt;structure your React project&lt;/strong&gt; before your codebase transforms into an unsolvable mystery novel.&lt;/p&gt;

&lt;p&gt;How a project should look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;src
|
+-- assets            
|
+-- components        
|
+-- config           
|
+-- features          
|
+-- hooks             
|
+-- lib               
|
+-- providers         
|
+-- routes            
|
+-- stores            
|
+-- test              
|
+-- types             
|
+-- utils            
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;components&lt;/code&gt;: Shared components that grace the entire kingdom&lt;br&gt;
&lt;code&gt;config&lt;/code&gt;: The vault of global configurations, env variables, and &lt;code&gt;secrets&lt;/code&gt;&lt;br&gt;
&lt;code&gt;features&lt;/code&gt;: Feature based modules&lt;br&gt;
&lt;code&gt;hooks&lt;/code&gt;: Mystical hooks, shared across the entire realm&lt;br&gt;
&lt;code&gt;libs&lt;/code&gt;: re-exporting different libraries preconfigured for the application&lt;br&gt;
&lt;code&gt;providers&lt;/code&gt;: Keepers of the application’s life force, the providers&lt;br&gt;
&lt;code&gt;routes&lt;/code&gt;: routes configuration&lt;br&gt;
&lt;code&gt;stores&lt;/code&gt;: global state stores&lt;br&gt;
&lt;code&gt;test&lt;/code&gt;: The arena of trials, where utilities and mock servers prove their mettle&lt;br&gt;
&lt;code&gt;types&lt;/code&gt;: base types used across the application&lt;br&gt;
&lt;code&gt;utils&lt;/code&gt;: shared utility functions&lt;/p&gt;



&lt;p&gt;Now, let’s descend into the heart of a feature.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;src/features/my-new-feature
|
+-- api         # Declarations and API hooks, a symphony of requests for this feature
|
+-- assets      # Treasures specific to the awesome feature
|
+-- components  # Components, artisans sculpting the visual identity of the feature
|
+-- hooks       # Hooks, magical spells woven into the fabric of this feature
|
+-- routes      # Paths leading to the feature's pages, a roadmap of wonder
|
+-- stores      # Keepers of state, guarding the feature's sacred truths
|
+-- types       # TypeScript types, a lexicon for the feature's domain
|
+-- utils       # The craftsmen, building utility functions exclusive to this feature
|
+-- index.ts    # The grand entrance, the public API of this feature, revealing its essence
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The index file
&lt;/h2&gt;

&lt;p&gt;Everything from a feature should be exported from the &lt;code&gt;index.ts&lt;/code&gt; file which behaves as the public API of the feature.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa6srugjczjqlxrt2r9bx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa6srugjczjqlxrt2r9bx.png" alt="Image description" width="688" height="400"&gt;&lt;/a&gt; Notice the index file for each component folder. ⤴&lt;/p&gt;

&lt;p&gt;You should import stuff from other features only by using:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;import {AwesomeComponent} from "@/features/awesome-feature"&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;and not&lt;/p&gt;

&lt;p&gt;&lt;code&gt;import {AwesomeComponent} from "@/features/awesome-feature/components/AwesomeComponent&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Set up absolute imports!
&lt;/h2&gt;

&lt;p&gt;Absolute imports can make your import statements cleaner and more readable. They also help in avoiding long relative import paths.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//  jsconfig.json/tsconfig.json
"compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@/*": ["./src/*"]
    }
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;Remember, every developer, seasoned or fledgling, has danced the maddening tango with spaghetti code. But with structure comes clarity, and with clarity comes the power to wield React with finesse.&lt;/p&gt;

&lt;p&gt;So, as you forge your own path in the realms of frontend development, let this blueprint be your guiding light, your treasure map to organized brilliance. May your React projects chuckle at bugs, scoff at chaos, and stand firm in the face of coding calamities.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Personal links.:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://rkph.me/"&gt;web&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/phukon"&gt;GitHub&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Footnotes:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://github.com/alan2207/bulletproof-react"&gt;https://github.com/alan2207/bulletproof-react&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>webdev</category>
      <category>javascript</category>
      <category>frontend</category>
    </item>
    <item>
      <title>WTF is a Monad?!</title>
      <dc:creator>phukon</dc:creator>
      <pubDate>Mon, 01 Apr 2024 10:12:54 +0000</pubDate>
      <link>https://forem.com/phukon/wtf-is-a-monad-21k8</link>
      <guid>https://forem.com/phukon/wtf-is-a-monad-21k8</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;A monad in X is a monoid in the category of endofunctors of X.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I came across the term MONAD in a meme and when I googled. The above sentence was what I got.&lt;br&gt;
Not very helpful when you’re trying to learn about monads in functional programming isn’t it?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw5bckw4ch34us640f8cj.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw5bckw4ch34us640f8cj.jpg" alt="Image description" width="800" height="404"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  All monads have three components:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Wrapper Type: A wrapper of some sorts that mark the type of the component.&lt;/li&gt;
&lt;li&gt;Wrap Function (allows entry to monad ecosystem): A function that takes normal values and wraps it up in a monad, like a constructor of sorts. These are called return, pure or unit&lt;/li&gt;
&lt;li&gt;Run Function (runs transformations on monadic values): Takes the wrapper type and transform function(not the Wrap Function) that accepts the unwrapped type and returns the wrapper type. Runs the transformation function on the argument passed in. aka bind, flatmap, '&amp;gt;&amp;gt;='' (this symbol)&lt;/li&gt;
&lt;/ul&gt;



&lt;p&gt;Let’s start with some code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="cm"&gt;/**
 * @see [GitHub](https://github.com/phukon/practice/tree/main/monadic-stuff)
 */&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;square&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;addOne&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&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="nf"&gt;addOne&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;square&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)));&lt;/span&gt;
&lt;span class="nx"&gt;The&lt;/span&gt; &lt;span class="nx"&gt;above&lt;/span&gt; &lt;span class="nx"&gt;code&lt;/span&gt; &lt;span class="nx"&gt;demonstrates&lt;/span&gt; &lt;span class="nx"&gt;basic&lt;/span&gt; &lt;span class="nx"&gt;arithmetic&lt;/span&gt; &lt;span class="nx"&gt;operations&lt;/span&gt; &lt;span class="nx"&gt;without&lt;/span&gt; &lt;span class="nx"&gt;using&lt;/span&gt; &lt;span class="nx"&gt;monads&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="nx"&gt;We&lt;/span&gt; &lt;span class="nx"&gt;have&lt;/span&gt; &lt;span class="nx"&gt;simple&lt;/span&gt; &lt;span class="nx"&gt;functions&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="nx"&gt;squaring&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="nx"&gt;and&lt;/span&gt; &lt;span class="nx"&gt;adding&lt;/span&gt; &lt;span class="nx"&gt;one&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Let’s spice it up a bit
&lt;/h3&gt;

&lt;p&gt;We undertake a substantial refactoring of the previous code, introducing a structured format that amalgamates the numerical output with an array of logs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="cm"&gt;/**
 * @see [GitHub](https://github.com/phukon/practice/tree/main/monadic-stuff)
 */&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;NumberWIthLog&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;result&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;logs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[];&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;square&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;NumberWIthLog&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="na"&gt;result&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;logs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;`Squared &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; to get &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;addOne&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;NumberWIthLog&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;NumberWIthLog&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="na"&gt;result&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;logs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;logs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;concat&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
      &lt;span class="s2"&gt;`Added 1 to &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; to get the result &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&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="p"&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="nf"&gt;addOne&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;square&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This restructuring serves as a preparatory step towards implementing a monadic pattern, aimed at proficiently managing computations while concurrently logging operations. Key components within this file include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;NumberWithLog Interface: This encapsulates both the result and log array, enhancing the code’s structural integrity.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Functions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;square: Computes the square of a number and meticulously logs the operation.&lt;/li&gt;
&lt;li&gt;addOne: Increments a given NumberWithLog input by one, effectively documenting this process within the logs.
The provided console log shows the usage of the addOne function on the square of 3.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  But there’s a catch
&lt;/h2&gt;

&lt;p&gt;When working with nested operations like square(square(2)) or addOne(5), we will encounter type mismatches and limitations within our code. To address these issue, we'll delve into implementing a more robust solution using monadic patterns.&lt;/p&gt;

&lt;h3&gt;
  
  
  The ‘NumberWithLog’ Interface
&lt;/h3&gt;

&lt;p&gt;Firstly, we define an interface called NumberWithLog to contain both the numerical result and logs, crucial for our computations.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;NumberWithLog&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;result&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;logs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&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;h2&gt;
  
  
  Creating a Wrapper Function
&lt;/h2&gt;

&lt;p&gt;We introduce a constructive function, wrapWithLogs, serving as a wrapper around a numerical value. It initializes a NumberWithLog object with the input number and an empty log array, priming it for subsequent operations.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="cm"&gt;/**
 * Constructs a 'NumberWithLog' object by wrapping a numerical value.
 * @param x The number to be wrapped within 'NumberWithLog'.
 * @returns A 'NumberWithLog' object initialized with the input number and an empty log array.
 */&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;wrapWithLogs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;NumberWithLog&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="na"&gt;result&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;logs&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Enhanced Functions for Operations
&lt;/h2&gt;

&lt;p&gt;We enhance the square and addOne functions to operate on NumberWithLog objects. square computes the square of a NumberWithLog and meticulously records the operation in the logs. Similarly, addOne increments the result within a NumberWithLog object by one while logging the process.&lt;/p&gt;

&lt;h3&gt;
  
  
  square function
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Tweaked versions of square and addOne functions to operate on NumberWithLog&lt;/span&gt;

&lt;span class="cm"&gt;/**
 * Computes the square of a 'NumberWithLog' and records the operation in logs.
 * @param x The 'NumberWithLog' object whose result will be squared.
 * @returns A 'NumberWithLog' object with the squared result and updated logs.
 */&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;square&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;NumberWithLog&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;NumberWithLog&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="na"&gt;result&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;logs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;`Squared &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; to get &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  addOne function
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="cm"&gt;/**
 * Adds one to the 'NumberWithLog' result and logs the operation.
 * @param x The 'NumberWithLog' object to which one will be added.
 * @returns A 'NumberWithLog' object with the incremented result and updated logs.
 */&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;addOne&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;NumberWithLog&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;NumberWithLog&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="na"&gt;result&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;logs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;logs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;concat&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
      &lt;span class="s2"&gt;`Added 1 to &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; to get the result &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Utilizing the Functions
&lt;/h2&gt;

&lt;p&gt;To showcase the functionality, we display the result of square(square(wrapWithLogs(2))) in the console. This demonstrates the nested application of these functions and the effective handling of computations and logging within our codebase.&lt;/p&gt;

&lt;p&gt;By leveraging these techniques, we resolve the type mismatch issues.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="cm"&gt;/**
 * Issues:
 * As evident, the previous implementation faces limitations with nested operations like square(square(2)) or addOne(5),
 * resulting in type mismatches. We aim to resolve this issue with a new function that acts as a constructor-like wrapper.
 * This wrapper function encapsulates the input within the 'NumberWithLog' structure to facilitate nested operations.
 * 
 * @see [GitHub](https://github.com/phukon/practice/tree/main/monadic-stuff) 
*/&lt;/span&gt;

&lt;span class="c1"&gt;// Interface to hold both the result and logs&lt;/span&gt;
&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;NumberWithLog&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;result&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;logs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[];&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="cm"&gt;/**
 * Constructs a 'NumberWithLog' object by wrapping a numerical value.
 * @param x The number to be wrapped within 'NumberWithLog'.
 * @returns A 'NumberWithLog' object initialized with the input number and an empty log array.
 */&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;wrapWithLogs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;NumberWithLog&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="na"&gt;result&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;logs&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="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Tweaked versions of square and addOne functions to operate on NumberWithLog&lt;/span&gt;

&lt;span class="cm"&gt;/**
 * Computes the square of a 'NumberWithLog' and records the operation in logs.
 * @param x The 'NumberWithLog' object whose result will be squared.
 * @returns A 'NumberWithLog' object with the squared result and updated logs.
 */&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;square&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;NumberWithLog&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;NumberWithLog&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="na"&gt;result&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;logs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;`Squared &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; to get &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&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="cm"&gt;/**
 * Adds one to the 'NumberWithLog' result and logs the operation.
 * @param x The 'NumberWithLog' object to which one will be added.
 * @returns A 'NumberWithLog' object with the incremented result and updated logs.
 */&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;addOne&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;NumberWithLog&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;NumberWithLog&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="na"&gt;result&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;logs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;logs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;concat&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
      &lt;span class="s2"&gt;`Added 1 to &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; to get the result &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&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="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Displaying the result of square(square(wrapWithLogs(2)))&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="nf"&gt;addOne&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;square&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;wrapWithLogs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;))));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The Monad
&lt;/h2&gt;

&lt;p&gt;We starts by addressing a challenge faced in prior implementations when dealing with nested operations like square(square(2)) or addOne(5). Attempting to modify square and addOne to accommodate ‘NumberWithLog’ inputs led to rendering these original functions obsolete.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Monadic Revelation:
&lt;/h3&gt;

&lt;p&gt;Enter ‘runWithLogs’, a game-changer in the landscape of this challenge. This higher-order function revolutionizes the approach without altering existing functions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="cm"&gt;/**
 * Executes a transformation on a 'NumberWithLog' object using the provided function
 * and logs the operations performed.
 * @param input The 'NumberWithLog' object to transform.
 * @param transform The transformation function to apply to the 'NumberWithLog' object.
 * @returns A 'NumberWithLog' object after applying the transformation and logging the operations.
 */&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;runWithLogs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;NumberWithLog&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&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;NumberWithLog&lt;/span&gt;
&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;NumberWithLog&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;newNumberWithLog&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;result&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="na"&gt;result&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;newNumberWithLog&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;logs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;logs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;concat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newNumberWithLog&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;logs&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;p&gt;It gracefully accepts NumberWithLog objects and transformation functions, enabling seamless chaining of operations while retaining meticulous logs. This paradigm shift aligns with the monadic pattern, offering enhanced flexibility, maintainability, and a definitive resolution to type mismatch issues.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Example usage of 'runWithLogs' function to chain operations on 'NumberWithLog' object&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;wrapWithLogs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&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;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;runWithLogs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;addOne&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;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;runWithLogs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;square&lt;/span&gt;&lt;span class="p"&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="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A simple console log demonstrates the prowess of ‘runWithLogs’, showcasing its ability to seamlessly chain ‘addOne’ and ‘square’ operations on a ‘NumberWithLog’ object initialized with a value of 2.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mapping the components to the code in this tutorial
&lt;/h2&gt;

&lt;p&gt;Remember I said that all monads have three components? This is how our code maps to the components :-&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Wrapper Type: NumberWithLog&lt;/li&gt;
&lt;li&gt;Wrap Function: function wrapWithLogs&lt;/li&gt;
&lt;li&gt;Run Function: function runWithLogs&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Animation
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fse8lrfyqdc1nb79jwdko.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fse8lrfyqdc1nb79jwdko.gif" alt="Image description" width="1212" height="681"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you look closely, Monads allow a user to chain operations while the Monad manages the secret work behind the scenes.&lt;/p&gt;




&lt;p&gt;Footnotes:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=ENo_B8CZNRQ"&gt;A monad is a monoid in the category of endofunctors. Whats the problem?&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.youtube.com/watch?v=t1e8gqXLbsU"&gt;What is a Monad? — Computerphile&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.youtube.com/watch?v=C2w45qRc3aU"&gt;The Absolute Best Intro to Monads For Software Engineers&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>typescript</category>
      <category>lambda</category>
      <category>computerscience</category>
    </item>
  </channel>
</rss>
