<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Blue Tomato Dev</title>
    <description>The latest articles on DEV Community by Blue Tomato Dev (@btdev).</description>
    <link>https://dev.to/btdev</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Forganization%2Fprofile_image%2F139%2F95276616-c634-4a46-80dd-12c281692945.jpg</url>
      <title>DEV Community: Blue Tomato Dev</title>
      <link>https://dev.to/btdev</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/btdev"/>
    <language>en</language>
    <item>
      <title>For fun and learning: playing around with JavaScript face detection and html5 canvas</title>
      <dc:creator>Markus Tiefenbacher</dc:creator>
      <pubDate>Fri, 10 Apr 2020 11:36:52 +0000</pubDate>
      <link>https://dev.to/btdev/for-fun-and-learning-playing-around-with-javascript-face-detection-and-html5-canvas-3km4</link>
      <guid>https://dev.to/btdev/for-fun-and-learning-playing-around-with-javascript-face-detection-and-html5-canvas-3km4</guid>
      <description>&lt;p&gt;It’s easter and wanted to make some fun for my coworkers and what should be better than some Covid-19 fun in this surreal times.&lt;/p&gt;

&lt;p&gt;I had the idea to put every model in our webshop a surgical mask on their face.&lt;/p&gt;

&lt;p&gt;But how should I solve this?&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Face Detection!&lt;/em&gt;&lt;br&gt;
This was a topic I ever wanted to discover and so it was a perfect match for this. I started reading the &lt;a href="https://github.com/justadudewhohacks/face-api.js" rel="noopener noreferrer"&gt;face-api.js&lt;/a&gt; documentation and after some hours of playing around with it I was ready to ship the easter egg on our testing server.&lt;/p&gt;

&lt;h2&gt;
  
  
  Result:
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Flctgbucs7ik46v48bfrr.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Flctgbucs7ik46v48bfrr.jpg" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it yourself:
&lt;/h2&gt;

&lt;p&gt;I made also a version where you can try it yourself: &lt;a href="https://tiefenb.github.io/use-a-mask/" rel="noopener noreferrer"&gt;https://tiefenb.github.io/use-a-mask/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;... and here are the source code: &lt;a href="https://github.com/tiefenb/use-a-mask" rel="noopener noreferrer"&gt;https://github.com/tiefenb/use-a-mask&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Reactions so far:
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fm07frd0hxpro04cock0g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fm07frd0hxpro04cock0g.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Learnings:
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image" rel="noopener noreferrer"&gt;Loading images for HTML5 canvas is only possible with images with crossorigin attribute&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;crossorigin attribute has to be set on the image tag before the image is loaded - it’s not possible afterwards. That means also, if you create the image element with JavaScript you have to add the crossorigin-attribute before the src-attribute.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://stackoverflow.com/a/16546061/1156058" rel="noopener noreferrer"&gt;Rotating an single image in html5 canvas is not possible in the way most of us think. you have to rotate the canvas-context, than you put on the canvas the image and you rotate the canvas-context back to your normal angle&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://stackoverflow.com/a/15504471/1156058" rel="noopener noreferrer"&gt;Putting an image on a canvas is only possible after the image is full loaded - so you have to listen in the image.onload event&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;face-api.js tensorflow.js-models are quite big - better to make detection it on the server not the client&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Thank's for reading and happy easter!&lt;/p&gt;

</description>
      <category>facedetectionhtml5canvas</category>
    </item>
    <item>
      <title>Dear appear.js, I have met someone new. Her name is IntersectionObserver.</title>
      <dc:creator>Markus Tiefenbacher</dc:creator>
      <pubDate>Tue, 14 May 2019 13:19:10 +0000</pubDate>
      <link>https://dev.to/btdev/dear-appear-js-i-have-met-someone-new-her-name-is-intersectionobserver-5h01</link>
      <guid>https://dev.to/btdev/dear-appear-js-i-have-met-someone-new-her-name-is-intersectionobserver-5h01</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F2lmg5c5gnm74vdbq332a.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F2lmg5c5gnm74vdbq332a.jpg" alt="appear.js IntersectionObserver Meme"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Dear &lt;a href="https://creativelive.github.io/appear/" rel="noopener noreferrer"&gt;appear.js&lt;/a&gt;, I have met someone new. It was more or less a good time with you. But I want to break up and you have to leave your stack.&lt;/p&gt;

&lt;p&gt;The new one? Her name's IntersectionObserver. She is nice to me. She is smart, pretty syntax and very fast in doing things. I think I will have a good time with her.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Enough with joking.&lt;/strong&gt;&lt;br&gt;
At blue-tomato.com, we used some &lt;a href="https://appelsiini.net/projects/lazyload/v1/" rel="noopener noreferrer"&gt;jQuery based image lazy loading library&lt;/a&gt; and &lt;a href="https://creativelive.github.io/appear/" rel="noopener noreferrer"&gt;appear.js&lt;/a&gt; for lazyloading things and doing effect based on elements in the viewpoint.&lt;/p&gt;

&lt;p&gt;Both libraries listen on the scroll event and looking if the actual scroll position is in the range of the given elements position.&lt;/p&gt;

