<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Richard Oliver Bray</title>
    <description>The latest articles on Forem by Richard Oliver Bray (@richardbray).</description>
    <link>https://forem.com/richardbray</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%2F130379%2Fe9ae9e18-8011-4c88-9b0d-7b4697c057bc.jpg</url>
      <title>Forem: Richard Oliver Bray</title>
      <link>https://forem.com/richardbray</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/richardbray"/>
    <language>en</language>
    <item>
      <title>Why Shift+Enter doesn't work in Claude Code (and how to fix it)</title>
      <dc:creator>Richard Oliver Bray</dc:creator>
      <pubDate>Fri, 06 Mar 2026 16:03:22 +0000</pubDate>
      <link>https://forem.com/richardbray/why-shiftenter-doesnt-work-in-claude-code-and-how-to-fix-it-10f7</link>
      <guid>https://forem.com/richardbray/why-shiftenter-doesnt-work-in-claude-code-and-how-to-fix-it-10f7</guid>
      <description>&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Enable the Kitty keyboard protocol in your terminal (WezTerm: add &lt;code&gt;config.enable_kitty_keyboard = true&lt;/code&gt; to your &lt;code&gt;wezterm.lua&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Open a new terminal window&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;If you've been using Claude Code and noticed that Shift+Enter just submits your message instead of adding a new line, you're not imagining things — it genuinely doesn't work out of the box. The good news is it's actually a one-part fix, and once you know why it's broken, it makes total sense.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why it doesn't work
&lt;/h2&gt;

&lt;p&gt;Claude Code does support a &lt;code&gt;chat:newline&lt;/code&gt; action, but the reason Shift+Enter doesn't trigger it comes down to how your terminal handles key input.&lt;/p&gt;

&lt;p&gt;Most terminals, by default, send the exact same byte sequence for both Enter and Shift+Enter. That means even though Claude Code is perfectly capable of inserting a new line, your terminal never actually tells it that Shift+Enter was pressed — it just sees Enter, and submits.&lt;/p&gt;

&lt;p&gt;This is a known limitation of the traditional XTerm key encoding that most terminals use. The fix is to enable a newer keyboard protocol that can distinguish between modified keys.&lt;/p&gt;

&lt;h2&gt;
  
  
  The fix
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 1: Enable extended key reporting in your terminal
&lt;/h3&gt;

&lt;p&gt;This step depends on which terminal you're using. The key thing you need is support for the &lt;strong&gt;Kitty keyboard protocol&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If you've heard of the Kitty image protocol (which lets terminals display inline images), it's the same idea — a set of extensions to the traditional terminal protocol, created by the Kitty terminal, that other terminals have since adopted. Just like the image protocol adds capabilities the original terminal spec never had, the Kitty keyboard protocol adds the ability to send distinct escape sequences for key combinations that classic XTerm encoding can't distinguish — like Shift+Enter vs Enter.&lt;/p&gt;

&lt;p&gt;So even though you might not be using Kitty as your terminal, you can still benefit from the protocol it introduced. Most modern terminals have added support for it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;WezTerm&lt;/strong&gt; (this is the terminal I use and tested with):&lt;/p&gt;

&lt;p&gt;Add this to your &lt;code&gt;~/.config/wezterm/wezterm.lua&lt;/code&gt; (or wherever your config lives):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight lua"&gt;&lt;code&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;enable_kitty_keyboard&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Other terminals that support extended key reporting:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Kitty&lt;/strong&gt; — enabled by default&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ghostty&lt;/strong&gt; — enabled by default&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;iTerm2&lt;/strong&gt; — enable "CSI u" mode in Preferences → Profiles → Keys&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you're on a terminal that doesn't support any of these protocols, Shift+Enter likely can't be made to work without switching terminals.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Open a new terminal window
&lt;/h3&gt;

&lt;p&gt;This is the step that's easy to miss. The keyboard protocol is negotiated when a terminal session starts, so a config reload isn't enough. You need to open a &lt;strong&gt;new window&lt;/strong&gt; (not just a new tab in the same session) for the change to take effect.&lt;/p&gt;

&lt;p&gt;Once you do that, Shift+Enter should insert a new line exactly as you'd expect.&lt;/p&gt;

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

&lt;p&gt;It's possible that the Claude Code team will add better handling for terminals that don't support extended key reporting in the future, which would make this post completely unnecessary. If that happens, this post will age badly — and honestly, that would be great. But for now, these are the hoops you need to jump through to get it working.&lt;/p&gt;

</description>
      <category>claudecode</category>
      <category>terminal</category>
      <category>wezterm</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Why Rolldown-Vite Is Going To Replace Vite (And Why You Should Care)</title>
      <dc:creator>Richard Oliver Bray</dc:creator>
      <pubDate>Wed, 11 Jun 2025 18:38:54 +0000</pubDate>
      <link>https://forem.com/richardbray/why-rolldown-vite-is-going-to-replace-vite-and-why-you-should-care-1111</link>
      <guid>https://forem.com/richardbray/why-rolldown-vite-is-going-to-replace-vite-and-why-you-should-care-1111</guid>
      <description>&lt;p&gt;It feels like just yesterday I was writing about &lt;a href="https://dev.to/richardbray/how-to-replace-webpack-babel-with-vite-on-a-legacy-react-typescript-project-3ofg"&gt;replacing Webpack with Vite&lt;/a&gt;, and here we are again with another potential game-changer in the JavaScript build tool ecosystem. The world of JavaScript tooling moves really quickly, and now there's a &lt;a href="https://voidzero.dev/posts/announcing-rolldown-vite" rel="noopener noreferrer"&gt;new development&lt;/a&gt; that could make your existing Vite projects build up to 16 times faster: &lt;strong&gt;Rolldown-Vite&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=UPIIndneCo4" rel="noopener noreferrer"&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%2Fv7xs60n0b3ljbwo9utuf.png" alt="Watch a video talking about Rolldown-Vite" width="800" height="444"&gt;&lt;/a&gt;&lt;br&gt;
You can &lt;a href="https://www.youtube.com/watch?v=UPIIndneCo4" rel="noopener noreferrer"&gt;watch this article&lt;/a&gt; if you prefer video content.&lt;/p&gt;

&lt;p&gt;If you've been following the JavaScript tooling space, you'll know that we've seen this cycle before. First there was Grunt then there was Gulp, then Webpack dominated for years (and still kind of does in some cases). Recently Vite has been the go-to choice for new projects. Now, the Vite team themselves are working on something that could supercharge the tool we already love.&lt;/p&gt;
&lt;h2&gt;
  
  
  What is Rolldown-Vite?
&lt;/h2&gt;

&lt;p&gt;Rolldown-Vite is not a replacement for Vite itself. Instead, it's a Rust-based drop-in replacement for Vite's internal bundlers (ESBuild and Rollup). Think of it as Vite with a turbocharged engine under the hood.&lt;/p&gt;

&lt;p&gt;Developed by Evan You (creator of Vue.js) and the VoidZero team, Rolldown-Vite uses the high performance of Rust to deal with bottlenecks in the current JavaScript-based Vite toolchain.&lt;/p&gt;

&lt;p&gt;The numbers are very impressive:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A React project with 10,000 JSX components: 14 seconds with Vite → under 4 seconds with Rolldown-Vite (70% faster)&lt;/li&gt;
&lt;li&gt;Excalidraw's build time: 22.9 seconds → 1.4 seconds&lt;/li&gt;
&lt;li&gt;GitLab's build time: 2.5 minutes → 40 seconds&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Understanding Vite's Current Architecture
&lt;/h2&gt;

&lt;p&gt;To understand why Rolldown-Vite gives these performance improvements, we need to look at how Vite currently works:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Development&lt;/strong&gt;: Uses ESBuild (written in Go) for fast bundling and transformations&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Production&lt;/strong&gt;: Uses Rollup (written in JavaScript) for final builds (I think)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;While this setup has worked well for years, Rollup being written in JavaScript isn't the most performant option for building large-scale applications, especially in a CI/CD pipeline.&lt;/p&gt;
&lt;h2&gt;
  
  
  How Rolldown-Vite Changes the Game
&lt;/h2&gt;

&lt;p&gt;Rolldown-Vite replaces both ESBuild and Rollup with a single, unified Rust-based bundler called Rolldown. This provides:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Consistent performance&lt;/strong&gt; across development and production&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Massive speed improvements&lt;/strong&gt; thanks to Rust's performance characteristics&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reduced memory usage&lt;/strong&gt; - crucial for large projects&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Full compatibility&lt;/strong&gt; with existing Vite plugins and configurations&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;At the heart of this is &lt;strong&gt;Oxc&lt;/strong&gt;, a.k.a the Oxidation compiler which provides a &lt;strong&gt;parser*, for understanding JavaScript and TypeScript code. A **transformer&lt;/strong&gt; for converting modern syntax to compatible versions. A &lt;strong&gt;resolver&lt;/strong&gt; for handling module resolution. A &lt;strong&gt;minifier&lt;/strong&gt; for optimising production builds, and a &lt;strong&gt;linter&lt;/strong&gt; - for code quality checks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rolldown&lt;/strong&gt; then uses Oxc as its foundational layer to provide the bundling functionality. This means instead of having separate tools for different tasks, everything runs through a single, highly optimized Rust-based pipeline.&lt;/p&gt;
&lt;h2&gt;
  
  
  The Rust Revolution Continues
&lt;/h2&gt;

&lt;p&gt;There's definitely a pattern emerging in the JavaScript tooling space - everything is being rewritten in Rust. We've seen it with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;SWC&lt;/strong&gt; (replacing Babel)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Turbopack&lt;/strong&gt; (Webpack's successor)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RSPack&lt;/strong&gt; and &lt;strong&gt;Farm&lt;/strong&gt; (other bundling solutions)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rolldown&lt;/strong&gt; (now powering Vite)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Honestly, I'm not sure if I like (Golang FTW), it but it looks like things are going that way.&lt;/p&gt;

&lt;p&gt;Rust provides the performance benefits that JavaScript simply can't match when it comes to intensive tasks like bundling, minification, and code transformation.&lt;/p&gt;
&lt;h2&gt;
  
  
  How To Switch?
&lt;/h2&gt;

&lt;p&gt;The beauty of Rolldown-Vite is that it's designed as a true drop-in replacement. In most cases, you can try it by simply aliasing the Vite package to &lt;code&gt;rolldown-vite&lt;/code&gt; in your &lt;code&gt;package.json&lt;/code&gt;:&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="c1"&gt;// package.json&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dependencies&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="c1"&gt;// ...&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;vite&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;6.3.5&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="c1"&gt;// &amp;lt;-- before&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;vite&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;npm:rolldown-vite@latest&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="c1"&gt;// &amp;lt;-- after&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;If you're happy with your current Vite setup and build times aren't an issue, there's no urgent need to switch. I mean, for me Vite has always been super fast.&lt;/p&gt;

&lt;p&gt;But, if you're working on larger projects where build times are becoming a bottleneck, Rolldown-Vite can provide significant improvements with minimal effort.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>vite</category>
      <category>programming</category>
    </item>
    <item>
      <title>Understanding and Preventing Fetch Waterfalls in React</title>
      <dc:creator>Richard Oliver Bray</dc:creator>
      <pubDate>Thu, 02 Jan 2025 20:38:39 +0000</pubDate>
      <link>https://forem.com/richardbray/understanding-and-preventing-fetch-waterfalls-in-react-454k</link>
      <guid>https://forem.com/richardbray/understanding-and-preventing-fetch-waterfalls-in-react-454k</guid>
      <description>&lt;p&gt;If you're a React developer, it's a safe bet you've encountered fetch waterfalls - also called request waterfalls or network waterfalls. Their distinctive shape crops up in analytics tools when you go try to see what's taking the page you painstakingly designed is taking so long to load.&lt;/p&gt;

&lt;p&gt;In this blog post, we’ll go into what fetch waterfalls are, why they happen, how they affect your React applications, and, most importantly, how to avoid them.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is a Fetch Waterfall?
&lt;/h3&gt;

&lt;p&gt;Let’s start with the basics.&lt;/p&gt;

&lt;p&gt;A fetch waterfall is a performance issue that occurs when multiple API calls or fetch requests are chained together and executed one after another. Rather than sending multiple requests in parallel (which would allow them to complete concurrently), the requests are queued and executed in sequence. This results in significant delays in page rendering, especially if the number of fetches increases.&lt;/p&gt;

&lt;p&gt;Here's a simple visual representation of what this looks like:&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%2F34wnqsjbh7lhahf4x15r.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%2F34wnqsjbh7lhahf4x15r.png" alt="Network tab of dev tools showing fetch waterfall" width="800" height="133"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Source: &lt;a href="https://blog.sentry.io/fetch-waterfall-in-react/" rel="noopener noreferrer"&gt;Sentry.io&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From the image above, you can clearly see the &lt;strong&gt;sequential delays&lt;/strong&gt; in a 'waterfall' pattern. Each request starts only after the previous one has finished. In practice, even a slight delay in one request can cause the entire page load time to increase dramatically.&lt;/p&gt;

&lt;p&gt;This is particularly troublesome for user experience, as modern web users expect fast-loading applications. A few seconds of delay can lead to &lt;strong&gt;higher bounce rates&lt;/strong&gt; and &lt;strong&gt;lower engagement&lt;/strong&gt;, impacting your application's overall success.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Do Fetch Waterfalls Happen?
&lt;/h3&gt;

&lt;p&gt;Fetch waterfalls in React typically occur due to the hierarchical structure of components. Here’s a typical scenario:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Parent Component Fetches Data&lt;/strong&gt;: The parent component initiates a fetch request when it mounts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Child Components Await Data&lt;/strong&gt;: Child components rely on data fetched by the parent and are rendered only once the parent’s data is available.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sequential Requests&lt;/strong&gt;: If there are multiple nested components, each one might trigger fetch requests sequentially, causing a "waterfall" effect.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This cascading behavior occurs because components in React render asynchronously. When the parent component fetches data, child components may have to wait until the parent’s request is completed. If these fetches are not handled efficiently, you can end up with a significant delay as each request depends on the previous one.&lt;/p&gt;

&lt;h3&gt;
  
  
  How to Identify Fetch Waterfalls
&lt;/h3&gt;

&lt;p&gt;To identify if your React application is suffering from fetch waterfalls, you can use tools like &lt;strong&gt;Chrome DevTools&lt;/strong&gt; or &lt;strong&gt;React DevTools&lt;/strong&gt; to monitor network requests and performance. In Chrome DevTools, navigate to the &lt;strong&gt;Network&lt;/strong&gt; tab and look for &lt;strong&gt;sequential API calls&lt;/strong&gt; that are blocking the page’s loading process.&lt;/p&gt;

&lt;p&gt;In React DevTools, you can inspect component re-renders and identify any unnecessary dependencies causing fetch requests to be triggered multiple times.&lt;/p&gt;

&lt;p&gt;Here are some signs that a fetch waterfall may be occurring:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Slow page load times&lt;/strong&gt;: If your page takes longer than expected to load.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Suspicious performance patterns&lt;/strong&gt;: If you notice a series of API calls that appear to be made one after another instead of in parallel.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  How to Prevent Fetch Waterfalls in React
&lt;/h3&gt;

&lt;p&gt;Fortunately, there are several strategies to avoid fetch waterfalls and optimize your React applications for better performance.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. &lt;strong&gt;Fetch Data in Parallel&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Instead of waiting for each API request to complete before starting the next one, consider executing multiple fetch requests in parallel. This can be done using JavaScript’s &lt;code&gt;Promise.all()&lt;/code&gt; method, which allows you to run multiple promises concurrently.&lt;/p&gt;

&lt;p&gt;Here’s an example of fetching data in parallel:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fetchData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;data1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data3&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="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
  &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/api/data1&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;res&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()),&lt;/span&gt;
  &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/api/data2&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;res&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()),&lt;/span&gt;
  &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/api/data3&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;res&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()),&lt;/span&gt;
