<?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: Jonathan</title>
    <description>The latest articles on DEV Community by Jonathan (@jbsan).</description>
    <link>https://dev.to/jbsan</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F110594%2Fa78fbe97-d960-4fca-8c0a-9eadffe420b6.png</url>
      <title>DEV Community: Jonathan</title>
      <link>https://dev.to/jbsan</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jbsan"/>
    <language>en</language>
    <item>
      <title>Proxy components</title>
      <dc:creator>Jonathan</dc:creator>
      <pubDate>Sat, 23 Jan 2021 09:58:54 +0000</pubDate>
      <link>https://dev.to/jbsan/proxy-components-10f5</link>
      <guid>https://dev.to/jbsan/proxy-components-10f5</guid>
      <description>&lt;p&gt;Refactorability is.. not a word, but it should be, it should be defined as&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;To which degree or factor a piece of code or application is able to be changed with minimal impact on the code/application as a whole.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Refactorability and maintainability are closely related but separate concepts in my mind.&lt;br&gt;
maintainable code is something that can you write and make an effort to keep maintainable, and of course all of us should strive to write&lt;br&gt;
maintainable code, but what is refactorable code ?&lt;/p&gt;

&lt;p&gt;Well, I don't think there is &lt;strong&gt;one&lt;/strong&gt; answer to this, i found myself thinking about this on a recent project i was working on.&lt;br&gt;
If we take the above made up definition, refactorable code should make it easy to change without having much of an impact on other code using that code,&lt;/p&gt;

&lt;p&gt;I was working on a &lt;em&gt;legacy&lt;/em&gt; application, well it was using 6 month old packages witch is legacy in the frontend world..&lt;br&gt;
having old packages is not a problem in it self, but the application that was basically a large dynamic form, and it had grown so much since its first inception&lt;br&gt;
that we where experiencing some problems with sluggish inputs due to using the otherwise excellent &lt;a href="https://www.npmjs.com/package/formik"&gt;formik&lt;/a&gt; library.&lt;br&gt;
So, I decided to try out the &lt;a href="https://www.npmjs.com/package/react-final-form"&gt;react-final-form&lt;/a&gt; library, that has more fine grained control to optimize rendering.&lt;br&gt;
after some initial testing, it looked promising, so when i decided to replace formik I had &lt;code&gt;import { Field } from 'formik'&lt;/code&gt; sprinkled throughout the various components..&lt;/p&gt;

&lt;p&gt;&lt;em&gt;sigh&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;but I'll just do a quick search &amp;amp; replace for&lt;/p&gt;

&lt;p&gt;&lt;code&gt;import { Field } from 'formik' -&amp;gt; import { Field } from 'react-final-form'&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;and everything should be fine right ?&lt;/p&gt;

&lt;p&gt;well no so fast, The &lt;code&gt;Field&lt;/code&gt; from &lt;code&gt;formik&lt;/code&gt; does not have exactly the same props as the one from &lt;code&gt;react-final-form&lt;/code&gt;&lt;br&gt;
so for each place where i used &lt;code&gt;Field&lt;/code&gt; i need to change it so the props are the ones that the &lt;code&gt;Field&lt;/code&gt; component from &lt;code&gt;react-final-form&lt;/code&gt; expects.&lt;/p&gt;

&lt;p&gt;I decided that it would be nice to have a local &lt;code&gt;components/Field&lt;/code&gt; component, where i transform the props into the appropriate shape for the &lt;code&gt;react-final-form&lt;/code&gt; &lt;code&gt;Field&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Field&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;FinalFormField&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-final-form&lt;/span&gt;&lt;span class="dl"&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="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;Field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;//... tranform the props&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;FinalFormField&lt;/span&gt; &lt;span class="p"&gt;{...&lt;/span&gt;&lt;span class="nx"&gt;transformedProps&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and I lived happily ever after... almost, at the last moment we decided to update the version of our internal component library, where a breaking change to the &lt;code&gt;Input&lt;/code&gt; component, made it so that&lt;br&gt;
everywhere where we had imported it 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="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;FormInput&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;componentlib/lib/FormInput&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;i now had to do a&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;FormInput&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;componentlib&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;hey&lt;/strong&gt; this looks familiar, an "third party" component/library, needed to be changed, I know what to do..&lt;/p&gt;

&lt;p&gt;I create a &lt;code&gt;component/FormInput&lt;/code&gt; component which I use the application, I can then transform the props if the new version of the component requires it, all in one place.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;FormInput&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;XFormInput&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;componentlibX&lt;/span&gt;&lt;span class="dl"&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="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;FormInput&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;//... tranform the props&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;XFormInput&lt;/span&gt; &lt;span class="p"&gt;{...&lt;/span&gt;&lt;span class="nx"&gt;transformedProps&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;this repeated a couple of more times and it got me thinking, could this be a good pattern ?&lt;/p&gt;