&lt;p&gt;This technic was the default for long time, but since IntersectionObserver comes up, it was clear to switch sometimes to this. The main problem with the old method was the listing on the scroll-event was very expensive to browser performance.&lt;/p&gt;
&lt;h2&gt;
  
  
  Example
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Making a navigation bar sticky with appear.js
&lt;/h3&gt;

&lt;p&gt;In this example, after the &lt;code&gt;.main-content&lt;/code&gt; became visible, the &lt;code&gt;.navigation&lt;/code&gt; bar will get the CSS class &lt;code&gt;.navigation--sticky&lt;/code&gt; and will become sticky. When &lt;code&gt;.main-content&lt;/code&gt; disappers (e.g. by scrolling back to the top of the page) the &lt;code&gt;.navigation&lt;/code&gt; bar will become static by removing the &lt;code&gt;.navigation--sticky&lt;/code&gt; class.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;appear&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;elements&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;elements&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelectorAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.main-content&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;appear&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;appear&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.navigation&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;addClass&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.navigation--sticky&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;disappear&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;appear&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.navigation&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;removeClass&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.navigation--sticky&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Making a navigation bar sticky with InteractionObserver
&lt;/h3&gt;

&lt;p&gt;With InteractionObserver this would work in this way:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;element&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.main-content&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;observer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;IntersectionObserver&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;entries&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;entries&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;element&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;intersectionRatio&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.navigation&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;addClass&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.navigation--sticky&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.navigation&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;removeClass&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.navigation--sticky&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;rootMargin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;0px 0px&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;threshold&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.00&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nx"&gt;observer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;observe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Whats that rootMargin and thresold?
&lt;/h2&gt;

&lt;p&gt;Appear.js has only some "bounds" option to let it fire some pixels before the element is really in the viewport. IntersectionObserver has a really powerful and flexible method to control this via the root/rootMargin and thresold options. Have an eye on this article from Smashing Magazine where Denys Mishonnuc explains this very detailed: &lt;a href="https://www.smashingmagazine.com/2018/01/deferring-lazy-loading-intersection-observer-api/#intersectionobserver-initialization" rel="noopener noreferrer"&gt;https://www.smashingmagazine.com/2018/01/deferring-lazy-loading-intersection-observer-api/#intersectionobserver-initialization&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>performance</category>
      <category>webdev</category>
      <category>breakup</category>
    </item>
    <item>
      <title>src/.../styled.js - stairway to Styled-Component's CSS-in-JS heaven</title>
      <dc:creator>Manuel Penaloza</dc:creator>
      <pubDate>Tue, 08 Jan 2019 10:30:39 +0000</pubDate>
      <link>https://dev.to/btdev/srcstyledjs---stairway-to-styled-components-css-in-js-heaven-5cgf</link>
      <guid>https://dev.to/btdev/srcstyledjs---stairway-to-styled-components-css-in-js-heaven-5cgf</guid>
      <description>&lt;p&gt;Using a fabulous open source library like &lt;a href="https://github.com/styled-components/styled-components" rel="noopener noreferrer"&gt;Styled-Components&lt;/a&gt; often comes with the nice effect of appreciating what you can do with it more and more and more. If you are like me, at some point you get curious about what happens behind the (library-)scenes. I recently checked the Styled-Components Github repository to know better what's going on when using the library. As you can imagine the library does A LOT of cool things, so in the first attempt I limited my investigations to the library's &lt;em&gt;practical&lt;/em&gt; entry point.&lt;/p&gt;

&lt;p&gt;Remember, creating a styled component with the Styled-Components library is as simple as a that...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Button&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="s2"&gt;`
    font-size: 14px;
`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;...or as that&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;BorderedButton&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;`
  border: 2px solid white;
`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Please pay special attention to the differences of how the &lt;code&gt;styled&lt;/code&gt; function is used in the examples above.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;we call &lt;code&gt;a&lt;/code&gt; as a method of the &lt;code&gt;styled&lt;/code&gt; object passing it css as an argument&lt;/li&gt;
&lt;li&gt;we call the &lt;code&gt;styled&lt;/code&gt; function passing it the previously created styled component as an argument and add css as a next argument&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So how does the library provide that exposed possibilities for us? Let's take a look.&lt;/p&gt;

&lt;h2&gt;
  
  
  A CSS-in-JS holy grail named &lt;em&gt;styled&lt;/em&gt;
&lt;/h2&gt;