&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;span class="c1"&gt;// Use the data&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By fetching data in parallel, you reduce the total waiting time and allow the browser to load resources faster.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. &lt;strong&gt;Decouple Component Data Fetching&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;You can refactor your components so that they don't rely on the parent component’s data to trigger their own fetches. Instead, let each child component handle its own data fetching independently. This can be done by &lt;strong&gt;lifting state up&lt;/strong&gt; and passing down the necessary data or by using libraries like &lt;strong&gt;React Query&lt;/strong&gt; or &lt;strong&gt;SWR&lt;/strong&gt; to manage fetching at the component level.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. &lt;strong&gt;Use React Query or SWR&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Libraries like &lt;strong&gt;React Query&lt;/strong&gt; and &lt;strong&gt;SWR&lt;/strong&gt; are great for managing data fetching in React applications. They handle caching, background data fetching, and error handling, while also allowing you to fetch data in parallel efficiently.&lt;/p&gt;

&lt;p&gt;React Query, for instance, automatically handles caching, retries, and background syncing for data fetching, ensuring that your components don’t unnecessarily wait for data and that network calls are only made when needed.&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;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useQuery&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-query&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;fetchData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &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="nx"&gt;res&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;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/api/data&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;MyComponent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;isLoading&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useQuery&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dataKey&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fetchData&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;isLoading&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;&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="k"&gt;return&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;Data: &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&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;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. &lt;strong&gt;Cache Data to Reduce Redundant Requests&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Caching can significantly reduce the need for redundant requests to the server. By storing fetched data locally (in the component state, context, or a caching library like &lt;strong&gt;React Query&lt;/strong&gt;), you can avoid unnecessary network requests, making your application faster and more efficient.&lt;/p&gt;

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