&lt;h2&gt;
  
  
  The Pattern
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;For each component imported from a external library, create a local proxy component, so that if changes to the external library needs to be adapted&lt;br&gt;
you can do it in one place&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In any non trivial application you will always need to use third-party components. but when writing your actual component structure do we need to care that we are using Input from &lt;code&gt;material-ui&lt;/code&gt; or from &lt;code&gt;uilibX&lt;/code&gt; ?&lt;br&gt;
I think there is a point to always importing all components from &lt;code&gt;components/*&lt;/code&gt;, so if you have an Input from &lt;code&gt;material-ui&lt;/code&gt; you should create a &lt;strong&gt;Proxy component&lt;/strong&gt; that you then use in you app.&lt;/p&gt;

&lt;h3&gt;
  
  
  PROs
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;abstracts the third party library, so that you can make changes or update the underlying lib in one place.&lt;/li&gt;
&lt;li&gt;from the applications point of view you only ever import from local components, which makes it less tied to any specific library, if you want to change the &lt;code&gt;Input&lt;/code&gt; component to a custom input you make the change in the local component, and not in 100 places throughout the codebase.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  CONs
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;There is some overhead in every time you want to use a third party component, you have to create a corresponding component in your app, which can feel a bit redundant.&lt;/li&gt;
&lt;li&gt;Hiding what library that is used is not always wanted, although once inside of the &lt;code&gt;Input&lt;/code&gt; component it will be clear where it is imported from.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What makes code refactorable ?
&lt;/h2&gt;

&lt;p&gt;The ease to change the underlying implementation without impacting all of the components using it, or at least being able to make changes in a controlled way.&lt;br&gt;
with the above pattern we can update the underlying library or change it outright, and make temporary transformations to the props so that we can take our time and update the where it is used in a more controlled way.&lt;/p&gt;

&lt;h2&gt;
  
  
  Closing thoughts
&lt;/h2&gt;

&lt;p&gt;This is nothing new, we are used to creating more specific components that use third-party components in our application, like we might have a &lt;code&gt;Login&lt;/code&gt; component that uses &lt;code&gt;Auth0&lt;/code&gt; and other helpers, this is just my thoughts of how I could make my applications more resilient to fundamental changes of libraries etc.&lt;/p&gt;

</description>
      <category>react</category>
      <category>components</category>
      <category>pattern</category>
    </item>
    <item>
      <title>Building and serving gatsbyjs with docker</title>
      <dc:creator>Jonathan</dc:creator>
      <pubDate>Sat, 23 Jan 2021 09:14:11 +0000</pubDate>
      <link>https://dev.to/jbsan/building-and-serving-gatsbyjs-with-docker-2g7</link>
      <guid>https://dev.to/jbsan/building-and-serving-gatsbyjs-with-docker-2g7</guid>
      <description>&lt;p&gt;On a recent project I have been working on, I had to find a way to host a gatsbyjs project in a &lt;a href="https://www.docker.com/"&gt;docker&lt;/a&gt; container.&lt;br&gt;
After a quick search for &lt;code&gt;gatsbyjs docker&lt;/code&gt;, most of the result pointed me to the fact that gatsbyjs have &lt;a href="https://github.com/gatsbyjs/gatsby-docker"&gt;official docker images&lt;/a&gt;,&lt;br&gt;
but when using it like shown in the README&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; gatsbyjs/gatsby:onbuild as build&lt;/span&gt;

&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; gatsbyjs/gatsby&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; --from=build /app/public /pub&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I could not get it to work, after searching through the issues i found out that the &lt;a href="https://github.com/gatsbyjs/gatsby-docker/issues/38"&gt;docker images needs to be updated&lt;/a&gt; but its still open so i decided to take matters into my own hands.&lt;/p&gt;

&lt;h2&gt;
  
  
  Multistage docker builds
&lt;/h2&gt;

&lt;p&gt;Docker has this awesome feature called &lt;a href="https://docs.docker.com/develop/develop-images/multistage-build/"&gt;multistage build&lt;/a&gt; which allows us to basicly structure our dockerfile&lt;br&gt;
in a way to minimize the size of the final image. A traditional dockerfile would look something like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; node:14.11.0&lt;/span&gt;
&lt;span class="c"&gt;#&lt;/span&gt;
&lt;span class="c"&gt;# Install and setup nginx to serve static files, removed for brevity.&lt;/span&gt;
&lt;span class="c"&gt;#&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;

&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; package.json package-lock.json ./&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;npm ci

&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . ./&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;npm run build

&lt;span class="k"&gt;RUN &lt;/span&gt;&lt;span class="nb"&gt;mv&lt;/span&gt; /app/public /usr/share/nginx/html

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;this would work, but you see that &lt;code&gt;FROM node:14.11.0&lt;/code&gt; line at the top of the Dockerfile, that means that the final image will have node included, and all the dependencies that the application needs to build.&lt;br&gt;
there is a better way.&lt;/p&gt;

&lt;h3&gt;
  
  
  Enter multistage
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM node:14.11.0 AS builder
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci
COPY . ./
RUN npm run build

FROM nginx:alpine
COPY --from=builder /app/public /usr/share/nginx/html
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see it starts of similarly,we have one stage that uses the &lt;code&gt;node:14.11.0&lt;/code&gt; image, it sets everything up and builds the public folder with the generated gatsby site,&lt;br&gt;
but at the end of the file we have a new &lt;code&gt;FROM nginx:alpine&lt;/code&gt; and we then copy in only the public folder, This means that our final docker image will only contain our finished built site, and the bare minimun nginx to serve those files.&lt;/p&gt;

</description>
      <category>gatsby</category>
      <category>docker</category>
    </item>
  </channel>
</rss>