&lt;p&gt;Theoretically and taking into account Styled-Component's &lt;code&gt;package.json&lt;/code&gt; information, the technical runtime entry point to the library is the &lt;a href="https://github.com/styled-components/styled-components/blob/7dd09fd595611a5805b76eab2fbae6f90877340f/src/index.js" rel="noopener noreferrer"&gt;src/index.js&lt;/a&gt; file. But that said, the practical entry point enabling us to do all the cool things is the &lt;a href="https://github.com/styled-components/styled-components/blob/613480a612fe942d1b1298581c94122de880d65e/src/constructors/styled.js" rel="noopener noreferrer"&gt;styled.js file&lt;/a&gt; being part of the &lt;code&gt;/src/constructors&lt;/code&gt; directory. Next see what this file looks like (status 01/2019, branch master):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F8hrfkganpw1qmb491ekh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F8hrfkganpw1qmb491ekh.png" title="Styled-Components styled.js file" alt="Styled-Components styled.js file"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In a nutshell this file does the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;some internal imports (lines 2-4)&lt;/li&gt;
&lt;li&gt;one &lt;code&gt;const styled&lt;/code&gt; declaration referencing a function (line 8)&lt;/li&gt;
&lt;li&gt;one forEach loop (lines 11-13)&lt;/li&gt;
&lt;li&gt;finally the export of our holy grail &lt;code&gt;styled&lt;/code&gt; 🎉 (line 15)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The styled function and its function object methods
&lt;/h2&gt;

&lt;p&gt;Confused of that headline? Remember, in Javascript functions are objects! As a result developers can make use of this by i.e. adding methods to that function object. Styled-Components and the real entry point returned by &lt;code&gt;styled.js&lt;/code&gt; makes heavy use of this. Line 8 shows a &lt;code&gt;const styled&lt;/code&gt; declaration referencing a function, but more on that later. For now just keep in mind that a function referenced by the &lt;code&gt;styled&lt;/code&gt; const was created. Now take a special look at the lines &lt;em&gt;11 to 13&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F0qdlexyccjzdqnoeycsj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F0qdlexyccjzdqnoeycsj.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;We see a forEach loop iterating an &lt;a href="https://github.com/styled-components/styled-components/blob/master/src/utils/domElements.js" rel="noopener noreferrer"&gt;array of defined domElements.&lt;/a&gt; Each iteration attaches a method with the name of the iterated dom element to the &lt;code&gt;styled&lt;/code&gt; function object.&lt;/strong&gt; And voilá! There it is, the first hard-working component factory attaching dom element methods to the &lt;code&gt;styled&lt;/code&gt; function object like a boss. The body of each attached method is nothing else than the result of a &lt;code&gt;styled&lt;/code&gt; function call returning a properly built component constructor for each dom node. Having reached this point at runtime we can already call such an attached method like this in our own codebase:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Button&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="s2"&gt;`
    ...this will be the method argument in the form of css to the styled.a call...
`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Container&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="s2"&gt;`
    ...this will be the method argument in the form of css to the styled.div call...
`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So far we know (some kind of) what's going on when we use &lt;code&gt;styled.a&lt;/code&gt; or &lt;code&gt;styled.div&lt;/code&gt; in our codebases using Styled-Components. That said we've gone "half the way" to demystify what styled.js exports for us. Remember when I wrote &lt;em&gt;"Line 8 shows a &lt;code&gt;const styled&lt;/code&gt; declaration referencing a function, but more on that later."&lt;/em&gt;? It is that function we need to talk about more right now to demystify the other half. Here we go.&lt;/p&gt;

&lt;h2&gt;
  
  
  The &lt;em&gt;styled&lt;/em&gt; function: how it's constructed and distributed
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Constructed&lt;/em&gt; and &lt;em&gt;distributed&lt;/em&gt;? Yes!&lt;br&gt;
As you can see in line 8, &lt;code&gt;styled&lt;/code&gt; itself is declared as a function. It is either called directly by us developers using the &lt;strong&gt;distributed&lt;/strong&gt; default export of the &lt;code&gt;styled&lt;/code&gt; function or by calling the function object method which requires internal &lt;strong&gt;construction&lt;/strong&gt; as described above. So in concrete this means for us:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fix5dnqsh624jive341ac.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fix5dnqsh624jive341ac.png"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Container&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;div&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;` ...css... `&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Container&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="s2"&gt;` ...css... `&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;returnes exactly the same. But remember: we can conveniently use the second option in our codebase, as Styled-Components takes care of building the proper component constructor executing first option internally to add the function object method (here: &lt;code&gt;.div&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;styled&lt;/code&gt; function takes a &lt;code&gt;tag&lt;/code&gt; as a parameter and returns the result of calling the function &lt;code&gt;constructWithOptions&lt;/code&gt; (line 8) which receives two arguments.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;a &lt;code&gt;StyledComponent&lt;/code&gt; function&lt;/strong&gt; - 
Have you noticed I never mentioned &lt;code&gt;React&lt;/code&gt; in this post so far? Well, here we go. Let's not forget Styled-Components is part of the &lt;code&gt;React&lt;/code&gt; ecosystem. As a result this &lt;code&gt;StyledComponent&lt;/code&gt; argument is used to actually create a React component giving access to React &lt;em&gt;EventHandlers&lt;/em&gt; and all the other cool things React does for us.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;the &lt;code&gt;tag&lt;/code&gt; we've passed to the &lt;code&gt;styled&lt;/code&gt; function&lt;/strong&gt; - 
The argument is of type &lt;code&gt;Target&lt;/code&gt; which is either a dom node string or an already styled component. Check &lt;a href="https://github.com/styled-components/styled-components/blob/master/src/types.js#L16" rel="noopener noreferrer"&gt;this line&lt;/a&gt; to find the origin of how the &lt;code&gt;Target&lt;/code&gt; type is defined using Flow. The &lt;code&gt;tag&lt;/code&gt; argument is simply passed through to &lt;code&gt;constructWithOptions&lt;/code&gt; without any modifications.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Receiving these two arguments, the &lt;code&gt;constructWithOptions()&lt;/code&gt; function execution returns another function that let's us create a styled component already considering the &lt;code&gt;tag&lt;/code&gt; we want to use in our codebase. Using the returned function in the most basic form, the only thing to we need to pass it is pure &lt;em&gt;css&lt;/em&gt; within a tagged template literal argument. Check out &lt;a href="https://mxstbr.blog/2016/11/styled-components-magic-explained/" rel="noopener noreferrer"&gt;this post of Max Stoiber&lt;/a&gt; in case you want to go into detail about how this part of Javascript works.&lt;/p&gt;

