<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Krzysztof Żuraw blog's RSS Feed]]></title><description><![CDATA[Frontend | Design | Coffee]]></description><link>https://krzysztofzuraw.com</link><generator>GatsbyJS</generator><lastBuildDate>Thu, 31 Dec 2020 12:17:07 GMT</lastBuildDate><item><title><![CDATA[TIL - Chrome has emulate focused page]]></title><description><![CDATA[Today I learned that chrome has  settings. What such toggle is doing? It emulates that the page is focused and allows to debug select or…]]></description><link>https://krzysztofzuraw.com/blog/2020/chrome-emulate-focused-page</link><guid isPermaLink="false">https://krzysztofzuraw.com/blog/2020/chrome-emulate-focused-page</guid><pubDate>Fri, 11 Dec 2020 18:46:50 GMT</pubDate><content:encoded>&lt;p&gt;Today I learned that chrome has &lt;code class=&quot;language-text&quot;&gt;Emulate Focused Page&lt;/code&gt; settings.&lt;/p&gt;
&lt;p&gt;What such toggle is doing?&lt;/p&gt;
&lt;p&gt;It emulates that the page is focused and allows to debug select or dropdown that is triggered when
user focus input.&lt;/p&gt;
&lt;p&gt;You can see screenshot below:&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto;  max-width: 590px;&quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/c0965faf02af450c469fd45c6eb335db/076ca/til.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 70.94594594594594%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAACXBIWXMAAAsSAAALEgHS3X78AAADGUlEQVQ4y3WTy08bZxTFLbGpKGCF2OPxazzgFzUUt6pIFjyU0v+kUioFRNSkGyQW3SUqEEBJIIZFSAUG7A01QtBV1az7B1RKu2irCEiCAWMbv/n1ftOSKo9+0tG9c0dz7jn3zmf79fc/OcjmeHEkOM5LPOWlxMNckVcneV5JruJeNs/zvQNWfjngy5/g1reTuDUnPr8fl0vHCJgEjAC2vf19jk9y5HJ5TvJn1OoNSuUKh9kj8oUzCsUShbMS1Vrdelco11BnavoedodGIBjB6/Pj0V14XE5svz17xsnxEdlsltPTPNVqlVKpxL40OpRaTmrFYlHqFc7Pz2nU6/8QTk3S3O6kI9xFzPRa6Ogwsf3x13Ne5koc50s0Gg3rI4VarWZB1c6qdVFWFZpz6qJSnbtzCT4wPkWPf4GvZwBPdz9695BYPnghMyqI3aKlrlypiOUyZUFF8orEnNjOFUpWA/Vene+mZmjTfBhdn2CEYrgCES75w9hWVlZIp1Ksra2xmkzy5Mn3pFJpdnd32dnZsfCj5Aqqtr29zc9Pn3L71tfYL8tSZIZ+sxOf141fYJudm5MBT3P//gMWFhZ48PAhiUQC1Ug1SUqTZPIiJq365uYmoyMjXNLceDtlKW7d2rYhsM0vPOJRYpHFxSUeP15meXnZ+jCdTovS1DtYX19na2uLm2NjtLs8eINRPIaJprvRnA5sav0zM7NMTk4xLfns7Bzz8/OvCTY2Nt7IlWpFOCIK2x1OzFCEUFhsy3/o84jlxaUlVldX/8O/1i4I3iZUCjOZDNevf4XudvNRrNsijHTFiES7sA0MDNDf34+Kg4ODDA4N0dfXx507d61ZKYL3Ed64MYJfrMa6PyYcjdIZDBGJCGFbWxutra1omobD4cBut9PU1MT4+Lhl7W3CC8ujo6P45Ib09vYSDoUwDINAQK6erus4nTILs0MKJm6x0dLSwsTEhKXkHYVCmMnIUm6OEY2EuXL1Kj09PQSDQfxqy0qVw3EZM+CVogzW56W5+cP/J5TnH6T+jfyHVz6Lc+3a5wwPDxOPxy2XfwPpAdndM+JuDAAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;TIL&quot;
        title=&quot;TIL&quot;
        src=&quot;/static/c0965faf02af450c469fd45c6eb335db/fcda8/til.png&quot;
        srcset=&quot;/static/c0965faf02af450c469fd45c6eb335db/12f09/til.png 148w,
/static/c0965faf02af450c469fd45c6eb335db/e4a3f/til.png 295w,
/static/c0965faf02af450c469fd45c6eb335db/fcda8/til.png 590w,
/static/c0965faf02af450c469fd45c6eb335db/efc66/til.png 885w,
/static/c0965faf02af450c469fd45c6eb335db/076ca/til.png 914w&quot;
        sizes=&quot;(max-width: 590px) 100vw, 590px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;You can find this setting under &lt;code class=&quot;language-text&quot;&gt;Rendering/Emulate Focused Page&lt;/code&gt; inside chrome devtools.
&lt;code class=&quot;language-text&quot;&gt;Rendering&lt;/code&gt; tab can be accessed by &lt;code class=&quot;language-text&quot;&gt;CMD+SHIFT+P&lt;/code&gt; and typing &lt;code class=&quot;language-text&quot;&gt;Rendering&lt;/code&gt;.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[TIL - how height:auto works]]></title><description><![CDATA[Today I learned a bit more on how  works. Let’s say you have a box that has
implicit  &  set to . Inside this box you place 1px by 1px image…]]></description><link>https://krzysztofzuraw.com/blog/2020/height-auto</link><guid isPermaLink="false">https://krzysztofzuraw.com/blog/2020/height-auto</guid><pubDate>Wed, 02 Dec 2020 18:58:50 GMT</pubDate><content:encoded>&lt;p&gt;Today I learned a bit more on how &lt;code class=&quot;language-text&quot;&gt;height:auto&lt;/code&gt; works. Let’s say you have a box that has
implicit &lt;code class=&quot;language-text&quot;&gt;height&lt;/code&gt; &amp;#x26; &lt;code class=&quot;language-text&quot;&gt;width&lt;/code&gt; set to &lt;code class=&quot;language-text&quot;&gt;250px&lt;/code&gt;. Inside this box you place 1px by 1px image.
You give image &lt;code class=&quot;language-text&quot;&gt;height: auto&lt;/code&gt;. What is happening? This image is taking whole 250px height!
&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto;  max-width: 327px;&quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/b5a79eae0996f1cca8a230cb2026d02c/00e65/1.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 95.27027027027027%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAATCAYAAACQjC21AAAACXBIWXMAAAsSAAALEgHS3X78AAAA6ElEQVQ4y+2UP65EYBRH7UNBIgRBiH+FRC3WoZCwAp1E6K1DFOxBbyMUohJ+75HMm0Lzvcx0Mzc5yVece7rvUvid4zjw6jwa1OMxDAPatkXf9+i6jojTbZoG4zhejX3fn8EoisAwDBRFgSzLRKiqCpqmkef51di27RlM0/SSXNeFZVlEnK4gCKiq6h5MkgSiKMK2bZimSYTjOOB5HmVZfoPf4AcFJUm6pLd8vTiOwXEcdF2HpmlEGIYBlmVRFMU9mGUZfN9HGIYIgoCI0/U8D3Vd34PLsmCaJszz/C/OnXVd/44s9e6L/QOzArE9gjHD8AAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;one on one px box&quot;
        title=&quot;one on one px box&quot;
        src=&quot;/static/b5a79eae0996f1cca8a230cb2026d02c/00e65/1.png&quot;
        srcset=&quot;/static/b5a79eae0996f1cca8a230cb2026d02c/12f09/1.png 148w,