&lt;p&gt;Fetch waterfalls in React can be a major source of performance bottlenecks, but with the right strategies, they can be easily avoided. By fetching data in parallel, decoupling data fetching from components, and leveraging powerful libraries like React Query, you can improve the performance of your React applications and enhance the user experience.&lt;/p&gt;

&lt;p&gt;If you're dealing with frequent fetch waterfalls in your React codebase, it's worth taking a step back to analyze your data fetching patterns and implementing these best practices. Ultimately, optimizing how your application interacts with APIs will result in faster, more reliable, and scalable applications.&lt;/p&gt;

</description>
      <category>react</category>
      <category>webdev</category>
      <category>javascript</category>
      <category>frontend</category>
    </item>
    <item>
      <title>Crafting a Captivating CV: The Secret to Standing Out as a Software Engineer in 2024</title>
      <dc:creator>Richard Oliver Bray</dc:creator>
      <pubDate>Tue, 09 Jan 2024 17:24:36 +0000</pubDate>
      <link>https://forem.com/richardbray/crafting-a-captivating-cv-the-secret-to-standing-out-as-a-software-engineer-in-2024-jdn</link>
      <guid>https://forem.com/richardbray/crafting-a-captivating-cv-the-secret-to-standing-out-as-a-software-engineer-in-2024-jdn</guid>
      <description>&lt;p&gt;Getting a job as a software engineer in 2024 is going to be tough. Not only have a lot of good developers been laid off but companies are hiring less in general. So what can you do to stand out from the crowd?&lt;/p&gt;

&lt;p&gt;Learn some new skills, practise data structures and algorithms or write an outstanding CV? If you do the first two things but have a terrible CV, you're not going to get an interview, so in my books, it makes sense to start with the CV.&lt;/p&gt;

&lt;p&gt;So in this article I'm going to talk about 5 things you can do to write a better CV and get more interviews.&lt;/p&gt;

&lt;h3&gt;
  
  
  Shameless Plug
&lt;/h3&gt;

&lt;p&gt;I've created an &lt;a href="(https://www.courses.orva.studio/cv)"&gt;online course&lt;/a&gt; to help you write the best possible software engineer CV which you can get access to here.&lt;/p&gt;

&lt;p&gt;If you enjoy this article I highly recommend you check it out.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Have a One Page, Single Column CV
&lt;/h2&gt;

&lt;p&gt;Your CV should be just one page long. Not two, not one and a half, but one page. The person reading your CV doesn't have time to dig through two pages of information to find what they're looking for.&lt;/p&gt;

&lt;p&gt;The person who is going to review your CV is only going to look at it for an average of 6 to 8 seconds therefore just the important information, so skills, experience and qualifications, should be able to fit on one page. And if it can't, then that means you may have to cut some things out. You could have one or two columns in your CV. And for the most part, it doesn't really matter. But, in my opinion, it's much easier to read a single column CV than a two column CV.&lt;/p&gt;

&lt;p&gt;And if the aim is to make it as easy as possible to read, for the person going through your CV to find the information they're looking for, then a single column CV is the way to go.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Focus on Skills, Experience and Education
&lt;/h2&gt;

&lt;p&gt;In the 6 to 8 seconds a hiring manager or recruiter is going to spend reading your CV, they're going to be looking for these three things. 1. Do you have the skills they're looking for? 2. Do you have the experience they're looking for? And 3. Do you have the qualifications they're looking for? Skills, experience and qualifications.&lt;/p&gt;

&lt;p&gt;This is how you should structure your CV. You have to put these things at the forefront so that they're easy to find. If a person looking at your CV can't find these things easily, say in 6 8 seconds, then they're going to move on to the next CV. And yours will be one of the 80 percent that get rejected.&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%2Fjd4s81vyr98zvtthrntq.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%2Fjd4s81vyr98zvtthrntq.png" alt="Example CV Layout" width="800" height="1132"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At the top of your CV you should have your name, address, GitHub, LinkedIn, websites, telephone number, etc. Then, right underneath you need to have a section called Skills. You can put technical skills, but I like the word skills because it's really easy to read and find.&lt;/p&gt;

&lt;p&gt;In this skills section, you should list all the skills you have that are relevant to the job. So if you're a front end developer, list all the languages and frameworks that you know. So things like React, JavaScript, CSS, Angular, etc. List them all in the Skills section.&lt;/p&gt;

&lt;p&gt;A recruiter would come here first and see if your skills match the skills that they're looking for and if they do match, then they'll move on to the next section which should be experience. You can call it Work Experience but to keep things simple I like having sections with one word so just Experience is fine.&lt;/p&gt;

&lt;p&gt;The most recent job or piece of experience should be at the top and the oldest one should go at the bottom. If you've never had a job, then you can change this experience to projects and you can list all the projects that you've worked on in your bootcamp or in your spare time. I would say however, it's really important to try and get some experience if you don't have any.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;I'm planning to write an article on how to get experience without a job in the future but if you can't wait till then, I've outlined exactly how to do it in my &lt;a href="https://www.courses.orva.studio/cv" rel="noopener noreferrer"&gt;CV course&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Each piece of job experience you should have no more than five bullet points, and the more you go down, the less bullet points you should have. Then below the experience section, then, you should have a section called education.&lt;/p&gt;

&lt;p&gt;This could also be qualifications. But as long as it's one word, I'm okay. This should contain the highest qualification you have related to software engineering. And the qualification should just have one bullet point.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. What You Did, Why You Did It and The Results
&lt;/h2&gt;

&lt;p&gt;This is one of the most important parts of this article. If you take no other advice away, then please take the advice from this point, this alone could make a huge difference to your CV. Whenever you're writing bullet points for the experience part of your CV, you need to follow this formula. What did you do? Why did you do it? And what was the outcome?&lt;/p&gt;

&lt;p&gt;Why did you do it? And what was the outcome? Let's go through a quick example.&lt;/p&gt;

&lt;p&gt;Imagine a bullet point in the experience section under a specific job is;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;'Built a website using React and Node.js'.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This at the moment is not that good. It tells the employer what you did, but it doesn't tell the employer anything else. Any developer could have done this so what makes you doing it so special? Let's look at how this can be improved.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;'Built a website using react and Nodejs To help people find jobs'.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is better. We've added the why we're helping people find jobs, but how many people have we helped? Basically, what was the outcome? Let's see how this can be rewritten.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;'Designed and developed a web application using React and Node.js to help people find tech jobs. This application helped 50 to 100 people find jobs every month.'&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is much better. You can read what was done, we can see why it was done and the outcome.&lt;/p&gt;

&lt;p&gt;No jargon, no slang and no personal pronouns. So don't use words like I, it's implied that you did it. Keep it short, as simple as you can and make it sound professional.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Use a PDF
&lt;/h2&gt;

&lt;p&gt;What format should your CV be in? Simple answer is PDF. Not a Word document, not a Google Doc, not pages or anything else. Just a PDF. The recruiter or hiring manager might have a different version of Word than what you use to create the CV. Therefore, if they open it, the layout could be messed up. And also, Documents can look different on different operating systems.&lt;/p&gt;

&lt;p&gt;So if you wrote your CV on a Linux machine, and the person receiving it is using a Windows then there might be some issues with formatting and compatibility. But a PDF will look the same on any machine, no matter the version or operating system. So in my opinion, it's the safest option to use.&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%2F8pr3irwsl5r3scxk346y.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%2F8pr3irwsl5r3scxk346y.jpg" alt="Image of incorrectly formatted CV" width="800" height="598"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If we have a look at the image above, this is an image of someone who created their CV using a Word document, and they put boxes all over it. But when the recruiter opened it, this is what they saw. The layout and the formatting had been distorted so much that it was completely impossible to read.&lt;/p&gt;

&lt;p&gt;Please don't let that be you. Just use a PDF for your CVs all the time.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Don't add a Hobbies or Interests Section
&lt;/h2&gt;

&lt;p&gt;Instead of writing a list of hobbies and interests, you can replace that whole section with a list of achievements you've had using the what you did, why you did it and what was the outcome technique, let's try it. So imagine this specific bullet point was in the hobby section of a CV:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"I like to play football."&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now, in my opinion, this is a terrible way to add a hobby to your CV. It doesn't give the employer any indication of how good you are and why you like playing football. Let's see how this hobby can be rephrased.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"Play as a goalkeeper for my local team and have won the league three times."&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is a bit better. It tells the outcome and what you do, and shows the employer that you have teamwork skills and dedication, since not everyone can play football long enough to win the league, especially three times. Again, let's see how this bullet point can be improved.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"Regularly play as a goalkeeper for my local team, London Lions, to maintain fitness, contributed to winning the league three times in the last five years."&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is much better, and this is what you should be aiming for when you're adding your hobbies. This contains the what, the why, and the outcome. And it sounds much more impressive than the first version.&lt;/p&gt;