&lt;p&gt;So to close the cycle of &lt;code&gt;styled.js&lt;/code&gt;... Now as we know what the styled function returns and how it is distributed or used for internal construction, we also know better what the different method bodies of the &lt;code&gt;styled&lt;/code&gt; function object methods do. &lt;code&gt;styled.a&lt;/code&gt; works as the &lt;code&gt;styled(domElement)&lt;/code&gt; execution in line 12 of styled.js &lt;strong&gt;distributes&lt;/strong&gt; a "tag-predefined" styled component constructor to it! 🎉&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fej1oi2gi6kydqoye62y8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fej1oi2gi6kydqoye62y8.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Thx for reading!
&lt;/h2&gt;

&lt;p&gt;As you can see, &lt;code&gt;styled&lt;/code&gt; provides a lot of things. On the one hand a function, on the other hand it acts as an object providing predefined methods for each dom node to build styled components. In my opinion this approach the library provides us to style our components is pure gold.&lt;/p&gt;

&lt;p&gt;I hope this post helps you to better understand what styled.js does and how it exposes stuff we can use. Please note all information is based on the Styled-Component's master branch by Jan 2019. In case there'll be changes I don't notice, feel free to contact me in order to update this post.&lt;/p&gt;

&lt;p&gt;This post was &lt;a href="https://manpenaloza.dev/stairway-to-styled-components-css-in-js-heaven/" rel="noopener noreferrer"&gt;originally posted here&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>styledcomponents</category>
      <category>react</category>
      <category>cssinjs</category>
      <category>css</category>
    </item>
    <item>
      <title>What are those PeerDependencies in a NodeJS project?</title>
      <dc:creator>Manuel Penaloza</dc:creator>
      <pubDate>Fri, 30 Nov 2018 20:07:16 +0000</pubDate>
      <link>https://dev.to/btdev/what-are-those-peerdepenedencies-in-a-nodejs-project-51jo</link>
      <guid>https://dev.to/btdev/what-are-those-peerdepenedencies-in-a-nodejs-project-51jo</guid>
      <description>&lt;p&gt;&lt;em&gt;PeerDependencies&lt;/em&gt;, one of the terms that brought up confusion at least to me when I got a PeerDependency warning in my terminal like the following:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F3saoi2jo707mx6uzzqrg.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F3saoi2jo707mx6uzzqrg.jpg" title="NPM peer dependency warning" alt="alt text" width="563" height="170"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/dominictarr/event-stream/issues/116" rel="noopener noreferrer"&gt;Recent happenings about a malicious code attack in a node package&lt;/a&gt; that heavily include the topic of PeerDependencies finally made me that curious about this topic to start some deeper investigation about how PeerDependencies work. In this blog post I'll write down what I found out about NodeJS PeerDependencies in a way that also might help you to better understand this topic.&lt;/p&gt;

&lt;p&gt;Searching for &lt;code&gt;"What are peer dependencies"&lt;/code&gt; using Google - of course - returns some results. Nevertheless none of the main references Google returned made me understand PeerDependencies in way I was satisfied with. After some time I found this &lt;a href="https://stackoverflow.com/questions/26737819/why-use-peer-dependencies-in-npm-for-plugins/34645112#34645112" rel="noopener noreferrer"&gt;Stackoverflow Page&lt;/a&gt; including a great PeerDependency explanation of &lt;a href="https://stackoverflow.com/users/286685/stijn-de-witt" rel="noopener noreferrer"&gt;Stijn De Witt&lt;/a&gt;. His explanation came quite close to a version that made me understand the basics of PeerDependencies and brought up some imaginary "Aha!" moments  (Thank you Stijn!). But somehow and as I am more a visual learning type Stijn's "text-driven" Stackoverflow explanation did not bring up that imaginary last-mile satisfaction for me in terms of understanding PeerDependencies. As a result I draw some code around his explanation (you can see quoted below) and suddenly things became more clear to me.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's the problem?
&lt;/h2&gt;