/static/b5a79eae0996f1cca8a230cb2026d02c/e4a3f/1.png 295w,
/static/b5a79eae0996f1cca8a230cb2026d02c/00e65/1.png 327w&quot;
        sizes=&quot;(max-width: 327px) 100vw, 327px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;But you do the same with image 250px by 1px (250px width by 1px height) - image is taking only 1px height.
&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto;  max-width: 313px;&quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/0f909b3e4215f198efab499c193efe5e/80977/250.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 95.94594594594595%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAATCAYAAACQjC21AAAACXBIWXMAAAsSAAALEgHS3X78AAAAeklEQVQ4y+2USwrAIAxEvf9hQ9z5TxlBaakUDS66MDAgAV8mBmNKKbIrwDI45JzFey8hBLXAQFQgEkQk1lqVmLkyOjClJDHGbntFrcN2fwhcebMpoMbhZ8vbHR7gFPAM5Yc/5QWEtDGcsnOuVtHsQuzSh0NYRxWt7u1fCp/iTx7vhBYAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;250 px on on px box&quot;
        title=&quot;250 px on on px box&quot;
        src=&quot;/static/0f909b3e4215f198efab499c193efe5e/80977/250.png&quot;
        srcset=&quot;/static/0f909b3e4215f198efab499c193efe5e/12f09/250.png 148w,
/static/0f909b3e4215f198efab499c193efe5e/e4a3f/250.png 295w,
/static/0f909b3e4215f198efab499c193efe5e/80977/250.png 313w&quot;
        sizes=&quot;(max-width: 313px) 100vw, 313px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;So if you want your image to take only 1px with &lt;code class=&quot;language-text&quot;&gt;height:auto&lt;/code&gt; make sure that such image has full width
of parent.&lt;/p&gt;
&lt;p&gt;You can see example in this &lt;a href=&quot;https://codepen.io/krzysztofzuraw/pen/oNzXEGY&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;codepen&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Tooling overload in JS]]></title><description><![CDATA[Before I start let me clarify what I mean by tooling in the context of programming language: all ecosystem of tools/libraries/frameworks…]]></description><link>https://krzysztofzuraw.com/blog/2020/tooling-overload-js</link><guid isPermaLink="false">https://krzysztofzuraw.com/blog/2020/tooling-overload-js</guid><pubDate>Thu, 26 Nov 2020 18:40:50 GMT</pubDate><content:encoded>&lt;p&gt;Before I start let me clarify what I mean by tooling in the context of programming language: all ecosystem of tools/libraries/frameworks that are needed to use with a given programming language.&lt;/p&gt;
&lt;p&gt;When I’m thinking about tooling and how cumbersome it can be the first thing that comes to my mind is JavaScript. You probably heard of the black hole of node modules or &lt;a href=&quot;https://dayssincelastjavascriptframework.com/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;days since the last JavaScript framework website&lt;/a&gt;. It means that either ecosystem is a black mess with a huge dependency list and new dependencies come every day.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto;  max-width: 590px;&quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/70ebf207b6e413a8914d64afb84fb33d/7a3d6/node-weight.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 71.62162162162163%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAIAAACgpqunAAAACXBIWXMAAAsSAAALEgHS3X78AAABzUlEQVQoz42R+3KaQBTGfc88VV8g1UkzdSjEXLw0oZkaBC8xiNhqVBS5aMALEmOLIAtkdzHTS5w23x8759s9v7Pf7Ca2ILiV7fz3daFpFESTqGmXTf1KHOd47aSuE5UR3Zp8Fsbf9EdxND9mZXh0wWvcveEDkJDnzte2seyRLWlw1VlWBlZ1aEvTn5y0ZCWrCue2pkzPotsz1drwyionTpn+sthdLNZeIoqih8WjSh/078t+hDSc/fhUn8zXLnZRqb84LKmwgBnhet2Zf6zqsAjCMBF3rN0QhFGI69nKTTEKPAuwF1SbupsgGPvywMqKBixAgGHcE4YQxtXDyn1XVCMEIy8oO9gHyHKSlRPNX/ALv1sdP2hMnThYDJ/8B4b3/KY4yJvgECv6U3AHoClRA8Ue74djzLbtXq+r62NZHrbbHXkoe9ttPE/Qnk7FGYKDVzAMaZomV+aSyfepVCqTyRx9OKIoSpIGhoGaat1J8lLANwd/wwCAfC5LkiRNf2FZ9rbO12oVpsTc3BSz+QJsgiP4RhN3B/tjKyPl4vz87OyUokiCINLptKbruw98Ufx+e17b933XdTebjed5W89zHAfuxCT+iPBf8Fv0Gn4GXgwBEAkAKrQAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;node modules is the heaviest&quot;
        title=&quot;node modules is the heaviest&quot;
        src=&quot;/static/70ebf207b6e413a8914d64afb84fb33d/fcda8/node-weight.png&quot;
        srcset=&quot;/static/70ebf207b6e413a8914d64afb84fb33d/12f09/node-weight.png 148w,
/static/70ebf207b6e413a8914d64afb84fb33d/e4a3f/node-weight.png 295w,
/static/70ebf207b6e413a8914d64afb84fb33d/fcda8/node-weight.png 590w,
/static/70ebf207b6e413a8914d64afb84fb33d/efc66/node-weight.png 885w,
/static/70ebf207b6e413a8914d64afb84fb33d/7a3d6/node-weight.png 990w&quot;
        sizes=&quot;(max-width: 590px) 100vw, 590px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;h2&gt;Why is that?&lt;/h2&gt;
