<?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>DEV Community: bob.ts</title>
    <description>The latest articles on DEV Community by bob.ts (@rfornal).</description>
    <link>https://dev.to/rfornal</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%2F122951%2F11c1127c-0459-46ed-97b9-502fe31ead65.jpg</url>
      <title>DEV Community: bob.ts</title>
      <link>https://dev.to/rfornal</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rfornal"/>
    <language>en</language>
    <item>
      <title>What is CodeMash?</title>
      <dc:creator>bob.ts</dc:creator>
      <pubDate>Wed, 21 Jan 2026 18:14:00 +0000</pubDate>
      <link>https://dev.to/rfornal/what-is-codemash-1g0f</link>
      <guid>https://dev.to/rfornal/what-is-codemash-1g0f</guid>
      <description>&lt;h1&gt;
  
  
  CodeMash
&lt;/h1&gt;

&lt;p&gt;CodeMash is a conference that runs early in January each year at the &lt;a href="https://www.kalahariresorts.com/ohio/" rel="noopener noreferrer"&gt;Kalahari&lt;/a&gt; in Sandusky, Ohio.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F70pgzn029f9gh0h990ef.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F70pgzn029f9gh0h990ef.png" alt="CodeMash gear head on an orange background" width="800" height="336"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  30-second Overview
&lt;/h2&gt;

&lt;p&gt;A few weeks before the conference, I was asked to provide a 30-second overview of the event. I went on for &lt;strong&gt;more than 10 minutes&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who I Am
&lt;/h2&gt;