&lt;p&gt;Upfront: in the upcoming example, &lt;code&gt;JillsModule&lt;/code&gt; will be the tricky part (subsequently the PeerDependency) of the process. That's why I added fictional version appends (@1.0, @2.0) when using it.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Let's say we are building &lt;code&gt;OurCoolProject&lt;/code&gt; and are using &lt;code&gt;JacksModule&lt;/code&gt; and &lt;code&gt;JillsModule@2.0&lt;/code&gt;. Also let's suppose that &lt;code&gt;JacksModule&lt;/code&gt; also depends on JillsModule, but on a different version, say &lt;code&gt;JillsModule@1.0&lt;/code&gt;. As long as those 2 versions don't meet, there is no problem. The fact that &lt;code&gt;JacksModule&lt;/code&gt; is using &lt;code&gt;JillsModule&lt;/code&gt; below the surface is just an implementation detail. We are bundling &lt;code&gt;JillsModule&lt;/code&gt; (as the code uses 2 different versions, but not related to each other (!)) twice, but that's a small price to pay when we get stable software out of the box.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In code this means something like&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// OurCoolProcject.js&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;JacksModule&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;jacksmodule&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nc"&gt;JillsModule&lt;/span&gt;&lt;span class="p"&gt;(@&lt;/span&gt;&lt;span class="nd"&gt;2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;jillsmodule(@2.0)&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;OurCoolProcject&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// do some stuff with JacksModule&lt;/span&gt;
    &lt;span class="c1"&gt;// do some stuff with JillsModule(@2.0). stuff won't break as we have the compatible @2.0 version of JillsModule available in this scope.&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;OurCoolProject&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// jacksmodule.js (an npm module)&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nc"&gt;JillsModule&lt;/span&gt;&lt;span class="p"&gt;(@&lt;/span&gt;&lt;span class="nd"&gt;1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;jillsmodule(@1.0)&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;JacksModule&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// do some stuff with JillsModule(@1.0). stuff won't break as we have the compatible @1.0 version of JillsModule available in this scope.&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;JacksModule&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But next this dependency relationship gets more tricky.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Now let's suppose that &lt;code&gt;JacksModule&lt;/code&gt; exposes its dependency on &lt;code&gt;JillsModule&lt;/code&gt; in some way. It accepts an &lt;code&gt;object instanceof JillsClass&lt;/code&gt; for example... What happens when we create a &lt;code&gt;new JillsClass&lt;/code&gt; using version 2.0 of the library and pass it along to &lt;code&gt;jacksFunction&lt;/code&gt; (that excepts the 1.0 version as we know!)? All hell will break loose! Simple things like &lt;code&gt;jillsObject instanceof JillsClass&lt;/code&gt; will suddenly return &lt;code&gt;false&lt;/code&gt;, because &lt;code&gt;jillsObject&lt;/code&gt; is actually an instance of another &lt;code&gt;JillsClass&lt;/code&gt;, the 2.0 version.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In code this means something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// OurCoolProcject.js&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;jacksFunction&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;jacksmodule&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nc"&gt;JillsModule&lt;/span&gt;&lt;span class="p"&gt;(@&lt;/span&gt;&lt;span class="nd"&gt;2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;jillsmodule(@2.0)&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// node resolves to OUR dependency of JillsModule which is 2.0!&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;OurCoolProcject&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;    
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;jillsObject&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;JillsModule&lt;/span&gt;&lt;span class="p"&gt;(@&lt;/span&gt;&lt;span class="nd"&gt;2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;JillsClass&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// next the beginning of all evil, we'll pass a jillsObject of version 2.0&lt;/span&gt;
    &lt;span class="c1"&gt;// to jacksFunction (that would expect jillsObject of version 1.0 🤦‍♀️)&lt;/span&gt;
    &lt;span class="nf"&gt;jacksFunction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;jillsObject&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;OurCoolProject&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// jacksmodule.js (an npm module)&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nc"&gt;JillsModule&lt;/span&gt;&lt;span class="p"&gt;(@&lt;/span&gt;&lt;span class="nd"&gt;1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;jillsmodule(@1.0)&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;jacksFunction&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;jillsObject&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// make sure jillsObject is compatible for further usage in this function&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;jillsObjectRocks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jillsObject&lt;/span&gt; &lt;span class="nx"&gt;instanceOf&lt;/span&gt; &lt;span class="nc"&gt;JillsModule&lt;/span&gt;&lt;span class="p"&gt;(@&lt;/span&gt;&lt;span class="nd"&gt;1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;JillsClass&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="c1"&gt;// └─&amp;gt; 🔥🔥🔥 `jillsObjectRocks` will be a big, fat FALSE&lt;/span&gt;
            &lt;span class="c1"&gt;// as the JillsModule dependencies actively used in this function and&lt;/span&gt;
            &lt;span class="c1"&gt;// passed to this function differ in versions (1.0 vs. 2.0) 🤦‍♀️&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;jacksFunction&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Do you notice what's going on here? &lt;code&gt;jacksFunction&lt;/code&gt; receives an incompatible &lt;code&gt;jillsObject&lt;/code&gt; as the object was constructed from JillsModule(2.0) and not from JillsModule(1.0) &lt;code&gt;JacksModule&lt;/code&gt; is be compatible with. So far, &lt;em&gt;this only shows the problem&lt;/em&gt; that in the worst case, leads to non-working software.&lt;/p&gt;

&lt;h2&gt;
  
  
  How PeerDependencies solve this problem
&lt;/h2&gt;

&lt;p&gt;Luckily npm has some built-in intelligence trying to solve this. If JacksModule declares JillsModule(@1.0) as a PeerDependency, npm can warn the user about this when installing dependencies of your project. So JacksModule's &lt;code&gt;package.json&lt;/code&gt; should include this declaration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;JacksModule&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;peerDependencies&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;JillsModule&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1.x&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So npm's PeerDepenedency intelligence basically triggers a console output notifying us developers with a warning saying this:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;"Hey, this is JacksModule speaking here. Let me tell you: I need this specific package of JillsModule, but I really need the version that is part of my JacksModule project and listed in my package.json file. So please make sure it's installed and make sure it's not some other version of JillsModule you might have installed for your own usage somewhere else in your application."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;So in the end - thinking this further - depending on npm packages that require PeerDependencies can be tricky. In case you need a new version of the package X for separated usage in your application this might lead to problems if another dependency you use in your application has a PeerDependency on another version of package X. If this pops up - and in the worst case also leads to problems with your software - you are on your own to decide which package to use or which code maybe needs refactoring to meet all requirements.&lt;/p&gt;

&lt;p&gt;I hope those explanations and code examples made sense for you and closed the last thought gap you've had about PeerDependencies. If you've questions or want to suggest some article optimization, feel free to contact me or leave a comment.&lt;/p&gt;

&lt;p&gt;This post was &lt;a href="https://manpenaloza.dev/what-are-those-peerdepenedencies-in-a-nodejs-project/" rel="noopener noreferrer"&gt;originally posted here&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>npm</category>
      <category>node</category>
      <category>javascript</category>
    </item>
    <item>
      <title>SVG-based image lazyloading as a matter of enjoyable UX</title>
      <dc:creator>Manuel Penaloza</dc:creator>
      <pubDate>Tue, 06 Feb 2018 11:57:05 +0000</pubDate>
      <link>https://dev.to/btdev/hey-user-you-already-see-me11---svg-based-image-lazyloading-as-a-matter-of-enjoyable-ux-1de9</link>
      <guid>https://dev.to/btdev/hey-user-you-already-see-me11---svg-based-image-lazyloading-as-a-matter-of-enjoyable-ux-1de9</guid>
      <description>&lt;p&gt;There was that day somewhere in November 2017, when our team came across &lt;a href="https://jmperezperez.com/svg-placeholders/" rel="noopener noreferrer"&gt;this article&lt;/a&gt; by José M. Pérez including tons of new-to-us stuff regarding image placeholding and lazyloading. Watching the examples mentioned in the article compared to how we handled it that day was impressing. So impressing that we decided to give it a shot and implement the technique of image lazyloading using inline SVGs on our &lt;a href="https://www.blue-tomato.com/blue-world/" rel="noopener noreferrer"&gt;blue-tomato.com content section&lt;/a&gt; named Blue World. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FdwiuG5V.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FdwiuG5V.jpg" title="SVG-based image lazyloading" alt="SVG-based image lazyloading" width="800" height="166"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;pretty much the transition we've strived for&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Apart from the impressing "magic-happens" moment when the SVG resolves to the high-resolution image, we encountered even more advantages that improve user experience:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;immediate visual response when DOM is ready, as SVG placeholders are inlined and thus part of html source code&lt;/li&gt;
&lt;li&gt;reduce amount of requests to get all small-pixeled lazyloading initial placeholders&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Mentioned upfront: we managed to implement it and have already deployed it, so &lt;a href="https://www.blue-tomato.com/blue-world/" rel="noopener noreferrer"&gt;check it out&lt;/a&gt; in our Blue World Section or take a quick look in the video up next to see the implementation.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/HhpayDoMK5w"&gt;
&lt;/iframe&gt;
&lt;br&gt;
&lt;em&gt;Implementation - slowmo showcase&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The development journey went along with technical challenges, conceptual tasks and finally some rewrites of the implementation. So in case you like SVG-based image lazyloading and want to implement it on your own, check our upcoming hints and implementation notes so you can do this too (without those annoying rewrites). The main stack we used to accomplish it consists of the following awesome libraries:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/fogleman/primitive" rel="noopener noreferrer"&gt;Primitive&lt;/a&gt;: Golang tool reproducing images with geometric primitives&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/svg/svgo" rel="noopener noreferrer"&gt;Svgo&lt;/a&gt;: Nodejs tool for optimizing SVG vector graphics files&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://creativelive.github.io/appear/" rel="noopener noreferrer"&gt;appear.js&lt;/a&gt;: execute callbacks when DOM elements appear in and out of view&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://processwire.com/" rel="noopener noreferrer"&gt;Processwire&lt;/a&gt;: PHP-based cms; no need to go with that cms, choose whatever cms you want following the concepts and solutions we suggest up next&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Implementation details SVG-based image lazyloading
&lt;/h2&gt;

&lt;p&gt;We won’t go through every line of code we shipped to our repository to make SVG-based image lazyloading happen. Our code is tightly coupled to our internal systems (primarily Processwire cms) and it wouldn’t make sense in terms of giving you a good overview of how we solved the implementation. Instead we will equip you with our roadmap we’d consider today if we’d have to do it again from scratch. Given below you'll be guided through these main steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Generate and save SVG placeholders&lt;/li&gt;
&lt;li&gt;Check for SVG availability and ship it&lt;/li&gt;
&lt;li&gt;Proper SVG lazyload placeholder frontend handling&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;1st&lt;/strong&gt; Generate and save SVG placeholders
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Challenges&lt;/em&gt;&lt;br&gt;
Our &lt;strong&gt;first&lt;/strong&gt; approach was to generate the SVGs during the upload process in the admin panel of our cms. The first problem we faced was that the upload process of an image would take longer due to the converting process we triggered using the excellent &lt;a href="https://github.com/fogleman/primitive" rel="noopener noreferrer"&gt;Primitive&lt;/a&gt; library. But this was the smaller of the two problems. The second issue was that our image assets management system (Adobe Scene7) created all required image formats on the fly. So initially we created only one SVG using the format of the uploaded image without considering other formats handled by the image assets management system.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff58lxi4bq2acrtzpm8lr.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff58lxi4bq2acrtzpm8lr.jpg" alt="different image formats as a challenge for creating svg-based lazyload images" width="800" height="652"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Different image formats require different SVG formats&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Example&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
Uploaded image format:&lt;br&gt;
15:4&lt;/p&gt;

&lt;p&gt;BUT formats used in our templates:&lt;br&gt;
skateboard-image.jpg?format=16:9&lt;br&gt;
skateboard-image.jpg?format=4:3&lt;br&gt;
skateboard-image.jpg?format=1:1&lt;/p&gt;

&lt;p&gt;As we've only had that one SVG based on the original upload image width/height ratio that sometimes led to awkward looking effects transitioning from that one SVG to the original images once those were loaded from the server.&lt;/p&gt;

&lt;p&gt;Our &lt;strong&gt;second&lt;/strong&gt; approach was to generate the SVG file on the fly and cache the whole generated html files having all required SVGs inlined. We knew the initial process of producing and caching the whole markup file including all SVGs would take long. But in the end it would not affect user experience. So was our assumption :). Well, finally we ran into http timeout issues our editors would struggle with when saving pages that require a long SVG generation loop.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Solution&lt;/em&gt;&lt;br&gt;
Our &lt;strong&gt;third&lt;/strong&gt; approach led to our current working solution. If an editor uploads an image and the SVG is not yet produced in our network file system we automatically create a "svg-to-be-produced-soon.json" file. This file includes an information object about the SVG (dimensions, image server source, hashed name, etc.) that needs to be produced.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;  
   &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;jpgTmpFilePath&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/root_path/assets/primitives/tmp/kwleklsl090309f0g0.jpg&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;svgFilePath&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/root_path/assets/primitives/svg/kwleklsl090309f0g0.svg&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;svgMinFilePath&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/root_path/assets/primitives/svg/kwleklsl090309f0g0.min.svg&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bgColor&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;inputUrl&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;http://s7w2p3.scene7.com/is/image/bluetomato/ugc/2-1508153542.tif?$mc1$&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;inputUrlHash&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;kwleklsl090309f0g0&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;env&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;production&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Example of a svg-to-be-produced-soon.json file&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;As you can see, this svg-to-be-produced-soon object is quite "hash-intense". We use that hash - being taken from the &lt;code&gt;inputUrlHash&lt;/code&gt; property - to match the image and the SVG to have a proper asset identification process starting at the SVG creation up to the usage in our template files.&lt;/p&gt;