&lt;p&gt;I read somewhere that JavaScript as an ecosystem is a baby. It means that we have many &lt;a href=&quot;https://css-tricks.com/the-widening-responsibility-for-front-end-developers&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;responsibilities&lt;/a&gt; and so little knowledge about how to handle such a range of responsibilities. Where can we learn? Maybe we can look into other languages - how &amp;#x26; what they are doing?&lt;/p&gt;
&lt;p&gt;I think you expect me to write about how beautifully other languages are doing the things that JavaScript cannot or not yet done. Sorry to disappoint you - but I don’t. I think I don’t know enough yet to do this. But I can give an example of my journey with one piece of the tooling ecosystem - bundlers.&lt;/p&gt;
&lt;h2&gt;Example from my work&lt;/h2&gt;
&lt;p&gt;I wanted to develop React &amp;#x26; Typescript application. In a typical situation,you expect me to use something like &lt;a href=&quot;https://reactjs.org/docs/create-a-new-react-app.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;create-react-app&lt;/a&gt;. I personally like to set up my own tooling and choose parts of the toolchain instead of being surprised when I eject.&lt;/p&gt;
&lt;p&gt;I choose a &lt;a href=&quot;https://parceljs.org/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;parcel&lt;/a&gt; as a main piece of the toolchain.‌ Why? It is the easiest to start and I don’t need to write any config. I added &lt;a href=&quot;https://ant.design/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;ant design&lt;/a&gt; too.&lt;/p&gt;
&lt;p&gt;Two weeks of development passed and I need to render the &lt;a href=&quot;https://ant.design/components/table/#header&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Table&lt;/a&gt;. I import it via &lt;code class=&quot;language-text&quot;&gt;import {Table} from &amp;#39;antd&amp;#39;&lt;/code&gt; and tried to run the project in development mode. I got an error telling me that &lt;code class=&quot;language-text&quot;&gt;parcel&lt;/code&gt; can’t create a JavaScript bundle. I started searching around the web for this problem.&lt;/p&gt;
&lt;p&gt;After a while, I found a corresponding issue inside ant design GitHub repository. The main conclusion was that table won’t work with &lt;code class=&quot;language-text&quot;&gt;parcel&lt;/code&gt;. I checked issue tracker inside &lt;code class=&quot;language-text&quot;&gt;parcel&lt;/code&gt; repository to see that issue was stale. I had two options there - either fix the issue or change the bundler to one that works with antd.&lt;/p&gt;
&lt;p&gt;I choose webpack as it is a recommend bundler to use with antd. I have to migrate the application from parcel to webpack. I started by adding TypeScript and Babel plugins &amp;#x26; configs. After that, I need to add &lt;a href=&quot;https://emotion.sh/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;emotion.js&lt;/a&gt; babel plugins in proper versions in order for &lt;code class=&quot;language-text&quot;&gt;css prop&lt;/code&gt; to work. I the meantime I forgot about &lt;code class=&quot;language-text&quot;&gt;less&lt;/code&gt; loader for antd - I had to add it as well.&lt;/p&gt;
&lt;p&gt;It took about 3 hours of running &lt;code class=&quot;language-text&quot;&gt;webpack&lt;/code&gt; server, fixing building errors, fixing TypeScript errors but in the end I made it!. No errors from &lt;code class=&quot;language-text&quot;&gt;tsc&lt;/code&gt;, no errors from &lt;code class=&quot;language-text&quot;&gt;eslint&lt;/code&gt; (which setup requires additional 5 packages in order it to work with TS), no errors from &lt;code class=&quot;language-text&quot;&gt;npm run dev&lt;/code&gt;. I’m done here 🎉.&lt;/p&gt;
&lt;p&gt;Until the next update of webpack or babel or any part of the toolchain.&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;This was a mind dump about the tooling ecosystem in JavaScript world. I wrote about my problems with ant design in conjunction with &lt;code class=&quot;language-text&quot;&gt;parcel&lt;/code&gt;. Takeaway? It is hard but we are moving in a good direction.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Stack & Column in CSS-in-JS]]></title><description><![CDATA[Today I want to write more about new emotion components that we try at Ingrid. Those components help us with spacing. The problem I want to…]]></description><link>https://krzysztofzuraw.com/blog/2020/stack-column-css-in-js</link><guid isPermaLink="false">https://krzysztofzuraw.com/blog/2020/stack-column-css-in-js</guid><pubDate>Fri, 06 Nov 2020 18:07:50 GMT</pubDate><content:encoded>&lt;p&gt;Today I want to write more about new emotion components that we try at &lt;a href=&quot;https://www.ingrid.com/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Ingrid&lt;/a&gt;. Those components help us with spacing.&lt;/p&gt;
&lt;h2&gt;The problem&lt;/h2&gt;
&lt;p&gt;I want to implement this footer:&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto;  max-width: 349px;&quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/360c4362a5cf216894f3775e2cf23b52/e9bf8/example-layout.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 32.43243243243243%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAYAAADDl76dAAAACXBIWXMAAAsSAAALEgHS3X78AAABKElEQVQY01WRW2+CQBCF+f8/qTbxoYESVCCpFx6IlDsCIiyIl2hOOdM0qZNMdpgdzp79VjudTgjDEFmWoShypGmKKIoRx7HUSZK8JPv/vznDf8uyRFVV0NjsezVljzAq0EwHPJ8P3G53tG2L8/kMpZSsnBnH8aUehgE01TQN9vs9tDzPZfPTzvFutPhYHNAPIxie52G1Wkk6joMgCCb3EbbbLY7HIwzDwGw2g2VZIkanGq+ZF+UkVsL8At70bnJ6EMGuUxOGAr7vwzRNEdpsNtB1XWrXdTGfz7Fer2Weh2hUfTzuSLIaCzeCH/yKMeI4EUdkvFwuxTHF6Wi320lt27b0GXVdQwvDbwGtVIuubWT9Y0IUZERm1+tVmDEvl4v0uU++nOejUOcHidC6Ng7aIWgAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;Footer to implement&quot;
        title=&quot;Footer to implement&quot;
        src=&quot;/static/360c4362a5cf216894f3775e2cf23b52/e9bf8/example-layout.png&quot;
        srcset=&quot;/static/360c4362a5cf216894f3775e2cf23b52/12f09/example-layout.png 148w,
/static/360c4362a5cf216894f3775e2cf23b52/e4a3f/example-layout.png 295w,
/static/360c4362a5cf216894f3775e2cf23b52/e9bf8/example-layout.png 349w&quot;
        sizes=&quot;(max-width: 349px) 100vw, 349px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;It has a logo, text in two rows and horizontal space between them. It sounds not bad.
I added a logo, then left margin and in the end two rows of text. Or I can use css grid to have the same effect.&lt;/p&gt;
&lt;p&gt;Yet after two weeks requirements change and I don’t need to display the telephone number to the user if there is no enough data. In this case, I won’t render this component. Yet I have a problem - &lt;code class=&quot;language-text&quot;&gt;margin-top&lt;/code&gt; between &lt;code class=&quot;language-text&quot;&gt;contact our support&lt;/code&gt; &amp;#x26; &lt;code class=&quot;language-text&quot;&gt;at 555-555-555&lt;/code&gt;.
I can either refactor that to grid/flexbox with a &lt;code class=&quot;language-text&quot;&gt;gap&lt;/code&gt; instead of &lt;code class=&quot;language-text&quot;&gt;margin-top&lt;/code&gt; (the best way) or I can add conditional inside my &lt;a href=&quot;https://emotion.sh/docs/css-prop&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;css prop&lt;/a&gt; telling emotion to reset &lt;code class=&quot;language-text&quot;&gt;margin-top&lt;/code&gt; to 0 (the worst way). In the worst case, my code started to look like spaghetti, in the best case in mix flexbox or grid definitions with margins, colours &amp;#x26; fonts making my code less readable.&lt;/p&gt;
&lt;h2&gt;Solution&lt;/h2&gt;
&lt;p&gt;What is solution for this problem? Use specialised components. Specialised component has one task - to give spacing and make sure that elements lay in the place where they should be. Below you will find example of those specialised components in action:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;tsx&quot;&gt;&lt;pre class=&quot;language-tsx&quot;&gt;&lt;code class=&quot;language-tsx&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Columns&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;space&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;0.5rem&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;alignY&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;flex-start&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;img&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;src&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;logo.svg&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Stack&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;space&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;0&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;p&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;Contact our support&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;p&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;p&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;at 555-555-555&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;p&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Stack&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Columns&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I now have &lt;code class=&quot;language-text&quot;&gt;Columns&lt;/code&gt; component to create columns from its children - in my case &lt;code class=&quot;language-text&quot;&gt;img&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;Stack&lt;/code&gt;. &lt;code class=&quot;language-text&quot;&gt;Stack&lt;/code&gt; is making sure that &lt;code class=&quot;language-text&quot;&gt;p&lt;/code&gt; children have spacing between them.&lt;/p&gt;
&lt;p&gt;What are the pros? I have a nice abstraction that can be shared across a team of people. I can point my teammates into those components when they need to create other combinations of layouts. Because this is abstraction I can think about layouts as a combination of different boxes (which is HTML sense they are). I found it much easier to combine them, reason about them, or change them. I can move my focus to other pieces of frontend instead of fighting layout &amp;#x26; spacing.&lt;/p&gt;
&lt;p&gt;Below you can find an example implementation of &lt;code class=&quot;language-text&quot;&gt;Columns&lt;/code&gt; &amp;#x26; &lt;code class=&quot;language-text&quot;&gt;Stack&lt;/code&gt; components in emotion + react:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;tsx&quot;&gt;&lt;pre class=&quot;language-tsx&quot;&gt;&lt;code class=&quot;language-tsx&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; React &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;react&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Props&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  space&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;string&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// it can be typeof keyof Theme[&apos;spacing&apos;]&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; Stack&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; React&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;FunctionComponent&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Props&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt; = ({ children, space }) =&gt; &lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt;
      &lt;span class=&quot;token attr-name&quot;&gt;css&lt;/span&gt;&lt;span class=&quot;token script language-javascript&quot;&gt;&lt;span class=&quot;token script-punctuation punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&apos;&gt; * + *&apos;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
          marginTop&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; space&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;children&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;tsx&quot;&gt;&lt;pre class=&quot;language-tsx&quot;&gt;&lt;code class=&quot;language-tsx&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; React &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;react&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Props&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  space&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;string&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// it can be typeof keyof Theme[&apos;spacing&apos;]&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; Columns&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; React&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;FunctionComponent&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Props&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt; = ({ children, space }) =&gt; &lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt;
      &lt;span class=&quot;token attr-name&quot;&gt;css&lt;/span&gt;&lt;span class=&quot;token script language-javascript&quot;&gt;&lt;span class=&quot;token script-punctuation punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        display&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;flex&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        alignItems&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;center&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&apos;&gt; * + *&apos;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
          marginLeft&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; space&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;children&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;HTML examples can be found on &lt;a href=&quot;https://codepen.io/krzysztofzuraw/pen/GRqrwEG&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;codepen&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;In this blog post, I wrote on how one can use &lt;code class=&quot;language-text&quot;&gt;Stack&lt;/code&gt; &amp;#x26; &lt;code class=&quot;language-text&quot;&gt;Columns&lt;/code&gt; components for creating layouts.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Intl Collator in JavaScript]]></title><description><![CDATA[Recently I needed to sort an array of objects from A to Z. Usually for such task I’m using the