&lt;p&gt;This is what you can do to turn just any hobby into an achievement. And this is why I highly recommend you do not have a Hobbies or Hobbies and Interests section. Instead, turn those around into an Achievements section and this will make you look much more impressive in the eyes of an employer.&lt;/p&gt;

&lt;h2&gt;
  
  
  To Wrap it All up
&lt;/h2&gt;

&lt;p&gt;So there you have it, five things you can do to write a better CV and get more interviews. Weather you're a junior developer frontend developer or a senior developer fullstack developer, these tips will be sure to help you out.&lt;/p&gt;

&lt;p&gt;If you want to learn more about how to write a better CV, again check out &lt;a href="https://www.courses.orva.studio/cv" rel="noopener noreferrer"&gt;my online course&lt;/a&gt; that goes into a lot more detail than this article. I've put a lot of work into this talking to recruiters, hiring managers and combining it with my own experience, so be sure to check it out.&lt;/p&gt;

&lt;p&gt;Until next time. Happy coding 👋&lt;/p&gt;

</description>
    </item>
    <item>
      <title>You've been structuring files in projects wrong</title>
      <dc:creator>Richard Oliver Bray</dc:creator>
      <pubDate>Wed, 19 Oct 2022 15:14:58 +0000</pubDate>
      <link>https://forem.com/richardbray/youve-been-structuring-files-in-projects-wrong-1985</link>
      <guid>https://forem.com/richardbray/youve-been-structuring-files-in-projects-wrong-1985</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally posted here &lt;a href="https://medium.com/octopus-labs-london/how-to-structure-files-in-large-react-projects-48ee3dc424ed" rel="noopener noreferrer"&gt;https://medium.com/octopus-labs-london/how-to-structure-files-in-large-react-projects-48ee3dc424ed&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Okay I admit, I've got your attention with a somewhat catchy title but hear me out.&lt;/p&gt;

&lt;p&gt;When you tend to have large React, Svelte, Vue, any frontend framework (or library) project, it's easy to put all the components in a components folder, containers in the containers folder and so on. Well I have a different approach for really large projects. Something that looks a bit like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public/
package.json
index.ts
src/
│
├── components/
│   ├── Button/
│   │   ├── Button.tsx
│   │   ├── Button.tests.tsx
│   │   └── Button.css
│   ├── Dropdown/
│   ├── Toaster/
│   ├── Header/
│   └── Footer/
│ 
├── layouts/
│   └── StoreLayout/
│       ├── components/
│       │   ├── SearchDropdown/
│       └── StoreLayout.tsx
│ 
└── pages/
    ├── StoreProductPage/
    │   ├── components/
    │   │   ├── Carousel/
    │   │   └── ProductCard/
    │   └── StoreProductPage.tsx
    │
    └── StoreCheckoutPage/
        ├── components/
        │   └── ProductCheckoutCard/
        └── StoreCheckoutPage.tsx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This way it's easy to remove pages without other parts of the site. All the general components go in the components folder. But Page specific components go in a sub-folder.&lt;/p&gt;

&lt;h3&gt;
  
  
  Not quite convinced?
&lt;/h3&gt;

&lt;p&gt;Check out my video explanation on YouTube.&lt;/p&gt;

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

&lt;h3&gt;
  
  
  Let's talk
&lt;/h3&gt;

&lt;p&gt;It would be good to hear your thoughts on this approach, if you like or dislike it, and if you have any ideas for improvements. You can find me on &lt;a href="//linktr.ee/richardobray"&gt;the socials&lt;/a&gt;, or you can just write a comment below and I promise I'll respond 🙏&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Application specific preferences on my Mac have gone 😱</title>
      <dc:creator>Richard Oliver Bray</dc:creator>
      <pubDate>Sat, 15 Oct 2022 12:47:27 +0000</pubDate>
      <link>https://forem.com/richardbray/application-specific-preferences-on-my-mac-have-gone-1iba</link>
      <guid>https://forem.com/richardbray/application-specific-preferences-on-my-mac-have-gone-1iba</guid>
      <description>&lt;p&gt;A few weeks ago I head a problem with my applications where whenever I changed a setting they were not saving, or the settings had just reverted to their default. My VSCode, ZSH, mechanical keyboard settings had all gone.&lt;/p&gt;

&lt;p&gt;After hours I managed to figure out the issue and I've created a video below to show how I did it.&lt;/p&gt;

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

</description>
      <category>application</category>
      <category>mac</category>
      <category>tutorial</category>
      <category>dropbox</category>
    </item>
    <item>
      <title>How to use hooks in React Class components</title>
      <dc:creator>Richard Oliver Bray</dc:creator>
      <pubDate>Mon, 11 Apr 2022 16:44:49 +0000</pubDate>
      <link>https://forem.com/richardbray/how-to-use-hooks-in-react-class-components-4lhp</link>
      <guid>https://forem.com/richardbray/how-to-use-hooks-in-react-class-components-4lhp</guid>
      <description>&lt;p&gt;You're probably thinking, why on earth would anyone want to use a hook in a class based component, two words, legacy projects.&lt;/p&gt;

&lt;p&gt;Hooks are cool and so are functional components, but if you're working on a 4 year old project that has loads of class-based components, you don't have the time to convert them to function based components. What's more, loads of newer libraries only use hooks. &lt;/p&gt;

&lt;p&gt;So if you want to keep a legacy project up-to-date, this is a really helpful technique. &lt;/p&gt;

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



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useNavigate&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-router-dom&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Login&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;My awesome component&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="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"button"&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nf"&gt;handleClick&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;gt;&lt;/span&gt;
          Click here
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nf"&gt;handleClick&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;navigate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/dashboard&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;addHookTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;CompWithHook&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&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;navigate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useNavigate&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;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Component&lt;/span&gt; &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;navigate&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;navigate&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;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;CompWithHook&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nf"&gt;addHookTo&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Aaaaand that's it!&lt;/p&gt;

&lt;h3&gt;
  
  
  Credit where credit is due
&lt;/h3&gt;

&lt;p&gt;I could take all the credit and say my clever mind figured all this out but I actually saw it on the React Router website here -&amp;gt; &lt;a href="https://reactrouter.com/docs/en/v6/faq#what-happened-to-withrouter-i-need-it" rel="noopener noreferrer"&gt;https://reactrouter.com/docs/en/v6/faq#what-happened-to-withrouter-i-need-it&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;They have a good example on there of adding multiple hooks.&lt;/p&gt;

&lt;p&gt;Anyway, I hope you found this useful.&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How to replace webpack &amp; babel with Vite on a legacy React TypeScript project</title>
      <dc:creator>Richard Oliver Bray</dc:creator>
      <pubDate>Fri, 25 Mar 2022 14:37:28 +0000</pubDate>
      <link>https://forem.com/richardbray/how-to-replace-webpack-babel-with-vite-on-a-legacy-react-typescript-project-3ofg</link>
      <guid>https://forem.com/richardbray/how-to-replace-webpack-babel-with-vite-on-a-legacy-react-typescript-project-3ofg</guid>
      <description>&lt;p&gt;It's insane how fast the world of JavaScript moves. &lt;/p&gt;

&lt;p&gt;As far as build tools go I remember how popular &lt;a href="https://gruntjs.com/" rel="noopener noreferrer"&gt;Grunt&lt;/a&gt; was when it was first released, then it was &lt;a href="https://gulpjs.com/" rel="noopener noreferrer"&gt;Gulp&lt;/a&gt;, and &lt;a href="https://babeljs.io/" rel="noopener noreferrer"&gt;Babel&lt;/a&gt; came along to help you add new us features and get them working on older browsers. &lt;/p&gt;

&lt;p&gt;Then there was &lt;a href="https://webpack.js.org/" rel="noopener noreferrer"&gt;Webpack&lt;/a&gt; which seemed like it would be around for a while. Even after things like &lt;a href="https://parceljs.org/" rel="noopener noreferrer"&gt;Parcel&lt;/a&gt; and &lt;a href="https://www.snowpack.dev/" rel="noopener noreferrer"&gt;Snowpack&lt;/a&gt; came on the scene people still recommended Webpack. I mean, it's still the backbone of create-react-app. An then, &lt;a href="https://vitejs.dev/" rel="noopener noreferrer"&gt;Vite&lt;/a&gt; was released. &lt;/p&gt;