&lt;p&gt;So each new svg-to-be-produced-soon.json file is part of a queue a cronjob will take care of and trigger on an hourly base to generate the SVGs. Let's see what it does.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;

&lt;span class="k"&gt;for &lt;/span&gt;jsonFile &lt;span class="k"&gt;in&lt;/span&gt; /root_path/primitives/queue/&lt;span class="k"&gt;*&lt;/span&gt;.json
&lt;span class="k"&gt;do
  &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Processing &lt;/span&gt;&lt;span class="nv"&gt;$jsonFile&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

  &lt;span class="nv"&gt;primitiveBinary&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;root_path&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;tools/primitive"&lt;/span&gt; 

  &lt;span class="c"&gt;# primitive image&lt;/span&gt;
  &lt;span class="nv"&gt;goPrimitiveCommand&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$primitiveBinary&lt;/span&gt;&lt;span class="s2"&gt; -i &lt;/span&gt;&lt;span class="nv"&gt;$jpgTmpFilePath&lt;/span&gt;&lt;span class="s2"&gt; -o &lt;/span&gt;&lt;span class="nv"&gt;$svgFilePath&lt;/span&gt;&lt;span class="s2"&gt; -n 64 -m 1 -r 256 -bg='&lt;/span&gt;&lt;span class="nv"&gt;$bgColor&lt;/span&gt;&lt;span class="s2"&gt;'"&lt;/span&gt;
  &lt;span class="nb"&gt;eval&lt;/span&gt; &lt;span class="nv"&gt;$goPrimitiveCommand&lt;/span&gt;

  &lt;span class="c"&gt;# svgo&lt;/span&gt;
  &lt;span class="nv"&gt;svgoBinary&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;root_path&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;node_modules/svgo/bin/svgo"&lt;/span&gt;
  &lt;span class="nv"&gt;svgoCommand&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$svgoBinary&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$svgFilePath&lt;/span&gt;&lt;span class="s2"&gt; -o &lt;/span&gt;&lt;span class="nv"&gt;$svgMinFilePath&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
  &lt;span class="nb"&gt;eval&lt;/span&gt; &lt;span class="nv"&gt;$svgoCommand&lt;/span&gt;

  &lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="nv"&gt;$jsonFile&lt;/span&gt;