following piece of code: Yet I had a problem…]]></description><link>https://krzysztofzuraw.com/blog/2020/js-intl-collator</link><guid isPermaLink="false">https://krzysztofzuraw.com/blog/2020/js-intl-collator</guid><pubDate>Wed, 21 Oct 2020 18:23:50 GMT</pubDate><content:encoded>&lt;p&gt;Recently I needed to sort an array of objects from A to Z. Usually for such task I’m using the
following piece of code:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;tsx&quot;&gt;&lt;pre class=&quot;language-tsx&quot;&gt;&lt;code class=&quot;language-tsx&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; cities &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; name&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Wrocław&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; name&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Kraków&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; name&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Łódź&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

cities&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sort&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;city1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; city2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;city1&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; city2&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Yet I had a problem with this code - the last city &lt;code class=&quot;language-text&quot;&gt;Łódź&lt;/code&gt; was not in the right place. The proper order
should be:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;tsx&quot;&gt;&lt;pre class=&quot;language-tsx&quot;&gt;&lt;code class=&quot;language-tsx&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; name&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Kraków&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; name&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Łódź&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; name&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Wrocław&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;But code from previous example returned:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;tsx&quot;&gt;&lt;pre class=&quot;language-tsx&quot;&gt;&lt;code class=&quot;language-tsx&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; name&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Kraków&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; name&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Wrocław&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; name&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Łódź&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Why is that? Because &lt;code class=&quot;language-text&quot;&gt;Łódź&lt;/code&gt; is not starting from Unicode character - it is a &lt;a href=&quot;https://en.wikipedia.org/wiki/UTF-8&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;utf-8&lt;/a&gt; one.&lt;/p&gt;
&lt;p&gt;How then can I sort an array with &lt;code class=&quot;language-text&quot;&gt;utf-8&lt;/code&gt; characters? In turns out that all major browsers have support
for &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;localeCompare&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;What it is? I like to think about this method as a way of sorting with &lt;code class=&quot;language-text&quot;&gt;utf-8&lt;/code&gt; support. &lt;code class=&quot;language-text&quot;&gt;localeCompare&lt;/code&gt;
allows me to compare two strings with internationalization support. My sorting example now can be changed to:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;tsx&quot;&gt;&lt;pre class=&quot;language-tsx&quot;&gt;&lt;code class=&quot;language-tsx&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; cities &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; name&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Wrocław&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; name&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Kraków&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; name&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Łódź&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

cities&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sort&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;city1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; city2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; city1&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;localeCompare&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;city2&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// [{name: &apos;Kraków&apos;},{name: &apos;Łódź&apos;},{name: &apos;Wrocław&apos;}];&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;There is a lot of configuration options to &lt;code class=&quot;language-text&quot;&gt;localeCompate&lt;/code&gt; - if you want to know more I recommend
visiting &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;mdn&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;In this blog post, I wrote on how to use &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;localeCompare&lt;/a&gt;
to sort strings that are &lt;code class=&quot;language-text&quot;&gt;utf-8&lt;/code&gt;.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[How to split antd theme into smaller components]]></title><description><![CDATA[Recently I stumbled upon an interesting problem at work. I was using ant-design
and I wanted to customize default theme variables. To do…]]></description><link>https://krzysztofzuraw.com/blog/2020/split-antd</link><guid isPermaLink="false">https://krzysztofzuraw.com/blog/2020/split-antd</guid><pubDate>Wed, 14 Oct 2020 11:18:50 GMT</pubDate><content:encoded>&lt;p&gt;Recently I stumbled upon an interesting problem at work. I was using &lt;a href=&quot;https://ant.design/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;ant-design&lt;/a&gt;
and I wanted to customize default theme variables. To do that I’ve created a &lt;code class=&quot;language-text&quot;&gt;theme.less&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;less&quot;&gt;&lt;pre class=&quot;language-less&quot;&gt;&lt;code class=&quot;language-less&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;@import&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;~antd/dist/antd.less&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token variable&quot;&gt;@primary-color&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;/span&gt; #003dff&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token variable&quot;&gt;@dark-color&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;/span&gt; #38b6ab&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token variable&quot;&gt;@font-family&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;/span&gt; Inter&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Everything was fine until I looked into &lt;a href=&quot;https://www.npmjs.com/package/webpack-bundle-analyzer&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;webpack-bundle-analyzer&lt;/a&gt;
I saw that &lt;code class=&quot;language-text&quot;&gt;theme.less&lt;/code&gt; was taking a huge portion of the overall bundle size:&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto;  max-width: 590px;&quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/5740daf3f43db731e6999242b227cab7/e405b/bundle-analysis.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 83.78378378378379%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAARCAYAAADdRIy+AAAACXBIWXMAAAsSAAALEgHS3X78AAAD0klEQVQ4yz1UV3fiZhDVL07+QV7ik4d4vSeJ267XNhhsmkAFddGEqKIYjA0L7l7iElywcdl9uxl9Pmcf5synr9y5M3dGXKddgyREUXIsJGIhKFIChiZAFmMQU1FEdwIQkxF2JqYiiEWC4ONh2IYMUxdhqALSUhy2KeGg1wLnVfOIR4NwcjqBxaGleZgEqMgJdlGlb38/TQE0JQldSTGQfFZDxkojS2bpEgNngKfHfYwvRjgjf3H6FeenA5yfDH6ux+cjutjE8ahH+30M+02M+i0M9hvotsvo97z3b/KHX7vgpg8TTB9u8fI8xdvrDD++PzP/8vxI6xc8z6aYPT2QTXFyuI+MEUfBTiFr8khEvsBQonAyAjJ6HM1aHtzj9I49aDbrsC0D2+EtNLwq8vkMLFPD4WiAs9MjAn8l1kPUSibqZYtZs5ZFo5ph66qrY2+3Cm72dI/xtzMYugpdV5DN0GHFhVsssADdbhujYZ8xvjgboU6Au40COk2HeR+02yqi7eXQ6xCgf/H4aIh4LAJVlXFyPEJaFqFpaZiGhlQyAUlM4eb6EjdX5wgFlvHxwxxWFufxeWUBwY0lLP/zJ1t3WiVwt5NrYmWiQClmbN9nGaCqyHCcHEQhCUWR4LoOLsfHsHUeUjIMWdhGmkyTYxD4LQiJIDokEnd3e4Nyqchq2PBqlG4JuayNUslBi/b8IEUnj25nF9/OD+FVLJZq28sza9Vz76nXs9jzGd5NrpjC7yo/4cfbDN/JXv292QPeXh7ZmV/rk6M+Fd/4KYpXscnbzPti9To1cO1GEY1aDi3PQcW14GRVJr9fjz1KoZBRqJF5qJSaW9BJjCKxypO6WQLxQTPMSgWV3pT9xvYbeUhNuUcRGqhXCsjbMk2AxKxRzaHsGASmETs/fZseVlArmzDS20TCZEREfgOWFgf3cHeL2/9ucH83YU3sN6+U+ILg2gJ2An/BUiMMsOzoNJ4ySkWbMvKzsYk5jaYYRs6m0aMGLxdNcNdX/2Iw6OP66opaY8zStbUYFCFAgAtIpzZwsOfRmFVYGSxDQq2SQ5HAs6YAU41CTKwjFVtjTGlS7qnoT7i+vMDhsIfdpktgQSS2F7G2+BtdXEWv24RXd9Hfb5EIJgUJQIivQ5fDzKTkJmLhRbh51Wc4pmbuE4sGU9Ev9tb6PDZXf8fCH78ivPEBXRqpdsMl4QqUYgh8ZJVAAtSHW8RuE9HQEhI7y0wYbjK5wXDQhUdAbl5BleT32QU+zWF+7heENj5icLD7zq5CwTaXwEfX6JfFQ5NCiGz9jfj2CiR+nQH+D2n8WR1WrQsrAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;bundle-analysis&quot;
        title=&quot;bundle-analysis&quot;
        src=&quot;/static/5740daf3f43db731e6999242b227cab7/fcda8/bundle-analysis.png&quot;
        srcset=&quot;/static/5740daf3f43db731e6999242b227cab7/12f09/bundle-analysis.png 148w,