&lt;p&gt;Vite is fast, really fast. It requires very little config and is easy to setup. It sits on top of &lt;a href="https://esbuild.github.io/" rel="noopener noreferrer"&gt;esbuild&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I have no doubt there will be something in the future that will replace Vite, but for the simple fact that the config file for Vite can be around 10 lines whereas for Webpack it would have been around 100, I think it's a good choice to stick with for the next few years and something to upgrade your old Webpack project to. &lt;/p&gt;

&lt;p&gt;Plus you don't need Babel if you're using Vite so you can get rid of a tonne of dependencies and security vulnerability messages.&lt;/p&gt;

&lt;h2&gt;
  
  
  Main steps
&lt;/h2&gt;

&lt;p&gt;1 - First thing's first, let's create a new branch for our old project just in case we need to go back to it for any reason. We can delete the branch after a few months if we've never needed to refer to it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# oh-my-zsh git aliases&lt;/span&gt;
gcb old-webpack-babel
gpsup
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note: The above commands are aliased github commands that come by default with &lt;a href="https://ohmyz.sh/" rel="noopener noreferrer"&gt;oh-my-zsh&lt;/a&gt;. You can view the &lt;a href="https://kapeli.com/cheat_sheets/Oh-My-Zsh_Git.docset/Contents/Resources/Documents/index" rel="noopener noreferrer"&gt;full list&lt;/a&gt; here.&lt;/p&gt;

&lt;p&gt;2 - now let's go back to our main branch and remove all of our babel and webpack packages, brace yourself for one large command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm uninstall webpack webpack-merge webpack-dev-server
 webpack-cli ... you get the idea
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;3 - Delete all webpack and babel related files, webpack.common.js, webpack.dev.js etc...&lt;/p&gt;

&lt;p&gt;4 - Install Vite and the Vite React plugin&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm i vite @vitejs/plugin-react
&lt;span class="c"&gt;# then&lt;/span&gt;
npm i @types/node &lt;span class="nt"&gt;-D&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;5 - Create a &lt;strong&gt;vite.config.ts&lt;/strong&gt; file in the root of your project with the following code:&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="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="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;vite&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;react&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@vitejs/plugin-react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;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;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;react&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;6 - Update your package.json file with the following code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"dev": "vite",
"build": "vite build",
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And now run &lt;code&gt;npm run dev&lt;/code&gt;, and if all goes well your project should be fine. &lt;/p&gt;

&lt;h2&gt;
  
  
  Optional steps
&lt;/h2&gt;

&lt;p&gt;Depending on your project, the steps below might not be necessary.&lt;/p&gt;

&lt;h3&gt;
  
  
  Aliases
&lt;/h3&gt;

&lt;p&gt;If like me you have some random Webpack aliases in your code like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@/assets/styles/global&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can add that to your Vite config file like so:&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="c1"&gt;// At top of file&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;node:path&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// ...&lt;/span&gt;
  &lt;span class="nl"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;
      &lt;span class="na"&gt;alias&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;
        &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;__dirname&lt;/span&gt;&lt;span class="p"&gt;,)&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="nx"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;react&lt;/span&gt;&lt;span class="p"&gt;()]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  CSS Modules
&lt;/h3&gt;

&lt;p&gt;If you're using css modules, then I feel sorry for you. You need to change the extension of all your files to .module.css instead of just .css&lt;/p&gt;

&lt;p&gt;Then change the name of any compose properties you have in your css file as well:&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="c"&gt;/* from this */&lt;/span&gt;
&lt;span class="nt"&gt;composes&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;c-white&lt;/span&gt; &lt;span class="nt"&gt;from&lt;/span&gt; &lt;span class="s1"&gt;"../helpers.css"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="c"&gt;/* to this */&lt;/span&gt;
&lt;span class="nt"&gt;composes&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;c-white&lt;/span&gt; &lt;span class="nt"&gt;from&lt;/span&gt; &lt;span class="s1"&gt;"../helpers.module.css"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And also any JS/TS file that you are importing the css file in.&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="c1"&gt;// from this&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;buttonCss&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;@assets/styles/Buttons.css&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// to this&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;buttonCss&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;@assets/styles/Buttons.module.css&lt;/span&gt;&lt;span class="dl"&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 is really painful I know, but it does kind of make more sense. And also, find and replace all is your friend 💪&lt;/p&gt;

&lt;h3&gt;
  
  
  Vite environment variables
&lt;/h3&gt;

&lt;p&gt;You may want to set up environment variables to keep secrets or to insert bits of information based&lt;/p&gt;

&lt;p&gt;1 - Create a &lt;code&gt;.env&lt;/code&gt; file.&lt;br&gt;
2 - Put a &lt;strong&gt;VITE_&lt;/strong&gt; prefix in front of variables like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;VITE_TEST_VAR = "something secret"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;3 - Load them up in your code like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;secretVar&lt;/span&gt; &lt;span class="o"&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;meta&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;VITE_TEST_VAR&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;4 - If you're using Typescript you will need to create an &lt;code&gt;env.d.ts&lt;/code&gt; file in the root of your project&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;/// &amp;lt;reference types="vite/client" /&amp;gt;&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;ImportMetaEnv&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;VITE_APP_TITLE&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;
  &lt;span class="c1"&gt;// more env variables...&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;ImportMeta&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;readonly&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;ImportMetaEnv&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Install npm-check-updates
&lt;/h3&gt;

&lt;p&gt;Since you're upgrading one part of a legacy project, why not update all the other dependencies. The best way to do that is with the &lt;a href="https://github.com/raineorshine/npm-check-updates" rel="noopener noreferrer"&gt;npm-check-updates&lt;/a&gt; package.&lt;/p&gt;

&lt;p&gt;I'd recommend installing updates in by &lt;a href="https://semver.org/" rel="noopener noreferrer"&gt;semver&lt;/a&gt; levels, so patch updates first, then minor updates, then major. Testing the project still works in-between updates&lt;/p&gt;

&lt;p&gt;This can be done easily by running a command like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ncu &lt;span class="nt"&gt;-t&lt;/span&gt; patch &lt;span class="nt"&gt;-u&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;to update just the patch versions in the package.json file, then run&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;to actually install the updates.&lt;/p&gt;




&lt;p&gt;And that's pretty much it.&lt;/p&gt;

&lt;p&gt;I'm not expert on Vite but if you have any questions, feel free to write them down in the section below and I'll do my best to answer them.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>vite</category>
      <category>react</category>
    </item>
    <item>
      <title>Fix sameSite cookie issue in Cypress by installing an older version of Chromium</title>
      <dc:creator>Richard Oliver Bray</dc:creator>
      <pubDate>Tue, 01 Mar 2022 16:26:11 +0000</pubDate>
      <link>https://forem.com/richardbray/fix-samesite-cookie-issue-in-cypress-by-installing-an-older-version-of-chromium-43if</link>
      <guid>https://forem.com/richardbray/fix-samesite-cookie-issue-in-cypress-by-installing-an-older-version-of-chromium-43if</guid>
      <description>&lt;p&gt;Cypress out of the box doesn't allow you to visit different urls or domain from the base one in a given test. You can read more about that in the &lt;a href="https://docs.cypress.io/guides/guides/web-security" rel="noopener noreferrer"&gt;Cypress documentation on web security&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To get around that the following option can be for Chromium based browsers in the cypress.json file:&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;"chromeWebSecurity"&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This works great for most scenarios, but if like me, you're running a test suite that relies on putting cookies from one domain onto another, then you might face a problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why would a site need to share cookies between domains?
&lt;/h2&gt;

&lt;p&gt;This is quite common for passing information from one site to another or session information. If the cookie has expired it means the session has ended and the user cannot do much on the new site they've visited unless the get a new cookie from the previous site.&lt;/p&gt;

&lt;p&gt;This doesn't work in newer version of Cypress although it did work in older version. Since Chrome 80 the SameSite attribute needs to be specified in cookies to declare how restrictive they should be. Before Chrome 80 &lt;code&gt;SameSite=None&lt;/code&gt; was on all cookies by default but now it needs to be explicitly added in the API request or it's defaulted to &lt;code&gt;SameSite=Lax&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This means running this test suites that require cookies to be shared between domains won't work:&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%2Fd849m0ma1yot9cudcmjs.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%2Fd849m0ma1yot9cudcmjs.png" alt="Issue that appears in chrome dev tools when SameSite is Lax" width="800" height="274"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Unfortunately newer version of Chrome (94+) have also &lt;a href="https://www.chromium.org/updates/same-site/" rel="noopener noreferrer"&gt;removed the flags to disable this&lt;/a&gt;. The only way around this issue is to install an older version of Chromium where disabling SameSiteByDefaultCookies is possible with a flag.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Here's how that can be done.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;1 - Visit the &lt;a href="https://chromium.cypress.io/" rel="noopener noreferrer"&gt;Cypress chromium downloads site&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;2 - Find the latest stable version for 90 and download it for your relevant Operating System&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%2Ft639uidxwucbtsb9i1di.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%2Ft639uidxwucbtsb9i1di.png" alt="Where to download chromium 90 from cypress" width="800" height="501"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;NOTE: In theory any version below Chromium 94 should work but I only tested with 90 so that's why I'm recommending it.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;3 - Unzip the file and place the contents in an easily accessible location&lt;/p&gt;

