<?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: Eldad Bercovici</title>
    <description>The latest articles on Forem by Eldad Bercovici (@dutzi).</description>
    <link>https://forem.com/dutzi</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%2F90416%2F8f36e329-0c0b-4559-a856-9b6295ebac89.jpeg</url>
      <title>Forem: Eldad Bercovici</title>
      <link>https://forem.com/dutzi</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/dutzi"/>
    <language>en</language>
    <item>
      <title>I Built a Simple Serverless Storage Solution</title>
      <dc:creator>Eldad Bercovici</dc:creator>
      <pubDate>Sun, 24 May 2020 08:01:18 +0000</pubDate>
      <link>https://forem.com/dutzi/i-built-a-simple-serverless-storage-solution-4kh4</link>
      <guid>https://forem.com/dutzi/i-built-a-simple-serverless-storage-solution-4kh4</guid>
      <description>&lt;p&gt;Originally posted on &lt;a href="https://dutzi.party/"&gt;my blog&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Looking for apartments in Tel Aviv is a drag.&lt;/p&gt;

&lt;p&gt;Prices are high, demand is high and dealing with real estate brokers isn't fun. But most of all, Israeli websites (well, &lt;a href="https://yad2.co.il/"&gt;Yad2&lt;/a&gt;, the Israeli Redfin, is basically all we have) that help look for apartments are crappy as hell.&lt;/p&gt;

&lt;p&gt;To keep as low friction as I could with Yad2 I wanted to create a bot that'll send me a message (on Telegram) whenever a new apartment that asnwers my criteria is posted. Bot available &lt;a href="https://github.com/dutzi/yad2-notifier"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Sending a Telegram message was pretty straightforward, and so was getting the data, the only thing that bummed me was that I had to set up a database, so that the bot will "remember" which apartments it had already sent me. I was looking for a free storage (well, database actually) service that was easy to communicate with and required as little effort as possible.&lt;/p&gt;

&lt;p&gt;I couldn't find anything that was less than 3 clicks away, so I built one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introducing Cloud Local Stroage
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://cls.tools/"&gt;Cloud Local Storage&lt;/a&gt; (CLS) is the outcome of that weekend's worth. It's a very simple DB, built on top of Firebase that is accessible through a Node SDK, web API and a commnad line tool.&lt;/p&gt;

&lt;p&gt;Simply install 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="nv"&gt;$ &lt;/span&gt;yarn add cloud-local-storage
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And then, using a local-storage-like API, use it:&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="nx"&gt;cls&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;cloud-local-storage&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;cls&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;foo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;bar&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;cls&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;foo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// {bar: 1}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that's it! Without the need to signup or start a database you are able to store &amp;amp; load data from the cloud.&lt;/p&gt;

&lt;p&gt;Using CLS that way will store the data globally, meaning that if someone else calls &lt;code&gt;cls.setItem('foo', {bar: 2})&lt;/code&gt;, they will overwrite your content.&lt;/p&gt;

&lt;p&gt;To help with that you can either provide something more unique key than &lt;code&gt;foo&lt;/code&gt;, &lt;em&gt;or&lt;/em&gt; you could call &lt;code&gt;cls.setItem&lt;/code&gt; without passing a key (passing only the data). When doing so, CLS will generate a key using uuidv4 and return it to you:&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="nx"&gt;cls&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;cloud-local-storage&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;cls&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setItem&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;bar&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="c1"&gt;// c6cd9316…&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;cls&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;c6cd9316…&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// {bar: 1}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lastly, you can also namespace all your storaged keys under your account.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating Accounts
&lt;/h2&gt;

&lt;p&gt;Cloud Local Storage also supports account based storages. Using CLS's &lt;a href="https://cls.tools/docs#cli"&gt;commnad line tool&lt;/a&gt; you can sign up for CLS, you will then get a token, using that token you can store &amp;amp; load data under your account.&lt;/p&gt;

&lt;p&gt;First install the CLS's command line tool:&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="nv"&gt;$ &lt;/span&gt;yarn global add cloud-local-storage-cli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then initialize 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="nv"&gt;$ &lt;/span&gt;cls init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Follow the instuctions and after signing up the commnad line tool will save your token to &lt;code&gt;~/.clsrc&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now you can use the SDK with your token:&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="nx"&gt;cls&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;cloud-local-storage&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;myStorage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;cls&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;my-token-from-the-command-line-tool&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;myStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;userData&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="nx"&gt;myStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;userData&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// {a: 1}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Space or Bandwidth Restrictions
&lt;/h2&gt;

&lt;p&gt;Right now there aren't any space or bandwidth restrictions, but if it becomes pricey I might ask users to verify their account by phone beyond a certain usage threshold. The plan is to keep it free as long as I can and if it gets big find cheaper solutions (MongoDB, DynamoDb, etc...) or look for sponsership.&lt;/p&gt;

&lt;p&gt;Anyhow, hope you find this useful.&lt;/p&gt;