/static/5740daf3f43db731e6999242b227cab7/e4a3f/bundle-analysis.png 295w,
/static/5740daf3f43db731e6999242b227cab7/fcda8/bundle-analysis.png 590w,
/static/5740daf3f43db731e6999242b227cab7/efc66/bundle-analysis.png 885w,
/static/5740daf3f43db731e6999242b227cab7/c83ae/bundle-analysis.png 1180w,
/static/5740daf3f43db731e6999242b227cab7/e405b/bundle-analysis.png 1566w&quot;
        sizes=&quot;(max-width: 590px) 100vw, 590px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;h2&gt;What is the problem here?&lt;/h2&gt;
&lt;p&gt;It turns out that by &lt;code class=&quot;language-text&quot;&gt;@import &amp;#39;~antd/dist/antd.less&amp;#39;&lt;/code&gt; I accidentally imported whole antd styles.
Because of that &lt;code class=&quot;language-text&quot;&gt;theme.less&lt;/code&gt; is so big. How to fix it? After googling around I found out about 2 steps
that I could that to lower size of my bundle:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;customize antd theme via webpack&lt;/li&gt;
&lt;li&gt;tell transpiler (babel) to inject css when you are using antd components&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Customizing antd theme&lt;/h2&gt;
&lt;p&gt;How you can customize antd theme? According to &lt;a href=&quot;https://ant.design/docs/react/customize-theme#Customize-in-webpack&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;antd docs&lt;/a&gt;
you can add &lt;code class=&quot;language-text&quot;&gt;options&lt;/code&gt; to webpack &lt;code class=&quot;language-text&quot;&gt;less-loader&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// the rest of webpack config&lt;/span&gt;
module&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;exports &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  module&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    rules&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
      &lt;span class=&quot;token comment&quot;&gt;// the rest of loaders setup&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        test&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token regex&quot;&gt;/\.less$/&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        use&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
          &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            loader&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;style-loader&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            loader&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;css-loader&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            loader&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;less-loader&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            options&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
              lessOptions&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                modifyVars&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                  &lt;span class=&quot;token comment&quot;&gt;// override antd default styles&lt;/span&gt;
                  &lt;span class=&quot;token string&quot;&gt;&apos;primary-color&apos;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;#003dff&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                  &lt;span class=&quot;token string&quot;&gt;&apos;dark-color&apos;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;#38b6ab&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                  &lt;span class=&quot;token string&quot;&gt;&apos;font-family&apos;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Inter&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                javascriptEnabled&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
              &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;Setup babel to inject CSS&lt;/h2&gt;
&lt;p&gt;The second optimization I added was to extract only those styles that are used by antd components inside
my application via &lt;a href=&quot;https://www.npmjs.com/package/babel-plugin-import&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;babel-plugin-import&lt;/a&gt;. You can see
the recommended configuration of this plugin below:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;json&quot;&gt;&lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// rest of .babelrc&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;plugins&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
      &lt;span class=&quot;token string&quot;&gt;&quot;import&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token property&quot;&gt;&quot;libraryName&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;antd&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token property&quot;&gt;&quot;style&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;Summary &amp;#x26; TL;DR&lt;/h3&gt;
&lt;p&gt;In this blog post, I wrote on how to override &lt;a href=&quot;https://ant.design/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;antd&lt;/a&gt; theme without importing
whole library styles and how to use only those styles that are actually used in your application.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Setting up webpack for chrome extension development]]></title><description><![CDATA[Today I learned how to setup webpack for chrome extension development.
In this post I will show you how I did it. To start, you need to…]]></description><link>https://krzysztofzuraw.com/blog/2020/setting-up-chrome-extension-dev</link><guid isPermaLink="false">https://krzysztofzuraw.com/blog/2020/setting-up-chrome-extension-dev</guid><pubDate>Fri, 18 Sep 2020 11:18:50 GMT</pubDate><content:encoded>&lt;p&gt;Today I learned how to setup &lt;a href=&quot;https://webpack.js.org/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;webpack&lt;/a&gt; for chrome extension development.
In this post I will show you how I did it. To start, you need to install webpack and packages
from webpack ecosystem:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; --save-dev webpack webpack-cli html-webpack-plugin clean-webpack-plugin copy-webpack-plugin&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;First step done - now it is getting tricky. How to lay out development &amp;#x26; production config to avoid
nested ternary operators as you don’t want to spend 3 days setting up everything?&lt;/p&gt;
&lt;p&gt;Create &lt;code class=&quot;language-text&quot;&gt;webpack.common.js&lt;/code&gt;. Here you gonna put common settings that will be used by both development &amp;#x26; production config:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; path &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;path&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; HtmlWebpackPlugin &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;html-webpack-plugin&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; CleanWebpackPlugin &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;clean-webpack-plugin&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; CopyWebpackPlugin &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;copy-webpack-plugin&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

module&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;exports &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  entry&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; popup&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./src/popup/index.tsx&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; background&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./src/background/index.ts&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  module&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    rules&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; test&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token regex&quot;&gt;/\.tsx?$/&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; use&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;ts-loader&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; exclude&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token regex&quot;&gt;/node_modules/&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// do not forget to change/install your own TS loader&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  resolve&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    extensions&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;.tsx&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;.ts&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;.js&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  plugins&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;CleanWebpackPlugin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; cleanStaleWebpackAssets&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;HtmlWebpackPlugin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; template&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;src/popup/index.html&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;CopyWebpackPlugin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      patterns&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./src/manifest.json&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./src/icons/icon16.png&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./src/icons/icon48.png&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./src/icons/icon128.png&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  output&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; filename&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;[name].js&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; path&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; path&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;resolve&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;__dirname&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;dist&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// chrome will look for files under dist/* folder&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Config above have 2 entry points - because I am using both popup and background scripts.&lt;/p&gt;
&lt;p&gt;Webpack’s development config is a merge between &lt;code class=&quot;language-text&quot;&gt;common&lt;/code&gt; &amp;#x26; &lt;code class=&quot;language-text&quot;&gt;dev&lt;/code&gt; configs:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; merge &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;webpack-merge&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; common &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;./webpack.common.js&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