&lt;p&gt;&lt;em&gt;NOTE: I'd recommend contents of this folder not be pushed to somewhere like GitHub&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;4 - Open the browser you just downloaded and make sure you adhere to all the security requirements of your relevant operating system.&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%2Fno025ibkl2bt5ux0bpqx.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%2Fno025ibkl2bt5ux0bpqx.png" alt="MacOS security and privacy warning for installing new browser" width="800" height="707"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;5 - We'll now need to add some code to the  &lt;code&gt;cypress/plugins/index.js&lt;/code&gt;. The code is an addition to this &lt;a href="https://dev.to/poponuts/overcoming-samesite-cookie-issue-in-cypress-when-running-on-chrome-or-edge-274m"&gt;excellent solution from poponuts&lt;/a&gt;:&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;path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;path&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;//...&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;addChromiumBrowser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fullChromiumPath&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cypress/browsers/chrome-90-mac&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;chromiumOptions&lt;/span&gt; &lt;span class="o"&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;channel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;stable&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;family&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;displayName&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;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;90.0.4430.93&lt;/span&gt;&lt;span class="dl"&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="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;fullChromiumPath&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/chrome-90-mac/Chromium.app/Contents/MacOS/Chromium`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;majorVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;90&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;browsers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;chromiumOptions&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;on&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;before:browser:launch&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="nx"&gt;browser&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;launchOptions&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;browser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&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="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;launchOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;--disable-features=SameSiteByDefaultCookies,CookiesWithoutSameSiteMustBeSecure&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
            &lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;launchOptions&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="nf"&gt;addChromiumBrowser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;NOTE: If you are using a version of Chromium other than 90, please change the version and majorVersion fields as well&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;6 - If all went well, running &lt;code&gt;npx cypress open&lt;/code&gt; Should reveal a new browser in your list.&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%2Fufwt33ec3lqfyvdh4xxi.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%2Fufwt33ec3lqfyvdh4xxi.png" alt="New Chromium browser in Cypress" width="554" height="504"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Running in Chromium should fix whatever issue with SameSite cookies you have in Cypress.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sources
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://dev.to/poponuts/overcoming-samesite-cookie-issue-in-cypress-when-running-on-chrome-or-edge-274m"&gt;https://dev.to/poponuts/overcoming-samesite-cookie-issue-in-cypress-when-running-on-chrome-or-edge-274m&lt;/a&gt;&lt;br&gt;
&lt;a href="https://digitaldrummerj.me/cypress-custom-browser/" rel="noopener noreferrer"&gt;https://digitaldrummerj.me/cypress-custom-browser/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>cypress</category>
      <category>chromium</category>
      <category>samesite</category>
      <category>cookies</category>
    </item>
    <item>
      <title>Why the VAR and LET keywords shouldn't be used interchangeably</title>
      <dc:creator>Richard Oliver Bray</dc:creator>
      <pubDate>Thu, 13 Jan 2022 21:07:19 +0000</pubDate>
      <link>https://forem.com/richardbray/why-the-var-and-let-keywords-shouldnt-be-used-interchangeably-3n07</link>
      <guid>https://forem.com/richardbray/why-the-var-and-let-keywords-shouldnt-be-used-interchangeably-3n07</guid>
      <description>&lt;p&gt;If you'd asked me about the &lt;strong&gt;var&lt;/strong&gt; and &lt;strong&gt;let&lt;/strong&gt; Javascript keywords about a week ago I would say for the most part, they are interchangeable. Yes &lt;em&gt;&lt;strong&gt;var&lt;/strong&gt;&lt;/em&gt; is function scoped and &lt;em&gt;&lt;strong&gt;let&lt;/strong&gt;&lt;/em&gt; is block scoped but I really ran into a situation where switching them around caused any issues. Until recently...&lt;/p&gt;

&lt;p&gt;A friend of mine show me this piece of code:&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;function&lt;/span&gt; &lt;span class="nf"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;i&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="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&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="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="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;i&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nf"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="c1"&gt;// &amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt; Output &amp;lt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt;
&lt;span class="c1"&gt;// 3 (immediately)&lt;/span&gt;
&lt;span class="c1"&gt;// 3 (after one second)&lt;/span&gt;
&lt;span class="c1"&gt;// 3 (after two seconds)&lt;/span&gt;

&lt;span class="o"&gt;---&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&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="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&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="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="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;i&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nf"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// &amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt; Output &amp;lt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt;
&lt;span class="c1"&gt;// 0 (immediately)&lt;/span&gt;
&lt;span class="c1"&gt;// 1 (after one second)&lt;/span&gt;
&lt;span class="c1"&gt;// 2 (after two seconds)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I assumed it would loop though 0-2 with both keywords but I was shocked to see it only did that when &lt;strong&gt;let&lt;/strong&gt; was used and not &lt;strong&gt;var&lt;/strong&gt;. At the time I had no idea why that was the case so I did some research and thought I'd put my findings in a post for others to learn from.&lt;/p&gt;

&lt;p&gt;To fully understand why this happens we need to talk about two things; &lt;strong&gt;scope&lt;/strong&gt; and &lt;strong&gt;the event loop&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Scope
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;&lt;em&gt;var&lt;/em&gt;&lt;/strong&gt; keyword has function level scope and the &lt;strong&gt;&lt;em&gt;let&lt;/em&gt;&lt;/strong&gt; keyword has block level scope, but what does that actually mean?&lt;/p&gt;

&lt;p&gt;Scope in most programming languages refers to the access functions and objects have to variables depending on where they are placed. There is a great &lt;a href="https://www.youtube.com/watch?v=SBwoFkRjZvE" rel="noopener noreferrer"&gt;video by LeanCode.academy&lt;/a&gt; that explains the details of what scope is, but for the code I shared above, when the &lt;strong&gt;var&lt;/strong&gt; keyword is used, it can be read and reassigned outside of the loop within the fn function. When &lt;strong&gt;let&lt;/strong&gt; is used, it cannot be read or reassigned outside of the loop even within the function.&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%2Fgh6761ii4to8u3xbc2rj.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%2Fgh6761ii4to8u3xbc2rj.png" alt="the difference between block and function scope" width="800" height="382"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  2. The event loop
&lt;/h2&gt;

&lt;p&gt;Javascript is a single-thread language, I won't go into detail on what that means in this post, all you need to know is that it can't execute multiple things at the same time. However, with the power of the &lt;strong&gt;event loop&lt;/strong&gt; Javascript can give the illusion executing multiple things by putting some code aside and coming back to it later, when this happens really fast it sort of feels like multiple things are running at the same time. This is how the setTimeout function works.&lt;/p&gt;

&lt;p&gt;There's a great &lt;a href="https://www.youtube.com/watch?v=8aGhZQkoFbQ" rel="noopener noreferrer"&gt;video by Philip Roberts&lt;/a&gt; that explains in detail how the event loop works but for this post I'm going to simplify it a bit for our case.&lt;/p&gt;

&lt;p&gt;Javascript code in the browser is placed in the &lt;strong&gt;call stack&lt;/strong&gt; before being executed. If the code needs to be executed later (if it's a promise or setTimeout etc...) it is handled by some &lt;strong&gt;browser APIs&lt;/strong&gt; (which we won't talk about in detail), before going into the &lt;strong&gt;task&lt;/strong&gt; or &lt;strong&gt;event queue&lt;/strong&gt;. The &lt;strong&gt;event loop&lt;/strong&gt; is constantly checking if the call stack is empty, if it is, it will add an event from the event queue to the call stack to be executed. Let's go through our code with the event loop in mind.&lt;/p&gt;