&lt;span class="k"&gt;done

&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"All SVGs created"&lt;/span&gt;
&lt;span class="nb"&gt;exit&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The simplified cronjob (we removed our system-related code that'd lead to confusion) does four main things.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;loop over and get each new svg-to-be-produced-soon.json file&lt;/li&gt;
&lt;li&gt;get the primitive binary and execute it to create the SVG&lt;/li&gt;
&lt;li&gt;get the svgo binary and execute it to optimize the created SVG code&lt;/li&gt;
&lt;li&gt;delete the svg-to-be-produced-soon.json file&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The time between uploading the images and publishing the page is usually more than one hour. As a delightful result mostly the already available SVGs are shipped to our users instead of our (meantime internally uncool ;)) lazyload fallback option.&lt;/p&gt;

&lt;p&gt;So we finally got it! We have our created and saved SVGs. Let's go the next step and ship fancy and performant placeholder images to our users.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;2nd&lt;/strong&gt; Check for SVG availability and ship it
&lt;/h3&gt;

&lt;p&gt;Once the SVGs creation is done things get easier and more straight forward. We've defined a &lt;code&gt;createPrimitiveSvg&lt;/code&gt; function in our code base that takes an image and its format as arguments and returns the final SVG code packed into a base64-based data-uri.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;createPrimitiveSvg&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;$image&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;$format&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;inSvgCache&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;$image&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;$svgFromCache&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;loadFromSvgCache&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;$image&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// svg already available, get it&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;makeBase64DataUri&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;$svgFromCache&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;pushToSvgGenerationQueue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;$image&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;$format&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// svg not available, make sure it will be made&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;getBlurryImageUrl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;$image&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// ship old lazyload fallback&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Our PHP &lt;code&gt;createPrimitiveSvg&lt;/code&gt; function processing SVGs for our templates&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Further on using this function and passing the image's root data from our cms to it looks like this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"imageContainer"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt;
    &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"js-lazyload"&lt;/span&gt;
    &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;'{$image-&amp;gt;url|createPrimitiveSvg:"16:9"}'&lt;/span&gt;
  &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"imageContainer"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt;
    &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"js-lazyload"&lt;/span&gt;
    &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;'{$image-&amp;gt;url|createPrimitiveSvg:"4:3"}'&lt;/span&gt;
  &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;3rd&lt;/strong&gt; Proper SVG lazyload placeholder frontend handling