</description>
      <category>serverless</category>
      <category>jamstack</category>
      <category>database</category>
      <category>localstorage</category>
    </item>
    <item>
      <title>Animating Route Transitions Using React Router</title>
      <dc:creator>Eldad Bercovici</dc:creator>
      <pubDate>Sun, 05 Apr 2020 00:29:13 +0000</pubDate>
      <link>https://forem.com/dutzi/animating-route-transitions-using-react-router-5blp</link>
      <guid>https://forem.com/dutzi/animating-route-transitions-using-react-router-5blp</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Originally posted in &lt;a href="https://dutzi.party/animating-route-transitions-using-react-router/"&gt;my blog&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Working on a side-project I wanted to create nice "flow"-y animations for when the user navigates between routes. Routes had to implement different "enter" and "leave" animations depending on which page the user navigates to and from, i.e., navigating from the &lt;strong&gt;Sign In&lt;/strong&gt; page to the &lt;strong&gt;Home&lt;/strong&gt; page animates differently (the &lt;strong&gt;Sign In&lt;/strong&gt; page's &lt;em&gt;leave&lt;/em&gt; animation) than from the &lt;strong&gt;Sign In&lt;/strong&gt; page to the &lt;strong&gt;App&lt;/strong&gt; page.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DrQC62of--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/vidzanq4xenxil80kndp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DrQC62of--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/vidzanq4xenxil80kndp.png" alt="Animating From Sign In to Other Pages"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I ended up with a pretty neat Provider-and-hook duo that works nice with the popular &lt;a href="https://github.com/ReactTraining/react-router"&gt;React Router&lt;/a&gt;, so I thought I'd package it up nicely and share it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dutzi.github.io/react-route-transition/#/"&gt;See it live here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  react-route-transition
&lt;/h2&gt;

&lt;p&gt;So &lt;a href="https://github.com/dutzi/react-route-transition"&gt;react-route-transition&lt;/a&gt; is the outcome of that weekend's work.&lt;/p&gt;

&lt;p&gt;The way it works is dead simple.&lt;/p&gt;