&lt;p&gt;a. When our code first runs it adds our main function (fn), then the loop to the call stack. This happens for both let and var versions:&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%2F6zdr8c1jcrvpciqs6kwb.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%2F6zdr8c1jcrvpciqs6kwb.png" alt="main function and loop added to call stack" width="800" height="581"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;b. The first setTimeout is reached then added to the call stack, but then moved to the browser APIs to be handled later.&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%2Fq262ljwth6nzced54uhp.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%2Fq262ljwth6nzced54uhp.png" alt="first setTimeout moved to browser API" width="800" height="581"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;c. The first setTimeout has an instruction to execute after 0 milliseconds (1000 * i where i is 0 on the first loop). So that immediately get's sent to the event loop and will stay there until the call stack is empty.&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%2Fvualo2hrxz5vg91epwf4.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%2Fvualo2hrxz5vg91epwf4.png" alt="first setTimeout gets sent to event queue" width="800" height="581"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;d. The loop will run two more times and move the following setTimeout functions from the call stack to browser APIs with instructions to execute after 1000 and 2000 milliseconds respectively.&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%2Fk11x9spk1jreg619ipx8.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%2Fk11x9spk1jreg619ipx8.png" alt="all setTimeouts added to browser API column" width="800" height="581"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;e. After that's done the loop and the main function are popped off the call stack, the event loop checks if there's anything in the event queue and since there is, that get's moved to the call stack.&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%2F1scohct2nmjh4wdq0brl.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%2F1scohct2nmjh4wdq0brl.png" alt="call stack is empty and first setTimeout move to it because of event loop" width="800" height="581"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;f. At this point the first setTimeout function will run and &lt;strong&gt;i&lt;/strong&gt; will be set &lt;strong&gt;at the time this executes&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;Bear in mind that the loop has already run three times at this point, so when &lt;strong&gt;var&lt;/strong&gt; is used by the time this executes &lt;em&gt;i&lt;/em&gt; is equal to 3, why? The first time the loop runs &lt;em&gt;i&lt;/em&gt; is 0, then 1, then 2. Because var is function scoped it will increment from 2 to 3 and then not run the loop. &lt;/p&gt;

&lt;p&gt;In the case of &lt;strong&gt;let&lt;/strong&gt; however, because it is block scoped, even after the loop has run three times when &lt;em&gt;this&lt;/em&gt; setTimeout executes, the value of &lt;em&gt;i&lt;/em&gt; is 0, it hasn't been reassigned.&lt;/p&gt;

&lt;p&gt;g. The next setTimeout function moves to the event queue after 1000 milliseconds then with the help of the event loop quickly moves into the empty call stack and executes. Again at this stage if the &lt;strong&gt;var&lt;/strong&gt; keyword is used &lt;em&gt;i&lt;/em&gt; will equal 3, but for &lt;strong&gt;let&lt;/strong&gt; when the console log runs it looks for the block scoped value of &lt;em&gt;i&lt;/em&gt; is 1, this was retained when this event was first moved from the call stack to the browser api so that will print 1 to the console.&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%2Fjsemi3zyg0io6u178nty.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%2Fjsemi3zyg0io6u178nty.png" alt="The remaining setTimeout functions moving through the event loop cycle" width="800" height="581"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You've probably figured out what happens to the last setTimeout function so I won't go through that.&lt;/p&gt;




&lt;p&gt;If you add a breakpoint to the function in the setTimeout and look in the Chrome dev tools the difference between function and block scoping is a tiny bit more obvious.&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%2F5njmwyabuqxr7ly2of7s.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%2F5njmwyabuqxr7ly2of7s.png" alt="different between let and var in Chrome dev tools" width="354" height="417"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;var&lt;/strong&gt; shows the function scoped variable in the main function (fn), but &lt;strong&gt;let&lt;/strong&gt; shows the loop (_loop_1) inside the main function which is the extra bit of information saved in the event that goes through the event loop remembering the block scoped value of the variable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final words
&lt;/h2&gt;

&lt;p&gt;I know this post is quite long but I hope you found it useful. Whenever you can, use &lt;strong&gt;let&lt;/strong&gt; instead of &lt;strong&gt;var&lt;/strong&gt; . If you can't, there ware ways of getting block scoping with &lt;strong&gt;var&lt;/strong&gt; but it results in some weird looking code:&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;function&lt;/span&gt; &lt;span class="nf"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;i&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="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&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="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="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;i&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;))(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nf"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Happy coding 🧑🏿‍💻&lt;/p&gt;

&lt;h3&gt;
  
  
  Sources
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://www.outsystems.com/blog/posts/asynchronous-vs-synchronous-programming/" rel="noopener noreferrer"&gt;https://www.outsystems.com/blog/posts/asynchronous-vs-synchronous-programming/&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.educative.io/edpresso/what-is-an-event-loop-in-javascript" rel="noopener noreferrer"&gt;https://www.educative.io/edpresso/what-is-an-event-loop-in-javascript&lt;/a&gt;&lt;br&gt;
&lt;a href="https://stackoverflow.com/questions/31285911/why-let-and-var-bindings-behave-differently-using-settimeout-function" rel="noopener noreferrer"&gt;https://stackoverflow.com/questions/31285911/why-let-and-var-bindings-behave-differently-using-settimeout-function&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>keywords</category>
      <category>variables</category>
    </item>
    <item>
      <title>How to fix the ReferenceError: global is not defined error in SvelteKit/Vite</title>
      <dc:creator>Richard Oliver Bray</dc:creator>
      <pubDate>Fri, 03 Dec 2021 18:10:29 +0000</pubDate>
      <link>https://forem.com/richardbray/how-to-fix-the-referenceerror-global-is-not-defined-error-in-sveltekitvite-2i49</link>
      <guid>https://forem.com/richardbray/how-to-fix-the-referenceerror-global-is-not-defined-error-in-sveltekitvite-2i49</guid>
      <description>&lt;h2&gt;
  
  
  TL:DR
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// svelte.config.js&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;preprocess&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;preprocess&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="na"&gt;kit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;adapter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;adapter&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="na"&gt;target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#svelte&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="c1"&gt;// add this 👇&lt;/span&gt;
        &lt;span class="na"&gt;vite&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;define&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="na"&gt;global&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;p&gt;I spent hours trying to figure this out and it was really difficult to find the exact information on the web since this error message is very similar to an &lt;a href="https://angular.io/" rel="noopener noreferrer"&gt;Angular&lt;/a&gt; issue. However, the Angular solution is useless for &lt;a href="https://kit.svelte.dev/" rel="noopener noreferrer"&gt;SvelteKit&lt;/a&gt; so, I thought I'd put this post together.&lt;/p&gt;

&lt;p&gt;SvelteKit is &lt;a href="https://github.com/sveltejs/kit#read-this-first" rel="noopener noreferrer"&gt;currently in beta&lt;/a&gt; so who knows, maybe they might address this at some point in the future but anyway...&lt;/p&gt;

&lt;p&gt;SvelteKit uses &lt;a href="https://vitejs.dev/" rel="noopener noreferrer"&gt;Vite&lt;/a&gt; as its build tool which is great because Vite pre-bundles dependencies using &lt;a href="https://esbuild.github.io/" rel="noopener noreferrer"&gt;esbuild&lt;/a&gt; which is really really fast. But by default, Vite doesn't include &lt;a href="https://developer.mozilla.org/en-US/docs/Glossary/Shim" rel="noopener noreferrer"&gt;shims&lt;/a&gt; for NodeJS variables so these need to be added by the user.&lt;/p&gt;

&lt;p&gt;That sound simple enough to fix, just create a &lt;code&gt;vite.config.[js/ts]&lt;/code&gt; file, add it to your SvelteKit project and define global right?&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="c1"&gt;// vite.config.ts&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;define&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;global&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Well not quite...&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%2F4yqkd6s8xg6xk9735wj4.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%2F4yqkd6s8xg6xk9735wj4.png" alt="Adding a vite config to sveltekit is not a good idea" width="800" height="123"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This would usually be fine but SvelteKit doesn't play ball with a Vite config file, it will instead ask you to put the changes in a &lt;code&gt;svelte.config.file&lt;/code&gt;. Makes sense I guess🤷?&lt;/p&gt;

&lt;p&gt;Apart from the fact that a svelte config looks different from a vite config so it's not as simple as just copying and pasting into the main config object. Following the link in the error take you here -&amp;gt; &lt;a href="https://kit.svelte.dev/docs#configuration-vite" rel="noopener noreferrer"&gt;https://kit.svelte.dev/docs#configuration-vite&lt;/a&gt; which isn't super useful. But after a bit of googling I found &lt;a href="https://kit.svelte.dev/faq#aliases" rel="noopener noreferrer"&gt;this much more helpful example&lt;/a&gt; albeit on a different topic but it was good enough.&lt;/p&gt;

&lt;p&gt;And... that's what lead to the working solution below:&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="c1"&gt;// svelte.config.js&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;preprocess&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;preprocess&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="na"&gt;kit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;adapter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;adapter&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="na"&gt;target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#svelte&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="c1"&gt;// add this 👇&lt;/span&gt;
        &lt;span class="na"&gt;vite&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;define&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="na"&gt;global&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;p&gt;I should also mention I'm quite new to Svelte so there is a huge chance someone will call me out in the comments and add a much more elegant solution 😜&lt;/p&gt;

&lt;h2&gt;
  
  
  Sources
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/vitejs/vite/issues/2778" rel="noopener noreferrer"&gt;https://github.com/vitejs/vite/issues/2778&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/vitejs/vite/issues/728" rel="noopener noreferrer"&gt;https://github.com/vitejs/vite/issues/728&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/bevacqua/dragula/issues/602" rel="noopener noreferrer"&gt;https://github.com/bevacqua/dragula/issues/602&lt;/a&gt;&lt;br&gt;
&lt;a href="https://kit.svelte.dev/faq#aliases" rel="noopener noreferrer"&gt;https://kit.svelte.dev/faq#aliases&lt;/a&gt;&lt;/p&gt;