&lt;/h3&gt;

&lt;p&gt;appear.js does a great job checking whether a targeted asset in the DOM has reached the viewport. Using it to do so we can manage lazyloading on the frontend using pretty much lightweight code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;appear&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;elements&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelectorAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;img.js-lazyload&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="na"&gt;appear&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;img&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&amp;lt;img class='&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; image--fadeIn' alt='&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;alt&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;' /&amp;gt;`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;attr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;src&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;original&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;load&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;img&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;insertAfter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nf"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;2000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's see what this does:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Call &lt;code&gt;appear(config: Object)&lt;/code&gt; initializing all config object properties appear.js requires&lt;/li&gt;
&lt;li&gt;When the lazyload SVG image has reached the users's viewport, the &lt;code&gt;appear&lt;/code&gt; callback handles the high-resolution image tag creation&lt;/li&gt;
&lt;li&gt;Once the high-resolution image has loaded, it will be inserted &lt;em&gt;behind&lt;/em&gt; the already displayed SVG&lt;/li&gt;
&lt;li&gt;The SVG image will fade out using CSS3 and its blur transition options&lt;/li&gt;
&lt;li&gt;Removal of the lazyload SVG image from the DOM after 2 seconds&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That's it!&lt;/p&gt;

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

&lt;p&gt;We are super happy with the results and gains we profit from having SVG-based lazyloading implemented in our &lt;a href="https://www.blue-tomato.com/blue-world/" rel="noopener noreferrer"&gt;Blue World&lt;/a&gt;. In case you like the perceived user experience at least a little bit. Give it a try. It makes so much more fun seeing all of this happening in your own projects. Happy coding, happy lazyloading!&lt;/p&gt;

</description>
      <category>svg</category>
      <category>webperf</category>
      <category>showdev</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