module&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;exports &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;merge&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;common&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  mode&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;development&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  devtool&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;inline-source-map&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Prod configuration is following the same pattern:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; merge &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;webpack-merge&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; common &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;./webpack.common.js&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

module&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;exports &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;merge&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;common&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  mode&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;production&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Lastly I have two commands for webpack&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;json&quot;&gt;&lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;scripts&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;start&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;webpack --watch --config webpack.dev.js&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;build&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;webpack --config webpack.prod.js&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Below you have diagram presenting how &lt;code class=&quot;language-text&quot;&gt;npm start&lt;/code&gt; is working under the hood&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto;  max-width: 590px;&quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/488115076108e1ff5e73953bc9fb1d04/f663d/webpack-watch.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 54.72972972972974%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAAAsSAAALEgHS3X78AAABAElEQVQoz5VSi2rDMAz0///hBiusGy3p0lcaJ37fdGrMYEuzVCAsv3Q66Qx+mQ8Z+4PD6RLwdfTYNQ7na9D9536E8xlLZvjweos4nu+fvHzobcQwJtghSZwwunvc9RFWznnHsxCzAgzTWZBiDCuKchEmL6UoUl1rXPc5F3RSQNM6Bbl0AQdh0rQeNwE0eMJq0pTKY8oVfY3XCsnkEQuztqq6sk+skInpMf0AaIXPJGMiOlXwsumx3Y14e7c6fSpBhzL3eY6qSmqSDIfSnryqg4k4caqEw12VkO4nqv+ZmaM4R70XiSwB/hlKTUbxsi8f0hf2if3ZbC1eJXYuLwLTvgEq2mM5yqh7pQAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;How npm start is working under the hood&quot;
        title=&quot;How npm start is working under the hood&quot;
        src=&quot;/static/488115076108e1ff5e73953bc9fb1d04/fcda8/webpack-watch.png&quot;
        srcset=&quot;/static/488115076108e1ff5e73953bc9fb1d04/12f09/webpack-watch.png 148w,