</description>
      <category>svelte</category>
      <category>sveltekit</category>
      <category>vite</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Type conversion in Rust (as, From, and Into)</title>
      <dc:creator>Richard Oliver Bray</dc:creator>
      <pubDate>Fri, 15 Jan 2021 13:47:18 +0000</pubDate>
      <link>https://forem.com/richardbray/type-conversion-in-rust-as-from-and-into-493l</link>
      <guid>https://forem.com/richardbray/type-conversion-in-rust-as-from-and-into-493l</guid>
      <description>&lt;p&gt;I'm fairly new to &lt;a href="https://www.rust-lang.org/" rel="noopener noreferrer"&gt;Rust&lt;/a&gt; and it's a language I've actually enjoyed learning, mainly for game development with &lt;a href="https://bevyengine.org/" rel="noopener noreferrer"&gt;Bevy&lt;/a&gt;. As someone who is coming for a JS/TS background, there is a huge learning curve and I'm eventually planning to create a video course on how to make a simple game with Rust, but for now, I'm going to document things down (in the form of dev.to articles) as and when I learn them to help people who are having difficulties. &lt;/p&gt;

&lt;p&gt;This particular feature of Rust is something I've seen a lot in Bevy example code particularly when it comes to colours, for example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="n"&gt;materials&lt;/span&gt;&lt;span class="nf"&gt;.add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;rgb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.7&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.into&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;strong&gt;.into()&lt;/strong&gt; method is something that I've scratched my brain over for ages and I've finally been able to figure out what it does. Well, at least I think I have.&lt;/p&gt;

&lt;h2&gt;
  
  
  as
&lt;/h2&gt;

&lt;p&gt;Simple (explicit) type conversion or casting in Rust can be done with the &lt;strong&gt;as&lt;/strong&gt; keyword:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nb"&gt;u8&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;multiplied&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;times_ten&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;f32&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;multiplied&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 100&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;times_ten&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;f32&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;f32&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
  &lt;span class="n"&gt;val&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;10.0&lt;/span&gt; 
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  From
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;From&lt;/strong&gt; in Rust is one of two traits for type conversion (if you don't know what a trait I'm planning to write a post on it in the future).&lt;/p&gt;

&lt;p&gt;Let's say I want to create my own special type called &lt;code&gt;MySpecialNumber&lt;/code&gt; and want to convert an existing u32 variable to my custom type, I would do it like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[derive(Debug)]&lt;/span&gt; &lt;span class="c1"&gt;// needed because struct displays nothing so needs to have a debug view&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nf"&gt;MySpecialNumber&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;u32&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="nb"&gt;From&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;u32&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;MySpecialNumber&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;num&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u32&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;Self&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;MySpecialNumber&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;num&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;existing_var&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;MySpecialNumber&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;existing_var&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{:?}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Prints -&amp;gt; MySpecialNumber(30)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;If this is the first time you've seen the &lt;code&gt;struct&lt;/code&gt; or &lt;code&gt;impl&lt;/code&gt; keyword again, don't worry. I'm planning to cover those in future posts. They're a bit, different if you're coming from Javascript, you can think of them as a slightly more complicated way of making an object.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The above code snippet takes the &lt;code&gt;existing_var&lt;/code&gt; of type u32 and changes it to type &lt;code&gt;MySpecialNumber&lt;/code&gt; using the from method written above.&lt;/p&gt;

&lt;p&gt;Because the From method is extending a trait it has to be written in a very specific way for it to work. If I changed the line &lt;code&gt;fn from(num: u32)&lt;/code&gt; to &lt;code&gt;fn from(num: f32)&lt;/code&gt; it wouldn't work. The source code for the From trait can be found on the &lt;a href="https://github.com/rust-lang/rust/blob/1.49.0/library/core/src/convert/mod.rs#L373" rel="noopener noreferrer"&gt;Rust Github repo&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Into
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Into&lt;/strong&gt; is the second trait in Rust used for type conversion. It works in the opposite direction to the From trait, instead of creating &lt;strong&gt;x&lt;/strong&gt; FROM &lt;strong&gt;y&lt;/strong&gt;, it turns &lt;strong&gt;y&lt;/strong&gt; INTO &lt;strong&gt;x&lt;/strong&gt;, makes sense? It's a bit confusing right. I feel like code is the best way to explain things so let's jump straight &lt;em&gt;into&lt;/em&gt; it (no pun intended).&lt;/p&gt;

&lt;h3&gt;
  
  
  First way to use Into
&lt;/h3&gt;

&lt;p&gt;If there's an implementation of the From trait already we can also use the Into trait which is pretty cool.&lt;/p&gt;

&lt;p&gt;To use into the main function of the above code snipped can be re-written as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="o"&gt;...&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;existing_var&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u32&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;MySpecialNumber&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;existing_var&lt;/span&gt;&lt;span class="nf"&gt;.into&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{:?}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Prints -&amp;gt; MySpecialNumber(30)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Arguably this was is more readable. The &lt;code&gt;existing_var&lt;/code&gt; is being converted to &lt;code&gt;MySpecialNumber&lt;/code&gt; because it has been added as a type annotation. If that get's removed Rust won't know what type to convert the existing variable to.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;existing_var&lt;/span&gt;&lt;span class="nf"&gt;.into&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// this won't work&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you &lt;em&gt;really&lt;/em&gt; wanted to, you could write a full Into method similar to the way I wrote the From method above using the &lt;a href="https://github.com/rust-lang/rust/blob/1.49.0/library/core/src/convert/mod.rs#L278" rel="noopener noreferrer"&gt;Into that from the Rust source code&lt;/a&gt;, but I think From is good enough.&lt;/p&gt;

&lt;h3&gt;
  
  
  Second way to use Into
&lt;/h3&gt;

&lt;p&gt;For this way we're going back to my &lt;code&gt;times_ten&lt;/code&gt; function I used above when desiring the &lt;strong&gt;as&lt;/strong&gt; keyword.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nb"&gt;u8&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;multiplied&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;times_ten&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;f32&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;multiplied&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 100&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;times_ten&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;f32&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;f32&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
  &lt;span class="n"&gt;val&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;10.0&lt;/span&gt; 
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of using &lt;strong&gt;as&lt;/strong&gt; we can use the &lt;strong&gt;Into&lt;/strong&gt; trait like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nb"&gt;u8&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;multiplied&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;times_ten&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;num&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;multiplied&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 100&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="n"&gt;times_ten&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Into&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;f32&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;f32&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
  &lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="nf"&gt;.into&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;10.0&lt;/span&gt; 
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So if you compare the last two code snippets, you'll see we can omit the &lt;strong&gt;as&lt;/strong&gt; keyword and the type to convert to and move that logic to the times_ten function in the form of a &lt;a href="https://doc.rust-lang.org/rust-by-example/generics.html" rel="noopener noreferrer"&gt;generic data type&lt;/a&gt; &lt;code&gt;T&lt;/code&gt; and the Into trait.&lt;/p&gt;

&lt;p&gt;No matter what type the argument is that is passed into the times_ten function it will always be converted fo an f32 before it is multiplied by 10. &lt;/p&gt;

&lt;p&gt;Don't worry if this doesn't make sense now, the more you use it, the more sense it will make.&lt;/p&gt;




&lt;p&gt;Like I said at the beginning I'm new to Rust so there's a chance I haven't explained something properly or I've missed something out when it comes to type conversion then please let me know.&lt;/p&gt;

&lt;p&gt;I've tried my best to explain this in the simplest way possible but if something I've said doesn't make any sense, again please let me know.&lt;/p&gt;

&lt;h3&gt;
  
  
  Sources
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://doc.rust-lang.org/rust-by-example/conversion/from_into.html" rel="noopener noreferrer"&gt;https://doc.rust-lang.org/rust-by-example/conversion/from_into.html&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.youtube.com/watch?v=vH5xXr81a2Y" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=vH5xXr81a2Y&lt;/a&gt;&lt;br&gt;
&lt;a href="https://play.rust-lang.org/?version=stable&amp;amp;mode=debug&amp;amp;edition=2018&amp;amp;gist=c749b272a173bfb34371092c562551fa" rel="noopener noreferrer"&gt;https://play.rust-lang.org/?version=stable&amp;amp;mode=debug&amp;amp;edition=2018&amp;amp;gist=c749b272a173bfb34371092c562551fa&lt;/a&gt;&lt;/p&gt;

</description>
      <category>rust</category>
      <category>programming</category>
      <category>gamedev</category>
    </item>
  </channel>
</rss>