&lt;p&gt;I am Bob Fornal:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A Senior Solutions Developer II with &lt;a href="http://leadingedje.com/" rel="noopener noreferrer"&gt;Leading EDJE, Inc.&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;A Microsoft MVP (information &lt;a href="https://mvp.microsoft.com/" rel="noopener noreferrer"&gt;HERE&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;A &lt;a href="https://platform.torc.dev/#/r/nYlXxsSi/cp" rel="noopener noreferrer"&gt;Torc Ambassador&lt;/a&gt;: their community is amazing (Discord &lt;a href="https://discord.com/invite/N2A9PkJJfG" rel="noopener noreferrer"&gt;HERE&lt;/a&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And, I work with the Board for CodeMash:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I am on the Speaker Selection Committee (I help pick the amazing talks).&lt;/li&gt;
&lt;li&gt;I am on the Safety Committee.&lt;/li&gt;
&lt;li&gt;I am on the DEI Committee.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I do a lot for the conference because it means something to me. This year, I volunteered and proctored many sessions, going beyond just participating.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fxawhkdsug6bdgmno2tut.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fxawhkdsug6bdgmno2tut.jpg" alt=" " width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;My wife and kids participate:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;My son has attended &lt;a href="https://codemash.org/kidzmash/" rel="noopener noreferrer"&gt;KidzMash&lt;/a&gt; with me for the last 6 years (KidzMash is free).&lt;/li&gt;
&lt;li&gt;My wife and daughter come up on Friday and stay until Sunday (my time to decompress).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Kalahari
&lt;/h2&gt;

&lt;p&gt;The Kalahari is not just a conference center. It is a hotel, conference center, and water park - all in one. It's amazing to be there for a week and never go outside!&lt;/p&gt;

&lt;h2&gt;
  
  
  KidzMash
&lt;/h2&gt;

&lt;p&gt;As I said, KidzMash is free (they do need an adult present), and there are workshops and sessions just for them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Workshops
&lt;/h2&gt;

&lt;p&gt;Tuesday &amp;amp; Wednesday are workshop sessions (generally 4 hours) where we learn and put the skills to the test. This is the time to build and create things.&lt;/p&gt;

&lt;p&gt;This year, I got to proctor for two close friends and two co-workers. It was a lot of fun helping their workshops come to life!&lt;/p&gt;

&lt;h2&gt;
  
  
  Sessions
&lt;/h2&gt;

&lt;p&gt;Thursday &amp;amp; Friday are what most would consider regular sessions. Quite a few attendees are here for just these two days. There are more people and the pace is faster; it becomes much more fun.&lt;/p&gt;

&lt;p&gt;I got to present on "Ditch your JavaScript for CSS!"&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F6g82g4dxkyo7v6x2hbo5.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F6g82g4dxkyo7v6x2hbo5.jpg" alt=" " width="800" height="326"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Additionally, I got to proctor four amazing talks (yes, some of the talks that I selected) and learn from my peers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Maker Space
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://codemash.org/makerspace/" rel="noopener noreferrer"&gt;MakerSpace&lt;/a&gt; is the "umbrella" that includes 3d printing, an electronics lab, hands-on sessions, and traditional presentations on Maker topics!&lt;/p&gt;

&lt;h2&gt;
  
  
  Sponsors
&lt;/h2&gt;

&lt;p&gt;This year's sponsor list is &lt;a href="https://events.codemash.org/2026CodeMashConference#/OurSponsors" rel="noopener noreferrer"&gt;HERE&lt;/a&gt;. These are the organizations that make a conference like this happen. They should always get a shout-out!&lt;/p&gt;

&lt;h2&gt;
  
  
  Outreach
&lt;/h2&gt;

&lt;p&gt;This year, we got snow.&lt;/p&gt;

&lt;p&gt;No real surprise.&lt;/p&gt;

&lt;p&gt;The weather hindered our outreach program because the high school sending students was closed.&lt;/p&gt;

&lt;p&gt;The plan was for them to attend a few sessions, have lunch with some of the speakers and attendees, and lead a workshop of their own.&lt;/p&gt;

&lt;p&gt;Maybe next year.&lt;/p&gt;

&lt;h2&gt;
  
  
  And, more ...
&lt;/h2&gt;

&lt;p&gt;Seriously.&lt;/p&gt;

&lt;p&gt;There is so much more to this conference that I haven't even touched (lightning talks, dinners with co-workers and friends, etc.).&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;CodeMash&lt;/strong&gt; is a fun and amazing conference.&lt;/p&gt;

&lt;p&gt;It's impossible to cover all the amazing things that go on at CodeMash.&lt;/p&gt;

&lt;p&gt;I am truly proud that they allow me to be such a significant part of this event that brings so much to our community!&lt;/p&gt;

</description>
      <category>softwaredevelopment</category>
      <category>career</category>
      <category>learning</category>
      <category>community</category>
    </item>
    <item>
      <title>Pixel-Perfect Designs versus AI</title>
      <dc:creator>bob.ts</dc:creator>
      <pubDate>Fri, 31 Oct 2025 15:43:00 +0000</pubDate>
      <link>https://dev.to/rfornal/pixel-perfect-designs-versus-ai-278h</link>
      <guid>https://dev.to/rfornal/pixel-perfect-designs-versus-ai-278h</guid>
      <description>&lt;h2&gt;
  
  
  Artificial Intelligence
&lt;/h2&gt;

&lt;p&gt;I see the boom and I poke at AI. I've got a pretty good understanding of Artificial Intelligence (AI), Machine Learning (ML), and Data Science. I will NEVER say I'm an expert, but I can hold my own when necessary.&lt;/p&gt;

&lt;p&gt;My fear has always been misuse.&lt;/p&gt;

&lt;p&gt;I've heard stories ...&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;People losing work.&lt;/li&gt;
&lt;li&gt;Databases getting deleted.&lt;/li&gt;
&lt;li&gt;Students using AI generated products and feeling the understand the content (code or otherwise).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Is there a place for AI in the coding world?&lt;/p&gt;

&lt;p&gt;I &lt;strong&gt;firmly believe&lt;/strong&gt; there is and that we're just beginning to scratch the surface of "good implementations."&lt;/p&gt;

&lt;p&gt;I &lt;strong&gt;also firmly believe&lt;/strong&gt; that we've got more "poor implementations" than good.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Pixel-Perfect Design
&lt;/h2&gt;

&lt;p&gt;A friend of mine, someone that is a good developer, asked me to step in and help him learn CSS.&lt;/p&gt;

&lt;h3&gt;
  
  
  Learning CSS
&lt;/h3&gt;

&lt;p&gt;This is a huge task, &lt;em&gt;monumental&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;I started researching and built an outline of content.&lt;/p&gt;

&lt;p&gt;This could be ...&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A new course for &lt;strong&gt;&lt;a href="https://code-squid.com" rel="noopener noreferrer"&gt;Code Squid&lt;/a&gt;&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;A series of articles.&lt;/li&gt;
&lt;li&gt;A series of videos.&lt;/li&gt;
&lt;li&gt;A series of conference presentations.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Oh, my ...&lt;/p&gt;

&lt;h3&gt;
  
  
  Back to the Design
&lt;/h3&gt;

&lt;p&gt;Yesterday, he showed me the Adobe XD design. It wasn't complicated. He told me that his company truly wanted a pixel-perfect design.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pixel-perfect&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F8vjqe4vg17a8fa7nmwqa.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F8vjqe4vg17a8fa7nmwqa.jpg" alt=" " width="800" height="336"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Pixel-perfect design is the meticulous creation of digital designs where every element is rendered exactly as intended, with precise attention to detail, alignment, spacing, and visual consistency across all devices and screens. It involves ensuring that the final product, such as a website or app, appears the same to users as it does in the original design file, paying close attention to every pixel. This approach aims for visual fidelity by meticulously controlling aspects like typography, color, and layout, using tools and systems to achieve exact specifications.&lt;br&gt;
&lt;a href="https://matridtech.net/what-is-actually-pixel-perfect-design-and-how-to-create-it/" rel="noopener noreferrer"&gt;What Is Actually Pixel Perfect Design and How to Create It?&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Then, I asked him to show me how he was working. What I saw was painful to watch.&lt;/p&gt;

&lt;p&gt;He showed me the code related to the design he was working on. We started with adjusting a breadcrumb element under the header.&lt;/p&gt;

&lt;p&gt;Then, I saw a strong, mid-level developer go into the DOM and select the element, right-click, and copy the element. Within his AI-tool of choice, he pasted the element an prompted it to "change the margin to 24px". This prompting had to be adjusted a few times to get the result "pixel-perfect."&lt;/p&gt;

&lt;p&gt;I actually watched him do this a few times.&lt;/p&gt;

&lt;p&gt;I asked about the title on the breadcrumb since it wasn't right.&lt;/p&gt;

&lt;p&gt;He started to write a prompt to change the text on the breadcrumb using the same copy, paste, prompt method.&lt;/p&gt;

&lt;p&gt;At this point, I stopped him ...&lt;/p&gt;

&lt;h2&gt;
  
  
  Confrontation
&lt;/h2&gt;

&lt;p&gt;I stopped him and asked why he was using AI for such simple tasks.&lt;/p&gt;

&lt;p&gt;In this case, doing a global search for the text to change yielded 3 results. The third value was the one that needed changed.&lt;/p&gt;

&lt;p&gt;This &lt;strong&gt;whole process&lt;/strong&gt; really relied on basic problem solving:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Define the problem (incorrect text).&lt;/li&gt;
&lt;li&gt;Generate potential solutions (the text probably exists within the project, find it and change it).&lt;/li&gt;
&lt;li&gt;Choose the best solution (step through the three versions and see if the content on-screen changes).&lt;/li&gt;
&lt;li&gt;Implement the solution (save).&lt;/li&gt;
&lt;li&gt;Evaluate the results (verified when changed above).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F8hvu22b05ss72875q4ee.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F8hvu22b05ss72875q4ee.jpg" alt=" " width="800" height="448"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;whole process&lt;/strong&gt; took just a few seconds and relied on problem solving skills. It didn't have to be offloaded to a tool&lt;/p&gt;

&lt;p&gt;I confronted him.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You have the skill to solve these problems. Try to do it yourself and learn rather than offloading the problem onto a tool that &lt;em&gt;might&lt;/em&gt; be able to solve the problem. Use the AI-tool when you get stuck and &lt;strong&gt;learn&lt;/strong&gt; from the answers provided.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Pixel-Perfect
&lt;/h2&gt;

&lt;p&gt;I confronted him ... and presented things in a different light.&lt;/p&gt;

&lt;p&gt;A pixel-perfect design is difficult to achieve.&lt;/p&gt;

&lt;p&gt;I suggested that this is as important as any online code challenge. The skills he can gain as a frontend developer will take him to a completely different level.&lt;/p&gt;

&lt;p&gt;Pixel-perfect designs were the most challenging for me, and the most fun. I am extremely good at what I do as a frontend developer and a lot of that comes to doing this kind of development work early in my career.&lt;/p&gt;

&lt;h2&gt;
  
  
  Notes from a Friend
&lt;/h2&gt;

&lt;p&gt;This is a different friend.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;People need to be a "good or GREAT" prompt engineers to use AI since AI's age level is (currently) around 5-8 years old brain. You have to explain in detail, and I mean every detail, then it will execute it correctly. It's all about weights in training. Most people don't know how AI is trained. They just want to use it and think it is on par with talking to a mid level developer or mid level expert -- which is all hyped up by social media.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;There's nothing "intelligent" in todays AI.&lt;/p&gt;

&lt;p&gt;It's an extremely good search engine that is providing results efficiently and in a &lt;em&gt;human-like&lt;/em&gt; manner.&lt;/p&gt;

&lt;p&gt;That doesn't mean it's bad. It's not a bad set of tools; neither is it a good set of tools. It's just simply that, a tool.&lt;/p&gt;

&lt;p&gt;If the tool is used correctly, you get good results.&lt;/p&gt;

&lt;p&gt;If the tool us used incorrectly, you get bad results.&lt;/p&gt;

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

&lt;p&gt;I understand that AI is everywhere and my fear has always been misuse.&lt;/p&gt;

&lt;p&gt;This is one more story.&lt;/p&gt;

&lt;p&gt;My friend is looking to do the best job he can and is doubting his abilities (maybe a bit of &lt;strong&gt;&lt;em&gt;imposter syndrome&lt;/em&gt;&lt;/strong&gt;). The results that AI can generate for him are alluring.&lt;/p&gt;

&lt;p&gt;The reality is, that at the end of the day he's got the skill and can do the job, he just needs to see it in himself.&lt;/p&gt;

&lt;p&gt;Is there a place for AI in the coding world?&lt;/p&gt;

&lt;p&gt;I &lt;strong&gt;firmly believe&lt;/strong&gt; there is and that we're just beginning to scratch the surface of "good implementations."&lt;/p&gt;

&lt;p&gt;I &lt;strong&gt;also firmly believe&lt;/strong&gt; that we've got more "poor implementations" than good.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>ai</category>
      <category>webdev</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Lazy-Loading as a Security Measure</title>
      <dc:creator>bob.ts</dc:creator>
      <pubDate>Mon, 06 Oct 2025 16:20:00 +0000</pubDate>
      <link>https://dev.to/rfornal/lazy-loading-as-a-security-measure-3odb</link>
      <guid>https://dev.to/rfornal/lazy-loading-as-a-security-measure-3odb</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Recently, an external red team (security) discovered a unique vulnerability in an application I maintain.&lt;/p&gt;

&lt;p&gt;All other work on this project has stopped until we get it not just patched, but appropriately fixed.&lt;/p&gt;

&lt;p&gt;The initial patch was simply a means of plugging the hole. It is intended to be temporary and something we can get in place quickly. While thinking about the patch, I had an odd thought.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;My thought, "Can lazy loading be used to protect our sensitive code?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Lazy loading has always been a means for me to make my code run faster and more efficiently. In most cases, I've skipped using it unless there was a specific need for a faster implementation.&lt;/p&gt;

&lt;p&gt;With the thought of protecting sensitive code in mind, I began conducting some research...&lt;/p&gt;

&lt;h2&gt;
  
  
  Lazy Loading
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.geeksforgeeks.org/angular-js/implementing-lazy-loading-in-angular/" rel="noopener noreferrer"&gt;Implementing Lazing Loading in Angular - GeeksForGeeks&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Server-Side Rendering
&lt;/h2&gt;

&lt;p&gt;Applications that rely heavily on server-side rendering typically do not experience this issue.&lt;/p&gt;

&lt;p&gt;The login page is rendered and shown. Once logged in, the server-side will present the sensitive pages as needed. If correctly designed, they will only load the content and endpoints required.&lt;/p&gt;

&lt;h3&gt;
  
  
  Angular
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Angular lazy loading is a technique used to improve the performance of Angular applications by loading modules or components only when they are needed, rather than loading everything at the initial application startup.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Module splitting&lt;/li&gt;
&lt;li&gt;Route configuration&lt;/li&gt;
&lt;li&gt;On-demand loading&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The benefits are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Faster initial load times&lt;/li&gt;
&lt;li&gt;Improved performance&lt;/li&gt;
&lt;li&gt;Reduced bandwidth usage&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Implementing Angular Lazy Loading ...
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// app-routing.module.ts&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;NgModule&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;@angular/core&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;RouterModule&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Routes&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;@angular/router&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;routes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Routes&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;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;redirectTo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/home&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;pathMatch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;full&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;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;home&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;loadChildren&lt;/span&gt;&lt;span class="p"&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="k"&gt;import&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./home/home.module&lt;/span&gt;&lt;span class="dl"&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;m&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;HomeModule&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;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;admin&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;loadChildren&lt;/span&gt;&lt;span class="p"&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="k"&gt;import&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./admin/admin.module&lt;/span&gt;&lt;span class="dl"&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;m&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;AdminModule&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="nd"&gt;NgModule&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;imports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;RouterModule&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forRoot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;routes&lt;/span&gt;&lt;span class="p"&gt;)],&lt;/span&gt;
  &lt;span class="na"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;RouterModule&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="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AppRoutingModule&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;Angular (in newer versions) also allows for the lazy loading of individual components or parts of templates using the &lt;code&gt;defer&lt;/code&gt; block. This offers even finer-grained control over when content is loaded, with options for triggers and placeholders.&lt;/p&gt;

&lt;h3&gt;
  
  
  React
&lt;/h3&gt;

&lt;p&gt;React lazy loading, also known as code-splitting, is a performance optimization technique that allows you to defer the loading of specific components until they are actually needed. This significantly reduces the initial bundle size, improving the application's loading time and overall performance.&lt;/p&gt;

&lt;p&gt;This includes ...&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reduced initial loading time&lt;/li&gt;
&lt;li&gt;Improved performance&lt;/li&gt;
&lt;li&gt;Optimized resource usage&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The benefits are ...&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Large or complex components&lt;/li&gt;
&lt;li&gt;Route-based code splitting&lt;/li&gt;
&lt;li&gt;Components with heavy dependencies&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  How to implement React lazy loading ...
&lt;/h4&gt;

&lt;p&gt;React provides built-in features, &lt;code&gt;React.lazy()&lt;/code&gt; and &lt;code&gt;Suspense&lt;/code&gt;, for implementing lazy loading.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&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;Suspense&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;OtherComponent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;lazy&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./OtherComponent&lt;/span&gt;&lt;span class="dl"&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;MyComponent&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;&lt;/span&gt;&lt;span class="nc"&gt;Suspense&lt;/span&gt; &lt;span class="na"&gt;fallback&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;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Loading...&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;OtherComponent&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="nc"&gt;Suspense&lt;/span&gt;&lt;span class="p"&gt;&amp;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;
  
  
  Vue and more
&lt;/h2&gt;

&lt;p&gt;Vue does something similar to React. I won't rehash that for simplicity's sake.&lt;/p&gt;

&lt;p&gt;I was asked about lazy-loading JavaScript code that should be protected natively. This is an interesting side track that I haven't explored yet, but I might delve into it in a future article.&lt;/p&gt;

&lt;h2&gt;
  
  
  Safe Lazy Loading
&lt;/h2&gt;

&lt;p&gt;My research was shocking ... to me.&lt;/p&gt;

&lt;p&gt;Only one of the frameworks or libraries even hinted at using lazy loading for security reasons, "code splitting." Security was not mentioned.&lt;/p&gt;

&lt;p&gt;In a more recent conversation, I realized that applications rendered server-side would be more protected by the implementation I'm discussing here.&lt;/p&gt;

&lt;p&gt;The sensitive code isn't returned until proper authentication occurs. Having said this, we still need to be careful about how much of the application is loaded; are we exposing more code than is necessary, even to logged-in users?&lt;/p&gt;

&lt;h3&gt;
  
  
  Implementation
&lt;/h3&gt;

&lt;p&gt;I've been exploring Microsoft's MSAL tooling and came across this code. There's nothing complicated here ...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&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;request&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;loginHint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name@example.com&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;scopes&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;User.Read&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="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;login&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="nx"&gt;error&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useMsalAuthentication&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;InteractionType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Silent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;request&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;login&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;InteractionType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Popup&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;request&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;error&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;accounts&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useMsal&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;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Anyone can see this paragraph.&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&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="nc"&gt;AuthenticatedTemplate&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;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Signed in as: &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;accounts&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]?.&lt;/span&gt;&lt;span class="nx"&gt;username&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;p&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="nc"&gt;AuthenticatedTemplate&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="nc"&gt;UnauthenticatedTemplate&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;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;No users are signed in!&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&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="nc"&gt;UnauthenticatedTemplate&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;... but ...&lt;/p&gt;

&lt;p&gt;The code &lt;code&gt;&amp;lt;p&amp;gt;Signed in as: {accounts[0]?.username}&amp;lt;/p&amp;gt;&lt;/code&gt;, while not an issue as written, could just as easily be &lt;code&gt;&amp;lt;complex-application /&amp;gt;&lt;/code&gt; that has tons of JavaScript available that could expose threat vectors.&lt;/p&gt;

&lt;p&gt;In my opinion, this is the ideal scenario to utilize the &lt;code&gt;&amp;lt;Suspense&amp;gt;&lt;/code&gt; element and &lt;code&gt;React.lazy()&lt;/code&gt; functionality to protect the code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Thoughts
&lt;/h2&gt;

&lt;p&gt;There is definitely more that I need to consider. There is definitely more research that I need to do. There's a depth of authentication and authorization that needs to be taken into account to protect the client's code and data appropriately.&lt;/p&gt;

&lt;p&gt;Having recently gone to a talk on &lt;a href="https://www.youtube.com/watch?v=XHIx4I3iI7I" rel="noopener noreferrer"&gt;"Data Validation and Sanitation&lt;/a&gt; by &lt;a href="https://www.linkedin.com/in/clairebourdondeveloper/" rel="noopener noreferrer"&gt;Claire Bourdon&lt;/a&gt;, I'm thinking of this as a "lifecycle" of security - maybe it's a "generational" handling. Whatever it's called, I'm realizing that there's more depth to protecting my code than I saw before.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fkgs5uvtyuysjhkg0vfiy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fkgs5uvtyuysjhkg0vfiy.png" alt="Traditional SPA versus Lazy Loaded SPA" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Examining the traditional SPA methodology, where everything is loaded at once, reveals "all code," including code that should be secure. Using &lt;strong&gt;LAZY LOADING&lt;/strong&gt; allows us to protect that code in a much more meaningful way. &lt;strong&gt;&lt;em&gt;This isn't a complete security solution&lt;/em&gt;&lt;/strong&gt;, but it's a significant step that should be taken into account when developing frontend code.&lt;/p&gt;

&lt;p&gt;Whenever code is loaded into the browser, it can be read or scanned. Sensitive information can be exposed unintentionally. We should limit exposure by using lazy loading and not solely relying on server-side security operations.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;My thought now is, "Should lazy loading be used to protect our sensitive code, beyond what is done server-side?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It absolutely should be used for improved code security.&lt;/p&gt;

&lt;p&gt;Please let me know your thoughts.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>security</category>
      <category>architecture</category>
      <category>frontend</category>
    </item>
    <item>
      <title>GemCity TECH Mini-Conference</title>
      <dc:creator>bob.ts</dc:creator>
      <pubDate>Mon, 14 Apr 2025 18:09:16 +0000</pubDate>
      <link>https://dev.to/rfornal/gemcity-tech-mini-conference-23i8</link>
      <guid>https://dev.to/rfornal/gemcity-tech-mini-conference-23i8</guid>
      <description>&lt;p&gt;Yesterday, I got the chance to go to a wonderful mini-conference put on by some amazing friends in Dayton, Ohio.&lt;/p&gt;

&lt;p&gt;Here are my insights and notes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Insights from Recent Conference Talks: Ethical Hacking, Asynchronous Programming, Leadership, Scaling, and Modern Architectures
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Ethical Hacking in the Age of AI by Brett Ewing
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Check out Brett Ewing's profile &lt;a href="https://www.linkedin.com/in/brettewing/" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fpfrwz9h48pumgq9d26vw.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fpfrwz9h48pumgq9d26vw.jpg" alt="Brett Ewing in front of the screen" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Brett Ewing's talk on ethical hacking emphasized a crucial point: trust. "Ethical hacking isn't about code - it's about trust," he stressed. The ethical hacker's toolkit includes vulnerability scans to identify what's broken, penetration tests to understand how weaknesses can be exploited, and the red hat technique which involves hiding to test how long an invader can go undetected.&lt;/p&gt;

&lt;p&gt;But as AI introduces new attack vectors, with attacks increasing in frequency and sophistication, there's an essential need to instill a layer of personal trust in addition to technical prowess. As AI enhances human connections instead of replacing them, our focus should be on teaching our machines what is important to us, hence revealing our priorities.&lt;/p&gt;

&lt;p&gt;Deepfakes represent a battlefield where AIs clash with trust instead of humans directly. To combat this, real relationships and ethical usage of screen time in meetings are vital. Building ethically sound AI tools depends on reflecting our values in the training data.&lt;/p&gt;

&lt;h3&gt;
  
  
  Understanding Asynchronous Programming with JavaScript by Brandon Bruno
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Discover more about Brandon Bruno &lt;a href="https://sessionize.com/s/brandonbruno/this-is-a-promise-that-youll-understand-asynchrono/54420" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is a talk I've seen before. It's totally different than my asynchronous JavaScript talk - and that's part of the fun!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fhmumbd5375c92547ergu.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fhmumbd5375c92547ergu.jpg" alt="Brandon Bruno in front of the screen" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Brandon Bruno delivered a great session on asynchronous programming in JavaScript, demystifying a topic that often confuses developers. Understanding promises and their role in managing asynchronous operations is key to creating responsive and efficient JavaScript applications.&lt;/p&gt;

&lt;p&gt;A promise in JavaScript can be pending, fulfilled, or rejected. Modern APIs and practices such as &lt;code&gt;async/await&lt;/code&gt; allow for more straightforward syntax, unwrapping them for easier readability. Tools like &lt;code&gt;Promise.all&lt;/code&gt;, &lt;code&gt;Promise.allSettled&lt;/code&gt;, and &lt;code&gt;Promise.race&lt;/code&gt; provide control over concurrent promise execution, solving issues like the "pyramid of doom" inherent in callback-based code.&lt;/p&gt;

&lt;h3&gt;
  
  
  Leadership is Earned by Phil Japikse
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Learn more about Phil Japikse &lt;a href="https://sessionize.com/s/skimedic/leaders-are-made-not-born/7266" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F60ep3l3p9qs64zenla4s.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F60ep3l3p9qs64zenla4s.jpg" alt="Phil Japikse in front of the screen" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Phil Japikse's thought-provoking session highlighted that leaders are made, not born. The journey begins with respect—giving it to get it. A mentor’s role is critical, acting as a guide, teacher, supporter, and encourager. Effective leadership involves anticipating change, adapting rather than reacting, and embracing continuous improvement.&lt;/p&gt;

&lt;p&gt;Essential practices for leaders include active listening, honesty, clarity, and effective communication. Leaders must prioritize team success by removing roadblocks, coaching, and using power wisely.&lt;/p&gt;

&lt;h3&gt;
  
  
  Scaling with Nx Strategies by Jordan Powell
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;More about Jordan Powell &lt;a href="https://sessionize.com/s/jordan/the-art-of-scaling-nx-strategies-for-enterprises/132057" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fs97bw1lywh4q4hu9wgyp.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fs97bw1lywh4q4hu9wgyp.jpg" alt="Jordan Powell in front of the screen" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Jordan Powell's session tackled the art of scaling through Nx strategies, especially focusing on monorepos. Larger organizations benefit from code sharing, reuse, and consistency found in monorepos, along with simplified dependencies and atomic commits.&lt;/p&gt;

&lt;p&gt;The business impact includes improved developer experience, better addressing of business problems, and more significant outcomes. However, monorepos come with their challenges, including scalability issues, codebase complexity, and slow CI processes. Addressing these requires specialized tooling and infrastructure management, coupled with efficient access control and security measures.&lt;/p&gt;

&lt;h3&gt;
  
  
  Modern Architectures with Microservices by Shawn Wallace
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Explore Shawn Wallace's work &lt;a href="https://sessionize.com/s/shawn-wallace/event-driven-architecture-micro-services-and-the-c/22017" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fi18h91awxf6hxsrh4awd.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fi18h91awxf6hxsrh4awd.jpg" alt="Shawn Wallace in front of the screen" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Shawn Wallace discussed the advantages of moving away from monolithic to microservices architectures. Monolithic applications are cumbersome and slow to change. Modern architectures that are scalable, resilient, fault-tolerant, and support incremental development are essential.&lt;/p&gt;

&lt;p&gt;Event-driven architecture ensures domains can communicate effectively, often through an enterprise service bus. Key principles include embracing eventual consistency databases, efficient data storage and querying, asynchronous updates, and adopting a schema design that prioritizes performance.&lt;/p&gt;

&lt;p&gt;Before implementation, start small, think about events, not endpoints, and wrap or adapt legacy systems incrementally. Monitoring and logging from the start are critical for success.&lt;/p&gt;

&lt;h3&gt;
  
  
  Thank you
&lt;/h3&gt;

&lt;p&gt;Thank you to the amazing team that actually made this event happen!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Foscyhy5kgnpnmmd6cyal.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Foscyhy5kgnpnmmd6cyal.jpg" alt="GemCity TECH Staff after the event" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;Each session delivered insights that are immensely valuable to today’s evolving technological landscape. From ethical hacking and the nuances of asynchronous programming to leadership in tech, strategies for scaling, and modern architectural practices, these thought leaders shared actionable wisdom for the betterment of our craft and practices. Whether it’s enhancing trust in AI, understanding JavaScript promises, building effective leadership, scaling applications, or adopting microservices, continuous learning and adaptation remain the keys to success.&lt;/p&gt;

</description>
      <category>development</category>
      <category>architecture</category>
      <category>leadership</category>
      <category>security</category>
    </item>
    <item>
      <title>GemCity TECH: Tech Roulette</title>
      <dc:creator>bob.ts</dc:creator>
      <pubDate>Thu, 13 Mar 2025 02:45:42 +0000</pubDate>
      <link>https://dev.to/rfornal/gemcity-tech-tech-roulette-oln</link>
      <guid>https://dev.to/rfornal/gemcity-tech-tech-roulette-oln</guid>
      <description>&lt;h2&gt;
  
  
  The Event
&lt;/h2&gt;

&lt;p&gt;Dayton has always been a special place for me for several reasons. So, when I heard about this event, I had to do.&lt;/p&gt;

&lt;h2&gt;
  
  
  Leveraging Networking and Tools for Job Search and Career Management
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Using Your Network to Find a Job
&lt;/h3&gt;

&lt;p&gt;Networking is a powerful tool in your job search arsenal. Building and maintaining a broad and diverse network can significantly enhance your career prospects.&lt;/p&gt;

&lt;h3&gt;
  
  
  Benefits of a Strong Network:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Leverage Organizations&lt;/strong&gt;: Connect with professional organizations within your field. They offer more than just job opportunities; they often provide career-long support and growth.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Expand Beyond Your Company&lt;/strong&gt;: Networking beyond your current workplace is crucial. Many professionals limit their networking to within their company, which can leave them floundering when they need to look outside.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Be a Collector of People&lt;/strong&gt;: Continuously build and maintain relationships. Research potential employers and understand their views on networking.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;LinkedIn Banners&lt;/strong&gt;: Using the LinkedIn "Open for Work" banner is an active signal that you are job hunting. It can catch the attention of a broad and diverse network. Remember, first-person referrals are invaluable and help you stand out.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Reconnecting with a Lost Network
&lt;/h3&gt;

&lt;p&gt;Refreshing old connections is essential to maintaining a vibrant network.&lt;/p&gt;

&lt;h4&gt;
  
  
  Strategies:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Local Events &amp;amp; Volunteering&lt;/strong&gt;: Participate in local events and volunteering activities. These settings offer excellent networking opportunities.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Courses &amp;amp; Classes&lt;/strong&gt;: Attend professional courses and classes. These often attract recruiters and industry leaders.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;University Events&lt;/strong&gt;: Engage in university alumni events and career functions to reconnect with your old network.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;References&lt;/strong&gt;: Strengthening your network is crucial for obtaining references, which are often necessary for job applications.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Is It Worth Applying to Highly Competitive Job Postings?
&lt;/h3&gt;

&lt;p&gt;When faced with job postings that attract hundreds (if not thousands) of applicants, it's natural to feel discouraged. However, it's still worth applying.&lt;/p&gt;

&lt;h4&gt;
  
  
  Key Points:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Unknown Applicant Pool&lt;/strong&gt;: You don’t know the skill set of the other applicants, so don't count yourself out.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Skill Fit&lt;/strong&gt;: If you have many of the required skills, it's worth taking the shot; if you have 50% of the requirements it's worth a try.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Realistic Job Descriptions&lt;/strong&gt;: Job postings often reflect an ideal candidate.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Network Inside the Company&lt;/strong&gt;: Identify people in your network who work at the company. Their referrals can make a significant difference.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tailor Your Application&lt;/strong&gt;: Customize your resume and cover letter to match the company’s language, and demonstrate your passion and thorough research.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Alumni Networks&lt;/strong&gt;: Leverage the power of alumni networks and career services for additional support.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Key Skills and Resume Insights
&lt;/h3&gt;

&lt;p&gt;When evaluating resumes, certain factors can set you apart.&lt;/p&gt;

&lt;h4&gt;
  
  
  What to Highlight:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Outcomes and Patterns&lt;/strong&gt;: Showcase the results of your work. A pattern of success is compelling.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Willingness to Learn&lt;/strong&gt;: Demonstrate a commitment to learning, which is highly valued. Transitional roles can signify growth.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Certifications and Unlearning&lt;/strong&gt;: Highlight relevant certifications and what outdated practices you've abandoned.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Problem-Solving Skills&lt;/strong&gt;: Tech leaders consistently prioritize problem-solving abilities.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Research&lt;/strong&gt;: Investigate people at the target company to understand their skills and certifications.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Resume Length and Customization
&lt;/h3&gt;

&lt;p&gt;The length and depth of your resume depend on various factors.&lt;/p&gt;

&lt;h4&gt;
  
  
  Considerations:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Relevance&lt;/strong&gt;: Tailor the depth of your resume based on the relevance to the position.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Clarity&lt;/strong&gt;: Minimize unnecessary words and noise.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Authenticity&lt;/strong&gt;: Your resume should reflect your true self, not a generic template.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;LinkedIn Profile&lt;/strong&gt;: Use LinkedIn to present a broader view of your career history.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dynamic Resumes&lt;/strong&gt;: Have multiple versions of your resume, each telling a unique story suited to different opportunities.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Intentionality in Job Search
&lt;/h3&gt;

&lt;p&gt;Being intentional in your job search efforts can lead to better results.&lt;/p&gt;

&lt;h4&gt;
  
  
  Focus Areas:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Networking&lt;/strong&gt;: Be deliberate in expanding and maintaining your professional connections.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Company Research&lt;/strong&gt;: Thoroughly research target companies to understand their values and needs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tools Utilization&lt;/strong&gt;: Effectively use tools like LinkedIn and job search engines to enhance your resume’s visibility.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Growing Sectors and Opportunities
&lt;/h3&gt;

&lt;p&gt;Different regions may have unique growth sectors.&lt;/p&gt;

&lt;p&gt;Industry disruptions can set the stage for future growth opportunities.&lt;/p&gt;

&lt;h3&gt;
  
  
  Standing Out in Competitive Fields
&lt;/h3&gt;

&lt;p&gt;If transitioning from a government job or any competitive field, unique approaches can help.&lt;/p&gt;

&lt;h4&gt;
  
  
  Strategies:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Skill Transfer&lt;/strong&gt;: Highlight transferable skills to other industries where your experience is valuable.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Work Reallocation&lt;/strong&gt;: Understand that technology reallocates work rather than eliminating it.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Focus on DEI Initiatives
&lt;/h3&gt;

&lt;p&gt;Companies may be reconsidering their diversity, equity, and inclusion efforts.&lt;/p&gt;

&lt;h4&gt;
  
  
  Observations:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Surface Changes&lt;/strong&gt;: Some companies might appear to pull back from DEI, but foundational processes often remain unchanged.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Value Consistency&lt;/strong&gt;: Core values of organizations guide long-term goals and remain steadfast.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Workplace Perks
&lt;/h3&gt;

&lt;p&gt;Different perks can make a workplace more attractive.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Examples&lt;/strong&gt;: 

&lt;ul&gt;
&lt;li&gt;Bringing dogs to work.&lt;/li&gt;
&lt;li&gt;24x7 Work-from-Home flexibility.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;By focusing on these strategies, professionals can navigate their job searches and manage their careers more effectively. Leveraging networks, intentionality, and the right tools can significantly enhance career growth and opportunities.&lt;/p&gt;

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

&lt;p&gt;I met some amazing people the other day and learned a lot while at this presentation.&lt;/p&gt;

</description>
      <category>job</category>
      <category>search</category>
      <category>organizations</category>
      <category>meetup</category>
    </item>
    <item>
      <title>COSQAM: Evolving QA in Modern Agile Software Development</title>
      <dc:creator>bob.ts</dc:creator>
      <pubDate>Fri, 07 Mar 2025 13:52:57 +0000</pubDate>
      <link>https://dev.to/rfornal/cosqam-evolving-qa-in-modern-agile-software-development-5bei</link>
      <guid>https://dev.to/rfornal/cosqam-evolving-qa-in-modern-agile-software-development-5bei</guid>
      <description>&lt;h2&gt;
  
  
  DISCAIMER
&lt;/h2&gt;

&lt;p&gt;This is &lt;strong&gt;MY&lt;/strong&gt; article, views, and opinions of the CodeMash Conference, Sponsors, Speakers, Talks, and all associated activities.&lt;/p&gt;

&lt;p&gt;I wasn't asked to do this article.&lt;/p&gt;

&lt;p&gt;I am not getting compensated for this article.&lt;/p&gt;

&lt;p&gt;It's all ME from here on out.&lt;/p&gt;

&lt;h2&gt;
  
  
  Embracing Quality Assurance in Agile: Insights and Evolution
&lt;/h2&gt;

&lt;p&gt;These are my takeaways from this event (&lt;a href="https://www.meetup.com/techlifecolumbus/events/306317343/" rel="noopener noreferrer"&gt;COSQAM Presents: Evolving QA in Modern Agile Software Development&lt;/a&gt;).&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A panel discussion on how Software QA fits in with modern Agile practices.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F725caviajksu6vv15fxk.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F725caviajksu6vv15fxk.jpg" alt=" " width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  What Does Agile Look Like in Organizations?
&lt;/h3&gt;

&lt;h4&gt;
  
  
  The Diverse Flavors of Agile
&lt;/h4&gt;

&lt;p&gt;In discussing Agile methodologies, various organizations exhibit notable differences.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When implemented correctly, Agile helps teams gel and understand their value to the organization.&lt;/li&gt;
&lt;li&gt;Some exhibit a form of "zombie-scrum" where Agile practices exist without empowerment or effectiveness.&lt;/li&gt;
&lt;li&gt;Organizations can embody the versatility of Baskin-Robbins with "31 different flavors" of Agile. Such entities might follow Agile by the book, presenting a ‘vanilla’ version, yet they can encounter challenges at the enterprise level.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Flexibility and adaptation become key as these organizations strive for efficient feature delivery and continuous improvement.&lt;/p&gt;

&lt;h4&gt;
  
  
  Tailoring Processes to Teams
&lt;/h4&gt;

&lt;p&gt;Agile processes must be tailored to fit the unique needs of each team. Successful teams maintain a clear focus and objectives, approaching their goals with a flexible mindset. Implementation and understanding of Agile methodologies can differ across various organizational levels, emphasizing the need for a custom approach to fit the team dynamics.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Evolving Role of QA in Agile Teams
&lt;/h3&gt;

&lt;h4&gt;
  
  
  From Testers to Quality Evangelists
&lt;/h4&gt;

&lt;p&gt;The role of Quality Assurance (QA) has significantly evolved within Agile teams. Historically viewed as defect finders, QA professionals now act as custodians of quality, emphasizing customer satisfaction beyond the mere identification of defects. This transformation includes a shift from traditional testers to Quality Engineers (QE) and full-stack engineers that focus on business assurance.&lt;/p&gt;

&lt;h4&gt;
  
  
  Integrating QA with Development
&lt;/h4&gt;

&lt;p&gt;In the Agile paradigm, QA is no longer a separate entity but an integral part of the development team. Despite the evolving role, the fundamentals of QA remain essential, with manual testing and exploratory testing providing invaluable insights. Automation is crucial in scaling testing efforts, moving beyond manual practices to keep pace with rapid development cycles.&lt;/p&gt;

&lt;h3&gt;
  
  
  Transitioning to Modern QA Practices
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Embracing Automation
&lt;/h4&gt;

&lt;p&gt;New QA practitioners entering the QA space should focus on integrating automation into their skillset. While basic manual testing skills remain relevant, automation allows teams to focus on exploratory testing, which provides deeper insights. The mindset is that key tools can be taught, but the right approach and curiosity are what drive true quality improvements.&lt;/p&gt;

&lt;h4&gt;
  
  
  Collaborative Development
&lt;/h4&gt;

&lt;p&gt;QA professionals should work closely with developers, participating early in the development process to shape testing strategies. This collaborative environment ensures comprehensive testing, both manual and automated.&lt;/p&gt;

&lt;h3&gt;
  
  
  Addressing Misconceptions About QA
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Organizational Differences
&lt;/h4&gt;

&lt;p&gt;Every organization has unique practices regarding QA. A common misconception is that QA tasks are complete by the end of the sprint without properly accounting for the time that QA needs to complete testing. Effective Agile teams must integrate QA throughout the sprint, with flexibility to adapt roles as needed.&lt;/p&gt;

&lt;h4&gt;
  
  
  QA's Technical Skill
&lt;/h4&gt;

&lt;p&gt;Contrary to some beliefs, modern QA roles are highly technical. They go beyond the “black box” approach, demanding deep technical knowledge to understand and automate test cases efficiently.&lt;/p&gt;

&lt;h4&gt;
  
  
  Collaborative Quality Efforts
&lt;/h4&gt;

&lt;p&gt;Another misconception is viewing QA as an isolated role; in contrast, Agile promotes team ownership of quality. Successful teams integrate QA with development, breaking down silos and fostering collaboration.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Impact of AI on Development and QA
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Cautious Adoption of AI
&lt;/h4&gt;

&lt;p&gt;Artificial Intelligence (AI) is revolutionizing development and QA, but its application needs careful consideration. Inexperienced AI users may follow incorrect paths, resulting in brittle, poorly written tests. While AI can simplify laborious processes, the fundamental understanding of the system remains crucial.&lt;/p&gt;

&lt;h4&gt;
  
  
  Testing and Refining AI
&lt;/h4&gt;

&lt;p&gt;QA professionals should critically evaluate AI-generated outputs, ensuring they meet quality standards. Blind reliance on AI poses significant risks, as it lacks the true intelligence to conceptualize complex systems.&lt;/p&gt;

&lt;h3&gt;
  
  
  Leveraging AI Effectively
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Practical Applications
&lt;/h4&gt;

&lt;p&gt;Using AI for activities like syntax checking and rubber-duck debugging can provide immediate benefits. AI can also assist in testing itself, prompting critical thinking about its decision-making processes.&lt;/p&gt;

&lt;h4&gt;
  
  
  Future Prospects
&lt;/h4&gt;

&lt;p&gt;While AI holds the potential to revolutionize TDD (Test-Driven Development) and other practices, the journey to standardized, reliable AI-driven development tools is still years, if not decades, away.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cultivating a QA Mindset
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Team Ownership of Quality
&lt;/h4&gt;

&lt;p&gt;Quality should be a team commitment, not just the responsibility of QA. QA experts highlight gaps in thinking, but the entire team must collaborate to ensure comprehensive coverage.&lt;/p&gt;

&lt;h4&gt;
  
  
  Developing Critical Skills
&lt;/h4&gt;

&lt;p&gt;New QA professionals should adopt a critical mindset, learning to identify potential faults and deeply understanding the product. Influential figures in QA like &lt;a href="https://martinfowler.com/" rel="noopener noreferrer"&gt;Martin Fowler&lt;/a&gt;, &lt;a href="https://lisacrispin.com/" rel="noopener noreferrer"&gt;Lisa Crispin&lt;/a&gt;, and &lt;a href="https://testguild.com/about/" rel="noopener noreferrer"&gt;Joe Colantonio&lt;/a&gt; provide valuable insights and methodologies to adopt.&lt;/p&gt;

&lt;h3&gt;
  
  
  Advice for Aspiring QA Professionals
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Key Takeaways
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Speak up and ask questions:&lt;/strong&gt; Engagement and curiosity are crucial for growth.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Learn the tools and products:&lt;/strong&gt; Understanding the technical landscape and the product’s intricacies is vital.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  When Interviewing
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Effective communication:&lt;/strong&gt; Clearly articulating issues and collaborating with the team enhances overall quality.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Develop soft skills:&lt;/strong&gt; Inquisitiveness and interpersonal skills are as important as technical proficiency.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These can be just as effective at positioning yourself as any technical skills you might possess.&lt;/p&gt;

&lt;h4&gt;
  
  
  Retaining QA Talent
&lt;/h4&gt;

&lt;p&gt;To retain QA professionals, organizations should provide evolving responsibilities and acknowledge their role in the development process. Supporting their interests and career growth will foster a committed and motivated QA team.&lt;/p&gt;

&lt;p&gt;Quality Assurance in Agile environments is a dynamic field, constantly evolving to meet the demands of modern development practices. By embracing these changes and continually improving, organizations can ensure high-quality deliverables and customer satisfaction.&lt;/p&gt;

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

&lt;p&gt;There is a LOT to unpack here. I don't know that I can do it all justice in a sentence or two at the end of this article ...&lt;/p&gt;

</description>
      <category>qa</category>
      <category>agile</category>
      <category>organizations</category>
      <category>meetup</category>
    </item>
    <item>
      <title>[SCARY] Visual Regression Testing</title>
      <dc:creator>bob.ts</dc:creator>
      <pubDate>Wed, 29 Jan 2025 15:36:02 +0000</pubDate>
      <link>https://dev.to/rfornal/scary-visual-regression-testing-1him</link>
      <guid>https://dev.to/rfornal/scary-visual-regression-testing-1him</guid>
      <description>&lt;h2&gt;
  
  
  Background
&lt;/h2&gt;

&lt;p&gt;During one of our releases, we had to roll all the sites back (5 of them) because one of the developers found that a single page had changed unexpectedly. The rollback took almost 4-hours.&lt;/p&gt;

&lt;p&gt;I kept thinking that we found this issue on one of the sites. There was no guarantee that the issue was on all of the sites.&lt;/p&gt;

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

&lt;p&gt;I wanted something that could store information on a group of pages &lt;strong&gt;prior to the release&lt;/strong&gt; and compare them against the pages &lt;strong&gt;after the release&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;After checking with some friends, I looked into &lt;a href="https://playwright.dev/" rel="noopener noreferrer"&gt;Playwright&lt;/a&gt;, a library generally used for end-to-end testing.&lt;/p&gt;

&lt;p&gt;I started with this guide: &lt;a href="https://playwright.dev/docs/test-snapshots" rel="noopener noreferrer"&gt;Visual Comparisons&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Code
&lt;/h3&gt;

&lt;p&gt;I write a lot of Unit, Component, and Integration Tests.&lt;/p&gt;

&lt;p&gt;I broke all the rules.&lt;/p&gt;

&lt;p&gt;At it's core, I want to be able to test over 1-8 domains; quickly turning them off and on, as needed. Additionally, for each domain, I can have a lengthy list of paths to test.&lt;/p&gt;

&lt;p&gt;I came up with something like this as a configuration file: &lt;code&gt;/tests/smoke-tests.json&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"SMOKE_ONLY"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"MAX_DIFF_PIXEL_RATIO"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.001&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;

  &lt;/span&gt;&lt;span class="nl"&gt;"DOMAINS"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://www.bobfornal1.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"active"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://www.bobfornal2.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"active"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://www.bobfornal3.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"active"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://www.bobfornal4.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"active"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://www.bobfornal5.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"active"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://www.bobfornal6.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"active"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://www.bobfornal7.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"active"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://www.bobfornal8.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"active"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;

  &lt;/span&gt;&lt;span class="nl"&gt;"https://www.bobfornal4.com"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"smoke"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"/discover/gd/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"/discover/sa/eavestroughs/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"/discover/sa/gutter-guard/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"/discover/sa/installation/"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"detailed"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;smoke&lt;/code&gt; and &lt;code&gt;detailed&lt;/code&gt; keys give me the option to store paths that aren't being used in a way that they aren't tested, but could be quickly with the &lt;code&gt;SMOKE_ONLY&lt;/code&gt; option.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;MAX_DIFF_PIXEL_RATIO&lt;/code&gt; is how closely we want to look a differences. The closer to zero, the more accurate a match must be.&lt;/p&gt;

&lt;p&gt;My &lt;code&gt;playwright.config.ts&lt;/code&gt; file looks like this.&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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;defineConfig&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;devices&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;@playwright/test&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="k"&gt;default&lt;/span&gt; &lt;span class="nf"&gt;defineConfig&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;testDir&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./tests&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;fullyParallel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;forbidOnly&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;!!&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;CI&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;retries&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;CI&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="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;workers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;CI&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;reporter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;html&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;use&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;trace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;on-first-retry&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;projects&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;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;chromium&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;use&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;devices&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Desktop Chrome&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="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Mobile Chrome&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;use&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;devices&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Pixel 5&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="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;Clearly, more browsers could be used, but this is enough for my use-case.&lt;/p&gt;

&lt;p&gt;Here's the test code: &lt;code&gt;/tests/smoke-tests.spec.ts&lt;/code&gt;.&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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;expect&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;@playwright/test&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;core&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;./smoke-tests.json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;DomainPattern&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;url&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="nl"&gt;active&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&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;smokeOnly&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;core&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;SMOKE_ONLY&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;maxDiffPixelRatio&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;core&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;MAX_DIFF_PIXEL_RATIO&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Smoke Tests&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="nx"&gt;core&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DOMAINS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="na"&gt;domain&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;DomainPattern&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;domain&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;active&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="kc"&gt;true&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="na"&gt;paths&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;smokeOnly&lt;/span&gt;
        &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;core&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;domain&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;smoke&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;core&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;domain&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;detailed&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;core&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;domain&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;smoke&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

      &lt;span class="nx"&gt;paths&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&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="na"&gt;path&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="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="na"&gt;fullpath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;domain&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&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="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`for "&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;fullpath&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="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;page&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;await&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;goto&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fullpath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;60000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;waitUntil&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;networkidle&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
          &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;waitForTimeout&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;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toHaveScreenshot&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="na"&gt;fullPage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="nx"&gt;maxDiffPixelRatio&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="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;
  
  
  What It Does
&lt;/h3&gt;

&lt;p&gt;This code looks through the &lt;code&gt;domains&lt;/code&gt;, builds an array of paths and loops through those. Each &lt;code&gt;domain&lt;/code&gt; &lt;code&gt;path&lt;/code&gt; combination is a test (note the name change to "for ${fullpath}" ensuring a different name for each test.&lt;/p&gt;

&lt;p&gt;We go to the page, wait 5 seconds, and expect a screenshot comparison of the full page.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tooling
&lt;/h3&gt;

&lt;p&gt;This code is run from the command line with&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx playwright test
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Simple.&lt;/p&gt;

&lt;p&gt;You then get something like this in the command line.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fozijp4p2fb3ey553ekpa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fozijp4p2fb3ey553ekpa.png" alt="CLI run of the Visual Regression Test" width="800" height="291"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;... and, your browser opens with the test results.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fypzxnpaj1c54bnippn3i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fypzxnpaj1c54bnippn3i.png" alt="Browser results of a test run" width="800" height="543"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I generally click "Failed" to reduce what I need to check.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fwuwoyp6kj5zv9grle8mr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fwuwoyp6kj5zv9grle8mr.png" alt="Browser results of a test run, failed only" width="800" height="410"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At this point, I need to &lt;strong&gt;manually&lt;/strong&gt; check the pages. Clicking on one of the failed tests takes me to a page; scrolling down I can see a heatmap overlay (note the red).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F5709lxmzzqx96ahwx6vu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F5709lxmzzqx96ahwx6vu.png" alt=" " width="800" height="478"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Clicking the "Slider" option is one of my favorites that allows us to compare the before and after changes by sliding a scrollbar left and right.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fr92wya90vjmof1zif09i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fr92wya90vjmof1zif09i.png" alt=" " width="800" height="508"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Remember
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;REMEMBER&lt;/strong&gt; that this test suite has to be run &lt;strong&gt;&lt;em&gt;before&lt;/em&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;em&gt;after&lt;/em&gt;&lt;/strong&gt; each release. The &lt;strong&gt;before&lt;/strong&gt; run generates the new images, so you should delete the created &lt;code&gt;/tests/smoke-tests.spec.ts-snapshots&lt;/code&gt; folder each time to allow for new image captures.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;Scary?&lt;/p&gt;

&lt;p&gt;No. This test is 37-lines long and provides a level of assurance that got applause the first time it was run for this team.&lt;/p&gt;

&lt;p&gt;I am able to test almost 300 pages in a matter of minutes; that's powerful!&lt;/p&gt;

</description>
      <category>devops</category>
      <category>testing</category>
      <category>playwright</category>
      <category>frontend</category>
    </item>
    <item>
      <title>CodeMash 2025</title>
      <dc:creator>bob.ts</dc:creator>
      <pubDate>Tue, 21 Jan 2025 16:01:21 +0000</pubDate>
      <link>https://dev.to/rfornal/codemash-2025-33o7</link>
      <guid>https://dev.to/rfornal/codemash-2025-33o7</guid>
      <description>&lt;h2&gt;
  
  
  DISCAIMER
&lt;/h2&gt;

&lt;p&gt;This is &lt;strong&gt;MY&lt;/strong&gt; article, views, and opinions of the CodeMash Conference, Sponsors, Speakers, Talks, and all associated activities.&lt;/p&gt;

&lt;p&gt;I wasn't asked to do this article.&lt;/p&gt;

&lt;p&gt;I am not getting compensated for this article.&lt;/p&gt;

&lt;p&gt;It's all ME from here on out.&lt;/p&gt;

&lt;h2&gt;
  
  
  Content Starts Here ...
&lt;/h2&gt;

&lt;p&gt;I consider &lt;strong&gt;&lt;a href="https://www.codemash.org" rel="noopener noreferrer"&gt;CodeMash&lt;/a&gt;&lt;/strong&gt; to be one of the finest conferences around (and not just in the Ohio area). I first got exposed to this conference over a decade ago and have attended as often as I can.&lt;/p&gt;

&lt;p&gt;I currently am on the Speaker Selection Committee, DE&amp;amp;I Committee, and Safety Committee; maybe I am a little biased, but I do these things because I care about this conference and the experience it provides.&lt;/p&gt;

&lt;p&gt;I tell people ...&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;CodeMash: Think about a conference where the hotel and conference center are one building. It's at the &lt;a href="https://www.kalahariresorts.com/ohio/" rel="noopener noreferrer"&gt;Kalahari&lt;/a&gt; in Sandusky, Ohio, a facility with an indoor waterpark where you can attend in the cold of January and never go outside. The conference is four days long with two days of precompilers where you get to build something and two days of amazing hour-long sessions.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  About
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;CodeMash is a conference for developers. We eat, drink, and learn about all things code and do it all in shorts and sandals by a pool.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/edzuvldiYFU"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;CodeMash is a unique event that educates developers on current practices, methodologies and technology trends in a variety of platforms and development languages. Held every January at the lush Kalahari Resort in Sandusky, Ohio, attendees will be able to attend a world-class technical conference amid Ohio’s largest indoor waterpark. Nobody will frown if you show up in shorts, sandals, and your loudest t-shirt. You might even win a prize for doing so.&lt;/p&gt;

&lt;p&gt;It’s not just about a grind of sessions, but also providing attendees the opportunity of continuing the conversations and networking outside of the daily conference events. The goal has always been to achieve this mission by creating a conference environment that focuses on professionalism and respect for one another.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  From a Survivor
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;“This was the best four days of my life. Since CodeMash I’ve reinvented my life, purchased my dream electric car, built a water slide in my backyard and adopted a baby penguin. CodeMash changes lives – forever.” - James – CodeMash Survivor&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Sponsors
&lt;/h2&gt;

&lt;p&gt;Before I got into what it was like for me attending this year, I want to thank the sponsors. Having participated in many conferences (as an attendee and speaker) I know that no conference happens without solid sponsors.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://infernored.com/" rel="noopener noreferrer"&gt;InfernoRed Technology&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fqg71gh6y228qy8awpqpi.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fqg71gh6y228qy8awpqpi.jpg" alt="InfernoRed Booth" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://digitalocean.com/" rel="noopener noreferrer"&gt;DigitalOcean&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fksc4j5wcofqkiz6k49ln.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fksc4j5wcofqkiz6k49ln.jpg" alt="Digital Ocean Booth" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://www.cgi.com/us/en-us" rel="noopener noreferrer"&gt;CGI&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fdfhflz7o6a5j3r8o9d3v.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fdfhflz7o6a5j3r8o9d3v.jpg" alt="CGI Booth" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://www.jumpmind.com/data/" rel="noopener noreferrer"&gt;Jumpmind&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fm1amu6ie0zpssexn2ovp.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fm1amu6ie0zpssexn2ovp.jpg" alt="Jumpmind Booth" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Jumpmind is a software company specializing in enterprise commerce and data integration software.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://www.jpmorganchase.com/careers" rel="noopener noreferrer"&gt;JPMorganChase&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F9f8yp0d8m120vx4l6o01.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F9f8yp0d8m120vx4l6o01.jpg" alt="JPMorganChase" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://platform.uno/" rel="noopener noreferrer"&gt;Uno Platform&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fs6c67vk56o6e81p2g4co.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fs6c67vk56o6e81p2g4co.jpg" alt="Uno Booth" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Uno has The Uno Platform Studio Community version that is free. It provides access to the most complete &lt;strong&gt;Hot Reload&lt;/strong&gt; in the .NET ecosystem.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://www.secureideas.com/" rel="noopener noreferrer"&gt;Secure Ideas LLC&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fhab11ha6joeuevbelu2g.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fhab11ha6joeuevbelu2g.jpg" alt="Secure Ideas Booth" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://www.netjets.com/en-us/" rel="noopener noreferrer"&gt;NetJets&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F564xfhd8bj97bt5d939z.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F564xfhd8bj97bt5d939z.jpg" alt=" " width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://aws.amazon.com/" rel="noopener noreferrer"&gt;AWS&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fhz7l9q1xg9vzg59zbesu.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fhz7l9q1xg9vzg59zbesu.jpg" alt="AWS Booth" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://www.bpstechnologies.com/" rel="noopener noreferrer"&gt;BPS Technologies&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fdpcsgfvtkcelc2d0varo.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fdpcsgfvtkcelc2d0varo.jpg" alt="BPS Technologies" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://www.cas.org/" rel="noopener noreferrer"&gt;CAS&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fmsv2k8uec6zvbxp1ij8x.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fmsv2k8uec6zvbxp1ij8x.jpg" alt="CAS Booth" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Having worked at CAS, it's always amazing seeing them sponsoring and continuing to strengthen our community.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://www.dryrun.security/" rel="noopener noreferrer"&gt;DryRun Security&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fq9r17q1t9rk61gdi9ps7.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fq9r17q1t9rk61gdi9ps7.jpg" alt="DryRun Security Booth" width="800" height="1066"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://www.immy.bot/" rel="noopener noreferrer"&gt;ImmyBot&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fwlxy33o85y5siynaflnl.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fwlxy33o85y5siynaflnl.jpg" alt="ImmyBot Booth" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Sponsors without Booths
&lt;/h3&gt;

&lt;p&gt;There are a few sponsors that didn't have booths. They hosted particular activities.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://nx.dev/" rel="noopener noreferrer"&gt;Nx&lt;/a&gt; (sponsored the Lightning Talks)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://manifestcorp.com/" rel="noopener noreferrer"&gt;Manifest Solutions Corp.&lt;/a&gt; (sponsored the Thursday Night Cocktail Party)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://cipp.app/" rel="noopener noreferrer"&gt;CyberDrain&lt;/a&gt; (sponsored the Water Park Party)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.cnwr.com/" rel="noopener noreferrer"&gt;CNWR&lt;/a&gt; (sponsored the Water Park Party)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.improving.com/" rel="noopener noreferrer"&gt;Improving&lt;/a&gt; (sponsored the Game Room)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://nimblepros.com/" rel="noopener noreferrer"&gt;NimblePros&lt;/a&gt; (sponsored the KidzMash - Key Sponsor)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Day 1
&lt;/h2&gt;

&lt;p&gt;I spent some of this morning in a rush, getting my Staff gear and settling in. I forgot a cable and needed to track down information for two "lunch panels" I'm coordinating for Thursday and Friday.&lt;/p&gt;

&lt;p&gt;Today and tomorrow are precompiler days (workshops). Each session is 4 hours.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fo0iddqb67utyhlghvphx.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fo0iddqb67utyhlghvphx.jpg" alt=" " width="800" height="1066"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The first session I'm attending is &lt;strong&gt;GitHub Actions: From Zero to Hero&lt;/strong&gt; by &lt;a href="https://www.linkedin.com/in/scottsauber/" rel="noopener noreferrer"&gt;Scott Sauber&lt;/a&gt; learning to build robust pipelines from the ground up using GitHub Actions.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fgougljsfe1xon4suibp3.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fgougljsfe1xon4suibp3.jpg" alt="Scott Sauber speaking" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then ...&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F6ui8ia60e6w0l9eib2uf.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F6ui8ia60e6w0l9eib2uf.jpg" alt="Lunch on Day One" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;... there was LUNCH!&lt;/p&gt;

&lt;p&gt;The second session I attended was &lt;strong&gt;Enterprise Grade Micro Frontends&lt;/strong&gt; with &lt;a href="https://www.linkedin.com/in/m-thompson-code/" rel="noopener noreferrer"&gt;Mark Thompson&lt;/a&gt; &amp;amp; &lt;a href="https://www.linkedin.com/in/david-nicholas-38b789b0/" rel="noopener noreferrer"&gt;David Nicholas&lt;/a&gt;. We explored implementing various techniques within a Micro Frontend architecture.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fot3nequrlow0iuft7ru5.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fot3nequrlow0iuft7ru5.jpg" alt="Microfrontend Session" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Throughout the day I had some amazing conversations with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.linkedin.com/in/larryrickard/" rel="noopener noreferrer"&gt;Larry Rickard&lt;/a&gt; an amazing Recruiter I used to work with.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.linkedin.com/in/cassandrafaris/" rel="noopener noreferrer"&gt;Cassandra Faris&lt;/a&gt; another recruiter I've known for a while.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.linkedin.com/in/kyle-jenkins/" rel="noopener noreferrer"&gt;Kyle Jenkins&lt;/a&gt; a Principal Engineer I've worked with.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.linkedin.com/in/eric-amiralian-91318548/" rel="noopener noreferrer"&gt;Eric Amiralian&lt;/a&gt; a strong developer I worked closely with.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There were probably a dozen (or more) side conversations with people that didn't go into hour-long talks; people I've worked with, met at other conferences and meetups, or just simply had a Coffee Chat with.&lt;/p&gt;

&lt;h2&gt;
  
  
  Day 2
&lt;/h2&gt;

&lt;p&gt;I got a late start on day two due to the NASA tour.&lt;/p&gt;

&lt;h3&gt;
  
  
  NASA Tour
&lt;/h3&gt;

&lt;p&gt;This was an amazing tour of some of their test facilities. The tour guides were wonderful. They truly enjoyed showing off the work that they do. I can't recommend this event enough.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fuyn3qgy4ob470kvr66nw.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fuyn3qgy4ob470kvr66nw.jpg" alt="NASA" width="800" height="393"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Back at CodeMash
&lt;/h3&gt;

&lt;p&gt;Upon getting back, I changed and got lunch.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fei2yz691ydkkrobyy1qe.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fei2yz691ydkkrobyy1qe.jpg" alt="Fisherman Bob" width="800" height="1066"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;(I told my wife that I dressed myself, but didn't get to pick the color scheme here).&lt;/p&gt;

&lt;p&gt;After lunch, I got a chance to speak with a good friend, &lt;a href="https://www.linkedin.com/in/john-gaynor1/" rel="noopener noreferrer"&gt;John Gaynor&lt;/a&gt;, about both tech and faith.&lt;/p&gt;

&lt;p&gt;Then, I had a meeting for the CodeMash Outreach committee (we've got two high schools bringing students over the next few days). We needed to finalize a few details.&lt;/p&gt;

&lt;p&gt;I &lt;strong&gt;might&lt;/strong&gt; got to the Lightning Talks tonight; 6-minute talks on any topic. We'll see, they've been fun in the past.&lt;/p&gt;

&lt;h3&gt;
  
  
  Day 2 Update
&lt;/h3&gt;

&lt;p&gt;I just finished dinner with a good friend from Dayton. Do any of you have those people that feel like you've known them forever? Even if it's only been a short time?&lt;/p&gt;

&lt;p&gt;I got to know &lt;a href="https://www.linkedin.com/in/hanen/" rel="noopener noreferrer"&gt;Hanen Alkhafaji&lt;/a&gt; when she reached out via LinkedIn to ask if I wanted to speak at a Meetup in Dayton (&lt;a href="https://www.meetup.com/gem-city-tech/?eventOrigin=event_home_page" rel="noopener noreferrer"&gt;HERE&lt;/a&gt;). As a graduate of the &lt;a href="https://udayton.edu/" rel="noopener noreferrer"&gt;University of Dayton&lt;/a&gt;, I was honored. The talk was fun ...&lt;/p&gt;

&lt;p&gt;... tonight, she showed up just as I was going to default to a pizza. Instead, I managed a good burger and a wonderful conversation with a friend.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I keep thinking I need to get all of my friends together. Then I realized that most of them are here at CodeMash.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Day 3
&lt;/h2&gt;

&lt;p&gt;OK.&lt;/p&gt;

&lt;p&gt;Today was one of the busiest days I've ever had attending CodeMash.&lt;/p&gt;

&lt;p&gt;I started the day working with our Outreach program - shirts and attending their track sessions.&lt;/p&gt;

&lt;p&gt;Then I tried to go to sessions ...&lt;/p&gt;

&lt;p&gt;... and managed one all day.&lt;/p&gt;

&lt;h3&gt;
  
  
  8-Bit
&lt;/h3&gt;

&lt;p&gt;This was an amazing session by Steven Swenson.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fylpcmbubai74hk4ddil0.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fylpcmbubai74hk4ddil0.jpg" alt=" " width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;While I was excited about seeing a modern 6502 chip, I didn't get to attend as much of the session as I would have liked.&lt;/p&gt;

&lt;h3&gt;
  
  
  Outreach Panelists
&lt;/h3&gt;

&lt;p&gt;I coordinated the Outreach lunch, during which these students would get a chance to speak with different people in the industry. We had about six (6) panelists who rotated tables.&lt;/p&gt;

&lt;p&gt;Everyone had fun.&lt;/p&gt;

&lt;p&gt;It did shorten my time in sessions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Sessions
&lt;/h3&gt;

&lt;p&gt;I attended a complete session, "Testing Strategies for Monoliths and Microservices" by &lt;a href="https://x.com/DavidDLucas" rel="noopener noreferrer"&gt;David Lucas&lt;/a&gt;. It was a solid session with good details.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fnwhxzb7nty7ksfav470l.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fnwhxzb7nty7ksfav470l.jpg" alt="Testing Strategies for Monoliths and Microservices Presentation" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Day 4
&lt;/h2&gt;

&lt;p&gt;This was another busy day, given a second Outreach day. I was running almost non-stop all day.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fs72bdgl9ztcryobi3fuu.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fs72bdgl9ztcryobi3fuu.jpg" alt="Bob with orange hat and grumpy gorilla behind him" width="800" height="1066"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I did get to go to "The Power of Feature Flags in CSS Development" by &lt;a href="https://www.linkedin.com/in/chrisdemars/" rel="noopener noreferrer"&gt;Chris Demars&lt;/a&gt;. This was a great talk about Split Tests and "testing in development."&lt;/p&gt;

&lt;p&gt;My family arrived about 4 PM. My son immediately went to track down a few of his friends and was in the board-game room for quite a while. Jen and Anne hustled to the water park.&lt;/p&gt;

&lt;p&gt;At the closing, I was honored to be listed as a "Special Advisor" for the conference (close friends told me I got the same honor last year and don't remember due to the drugs I was taking to stay on my feet) ...&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F7c9l9ig9x5q11vcsqq4k.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F7c9l9ig9x5q11vcsqq4k.jpg" alt="Special Advisors to the CodeMash Board" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Oh.&lt;/p&gt;

&lt;p&gt;CodeMash will be returning (mark your calendars) on &lt;strong&gt;January 13-16. 2026&lt;/strong&gt;!&lt;/p&gt;

&lt;h2&gt;
  
  
  Decompile (Day 5)
&lt;/h2&gt;

&lt;p&gt;No, there is not a fifth day.&lt;/p&gt;

&lt;p&gt;I like to book a few more nights to allow my family to come in and enjoy the &lt;a href="https://www.kalahariresorts.com/ohio/" rel="noopener noreferrer"&gt;Kalahari&lt;/a&gt; Waterpark. This is my decompression.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fpb7e8m26cei8g3ss02dk.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fpb7e8m26cei8g3ss02dk.jpg" alt=" " width="800" height="1066"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>conference</category>
      <category>speaker</category>
      <category>learning</category>
    </item>
    <item>
      <title>Setting and Managing Daily Goals</title>
      <dc:creator>bob.ts</dc:creator>
      <pubDate>Thu, 09 Jan 2025 13:50:30 +0000</pubDate>
      <link>https://dev.to/rfornal/setting-and-managing-daily-goals-4ij</link>
      <guid>https://dev.to/rfornal/setting-and-managing-daily-goals-4ij</guid>
      <description>&lt;h2&gt;
  
  
  Daily Goals
&lt;/h2&gt;

&lt;p&gt;Some people struggle with daily goals. Some people struggle with them, A LOT.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting Daily Goals
&lt;/h2&gt;

&lt;p&gt;Daily goals should be planned out the night before. If a task feels too large, break it down into pieces.&lt;/p&gt;

&lt;p&gt;Let’s say my goal for tomorrow is to add a feature to my Slide Deck Presentation Tool. This feature will allow me to filter a set of slides, removing those I’ve set to “hidden.”&lt;/p&gt;

&lt;p&gt;I would break this feature down into parts:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Set a “hidden” key/value on a deck.&lt;/li&gt;
&lt;li&gt;Adjust the service that loads a deck to include or remove “hidden” slides optionally. When presenting, they need to be hidden. When editing, they need to be visible.&lt;/li&gt;
&lt;li&gt;Change the presentation part of the application to load a deck without “hidden” slides.&lt;/li&gt;
&lt;li&gt;Change the editing part of the application to load a deck with “hidden” slides.&lt;/li&gt;
&lt;li&gt;Verify functionality.&lt;/li&gt;
&lt;li&gt;Write and verify Unit Tests.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now, looking at this, some of the tasks are significantly harder than others.&lt;/p&gt;

&lt;p&gt;I usually recommend that we order them from easiest to hardest … this becomes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Set a “hidden” key/value on a deck.&lt;/li&gt;
&lt;li&gt;Change the presentation part of the application to load a deck without “hidden” slides.&lt;/li&gt;
&lt;li&gt;Change the editing part of the application to load a deck with “hidden” slides.&lt;/li&gt;
&lt;li&gt;Adjust the service that loads a deck to include or remove “hidden” slides optionally. When presenting, they need to be hidden. When editing, they need to be visible.&lt;/li&gt;
&lt;li&gt;Write and verify Unit Tests.&lt;/li&gt;
&lt;li&gt;Verify functionality.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Remembering Daily Goals
&lt;/h2&gt;

&lt;p&gt;Some people have trouble remembering to get to their daily goals.&lt;/p&gt;

&lt;p&gt;Some people have trouble remembering they have daily goals.&lt;/p&gt;

&lt;p&gt;In my opinion, the simplest solution is to get a whiteboard and list the goals, easiest to hardest, in a place you will see them daily, probably someplace near your computer.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Ft68qy5pn063rktjkze6u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Ft68qy5pn063rktjkze6u.png" alt="White Board" width="448" height="393"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This way, your goals are always there and ready to go when you are!&lt;/p&gt;

&lt;h2&gt;
  
  
  Daily Goals on Off Days
&lt;/h2&gt;

&lt;p&gt;Off days.&lt;/p&gt;

&lt;p&gt;This can be a day where you don’t want to do anything.&lt;/p&gt;

&lt;p&gt;This can be a day where the goals seem to be too difficult.&lt;/p&gt;

&lt;p&gt;This can be a day where life simply wants to get in the way.&lt;/p&gt;

&lt;p&gt;The reason that I grouped the goals easiest to hardest is practical ...&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;On the day where you’re having an “off day,” tackle the goals easiest first.&lt;/li&gt;
&lt;li&gt;On the day that you’re fired up, tackle the hardest first.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Also realize that there are days where you will scrap all the goals and take some time off. We all need down time - time to rest and recuperate.&lt;/p&gt;

&lt;h2&gt;
  
  
  Your Take
&lt;/h2&gt;

&lt;p&gt;What would you add to this take on &lt;strong&gt;Daily Goals&lt;/strong&gt;? What would you change?&lt;/p&gt;

</description>
      <category>goals</category>
      <category>daily</category>
      <category>planning</category>
      <category>organization</category>
    </item>
    <item>
      <title>CSS' only-child instead of Conditional Logic</title>
      <dc:creator>bob.ts</dc:creator>
      <pubDate>Fri, 25 Oct 2024 15:35:08 +0000</pubDate>
      <link>https://dev.to/rfornal/css-only-child-instead-of-conditional-logic-2k7c</link>
      <guid>https://dev.to/rfornal/css-only-child-instead-of-conditional-logic-2k7c</guid>
      <description>&lt;p&gt;In many of the frontend frameworks that I work with, there are options for ternaries or if-branches injected into the HTML logic. This is logic I use a lot. One particular case is to show when there is no data.&lt;/p&gt;

&lt;p&gt;I just stumbled on a CSS pattern that makes my life much easier: the &lt;code&gt;:only-child&lt;/code&gt; pseudo-class.&lt;/p&gt;

&lt;h2&gt;
  
  
  React
&lt;/h2&gt;

&lt;p&gt;In React, I would do "something" like this ...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;{
  data.length === 0
    ? &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;Nothing to show.&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    : &lt;span class="nt"&gt;&amp;lt;TableWithRecords&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Angular
&lt;/h2&gt;

&lt;p&gt;In Angular, I would do "something" like this ...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;@if (data.length === 0) {
   &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;Nothing to show.&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
} @else {
   &lt;span class="nt"&gt;&amp;lt;TableWithRecords&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Using CSS
&lt;/h2&gt;

&lt;p&gt;To put it simply, I have two cases.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;There is not data.&lt;/li&gt;
&lt;li&gt;There is data.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;h2&amp;gt;&lt;/span&gt;No Data Showing&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;ul&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;li&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"handle-no-data"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Nothing to show.&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
  &lt;span class="c"&gt;&amp;lt;!-- &amp;lt;li&amp;gt;Data here&amp;lt;/li&amp;gt; --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;h2&amp;gt;&lt;/span&gt;Data Showing&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;ul&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;li&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"handle-no-data"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Nothing to show.&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;Data here&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using a simple CSS class &lt;code&gt;.single&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;.handle-no-data&lt;/span&gt;&lt;span class="nd"&gt;:not&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;:only-child&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.handle-no-data&lt;/span&gt;&lt;span class="nd"&gt;:only-child&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&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;This CSS could be simplified to ...&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;.handle-no-data&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="err"&gt;&amp;amp;:not(:only-child)&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nd"&gt;:only-child&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="err"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here's the result of the code above ...&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fvnl3phyghyjbirf2gur7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fvnl3phyghyjbirf2gur7.png" alt=" " width="515" height="205"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  MDN Documentation
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/:only-child" rel="noopener noreferrer"&gt;:only-child&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Can I Use
&lt;/h2&gt;

&lt;p&gt;&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcaniuse.bitsofco.de%2Fstatic%2Fv1%2Fmdn-css__selectors__only-child-1730224323477.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcaniuse.bitsofco.de%2Fstatic%2Fv1%2Fmdn-css__selectors__only-child-1730224323477.jpg" alt="Data on support for the mdn-css__selectors__only-child feature across the major browsers from caniuse.com" width="800" height="366"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;As you can see, I would have to move the handling of the data to the table level, but the CSS is pretty straight forward to handle a "no data" scenario.&lt;/p&gt;

&lt;p&gt;This is exciting!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>css</category>
      <category>development</category>
      <category>frontend</category>
    </item>
    <item>
      <title>I took a Bootcamp Fullstack Course</title>
      <dc:creator>bob.ts</dc:creator>
      <pubDate>Tue, 17 Sep 2024 13:41:03 +0000</pubDate>
      <link>https://dev.to/rfornal/i-took-a-bootcamp-fullstack-course-47pg</link>
      <guid>https://dev.to/rfornal/i-took-a-bootcamp-fullstack-course-47pg</guid>
      <description>&lt;h2&gt;
  
  
  What I Did!
&lt;/h2&gt;

&lt;p&gt;I recently ran through a boot camp's two-hour video where I built and deployed a fullstack application.&lt;/p&gt;

&lt;p&gt;It only took me SIX-HOURS ...&lt;/p&gt;

&lt;p&gt;Here are some of my takeaways.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Proper patterns and conventions on inline CSS is difficult.&lt;/li&gt;
&lt;li&gt;Refactoring was not taken into account.&lt;/li&gt;
&lt;li&gt;Using the Node Server to push the React Build is awkward.&lt;/li&gt;
&lt;li&gt;There were no Unit Tests.&lt;/li&gt;
&lt;li&gt;Deployment was a simple external hook.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;None of these bad, strange, or odd patterns were discussed.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Good
&lt;/h2&gt;

&lt;p&gt;There were good things.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use of Context to handle Light and Dark Mode.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I need to look into other component libraries to see if this pattern is implemented there; is something similar for Angular and Vue?&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Did I Do This?
&lt;/h2&gt;

&lt;p&gt;I wasn't intentionally looking to see if they were teaching good or bad practices. I was looking to see what NodeJS, React, and deployment patterns were being used.&lt;/p&gt;

&lt;p&gt;I did this for my own &lt;strong&gt;learning and development&lt;/strong&gt; as a professional.&lt;/p&gt;

&lt;p&gt;I wanted to see ...&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What was being taught about React?&lt;/li&gt;
&lt;li&gt;What was being taught about NodeJs?&lt;/li&gt;
&lt;li&gt;How were they deploying the application?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are things that I do every day.&lt;/p&gt;

&lt;p&gt;And, I'm always looking to improve my skillset ...&lt;/p&gt;

&lt;p&gt;I &lt;strong&gt;&lt;em&gt;just&lt;/em&gt;&lt;/strong&gt; wanted to see if I was doing it right (I'm generally the expert that people reach out to) - &lt;strong&gt;Imposter Syndrome&lt;/strong&gt; might have been kicking in.&lt;/p&gt;

&lt;p&gt;There were a lot of issues that bothered me (mentioned above).&lt;/p&gt;

&lt;h2&gt;
  
  
  Issue: Inline CSS
&lt;/h2&gt;

&lt;p&gt;I don't just copy/paste code while training. I type it in (completely) to allow finer control and better learning.&lt;/p&gt;

&lt;p&gt;When I was entering the inline CSS, I found an issue ...&lt;/p&gt;

&lt;p&gt;... and, that issue was what &lt;strong&gt;&lt;em&gt;really&lt;/em&gt;&lt;/strong&gt; bugged me as I watched the remainder of the training.&lt;/p&gt;

&lt;p&gt;As I entered an attribute name, sometimes I pressed TAB and sometimes I entered the whole attribute name followed by an equal sign (=). This resulted in two different patterns that do the same thing.&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;TestComponent&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;&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt;
      &lt;span class="na"&gt;fontSize&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="s2"&gt;xl&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="na"&gt;textAlign&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"center"&lt;/span&gt;
    &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      No Products Found
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;&amp;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;In this context, &lt;code&gt;fontSize&lt;/code&gt; and &lt;code&gt;textAlign&lt;/code&gt; are doing the same thing.&lt;/p&gt;

&lt;p&gt;Standards and consistency when writing code are important. When your code is organized and clean, it’s much more likely to stay that way over time.&lt;/p&gt;

&lt;h3&gt;
  
  
  Additional Experience (Clean Code)
&lt;/h3&gt;

&lt;p&gt;In client code, I see ternaries nested in ternaries; I couldn’t tell you how deep. A simple case-statement, if-else structure, or object-pattern can make the code significantly easier to read and work with.&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%2Fpm7cyu3kn37u0dsk3qqn.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%2Fpm7cyu3kn37u0dsk3qqn.png" alt="Nested ternaries on a single line" width="800" height="33"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I saw the code above; again, I'm not calling anyone out.&lt;/p&gt;

&lt;p&gt;Let's look at a simpler 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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;H&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;C&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="kc"&gt;null&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;V&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nx"&gt;r&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;g&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;C&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;V&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nx"&gt;g&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;C&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;
             &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;g&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;C&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this nested ternary, it's nearly impossible to follow the logic.&lt;/p&gt;

&lt;p&gt;This code can be cleaned up and improved ...&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;let&lt;/span&gt; &lt;span class="nx"&gt;H&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;C&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="nx"&gt;H&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="k"&gt;else&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;V&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;H&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;g&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;C&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;V&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nx"&gt;g&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;H&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;C&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;2&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="nx"&gt;H&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;g&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;C&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;4&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;I'm not 100% sure what the logic here is supposed to do, but I can follow these if-else blocks more consistently than the nested ternaries above.&lt;/p&gt;

&lt;p&gt;The import of consistency cannot be overstated; it’s a fundamental basis for clean, manageable code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Issue: Lack of Refactoring
&lt;/h2&gt;

&lt;p&gt;In this simple codebase, there were several places where code was repeated.&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;success&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;updateProduct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;updatedProduct&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;success&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;message&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="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;success&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;toast&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="s1"&gt;Error&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;error&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;isClosable&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&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="nf"&gt;toast&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="s1"&gt;Success&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Product updated successfully.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;success&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;isClosable&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&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 code above shows a success-failure pattern that was repeated throughout the codebase.&lt;/p&gt;

&lt;p&gt;It could easily have been abstracted to show a simpler way to handle success or error. Even if this code wasn't cleaned up, it should have been mentioned.&lt;/p&gt;

&lt;h2&gt;
  
  
  Issue: Node Server hosting React
&lt;/h2&gt;

&lt;p&gt;I've seen this pattern used recently at an enterprise-level client.&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%2Fcsn3d49ipsc32llrvf9k.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%2Fcsn3d49ipsc32llrvf9k.png" alt="Node Server serving React static content. There is a Mongo DB Database." width="800" height="403"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It bothered me when I saw it there.&lt;/p&gt;

&lt;p&gt;It bothered me when I saw it in the video.&lt;/p&gt;

&lt;p&gt;This pattern isn't scalable.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The React code is static and can run in any cloud bucket.&lt;/li&gt;
&lt;li&gt;The NodeJS code can run as a Lambda or Function App with only minor adjustments.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;... then, they become truly scalable.&lt;/p&gt;

&lt;p&gt;As presented, ... the student would never see that other options might be better and more performant.&lt;/p&gt;

&lt;h2&gt;
  
  
  Issue: No Unit Tests
&lt;/h2&gt;

&lt;p&gt;There wasn't even a mention of Unit Tests.&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%2Fz9dmhmcagzoe4nhopu6y.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%2Fz9dmhmcagzoe4nhopu6y.png" alt="Unit Tests I am working on" width="800" height="384"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Granted, this was a simple application with relatively easy-to-understand code.&lt;/p&gt;

&lt;p&gt;But, ... this code could benefit from some rework to make the components more testable.&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%2F6a5szwjhtl39mi5t5fuc.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%2F6a5szwjhtl39mi5t5fuc.png" alt="Image description" width="800" height="507"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At a minimum, ... they should have discussed places to test and tools to use for testing so that the student had more information on what to look for in the future.&lt;/p&gt;

&lt;h2&gt;
  
  
  Issue: Deployment as a Hook
&lt;/h2&gt;

&lt;p&gt;Deployment, where Render watches my repository for changes (hooks into it), isn’t a bad pattern.&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%2Fgl1qtldspckm15uor8vw.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%2Fgl1qtldspckm15uor8vw.png" alt="Image description" width="800" height="361"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There’s no control over the deployment pipeline, which I had been hoping to see.&lt;/p&gt;

&lt;p&gt;I was disappointed, but this issue is minimal.&lt;/p&gt;

&lt;p&gt;Learning the basics of DevOps is an important part of understanding the whole development process.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;I am specifically not mentioning the boot camp or video that I watched. This article isn't meant to call anyone out directly.&lt;/p&gt;

&lt;p&gt;I want you to see where things could be improved.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;None of these bad, strange, or odd patterns were discussed.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ol&gt;
&lt;li&gt;Proper patterns and conventions on inline CSS is difficult.&lt;/li&gt;
&lt;li&gt;Refactoring was not taken into account.&lt;/li&gt;
&lt;li&gt;Using the Node Server to push the React Build is awkward.&lt;/li&gt;
&lt;li&gt;There were no Unit Tests.&lt;/li&gt;
&lt;li&gt;Deployment was a simple external hook.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I have  &lt;strong&gt;major concerns&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;That newer developers would see the code used in the video as the right way to do things.&lt;/li&gt;
&lt;li&gt;Without context, this will leave them and their company at a disadvantage.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This article will most likely become a video, conference talk, and/or a workshop series.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>beginners</category>
      <category>learning</category>
    </item>
    <item>
      <title>It's Always About Bob</title>
      <dc:creator>bob.ts</dc:creator>
      <pubDate>Thu, 29 Feb 2024 20:09:54 +0000</pubDate>
      <link>https://dev.to/rfornal/its-always-about-bob-2gcg</link>
      <guid>https://dev.to/rfornal/its-always-about-bob-2gcg</guid>
      <description>&lt;h2&gt;
  
  
  Bob
&lt;/h2&gt;

&lt;p&gt;It's always about Bob.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"What About Bob?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For me, the journey into considering who "Bob" is started with an amazingly funny movie ...&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fjywpsvdux9he5nbhsivo.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fjywpsvdux9he5nbhsivo.jpg" alt="What About Bob Movie Poster" width="700" height="1000"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then, there's the black cat in Luck, Bob.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F6twxnbep9rwtzquzcbhl.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F6twxnbep9rwtzquzcbhl.jpg" alt="Luck Movie Poster" width="800" height="232"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I've come to learn that it's &lt;strong&gt;all about Bob&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Some more "Bobs" ...&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Bob the Builder.&lt;/li&gt;
&lt;li&gt;B.O.B., the gelatinous, brainless blob in Monsters vs. Aliens.&lt;/li&gt;
&lt;li&gt;Bob Chatchit, from A Christmas Carol by Charles Dickens.&lt;/li&gt;
&lt;li&gt;Planet Bob, also known as New Earth, in the film Titan A.E.&lt;/li&gt;
&lt;li&gt;Sideshow Bob, a recurring character on The Simpsons.&lt;/li&gt;
&lt;li&gt;Bob, from the spinoff of Despicable Me known as Minions.&lt;/li&gt;
&lt;li&gt;Bob (Robert Reynolds), the subject in a secret Super-Soldier experiment in the Thunderbolts.&lt;/li&gt;
&lt;li&gt;There's also &lt;a href="https://www.iheart.com/live/965-bob-fm-5802/" rel="noopener noreferrer"&gt;96.5 Bob FM: We Play Anything for Fayetteville&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Work
&lt;/h2&gt;

&lt;p&gt;At my company, I got an email about an HR system called &lt;a href="https://www.hibob.com/" rel="noopener noreferrer"&gt;HiBob&lt;/a&gt;. I deleted the email immediately since it was clearly a scam.&lt;/p&gt;

&lt;p&gt;Then HR told us about a cool new system.&lt;/p&gt;

&lt;h2&gt;
  
  
  This Journey
&lt;/h2&gt;

&lt;p&gt;I was just starting to think about the name, Bob, what I came across &lt;a href="https://existentialcrisisbob.com/" rel="noopener noreferrer"&gt;Existential Crisis Bob&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F3aegbasy3kzkyocsatnn.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F3aegbasy3kzkyocsatnn.jpeg" alt="Existential Crisis Bob Plush Advertisement" width="800" height="1394"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Someone asked me the same day, "Why is Bob a shortened form of Robert?"&lt;/p&gt;

&lt;p&gt;Can you &lt;strong&gt;&lt;em&gt;believe&lt;/em&gt;&lt;/strong&gt; that this had never occurred to me?&lt;/p&gt;

&lt;h2&gt;
  
  
  My Beginning
&lt;/h2&gt;

&lt;p&gt;I was born, Robert.&lt;/p&gt;

&lt;p&gt;Most of by childhood, I was called Bobby (today, only my sister calls me that).&lt;/p&gt;

&lt;p&gt;Then, I met a girl named Bobbie and thought that Bobby was a bit childish and started going by Bob.&lt;/p&gt;

&lt;h2&gt;
  
  
  Learning About Bob
&lt;/h2&gt;

&lt;p&gt;Then, I wanted to learn about why Bob is a shortened version of Robert ... it does seem strange.&lt;/p&gt;

&lt;p&gt;From Wikipedia: &lt;a href="https://en.wikipedia.org/wiki/Bob_(given_name)" rel="noopener noreferrer"&gt;HERE&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Bob is a male given name or a diminutive form of a persons name, usually of Robert, and sometimes a diminutive of Bobby. It is most common in English-speaking countries such as the United States, Canada, Ireland, the United Kingdom, Australia, and New Zealand and some Anglophone African countries.&lt;/p&gt;

&lt;p&gt;It most likely originated from the diminutive Rob, short for Robert. Rhyming names were popular in the Middle Ages, so Richard became Rick, Hick, or Dick, William became Will, Gill, or Bill, and Robert became Rob, Hob, Dob, Nob, or Bob.&lt;/p&gt;

&lt;p&gt;It can also be used as a nickname for the name Vladimir, since a commonly used nickname for Vladimir is Vova which in Cyrillic script (Вова) resembles the name Bob in Latin script; historically, both names (Robert and Vladimir) share the same meaning (bright fame).&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>watercooler</category>
      <category>frontend</category>
      <category>writing</category>
    </item>
  </channel>
</rss>