/static/488115076108e1ff5e73953bc9fb1d04/e4a3f/webpack-watch.png 295w,
/static/488115076108e1ff5e73953bc9fb1d04/fcda8/webpack-watch.png 590w,
/static/488115076108e1ff5e73953bc9fb1d04/efc66/webpack-watch.png 885w,
/static/488115076108e1ff5e73953bc9fb1d04/c83ae/webpack-watch.png 1180w,
/static/488115076108e1ff5e73953bc9fb1d04/f663d/webpack-watch.png 1511w&quot;
        sizes=&quot;(max-width: 590px) 100vw, 590px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;All you need to do after running &lt;code class=&quot;language-text&quot;&gt;npm start&lt;/code&gt; is to tell chrome that there is unpacked extension in the &lt;code class=&quot;language-text&quot;&gt;dist/*&lt;/code&gt; folder. To do that you need to go to &lt;code class=&quot;language-text&quot;&gt;chrome://extensions/&lt;/code&gt; and select options which are visible in the picture below (numbers indicate ordered selection of buttons/switches):&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto;  max-width: 590px;&quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/1547ac50c1339b21fb5e5c8018c5dc6f/39148/load-ext.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 35.810810810810814%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAYAAAAIy204AAAACXBIWXMAAAsSAAALEgHS3X78AAABmklEQVQozzWR2W7bMBBF9Rt1Y7teYknWSi2UZG20vFSxHQduijy0CIqiRf//D05pAXkg5oKYGV7eY5RVS6N23KvMSlrVkaQSKTPiSJBlEtU0tHWNTFNyKdkU+XCiOMVxQ+IkR3UH+r7HiJMM1XasvRDb8SmKktPTE/3zK93pB/vrL/rvf7m8/eNwfWd7/snx9puv3/5Q1DtWpo219vB9oRdvMBaPa2zbx7Q8lqZHKGJa7WijesrTO1Z8ZOoqFuGOrHvFzU/M/A5bnohkzWy+ZLZYMZ7MBjPGSIvEsrgVGaZ2mecFSm2165a6LPDdNZ5jD1UmESLwBh0Ln6ZpqRpFmhV8Go25vtwwpl8WrFY2YSgQOotNpdh2O6qqoaobPC/AcTxc19dfSgl0312HYUTddOTVljBKGD1MOV+ueuF0zqPp4AsdsB9RbCr2+wNlWdG2CiEigiAYHswyDSpOEFrHGsg9/5W1HuYepkvO52eM8WSuSWkYZU2kG/wgHIZDveju6IN4+kFe36m2Qe7eCIojIooRsWT0ecLl8sJ/gsbkaK/ReKgAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;Load unpacked extension configuration&quot;
        title=&quot;Load unpacked extension configuration&quot;
        src=&quot;/static/1547ac50c1339b21fb5e5c8018c5dc6f/fcda8/load-ext.png&quot;
        srcset=&quot;/static/1547ac50c1339b21fb5e5c8018c5dc6f/12f09/load-ext.png 148w,
/static/1547ac50c1339b21fb5e5c8018c5dc6f/e4a3f/load-ext.png 295w,
/static/1547ac50c1339b21fb5e5c8018c5dc6f/fcda8/load-ext.png 590w,
/static/1547ac50c1339b21fb5e5c8018c5dc6f/efc66/load-ext.png 885w,
/static/1547ac50c1339b21fb5e5c8018c5dc6f/c83ae/load-ext.png 1180w,
/static/1547ac50c1339b21fb5e5c8018c5dc6f/39148/load-ext.png 2876w&quot;
        sizes=&quot;(max-width: 590px) 100vw, 590px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;In today’s blog post I described setting up webpack for browser’s extension development.
You can check a working example in my latest side project - &lt;a href=&quot;https://github.com/krzysztofzuraw/rabat&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;rabat&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[RxJS and auth token expiration timers]]></title><description><![CDATA[Recently in my work, I stumbled upon an interesting problem to solve. I needed to inform users that they have
a valid token only for the…]]></description><link>https://krzysztofzuraw.com/blog/2020/rxjs-auth-expiration-timers</link><guid isPermaLink="false">https://krzysztofzuraw.com/blog/2020/rxjs-auth-expiration-timers</guid><pubDate>Fri, 21 Aug 2020 14:50:01 GMT</pubDate><content:encoded>&lt;p&gt;Recently in my work, I stumbled upon an interesting problem to solve. I needed to inform users that they have
a valid token only for the next 10 minutes and after that 10 minutes logout them.
You can see the user flow with more details on the illustration below.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto;  max-width: 590px;&quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/f79a01592f60e7098fbb863bbc0546d9/2a50e/token-flow.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 25.675675675675674%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAFCAIAAADKYVtkAAAACXBIWXMAAAsSAAALEgHS3X78AAAAkUlEQVQY022OQQrDIBREvf/9guCyG41gFDU2mNj2tZJUSmfxUf/Mc8Tznx6nOMcYlVLTNEkp13UdbeI4jmVZcGzbVmvl2lq7EPePQgjW2lIKK2zfMA4y+74T6+7bqZTSBeosJo/GGHCwxFgDK8Vowcw592+Bjh7vPVzy7zCdtda0mue5F/vBYWDrnGPCoua1fQH89yHGcJwS+wAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;Expiration token flow&quot;
        title=&quot;Expiration token flow&quot;
        src=&quot;/static/f79a01592f60e7098fbb863bbc0546d9/fcda8/token-flow.png&quot;
        srcset=&quot;/static/f79a01592f60e7098fbb863bbc0546d9/12f09/token-flow.png 148w,
/static/f79a01592f60e7098fbb863bbc0546d9/e4a3f/token-flow.png 295w,
/static/f79a01592f60e7098fbb863bbc0546d9/fcda8/token-flow.png 590w,
/static/f79a01592f60e7098fbb863bbc0546d9/efc66/token-flow.png 885w,
/static/f79a01592f60e7098fbb863bbc0546d9/c83ae/token-flow.png 1180w,
/static/f79a01592f60e7098fbb863bbc0546d9/2a50e/token-flow.png 2352w&quot;
        sizes=&quot;(max-width: 590px) 100vw, 590px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;For this use case, I decided to use a &lt;a href=&quot;https://redux-observable.js.org/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;redux-observable&lt;/a&gt; - in this blog
post, I will write how I did it. I assume that you are familiar with the &lt;a href=&quot;https://rxjs-dev.firebaseapp.com/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;RxJS&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Why the RxJS and not other redux middleware was used for async actions? To be honest it was my personal preference
and this library includes helper functions that are perfect for this use case.&lt;/p&gt;
&lt;p&gt;Going back to the topic - let’s start with the first event - user logs in.&lt;/p&gt;
&lt;h2&gt;User logs in&lt;/h2&gt;
&lt;p&gt;I used &lt;a href=&quot;https://auth0.com/docs/libraries/lock&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Auth0 lock&lt;/a&gt; as an entry point to my application.
When the user enters login &amp;#x26; password then is redirected back with &lt;a href=&quot;https://jwt.io/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;JWT token&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Read expiration time from token&lt;/h2&gt;
&lt;p&gt;JWT token has handy information about its expiration time.
I have used &lt;a href=&quot;https://www.npmjs.com/package/jwt-decode&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;jwt-decode&lt;/a&gt; to decode a token and to extract expiration
time. If you are using TypeScript you need to type what is inside the token:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;tsx&quot;&gt;&lt;pre class=&quot;language-tsx&quot;&gt;&lt;code class=&quot;language-tsx&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; jwtDecode &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;jwt-decode&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; decodedToken &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;jwtDecode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;authToken&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;When it comes to date manipulation I have used &lt;a href=&quot;https://date-fns.org/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;date-fns&lt;/a&gt;.
Firstly, I converted &lt;code class=&quot;language-text&quot;&gt;exp&lt;/code&gt; which is a UNIX timestamp to date and then
&lt;a href=&quot;https://date-fns.org/v2.15.0/docs/sub&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;sub&lt;/a&gt; function help me to get date 10 minutes before &lt;code class=&quot;language-text&quot;&gt;expirationDate&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;tsx&quot;&gt;&lt;pre class=&quot;language-tsx&quot;&gt;&lt;code class=&quot;language-tsx&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; fromUnixTime&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; sub &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;date-fns&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; expirationDate &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;fromUnixTime&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;decodedToken&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;exp&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; firstNotificationDate &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;sub&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;expirationDate&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; minutes&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;Epics&lt;/h2&gt;
&lt;p&gt;Now it is time to set up two &lt;a href=&quot;https://redux-observable.js.org/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;redux-observable&lt;/a&gt; epics.&lt;/p&gt;
&lt;p&gt;The first epic has one job: to dispatch notification action 10 minutes before &lt;code class=&quot;language-text&quot;&gt;expirationDate&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;tsx&quot;&gt;&lt;pre class=&quot;language-tsx&quot;&gt;&lt;code class=&quot;language-tsx&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; isActionOf &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;typesafe-actions&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; filter&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; delay&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; mergeMap&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; takeUntil &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;rxjs/operators&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;of&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;rxjs&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;setLogoutNotificationEpic&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;action$&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; state$&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt;
  action$&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pipe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;isActionOf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;setupAuthorization&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;mergeMap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;of&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;showLogoutNotification&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
          &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pipe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;delay&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;firstNotificationDate&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
          &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pipe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;takeUntil&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;action$&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pipe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;isActionOf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;logoutUser&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// unsubscribe when user logs out&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;RxJS has a handy helper for delaying action emission (in my case &lt;code class=&quot;language-text&quot;&gt;showLogoutNotification&lt;/code&gt;) called
&lt;a href=&quot;https://www.learnrxjs.io/learn-rxjs/operators/utility/delay&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;delay&lt;/a&gt;. What is neat about it? It can
take both the number of milliseconds and the date to delay stream of actions.
It has one bug though but more about it later.&lt;/p&gt;
&lt;p&gt;I had the first epic in place so I can create the second one. This epic main task is
to logout user (dispatch action to logout user to be precise) on the expiration date.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;tsx&quot;&gt;&lt;pre class=&quot;language-tsx&quot;&gt;&lt;code class=&quot;language-tsx&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;setLogoutEpic&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;action$&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; state$&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt;
  action$&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pipe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;isActionOf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;setupAuthorization&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;mergeMap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;of&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;logoutUser&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pipe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;delay&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;tokenExpirationDate&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pipe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
          &lt;span class=&quot;token function&quot;&gt;takeUntil&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;action$&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pipe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;isActionOf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;authActions&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;logoutUser&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// unsubscribe when user logs out&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As you can see only actions and data passed to &lt;code class=&quot;language-text&quot;&gt;delay&lt;/code&gt; is different from the previous example.&lt;/p&gt;
&lt;p&gt;You may ask why do I need to have those delays inside two different epics. It is because of the
&lt;a href=&quot;https://github.com/ReactiveX/rxjs/issues/5232&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;bug&lt;/a&gt; in RxJS. Long story short - when you have two
delays inside the same epic they will not work. I took this opportunity and I made my code more
readable (at least I think I did).&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;I wrote a blog post on how to use the RxJS &lt;a href=&quot;https://www.learnrxjs.io/learn-rxjs/operators/utility/delay&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;delay&lt;/a&gt;
operator to dispatch two actions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;10 minutes before JWT token expires,&lt;/li&gt;
&lt;li&gt;when JWT token expires.&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[How to setup emotion css prop to work with Parcel & TypeScript]]></title><description><![CDATA[In this blog post I will look into how to setup Emotion 
with Parcel & TypeScript.
There are two ways those tools work with each other.
You…]]></description><link>https://krzysztofzuraw.com/blog/2020/emotion-css-prop-parcel-typescript</link><guid isPermaLink="false">https://krzysztofzuraw.com/blog/2020/emotion-css-prop-parcel-typescript</guid><pubDate>Sat, 08 Aug 2020 11:05:06 GMT</pubDate><content:encoded>&lt;p&gt;In this blog post I will look into how to setup &lt;a href=&quot;https://emotion.sh/docs/introduction&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Emotion&lt;/a&gt; &lt;code class=&quot;language-text&quot;&gt;css prop&lt;/code&gt;
with &lt;a href=&quot;https://parceljs.org/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Parcel&lt;/a&gt; &amp;#x26; &lt;a href=&quot;https://www.typescriptlang.org/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;TypeScript&lt;/a&gt;.
There are two ways those tools work with each other.
You can either use &lt;code class=&quot;language-text&quot;&gt;/** @jsx jsx */&lt;/code&gt; pragma on every file you want to
use &lt;code class=&quot;language-text&quot;&gt;css prop&lt;/code&gt; or you can tell babel to do it for you.
I’m a bit lazy so I prefer the second option. Below you will find a quick guide on how to do it.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Create the &lt;code class=&quot;language-text&quot;&gt;.babelrc&lt;/code&gt; file inside the root of your repository. Put the following contents inside:&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;json&quot;&gt;&lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;plugins&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;transform-inline-environment-variables&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
      &lt;span class=&quot;token string&quot;&gt;&quot;babel-plugin-jsx-pragmatic&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token property&quot;&gt;&quot;export&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;jsx&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token property&quot;&gt;&quot;module&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;@emotion/core&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token property&quot;&gt;&quot;import&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;___EmotionJSX&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
      &lt;span class=&quot;token string&quot;&gt;&quot;@babel/plugin-transform-react-jsx&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token property&quot;&gt;&quot;pragma&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;___EmotionJSX&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token property&quot;&gt;&quot;pragmaFrag&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;React.Fragment&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;emotion&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In essence you are telling babel to add &lt;a href=&quot;https://www.gatsbyjs.org/blog/2019-08-02-what-is-jsx-pragma/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;jsx-pragma&lt;/a&gt;