&lt;p&gt;It exports a Provider you need to wrap your app with (place it &lt;em&gt;inside&lt;/em&gt; of react-router's &lt;code&gt;Router&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Behind the scenes, that Provider simply wraps its children (your app) with a &lt;a href="https://github.com/dutzi/react-route-transition/blob/master/src/TransitionProvider.tsx#L26"&gt;Context Provider&lt;/a&gt;. It sets up the Context Provider, passing it a push (&lt;code&gt;history.push&lt;/code&gt;, or react-router's &lt;code&gt;push&lt;/code&gt; method provided by their &lt;code&gt;useHistory&lt;/code&gt; hook) function, location (&lt;code&gt;window.location&lt;/code&gt;, or react-router's &lt;code&gt;usLocation()&lt;/code&gt; return value) and an (empty) array of &lt;strong&gt;listeners&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The two hooks provided by react-route-transition (&lt;code&gt;useTransition()&lt;/code&gt; and &lt;code&gt;useTransitionHistory()&lt;/code&gt;) will later read from and write to that context.&lt;/p&gt;

&lt;p&gt;After wrapping your app with it, you can declare how your animations behave. To do so, you call the &lt;code&gt;useTransition()&lt;/code&gt; hook.&lt;/p&gt;

&lt;h2&gt;
  
  
  Describing An Animation
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;useTransition()&lt;/code&gt; accepts an object the has a key named &lt;code&gt;handlers&lt;/code&gt; whose value is an array of &lt;strong&gt;Handlers&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A Handler is an object that describes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;an animation&lt;/li&gt;
&lt;li&gt;when to fire said animation&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A Handler object is comprised of the following keys:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;path&lt;/code&gt; - a string (or array of strings) specifying which path(s) the animation functions should fire when entering/leaving those paths.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;onEnter&lt;/code&gt; - an async function that is fired once the user navigates to &lt;code&gt;path&lt;/code&gt;. This one is where the animation code sits, it should resolve when the animation is done.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;onLeave&lt;/code&gt; - same as &lt;code&gt;onEnter&lt;/code&gt;, only this one fires when leaving &lt;code&gt;path&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here's an example of usage of &lt;code&gt;useTransition()&lt;/code&gt;:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;useTransition&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;handlers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;onEnter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;gsap&lt;/span&gt;  &lt;span class="c1"&gt;// highlight-line&lt;/span&gt;
          &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;timeline&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;  &lt;span class="c1"&gt;// highlight-line&lt;/span&gt;
          &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fromTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="c1"&gt;// highlight-line&lt;/span&gt;
            &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;[data-home-main] &amp;gt; *, [data-home-footer]&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;// highlight-line&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;  &lt;span class="c1"&gt;// highlight-line&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;duration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;stagger&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.125&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;  &lt;span class="c1"&gt;// highlight-line&lt;/span&gt;
          &lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;// highlight-line&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="na"&gt;onLeave&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;gsap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;timeline&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;[data-home-main] &amp;gt; *, [data-home-footer]&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;duration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;stagger&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.125&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;20&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;When &lt;em&gt;entering&lt;/em&gt; &lt;code&gt;/&lt;/code&gt; start &lt;strong&gt;onEnter&lt;/strong&gt; animation, when &lt;em&gt;leaving&lt;/em&gt;, start &lt;strong&gt;onLeave&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;When the component that called &lt;code&gt;useTransition()&lt;/code&gt; unmounts, the handlers it registered are also removed, so pages no longer in view will not start animations in the background.&lt;/p&gt;

&lt;p&gt;Now, if you're unfamiliar with &lt;a href="https://github.com/greensock/GSAP"&gt;gsap&lt;/a&gt;, it's an old school animation library from the 00's which is still really nice. A great, light-weight alternative is &lt;a href="https://github.com/juliangarnier/anime/"&gt;anime.js&lt;/a&gt;. They both expose simple APIs that make animating the DOM a breeze and (IMO) a lot more readable than declarative ones (see my disclaimer below).&lt;/p&gt;

&lt;p&gt;What the first animation block (the highlighted lines) does is dim out (transition opacity to 0) all the children of the element that has a data attribute named &lt;code&gt;home-main&lt;/code&gt; &lt;em&gt;and&lt;/em&gt; the element that has a data attribute named &lt;code&gt;home-footer&lt;/code&gt;. Each of the animated element will animate within 600ms and a staggering effect of 125ms will be applied.&lt;/p&gt;

&lt;p&gt;The rendered element for such an animation might look something like:&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;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&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;main&lt;/span&gt; &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="na"&gt;home&lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="na"&gt;main&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* this content will be animated */&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;main&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;footer&lt;/span&gt; &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="na"&gt;home&lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="na"&gt;footer&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* some stuff here as well */&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;footer&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;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;p&gt;Awaiting &lt;code&gt;gsap.timeline().to()&lt;/code&gt; means waiting for the animation to complete (its return value is then-able and resolves once it's done animating).&lt;/p&gt;

&lt;p&gt;We are now ready to see the animation play.&lt;/p&gt;

&lt;h2&gt;
  
  
  Starting Up An Animation
&lt;/h2&gt;

&lt;p&gt;react-route-transition will start an animation when the user navigates to (or from) a page for which an animation was required (in the example above, when the user animates to and from &lt;code&gt;/&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;The way you navigate pages with react-route-transition is same as with react-router, by calling &lt;code&gt;history.push("/some-path")&lt;/code&gt;, except the &lt;code&gt;history&lt;/code&gt; object here is the what's returned by &lt;code&gt;useTransitionHistory()&lt;/code&gt;, a hook provided by react-route-transition.&lt;/p&gt;

&lt;p&gt;react-route-transition handles navigating for you. It exports a hook named &lt;code&gt;useTransitionHistory()&lt;/code&gt; that accepts the path you want to navigate to. That hook &lt;a href="https://github.com/dutzi/react-route-transition/blob/master/src/use-transition-history.ts#L20-L56"&gt;orchestrates the animations&lt;/a&gt;. It goes over the list of registered handlers, finds which ones describe an &lt;code&gt;onLeave&lt;/code&gt; animation for the current location, fires up all these animations simultaneously, waits for them to complete and then &lt;strong&gt;calls history.push&lt;/strong&gt; (react-router's), this causes new components to mount and register their handlers (that may or may not describe &lt;code&gt;onEnter&lt;/code&gt; animations for this new view). Finally, it fires up all the &lt;code&gt;onEnter&lt;/code&gt; animations for the new location.&lt;/p&gt;

&lt;h2&gt;
  
  
  2 Animations 1 View
&lt;/h2&gt;

&lt;p&gt;Say you want one &lt;code&gt;onLeave&lt;/code&gt; animation to start when the user navigates from the &lt;strong&gt;Sign In&lt;/strong&gt; page to the &lt;strong&gt;Home&lt;/strong&gt; page but a different one for when the user navigates from the same &lt;strong&gt;Sign In&lt;/strong&gt; page to the &lt;strong&gt;App&lt;/strong&gt; page.&lt;/p&gt;

&lt;p&gt;You can do it by passing a &lt;code&gt;from&lt;/code&gt; and a &lt;code&gt;to&lt;/code&gt; options, instead of a passing the &lt;code&gt;path&lt;/code&gt; option, for example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;useTransition&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;handlers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;from&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/signin&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/app&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;onLeave&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Animation 1&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;from&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/signin&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;to&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="na"&gt;onLeave&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Animation 2&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;Will start Animation 1 when leaving to the &lt;strong&gt;App&lt;/strong&gt; page, and Animation 2 when leaving to the &lt;strong&gt;Home&lt;/strong&gt; page.&lt;/p&gt;

&lt;p&gt;Lastly, &lt;code&gt;path&lt;/code&gt;, &lt;code&gt;from&lt;/code&gt; and &lt;code&gt;to&lt;/code&gt; also accept an array of paths. That's useful when you want the same animation to be fired when navigating to (or from) multiple pages.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Imperative Animations?
&lt;/h2&gt;

&lt;p&gt;Personally, I don't like writing complex animations in a declarative manner. They're great for interactions, but I find that compared to animations written in an imperative way, the learning curve is steep, code readability suffers and playing around (just testing stuff out) is not as fun as the feedback loop tends to be longer. That may be because I started my way out as a Flash (ActionScript) developer, where tween animations were very popular, so don't take this as a fact. If you prefer the declarative approach keep at it and please let me know in the comments below, I'd love to hear about their upsides!&lt;/p&gt;

</description>
      <category>react</category>
      <category>router</category>
      <category>animation</category>
      <category>transition</category>
    </item>
    <item>
      <title>Enjoy a better development experience by enabling React Fast Refresh</title>
      <dc:creator>Eldad Bercovici</dc:creator>
      <pubDate>Sun, 12 Jan 2020 21:12:40 +0000</pubDate>
      <link>https://forem.com/dutzi/enjoying-a-better-development-experience-by-using-react-fast-refresh-4b4d</link>
      <guid>https://forem.com/dutzi/enjoying-a-better-development-experience-by-using-react-fast-refresh-4b4d</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Originally posted in &lt;a href="https://dutzi.party/react-fast-refresh/"&gt;my blog&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://github.com/facebook/react/issues/16604"&gt;React Fast Refresh&lt;/a&gt; is the successor to &lt;a href="https://github.com/gaearon/react-hot-loader"&gt;React Hot Loader&lt;/a&gt;, a configuration option that lets you enjoy a (much) better development experience, by doing the following:&lt;/p&gt;

&lt;p&gt;It listens to changes within your source files and sends them, and only them, to the browser (or mobile device, for &lt;a href="https://facebook.github.io/react-native/docs/fast-refresh"&gt;React Native&lt;/a&gt;). When those changes arrive at the browser, the code segment that has changed is being "injected" into its module, replacing the previous code. If that module is able to accept said changes without having to reload the page, then your app gets updated without losing its state.&lt;/p&gt;

&lt;p&gt;In other words, when you hit Save, instead of refreshing the page, React Fast Refresh will only reload the components affected by the change.&lt;/p&gt;

&lt;p&gt;Dan Abramov (and others) have recently re-wrote this feature, renaming it React Fast Refresh. It was initially out for React Native, while React developers were promised a similar experience. Finally, it seems like the days of waiting are over&lt;sup&gt;1&lt;/sup&gt; and, while it's still in development, you can now try it out in your Create React App (without even ejecting).&lt;/p&gt;

&lt;h2&gt;
  
  
  Trying React Fast Refresh
&lt;/h2&gt;

&lt;p&gt;Create React App, out of the box, does not yet support Fast Refresh (as it's still under development and may still contain some bugs). That means we either have to eject and modify Create React App's config files &lt;em&gt;or&lt;/em&gt; use a little magical tool called &lt;a href="https://github.com/timarney/react-app-rewired"&gt;&lt;code&gt;react-app-rewired&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;React-app-rewired&lt;/code&gt; lets you:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Override create-react-app webpack configs without ejecting&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's it. It's pretty cool since you can do some useful things with it, like &lt;a href="https://github.com/withspectrum/react-app-rewire-styled-components"&gt;including component names&lt;/a&gt; when using styled components, adding a &lt;a href="https://github.com/lwd-technology/react-app-rewire-define-plugin"&gt;webpack.DefinePlugin&lt;/a&gt; block to your config, and many more.&lt;/p&gt;

&lt;p&gt;It's important to take into account that &lt;code&gt;react-app-rewired&lt;/code&gt; is "lightly" maintained (mostly by the community), or as Dan Abramov somewhat officially &lt;a href="https://twitter.com/dan_abramov/status/1045809734069170176"&gt;tweeted&lt;/a&gt;: "Stuff can break".&lt;/p&gt;

&lt;p&gt;So with that, let's add it to our project!&lt;/p&gt;

&lt;h2&gt;
  
  
  Adding React App Rewired
&lt;/h2&gt;

&lt;p&gt;In order to add &lt;code&gt;react-app-rewired&lt;/code&gt; to our project, we start by installing it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;react-app-rewired &lt;span class="nt"&gt;--save-dev&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We then create a &lt;code&gt;config-overrides.js&lt;/code&gt; file, next to our &lt;code&gt;package.json&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="cm"&gt;/* config-overrides.js */&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="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;override&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;env&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// do stuff with the webpack config...&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;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;And finally, modify the &lt;code&gt;scripts&lt;/code&gt; section of our &lt;code&gt;package.json&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"react-app-rewired start"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"build"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"react-app-rewired build"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"test"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"react-app-rewired test --env=jsdom"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"eject"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"react-scripts eject"&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;That's it for &lt;code&gt;react-app-rewired&lt;/code&gt;. We are now ready to enable React Fast Refresh.&lt;/p&gt;

&lt;h2&gt;
  
  
  Enabling React Fast Refresh
&lt;/h2&gt;

&lt;p&gt;To do that, we'll install two packages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/arackaf/customize-cra/"&gt;&lt;code&gt;customize-cra&lt;/code&gt;&lt;/a&gt;, which is a &lt;a href="https://github.com/arackaf/customize-cra/blob/master/api.md"&gt;set of utility functions&lt;/a&gt; that help modify config objects. It exposes functions like &lt;code&gt;addBabelPlugin&lt;/code&gt; and &lt;code&gt;addWebpackPlugin&lt;/code&gt; which are necessary for our second package to work,&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/esetnik/customize-cra-react-refresh/"&gt;&lt;code&gt;customize-cra-react-refresh&lt;/code&gt;&lt;/a&gt;, this is the one that makes the necessary changes to Create React App's config files in order to get React Fast Refresh to work.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We'll install both of them:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-D&lt;/span&gt; customize-cra customize-cra-react-refresh
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Leaving us with the last and final step of modifying the &lt;code&gt;config-overrides.js&lt;/code&gt; file we created above:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="cm"&gt;/* config-overrides.js */&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;override&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&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;customize-cra&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;addReactRefresh&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&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;customize-cra-react-refresh&lt;/span&gt;&lt;span class="dl"&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="nx"&gt;override&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;addReactRefresh&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;disableRefreshCheck&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;}))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;And we're done! We can now restart our development server and enjoy a greatly improved feedback loop and overall developer experience within our Create React App.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Disclaimer:&lt;/strong&gt; I haven't thoroughly tested React Fast Refresh yet, I was very excited to find that it's ready to test out and wanted to share it. I will probably update this post in the coming days, adding the caveats I'll find along the way.&lt;/p&gt;

&lt;p&gt;&lt;sup&gt;1&lt;/sup&gt; If you don't mind a few hiccups here and there...&lt;/p&gt;

</description>
      <category>react</category>
      <category>reacthotloader</category>
      <category>fastrefresh</category>
    </item>
    <item>
      <title>Optimizing Webpack's build time by learning from the best</title>
      <dc:creator>Eldad Bercovici</dc:creator>
      <pubDate>Sun, 05 Jan 2020 22:07:43 +0000</pubDate>
      <link>https://forem.com/dutzi/things-i-ve-learnt-optimizing-our-build-time-18be</link>
      <guid>https://forem.com/dutzi/things-i-ve-learnt-optimizing-our-build-time-18be</guid>
      <description>&lt;p&gt;Where I work at (a small-medium startup called &lt;a href="https://www.spot.im/"&gt;Spot.IM&lt;/a&gt;) we use Webpack to bundle our products. After about 4 years and who knows how many hands contributing to the source code, our main product's build time reached a staggering &lt;strong&gt;90 seconds&lt;/strong&gt; for initial build and &lt;strong&gt;14 seconds&lt;/strong&gt; for re-build.&lt;/p&gt;

&lt;p&gt;That's 14 seconds you had to wait every time you hit save.&lt;/p&gt;

&lt;p&gt;Applying some easy wins which anyone can introduce to their stack we were able to slice those numbers down to &lt;strong&gt;20 seconds&lt;/strong&gt; for build and &lt;strong&gt;1 second&lt;/strong&gt; for re-build.&lt;/p&gt;

&lt;p&gt;In this post I will go through some simple changes you can make to improve your bundle's build time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; If you are using &lt;a href="https://github.com/facebook/create-react-app"&gt;Create React App&lt;/a&gt; (or any other fancy app generator) this post probably won't matter that much to you, if not it might help a lot, so keep reading!&lt;/p&gt;

&lt;h2&gt;
  
  
  Measuring Success
&lt;/h2&gt;

&lt;p&gt;Before we do anything, let's set up a way to measure our improvement. To do that we'll use a tool called &lt;a href="https://www.npmjs.com/package/speed-measure-webpack-plugin"&gt;&lt;code&gt;speed-measure-webpack-plugin&lt;/code&gt;&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;webpackConfig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&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;./webpack.config&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;SpeedMeasurePlugin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&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;speed-measure-webpack-plugin&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;smp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;SpeedMeasurePlugin&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;disable&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;MEASURE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="kr"&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="nx"&gt;smp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;wrap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;webpackConfig&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We wrap the Webpack config file with SMP (which we enable through an environment variable), later we pass that config object to Webpack, which will then print a nice report specifying each loader's processing time per each build. This way we win in two frontiers, one is that we get immediate feedback to our optimization attempts and the other is that we instantly get a full report of how long each loader (or actually "chain of loaders") took:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--pNDmvbBQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/2316eigj82zk0454cbre.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--pNDmvbBQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/2316eigj82zk0454cbre.png" alt="SMP Report"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Improving Initial Build Time
&lt;/h2&gt;

&lt;p&gt;After setting up SMP, we can start seeing how our build time changes as we make improvements, the first thing we'll tackle is the initial build time (i.e., the time it takes for Webpack to bundle our package since it has been initialized), we'll use a loader called &lt;code&gt;cache-loader&lt;/code&gt; to do that.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/webpack-contrib/cache-loader"&gt;&lt;code&gt;Cache-loader&lt;/code&gt;&lt;/a&gt; is a Webpack loader that caches the results of loaders preceding it on disk (or database). Meaning the &lt;em&gt;next time&lt;/em&gt; you run Webpack you'll (hopefully) see a significant improvement.&lt;/p&gt;

&lt;p&gt;Set up example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;rules&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="sr"&gt;jsx&lt;/span&gt;&lt;span class="se"&gt;?&lt;/span&gt;&lt;span class="sr"&gt;$/&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;use&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cache-loader&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// highlight-line&lt;/span&gt;
        &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;babel-loader&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="sr"&gt;scss$/&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;use&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;style-loader&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cache-loader&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// highlight-line&lt;/span&gt;
        &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;css-loader&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;postcss-loader&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;sass-loader&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Adding it before &lt;a href="https://www.npmjs.com/package/css-loader"&gt;&lt;code&gt;css-loader&lt;/code&gt;&lt;/a&gt; (for CSS) and before &lt;a href="https://www.npmjs.com/package/babel-loader/"&gt;&lt;code&gt;babel-loader&lt;/code&gt;&lt;/a&gt; (for JS) we were able to shave off around &lt;strong&gt;75 seconds&lt;/strong&gt; from the initial build time.&lt;/p&gt;

&lt;p&gt;Now let's tackle the re-build time, to do that we'll modify a property called &lt;code&gt;devtool&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Webpack Source Maps
&lt;/h2&gt;

&lt;p&gt;Within Webpack's configuration you'll find something called &lt;code&gt;devtool&lt;/code&gt;, which according to the &lt;a href="https://webpack.js.org/configuration/devtool/"&gt;docs&lt;/a&gt; lets you:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Choose a style of source mapping to enhance the debugging process. These values can affect build and rebuild speed dramatically.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In other words, modifying it will change what type of source maps you'll get, and more importantly, how long you'll have to wait until you get it.&lt;/p&gt;

&lt;p&gt;Playing with this one was a life changing experience. I really can't emphasize this enough. We changed it from &lt;code&gt;source-map&lt;/code&gt; (which is possibly the slowest one) to &lt;code&gt;eval-source-map&lt;/code&gt; and were able to improve our re-build time from 14 seconds down to 3.5 seconds.&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="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;devtool&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;NODE_ENV&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;development&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;eval-source-map&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;source-map&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;There are 12 different variants, Create React App &lt;a href="https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/config/webpack.config.js#L153-L157"&gt;uses &lt;code&gt;cheap-module-source-map&lt;/code&gt;&lt;/a&gt;, so play with it and see what's good for your needs.&lt;/p&gt;

&lt;p&gt;What you lose here is the quality of the source maps generated, and you feel the degradation once you start debugging the code. Luckily, browsers right now are keeping up the pace with TC39, so (at least while developing) you don't really need to transpile a lot of your code. If you set Babel up so that it will transpile Javascript to the latest browser version (as &lt;a href="https://github.com/facebook/create-react-app/blob/7ac8150af37d4f5617f4218619a2b607f2e20d56/packages/react-scripts/package.json#L98-L102"&gt;CRA does&lt;/a&gt;) you should be fine, as the source maps won't be too far off from the code itself.&lt;/p&gt;

&lt;p&gt;Here's how your &lt;code&gt;babel.config.js&lt;/code&gt; should look like should you want to transpile to the latest browser versions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;presets&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@babel/preset-env&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;targets&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
          &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;last 1 chrome version&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;last 1 safari version&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;last 1 firefox version&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;join&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="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that's it. 3 simple steps and our build time decreased significantly. Next time I will share how we later added Hot Module Replacement, a configuration that helped save precious time and improve the feedback loop we experience while developing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Learn From The Best
&lt;/h2&gt;

&lt;p&gt;When approaching such a task, the first idea that comes to mind is to delve in Webpack's docs and see what we could find. But it's not the only one.&lt;/p&gt;

&lt;p&gt;A different approach I found, that has really proven itself, was to go through &lt;code&gt;webpack.config&lt;/code&gt; files of existing open source projects. Specifically, &lt;a href="https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/config/webpack.config.js"&gt;Create React App's&lt;/a&gt; one. There's &lt;strong&gt;a lot&lt;/strong&gt; you can learn from it.&lt;/p&gt;

&lt;p&gt;I will definitely keep this approach, of learning from the best, in mind in future tasks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wait, You Said 1 Second.
&lt;/h2&gt;

&lt;p&gt;You're right!&lt;/p&gt;

&lt;p&gt;We were able to slice 2.5 more seconds, but it was by making a bunch of changes that were very domain specific, where the domain I refer to is our (Spot.IM's) needs. So sharing them down here just doesn't make much sense.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dependencies:&lt;/strong&gt;&lt;br&gt;
&lt;span&gt;&lt;a href="https://www.npmjs.com/package/speed-measure-webpack-plugin"&gt;speed-measure-webpack-plugin&lt;/a&gt;&lt;/span&gt;&lt;br&gt;
&lt;span&gt;&lt;a href="https://github.com/webpack-contrib/cache-loader"&gt;cache-loader&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;

</description>
      <category>webpack</category>
      <category>optimization</category>
      <category>build</category>
    </item>
    <item>
      <title>Yet Another List of (lesser known) VSCode Extensions</title>
      <dc:creator>Eldad Bercovici</dc:creator>
      <pubDate>Sat, 04 Jan 2020 07:13:56 +0000</pubDate>
      <link>https://forem.com/dutzi/yet-another-list-of-lesser-known-vscode-extensions-4n4j</link>
      <guid>https://forem.com/dutzi/yet-another-list-of-lesser-known-vscode-extensions-4n4j</guid>
      <description>&lt;p&gt;&lt;a href="https://code.visualstudio.com/"&gt;&lt;strong&gt;VSCode&lt;/strong&gt;&lt;/a&gt; is one hell of an editor. About two years after it was initially announced I started using it regularly, and, as much as I cherish Sublime Text, I haven't looked back since.&lt;/p&gt;

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

&lt;h2&gt;
  
  
  Naming Is Hard
&lt;/h2&gt;

&lt;p&gt;Naming things is one of the toughest problems I encounter daily while programming.&lt;/p&gt;

&lt;p&gt;A lot of times I would google the not-so-good name I came up with just to see what comes up.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=brunnerh.altervista-thesaurus"&gt;Altervista Thesaurus&lt;/a&gt;, &lt;a href="https://marketplace.visualstudio.com/items?itemName=FordLabs.cinnanyms"&gt;Cinnanyms&lt;/a&gt; and &lt;a href="https://marketplace.visualstudio.com/items?itemName=Compulim.compulim-vscode-dictionary"&gt;Dictionary Lookup&lt;/a&gt; all try solving this issue by listing synonyms of whatever word you give them.&lt;/p&gt;

&lt;p&gt;It's nice and it helps some of the time. But sometimes the word I'm looking for isn't an equivalent of some word. Sometimes I'll think of a word, and I'll want to know what is it a type of. For example, the word "example" is a type of "representation". For that, I'll use &lt;a href="https://www.wordsapi.com/"&gt;Words API&lt;/a&gt;. No VSCode extension for it yet.&lt;/p&gt;

&lt;h2&gt;
  
  
  Editing Utils
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=wmaurer.change-case"&gt;Change Case&lt;/a&gt; - It has been in my toolbelt since I've been using Sublime Text. I am using it so much that I've set up the following keybindings for it:&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="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"key"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cmd+i cmd+k"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"extension.changeCase.kebab"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"key"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cmd+i cmd+c"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"extension.changeCase.camel"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"key"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cmd+i cmd+p"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"extension.changeCase.pascal"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"key"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cmd+i cmd+s"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"extension.changeCase.snake"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"key"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cmd+i cmd+t"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"extension.changeCase.title"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=letrieu.expand-region"&gt;Expand Region&lt;/a&gt; - This one lets you bind a keyboard shortcut for expanding and contracting the selected region, having a GIF explain it makes so much sense, so check out the one in the link.&lt;/p&gt;

&lt;p&gt;I found the following keybinding best suiting for it:&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="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"key"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"alt+shift+up"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"expand_region"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"when"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"editorTextFocus"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"key"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"alt+shift+down"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"undo_expand_region"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"when"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"editorTextFocus &amp;amp;&amp;amp; editorHasSelection"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=wix.vscode-import-cost"&gt;Import Cost&lt;/a&gt; - Displays the size of an imported 3rd party module, next to the import statement. Doesn't &lt;em&gt;always&lt;/em&gt; work for me, but when it does it's really neat. Saves the hassle of going to &lt;a href="https://bundlephobia.com/"&gt;Bundle Phobia&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=nmsmith89.incrementor"&gt;Incrementor&lt;/a&gt; - Lets you bind a keyboard shortcut to increment/decrement the value within your current selection(s). I used to havily depend on this one but haven't much since I moved to VSCode. Maybe you'll find it useful though.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=Asuka.insertnumbers"&gt;Insert Numbers&lt;/a&gt; - Insert a range of numbers to all cursor positions.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=Cardinal90.multi-cursor-case-preserve"&gt;Multiple Cursor Case Preserve&lt;/a&gt; - Got a curser over a bunch of words cased differently? Once you start typing, this extensions will preserve the casing under each selection. I use this one a lot!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=christian-kohler.path-intellisense"&gt;Path Intellisense&lt;/a&gt; - Autocompletes paths as you write them.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=earshinov.permute-lines"&gt;Permute Lines&lt;/a&gt; - As the name suggests, this one exposes some nice line manipulation tools.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=mlewand.select-part-of-word"&gt;Select Part Of Word&lt;/a&gt; - This one lets you traverse camel-cased words easily.&lt;/p&gt;

&lt;p&gt;I have the following keybindings set up for it:&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="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"key"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ctrl+shift+right"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"selectPartOfWord.selectRight"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"key"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ctrl+shift+left"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"selectPartOfWord.selectLeft"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"key"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ctrl+backspace"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"selectPartOfWord.backspace"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"key"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ctrl+delete"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"selectPartOfWord.delete"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"key"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ctrl+left"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"selectPartOfWord.moveLeft"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"key"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ctrl+right"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"selectPartOfWord.moveRight"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Diff
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=ryu1kn.partial-diff"&gt;Partial Diff&lt;/a&gt; - VSCode has a nice UI for diffing files. This extension lets you enjoy that UI when diffing between a wider variety of input sources (files, clipboard and current selection), so you can diff between the contents of your clipboard and your current selection, for example.&lt;/p&gt;

&lt;h2&gt;
  
  
  Files
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=nemesv.copy-file-name"&gt;Copy File Name&lt;/a&gt; - Useful in projects where the filenames are the names of the classes/functions they contain. With it I can Cmd+Shift+P &amp;gt; Type "cfn" &amp;gt; Enter, then paste it somewhere I need it, and using the kybindings for Change Case, change its case to whatever.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=sleistner.vscode-fileutils"&gt;File Utils&lt;/a&gt; - This extension adds some useful file manipulation commands to the Command Palette.&lt;/p&gt;

&lt;h2&gt;
  
  
  Etc
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=nidu.copy-json-path"&gt;Copy JSON Path&lt;/a&gt; - Very useful in all sorts of use cases. One that pops to my mind immediately when thinking about this extension is where you need to specifiy the getter string (or JSON path) for an i18n string that resides in some lengthy JSON.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=artdiniz.quitcontrol-vscode"&gt;Quit Control for VSCode&lt;/a&gt; - Quit control will pop up a message box making sure you really want to leave once you hit Cmd+Q / Cmd+Shift+W. This one saved me so many times.&lt;/p&gt;

&lt;h2&gt;
  
  
  More Shortcuts
&lt;/h2&gt;

&lt;p&gt;Coming from Sublime Text, I'm pretty sure the first extension I added was &lt;a href="https://marketplace.visualstudio.com/items?itemName=ms-vscode.sublime-keybindings"&gt;Sublime Text Keymap and Settings Importer&lt;/a&gt; (check &lt;a href="https://github.com/Microsoft/vscode-sublime-keybindings#why-dont-all-sublime-text-commands-work"&gt;this&lt;/a&gt; out for even more extensions for people coming from ST).&lt;/p&gt;

&lt;p&gt;Here are some other useful keyboard shortcuts I set up along the years:&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="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Collapses&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;all&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;folders&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;within&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Explorer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Pane&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"key"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cmd+k cmd+c"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"workbench.files.action.collapseExplorerFolders"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Cancels&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;default&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;binding&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;cmd+k&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;cmd+r&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"key"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cmd+k cmd+r"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"-workbench.action.keybindingsReference"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Binds&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;cmd+k&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;cmd+r&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;refresh&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Explorer&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"key"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cmd+k cmd+r"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"workbench.files.action.refreshFilesExplorer"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Again&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;clears&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;existing&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;keybinding&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;(ctrl+t)&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"key"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ctrl+t"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"-editor.action.transposeLetters"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"when"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"textInputFocus &amp;amp;&amp;amp; !editorReadonly"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Binds&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;ctrl+t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Git&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Create&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Tag&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"key"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ctrl+t"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"extension.gitcreatetag"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Close&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;all&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;editors&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;right&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;of&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;current&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;one&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"key"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cmd+i cmd+r"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"workbench.action.closeEditorsToTheRight"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;And&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;completeness&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;not&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;so&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;useful&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;close-editor-to-the-left&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"key"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cmd+i cmd+l"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"workbench.action.closeEditorsToTheLeft"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Clears&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;terminal&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"key"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cmd+k cmd+k"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"workbench.action.terminal.clear"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"when"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"terminalFocus"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Increase&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;and&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;decrease&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;sidebar's&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;width&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;using&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;your&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;keyboard!&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"key"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ctrl+shift+left"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"workbench.action.decreaseViewSize"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"when"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"sideBarFocus"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"key"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ctrl+shift+right"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"workbench.action.increaseViewSize"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"when"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"sideBarFocus"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;The&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;following&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;ones&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;map&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Chrome's&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;DevTools&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;keybindings&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;VSCode's&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;debugger&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"key"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cmd+'"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"workbench.action.debug.stepOver"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"when"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"debugState == 'stopped'"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"key"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"f10"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"-workbench.action.debug.stepOver"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"when"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"debugState == 'stopped'"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"key"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cmd+;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"workbench.action.debug.stepInto"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"when"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"inDebugMode"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"key"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"f11"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"-workbench.action.debug.stepInto"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"when"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"inDebugMode"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"key"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"shift+cmd+&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"workbench.action.splitEditor"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"key"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cmd+&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"-workbench.action.splitEditor"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"key"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cmd+&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"workbench.action.debug.continue"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"when"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"inDebugMode"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"key"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"f5"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"-workbench.action.debug.continue"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"when"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"inDebugMode"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>vscode</category>
      <category>extensions</category>
      <category>keybindings</category>
    </item>
  </channel>
</rss>