when you are using &lt;code class=&quot;language-text&quot;&gt;css prop&lt;/code&gt;. If you want to know more I recommend &lt;a href=&quot;https://github.com/emotion-js/emotion/issues/1132&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;this issue&lt;/a&gt; on github.&lt;/p&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;Edit tsconfig with jsx &amp;#x26; types&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;json&quot;&gt;&lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;compilerOptions&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// the rest of configuration&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;jsx&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;preserve&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// for babel to work&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;types&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;@emotion/core&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// you can now use css prop on e.g div and TypeScript won&apos;t shout at you&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ol start=&quot;3&quot;&gt;
&lt;li&gt;Let parcel install needed deps. Run command for building your parcel project.
Parcel is smart enough to install needed dependencies by yourself. If you happen to get an error:
&lt;code class=&quot;language-text&quot;&gt;Conflicting babel versions found in .babelrc. Make sure all of your plugins and presets depend on the same major version of babel.&lt;/code&gt;
I recommend to add &lt;code class=&quot;language-text&quot;&gt;&amp;quot;@babel/core&amp;quot;: &amp;quot;7.10.5&amp;quot;&lt;/code&gt; as dev dependency inside package.json and run &lt;code class=&quot;language-text&quot;&gt;npm install&lt;/code&gt; again.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;In this blog post, I’ve looked into how to setup Emotion &lt;code class=&quot;language-text&quot;&gt;css prop&lt;/code&gt; with Parcel &amp;#x26; TypeScript. You can find
an example repo on my &lt;a href=&quot;https://github.com/krzysztofzuraw/parcel-emotion-typescript&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;github&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Cron under MacOS]]></title><description><![CDATA[I’m using plain text to store my information. This plain text is inside a git repo. To back it up I
need to commit changes & push them to…]]></description><link>https://krzysztofzuraw.com/blog/2020/cron-macos</link><guid isPermaLink="false">https://krzysztofzuraw.com/blog/2020/cron-macos</guid><pubDate>Wed, 22 Jul 2020 18:15:48 GMT</pubDate><content:encoded>&lt;p&gt;I’m using plain text to store my information. This plain text is inside a git repo. To back it up I
need to commit changes &amp;#x26; push them to the remote. I was doing that manually. Yet this is not effective.
I decided to use cron for that. Every 30min I want to execute a script that backs up my wiki.
How to do that under mac?&lt;/p&gt;
&lt;h2&gt;Cron under MacOS&lt;/h2&gt;
&lt;p&gt;You cannot use cron. Instead Apple encourage to use &lt;a href=&quot;https://ss64.com/osx/launchctl.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;launchctl&lt;/a&gt;.
How to set up launchctl? At first you need to create plist file:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;xml&quot;&gt;&lt;pre class=&quot;language-xml&quot;&gt;&lt;code class=&quot;language-xml&quot;&gt;&lt;span class=&quot;token prolog&quot;&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&lt;/span&gt;
&lt;span class=&quot;token doctype&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;!&lt;/span&gt;&lt;span class=&quot;token doctype-tag&quot;&gt;DOCTYPE&lt;/span&gt; &lt;span class=&quot;token name&quot;&gt;plist&lt;/span&gt; &lt;span class=&quot;token name&quot;&gt;PUBLIC&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;-//Apple//DTD PLIST 1.0//EN&quot;&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;http://www.apple.com/DTDs/PropertyList-1.0.dtd&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;plist&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;version&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;1.0&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;dict&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Label&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;com.krzysztofzuraw.wikibackup&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;

  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;ProgramArguments&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;array&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;/Users/kzuraw/wiki/backup.sh&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- script location --&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;array&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;

  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Nice&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;integer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;1&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;integer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;

  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;StartInterval&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;integer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;1800&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;integer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- 30min --&gt;&lt;/span&gt;

  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;RunAtLoad&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;

  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;StandardErrorPath&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;/tmp/wikibackup.err&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;

  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;StandardOutPath&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;/tmp/wikibackup.out&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;dict&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;plist&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Maybe you wonder what is &lt;code class=&quot;language-text&quot;&gt;nice&lt;/code&gt; key? After a bit of searching, I found out that it is used for scheduling priority. You can read more about
it on &lt;a href=&quot;https://www.manpagez.com/man/3/nice/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;man&lt;/a&gt; page of &lt;code class=&quot;language-text&quot;&gt;nice&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Going back to configuration. For launchctl to pick up your configuration plist file has to be placed
under &lt;code class=&quot;language-text&quot;&gt;~/Library/LaunchAgents&lt;/code&gt;. I prefer to use already existing plist naming convention: &lt;code class=&quot;language-text&quot;&gt;com.YOURNAME.CONFIGURATION_NAME.plist&lt;/code&gt;
I named my plist as &lt;code class=&quot;language-text&quot;&gt;com.krzysztofzuraw.wikibackup.plist&lt;/code&gt;. If you have this setup execute &lt;code class=&quot;language-text&quot;&gt;launchctl load com.krzysztofzuraw.wikibackup.plist&lt;/code&gt;.
Similarly if you need to unload it you can use &lt;code class=&quot;language-text&quot;&gt;launchctl unload com.krzysztofzuraw.wikibackup.plist&lt;/code&gt;.
To see which launchctl scripts are running try &lt;code class=&quot;language-text&quot;&gt;launchctl list&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;My &lt;code class=&quot;language-text&quot;&gt;lanuchctl&lt;/code&gt; script is running but how does &lt;code class=&quot;language-text&quot;&gt;backup.sh&lt;/code&gt; looks like?&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token shebang important&quot;&gt;#!/bin/zsh&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;cd&lt;/span&gt; ~/wiki &lt;span class=&quot;token comment&quot;&gt;# script still needs to enter folder even if backup script is inside the wiki&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; &lt;span class=&quot;token builtin class-name&quot;&gt;.&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; commit -a -m &lt;span class=&quot;token string&quot;&gt;&quot;updated on &lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;date&lt;/span&gt; +&lt;span class=&quot;token string&quot;&gt;&apos;%Y%m%d%H%M&apos;&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; push origin master&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;If you see to set up cron jobs under MacOS - use &lt;a href=&quot;https://ss64.com/osx/launchctl.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;launchctl&lt;/a&gt;. You
can read more at &lt;a href=&quot;https://alvinalexander.com/mac-os-x/mac-osx-startup-crontab-launchd-jobs/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Mac crontab: Creating MacOS startup jobs with crontab, er, launchd&lt;/a&gt;.
Original idea from &lt;a href=&quot;https://thelinell.com/using-vimwiki/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Using VimWiki&lt;/a&gt;.&lt;/p&gt;</content:encoded></item></channel></rss>