<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Andy Potts</title>
    <description>The latest articles on Forem by Andy Potts (@andypotts).</description>
    <link>https://forem.com/andypotts</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%2F356135%2F813fd243-2ddb-4b2f-88c7-8f97e0de4fe9.png</url>
      <title>Forem: Andy Potts</title>
      <link>https://forem.com/andypotts</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/andypotts"/>
    <language>en</language>
    <item>
      <title>Automatically upgrade security vulnerabilities with this Yarn audit fix  alternative</title>
      <dc:creator>Andy Potts</dc:creator>
      <pubDate>Wed, 05 Aug 2020 12:05:45 +0000</pubDate>
      <link>https://forem.com/andypotts/automatically-upgrade-security-vulnerabilities-with-this-yarn-audit-fix-alternative-3oo0</link>
      <guid>https://forem.com/andypotts/automatically-upgrade-security-vulnerabilities-with-this-yarn-audit-fix-alternative-3oo0</guid>
      <description>&lt;p&gt;In this short guide I will explain how to automatically update and fix package vulnerabilities using Yarn. Much like running &lt;code&gt;npm audit&lt;/code&gt;, running &lt;code&gt;yarn audit&lt;/code&gt; returns a list of packages with vulnerabilities. NPM provides a command (&lt;code&gt;npm audit fix&lt;/code&gt;) for automatically upgrading vulnerable packages and fixing the vulnerabilities but there isn't an equivalent command available within Yarn (as of 5th August, 2020).&lt;/p&gt;




&lt;p&gt;It's frustrating that yarn doesn't have the equivalent command but the solution, while not ideal, is incredibly simple. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Before you begin modifying your packages, you should ensure that you have version control in place so it's easy to revert any changes if you run into any issues.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;To start with you need to generate a package-lock.json by running&lt;br&gt;
&lt;/p&gt;

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



&lt;p&gt;Once this has been generated you need to delete the existing yarn.lock. Then run &lt;code&gt;npm audit fix&lt;/code&gt; to automatically upgrade and fix security vulnerabilities using NPM. Now we're going to generate a new yarn.lock based on the package-lock.json (which has had the security fixes applied to it) using &lt;a href="https://classic.yarnpkg.com/en/docs/cli/import/"&gt;the yarn import command&lt;/a&gt;. To do this simply run &lt;code&gt;yarn import&lt;/code&gt;, which should create our updated yarn.lock file. Finally delete the package-lock.json as we won't be needing it anymore.&lt;/p&gt;

&lt;p&gt;This won't always able to automatically fix all dependency vulnerabilities, especially if there isn't a dependency upgrade/fix available. However in one project I was recently able to automatically fix over 1000 dependency vulnerabilities, and in another ~30. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;If know what you're doing and you want to copy/paste the commands, all of the commands listed above combined are&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm i --package-lock-only
rm -rf yarn.lock
npm audit fix
yarn import
rm -rf package-lock.json
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;






&lt;p&gt;&lt;em&gt;If you found this useful, have any questions, or want more content like this, feel free to follow me on &lt;a href="https://twitter.com/AndyPotts_"&gt;twitter&lt;/a&gt;!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>npm</category>
      <category>todayilearned</category>
      <category>security</category>
    </item>
    <item>
      <title>Avoiding CORS errors on localhost (in 2020)</title>
      <dc:creator>Andy Potts</dc:creator>
      <pubDate>Thu, 23 Jul 2020 17:29:59 +0000</pubDate>
      <link>https://forem.com/andypotts/avoiding-cors-errors-on-localhost-in-2020-4mfn</link>
      <guid>https://forem.com/andypotts/avoiding-cors-errors-on-localhost-in-2020-4mfn</guid>
      <description>&lt;p&gt;When developing a website/web app on localhost which makes requests to another server, you might run into Cross Origin Resource Sharing (CORS) issues. I won’t go into too much detail about what CORS is in this post. All I will say is that CORS exists for security reasons, but when you’re developing locally it can be a pain! You can &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS"&gt;read more about CORS on the MDN docs&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I have written this simple guide to explain the main solutions for disabling cross origin restrictions on localhost (and therefore fixing any CORS errors whilst developing your app locally), which I will explain in more detail below.&lt;/p&gt;




&lt;h1&gt;
  
  
  1. Use the proxy setting in Create React App
&lt;/h1&gt;

&lt;p&gt;Create React App comes with a config setting which allows you to &lt;a href="https://create-react-app.dev/docs/proxying-api-requests-in-development/"&gt;simply proxy API requests in development&lt;/a&gt;. This is available in &lt;code&gt;react-scripts@0.2.3&lt;/code&gt;. To do this add the proxy setting to your package.json like this&lt;br&gt;
&lt;br&gt;
 &lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"proxy": "https://cat-fact.herokuapp.com/",
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now when you make an API request to &lt;a href="https://localhost:3000/api/facts"&gt;https://localhost:3000/api/facts&lt;/a&gt; Create React App will proxy the API request to &lt;a href="https://cat-fact.herokuapp.com/facts"&gt;https://cat-fact.herokuapp.com/facts&lt;/a&gt; and the CORS error will be resolved. &lt;/p&gt;

&lt;p&gt;This is a really simple solution which might not work with more complicated situations where multiple API's are involved, or certain types of API authentication is needed.&lt;/p&gt;

&lt;h1&gt;
  
  
  2. Disable CORS in the browser
&lt;/h1&gt;

&lt;p&gt;You can directly disable CORS in the browser. &lt;em&gt;If you do this, please be aware that you are disabling security restrictions which are there for a reason. I wouldn’t recommend browsing the web with CORS disabled; Just disable it whilst developing your website/app.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Chrome:
&lt;/h2&gt;

&lt;p&gt;The most reliable way to disable CORS in the latest version of Chrome on Mac (tested on v84) is to run it with web security disabled.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;em&gt;Force quit Chrome&lt;/em&gt; by going to the mac menu and pressing “force quit” (or pressing command Q).&lt;/li&gt;
&lt;li&gt;Then run this command to &lt;em&gt;open Chrome with web security disabled&lt;/em&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;open -n -a /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome — args — user-data-dir=”/tmp/chrome_dev_test” — disable-web-security
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Once you’re done developing, restart Chrome and it will go back to normal.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Firefox:
&lt;/h2&gt;

&lt;p&gt;The easiest and most reliable way to disable CORS in Firefox is to install the &lt;a href="https://addons.mozilla.org/en-GB/firefox/addon/cors-everywhere/"&gt;CORS Everywhere plugin&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Safari:
&lt;/h2&gt;

&lt;p&gt;The easiest and most reliable way to CORS in Safari is to disable CORS in the develop menu.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;em&gt;Enable the develop menu&lt;/em&gt; by going to Preferences &amp;gt; Advanced.&lt;/li&gt;
&lt;li&gt;Then select “&lt;em&gt;Disable Cross-Origin Restrictions&lt;/em&gt;” from the &lt;em&gt;develop menu&lt;/em&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;em&gt;Once you’re done developing, restart Safari and it will go back to normal.&lt;/em&gt;&lt;/p&gt;




&lt;h1&gt;
  
  
  3. Use a proxy to avoid CORS errors
&lt;/h1&gt;

&lt;p&gt;Alternatively you could use a proxy like cors-anywhere.&lt;br&gt;
If you want to easily demo cors-anywhere, &lt;a href="https://github.com/Rob--W"&gt;Rob — W&lt;/a&gt; has setup a public demo which is great for consuming public API's as it requires no registration or config &lt;a href="https://cors-anywhere.herokuapp.com"&gt;https://cors-anywhere.herokuapp.com&lt;/a&gt;. &lt;em&gt;As it’s just a demo, requests are limited&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;To use the public demo of cors-anywhere, just add the url you want to make the request to after the domain e.g. &lt;a href="https://cors-anywhere.herokuapp.com/https://cat-fact.herokuapp.com/facts"&gt;https://cors-anywhere.herokuapp.com/https://cat-fact.herokuapp.com/facts&lt;/a&gt; (*if you view this in the browser you might get an error about a missing request header. When you make an API request using in your app using something like Axios or Fetch this won’t be an issue).&lt;/p&gt;




&lt;p&gt;&lt;em&gt;If you found this useful, have any questions, or want more content like this, feel free to &lt;a href="https://twitter.com/andypotts_"&gt;follow me on twitter&lt;/a&gt;!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>cors</category>
      <category>tutorial</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Native lazy loading has arrived!</title>
      <dc:creator>Andy Potts</dc:creator>
      <pubDate>Wed, 17 Jun 2020 10:18:12 +0000</pubDate>
      <link>https://forem.com/andypotts/native-lazy-loading-has-arrived-repost-3gn4</link>
      <guid>https://forem.com/andypotts/native-lazy-loading-has-arrived-repost-3gn4</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a repost. Initially &lt;a href="https://medium.com/bbc-design-engineering/native-lazy-loading-has-arrived-c37a165d70a5"&gt;this was posted on Medium, under the BBC's D&amp;amp;E blog&lt;/a&gt;, but I want a copy of all my articles on dev.to&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;For those of you that haven’t already seen, &lt;a href="https://web.dev/native-lazy-loading/"&gt;Google recently introduced native lazy loading to Chrome version 76&lt;/a&gt;. Now you’re probably wondering, “what the heck is native lazy loading, and is it worth adding to my site?”.&lt;/p&gt;

&lt;p&gt;Well — that’s exactly what I’m hoping to answer for you, as I talk through my experience using it.&lt;/p&gt;




&lt;h2&gt;
  
  
  What is lazy loading?
&lt;/h2&gt;

&lt;p&gt;Lazy loading improves performance by loading resources, like images, when they’re required by the user. For example, when someone lands on your page it’ll load any images as they come into the viewport, rather than loading all of them when the page initially loads. This is beneficial because users won’t always see the images at the bottom of the page, so why make our users download all of those unnecessary &lt;del&gt;memes&lt;/del&gt; images?&lt;/p&gt;

&lt;p&gt;Previously, if we wanted to implement lazy loading we would have had to import a library or write some Javascript to check the position of elements relative to the user's viewport and lazy load resources when necessary. Sounds like a bit of work, doesn’t it?&lt;/p&gt;

&lt;p&gt;Native lazy loading is Google’s new built-in solution to this, meaning no additional Javascript needs to be written to include lazy loading (and hugely improve the performance of your website). Native lazy loading can be implemented as simply as adding the loading attribute to images or iFrames.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sounds good, right? But is it actually worth implementing?
&lt;/h2&gt;

&lt;p&gt;I decided to play around with implementing native lazy loading on one of our internal products at the BBC, a site that has ~3,000 active users per day. One of the most common actions on the site involves running a query which renders a list of up to 100 images — which I thought seemed like the ideal place to experiment with native lazy loading.&lt;/p&gt;

&lt;p&gt;So, was it worth it? Yes! Adding the loading attribute to the images decreased the load time on a fast network connection by ~50% — it went from ~1 second to &amp;lt; 0.5 seconds, as well as saving up to 40 requests to the server 🎊. All of those performance enhancements just from adding one attribute to a bunch of images!&lt;/p&gt;

&lt;h2&gt;
  
  
  Worked example
&lt;/h2&gt;

&lt;p&gt;So we’ve seen what it can do, let’s have a look at how it works. I’ll walk through how we might implement native lazy loading for images.&lt;/p&gt;

&lt;p&gt;It’s really easy — attaching the loading attribute, with the value of “lazy” will tell the browser to lazy load the image. Specifying the height and width will prevent any janky page layout changes as the images load.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;img src="/images/example.png" loading="lazy" width="400" height="400" /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/andypotts/embed/eqLgMX?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;&lt;em&gt;A simple native lazy loading codepen demo (take a look at the network inspector in Chrome 76 as you scroll down the pen).&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;To summarise, using native lazy loading is one of the simplest ways of providing genuine progressive performance enhancements for your users. It’s not a perfect solution, but if you’re not already utilising lazy loading and have lots of images/iframes it’s definitely worth trying out — especially as it’s so easy to implement!&lt;/p&gt;

&lt;p&gt;Unfortunately, native lazy loading isn’t a silver bullet. Because native lazy loading is a new browser feature, there’s currently a lack of browser support, so a polyfill or a fallback Javascript solution would have to be implemented to support other browsers. You can &lt;a href="https://caniuse.com/#feat=loading-lazy-attr"&gt;view more details about browsers that support native lazy loading on caniuse.com&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It’s also worth noting that background images can’t be loaded using native lazy loading, so if you’re using a lot of them then you might want to consider using a Javascript alternative to lazy load your background images.&lt;/p&gt;

&lt;p&gt;Have fun lazy loading!&lt;/p&gt;




&lt;p&gt;&lt;em&gt;If you found this useful, have any questions, or want more content like this, feel free to &lt;a href="https://twitter.com/andypotts_"&gt;follow me on twitter&lt;/a&gt;!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>beginners</category>
      <category>html</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Improve your JavaScript coding with optional chaining</title>
      <dc:creator>Andy Potts</dc:creator>
      <pubDate>Sun, 19 Apr 2020 13:41:01 +0000</pubDate>
      <link>https://forem.com/andypotts/improve-your-javascript-coding-with-optional-chaining-2b7n</link>
      <guid>https://forem.com/andypotts/improve-your-javascript-coding-with-optional-chaining-2b7n</guid>
      <description>&lt;p&gt;You might or might not have heard the term "optional chaining" bandied about in the past few months. In this article, I'm going to explain what it is and why you should be using it. Spending a few minutes gaining an understanding of how and when to use optional chaining will save you a lot of time and effort whilst writing/debugging JavaScript in the long run!&lt;/p&gt;




&lt;h2&gt;
  
  
  So what is Optional chaining?
&lt;/h2&gt;

&lt;p&gt;It's pretty simple actually, optional chaining makes dealing with nested objects much easier by making expressions shorter it reduces the amount of code you need to write. When you're consuming APIs or working with complex objects optional chaining is really useful. Optional chaining isn't a new concept, and it exists in other programming languages but support for it has only recently been added to JavaScript and it is now supported by most modern browsers. I'll explain later in the article how simple it is to add support for legacy browsers. But first, let's take a deeper look at what optional chaining is and some examples of why we need it.&lt;/p&gt;

&lt;h2&gt;
  
  
  How does it work?
&lt;/h2&gt;

&lt;p&gt;Have you ever come across an error that looks a bit like this whilst working with JavaScript? &lt;em&gt;TypeError: Cannot read property X of undefined&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--nWfS6XVC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/adkewwsji8w0jrrmkr9n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nWfS6XVC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/adkewwsji8w0jrrmkr9n.png" alt="Screenshot of optional chaining error"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This means that your code can't access the value you are trying to because the value's parent property is undefined. So in the example above the 'user' variable is initialized as an empty object and we're trying to access the 'firstName' value within the 'details' property. Because the 'details' property is not defined  JavaScript does not proceed with the expression and throws this error.&lt;/p&gt;

&lt;h2&gt;
  
  
  The old solution
&lt;/h2&gt;

&lt;p&gt;Previously to solve this you would check that the parent property is defined by doing something like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{user.details &amp;amp;&amp;amp; user.details.firstName ? (
    &amp;lt;p&amp;gt;{user.details.firstName}&amp;lt;/p&amp;gt;
) : null}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The problem with this is that your code quickly becomes messy as you add more if statements to check that properties exist.&lt;/p&gt;

&lt;h2&gt;
  
  
  Optional chaining to the rescue!
&lt;/h2&gt;

&lt;p&gt;This is where optional chaining comes in. Optional chaining allows you to add the '?' operator after a property, to check a property exists. If the property exists it carries on with the expression. Here's an example.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{user.details?.firstName ? (
    &amp;lt;p&amp;gt;{user.details.firstName}&amp;lt;/p&amp;gt;
) : null}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Sounds great! How do I use it in my app?
&lt;/h2&gt;

&lt;p&gt;Optional chaining is now supported by most modern browsers but you will still need to do a bit of work to get it working with older browsers. If your project is using React you will need to upgrade to React Scripts 3.3, or if you are using Typescript you will need to upgrade to Typescript 3.7 to be able to use optional chaining.&lt;/p&gt;




&lt;p&gt;If you found this useful, have any questions, or want more content like this, feel free to &lt;a href="https://twitter.com/AndyPotts_"&gt;follow me on twitter&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>beginners</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Creating a reusable Component Library with React, Storybook, and Webpack</title>
      <dc:creator>Andy Potts</dc:creator>
      <pubDate>Sat, 11 Apr 2020 14:01:33 +0000</pubDate>
      <link>https://forem.com/andypotts/creating-a-reusable-component-library-with-react-storybook-and-webpack-2ple</link>
      <guid>https://forem.com/andypotts/creating-a-reusable-component-library-with-react-storybook-and-webpack-2ple</guid>
      <description>&lt;p&gt;When working across large codebases using modern JavaScript libraries like React it becomes important to split our UI into small, manageable components, which can easily reused and distributed. Doing this can help us deliver a cohesive user experience at scale.  A nice example of a modern component library created by one of the teams at the BBC is &lt;a href="https://www.bbc.co.uk/iplayer/storybook/index.html?path=/story/style-guide--colours"&gt;the iPlayer component library, which can be seen here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In this guide I'll be outlining the steps to get you set up with your own basic React component library, so you can start reusing components across your React apps. To achieve this we will use React, Sass, Storybook, and Webpack.&lt;/p&gt;




&lt;h2&gt;
  
  
  Initialising the project
&lt;/h2&gt;

&lt;p&gt;First off, let's create a new directory, cd into it and run npm init to get started. Then we need to install the following dependencies&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn add react react-dom 

yarn add --dev @babel/core @babel/preset-env @babel/preset-react babel-loader node-sass sass-loader @storybook/react @storybook/addon-knobs webpack webpack-cli webpack-node-externals clean-webpack-plugin path
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Project Structure
&lt;/h2&gt;

&lt;p&gt;The directory structure of our components library will be very simple. We will have a src directory, a .storybook directory, and a dist directory. It will end up looking a bit like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/.storybook
  - main.js
/src
  - index.js
  /components
    /Button
      - index.js
      - button.scss
      - button.stories.js
/dist
  - index.js
- webpack.config.js
- package.json
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;If we wanted to structure our project with scaleability in mind, we could follow the &lt;a href="https://bradfrost.com/blog/post/atomic-web-design/"&gt;Atomic design pattern&lt;/a&gt;, and break our components down into Atoms, Molecules and Organisms. But in this tutorial we're just going to keep things simple.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating our React component/s
&lt;/h2&gt;

&lt;p&gt;Now we need to create our first React component. In the root of the project create a directory called src and inside the src directory, create another directory called components. Inside the components directory, create another directory which will be the name of your component; and inside this create an index.js file, which is where your component's code will live. I will be creating a simple component called Button. Here's what my Button component looks like&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// /src/components/Button/index.js
import React from 'react'

const Button = ({message = 'Hello world'}) =&amp;gt; (
   &amp;lt;button&amp;gt;{message}&amp;lt;/button&amp;gt;
)

export default Button
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Storybook
&lt;/h2&gt;

&lt;p&gt;Storybook makes it easy to visualize your components as you develop them, it's really simple to set up, and we've already installed the dependencies we need (@storybook/react and @storybook/addon-knobs). Inside the root of the project create a directory called .storybook, and inside this create a main.js file. Inside the main.js file add the following config, which tells Storybook where to look for the Storybook files, and to use the knobs addon (which is useful for when working with props).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// /.storybook/main.js
module.exports = {
  stories: ['../src/components/**/*.stories.[tj]s'],
  addons: ['@storybook/addon-knobs/register']
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Storybook will now automatically pull in each Storybook file we create inside the components directory, so we should create a Storybook file for every component. This is the Storybook file for the Button component I created earlier. It's telling Storybook to render my Button component and add an editable prop called "message", which you can edit directly within Storybook.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// /src/components/Button/button.stories.js
import React from 'react'
import Button from './index.js'
import { withKnobs, text } from '@storybook/addon-knobs'

export default { title: "'Button component', decorators: [withKnobs]}"

export const button = () =&amp;gt; {
  const message = text('Text', 'Click here now!')
  return &amp;lt;Button message={message}&amp;gt;&amp;lt;/Button&amp;gt;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now we need to add a Storybook script to the package.json.&lt;br&gt;
&lt;br&gt;
 &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;...
"scripts": {
  "start": "start-storybook"
},
...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Once we've added this we should be able to run yarn start/npm run start to start Storybook, which will pull in the component we just created. &lt;/p&gt;
&lt;h2&gt;
  
  
  Styling our components
&lt;/h2&gt;

&lt;p&gt;There are many choices for styling components with React, in this tutorial we'll be using Sass. To setup Storybook to work with Sass we need to edit the Storybook config we created earlier (/.storybook/main.js) and import the path package, and then add a Webpack rule to tell Storybook to load Sass files. Your Storybook config should now look like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// /.storybook/main.js
const path = require('path');

module.exports = {
  stories: ['../src/components/**/*.stories.[tj]s'],
  addons: ['@storybook/addon-knobs/register'],
  webpackFinal: async (config, { configType }) =&amp;gt; {
    config.module.rules.push({
      test: /\.scss$/,
      use: ['style-loader', 'css-loader', 'sass-loader'],
      include: path.resolve(__dirname, '../src'),
    });

    return config;
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now we've setup Storybook to import the Sass files we can add styling to the component we created previously. To do this we need to create a .scss file in the component's directory, so in /src/components/Button create a file called button.scss. In /src/components/Button/index.js we need to import the file we just created import './button.scss'. Now when we add styling to button.scss, we should be able to see these styles in Storybook 🎊&lt;/p&gt;

&lt;h2&gt;
  
  
  Bundling the project with Webpack
&lt;/h2&gt;

&lt;p&gt;To be able to import the components we've created into other React apps we need to bundle the code using Webpack. Inside the src directory we need to create an index.js file, which will be used to declare and export all of the components, which will look like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// /src/index.js
const { Button } = './components/Button'
export { Button }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Inside the package.json, we need to add a build script, for building the components using Webpack. Our  package.json should contain the following &lt;br&gt;
scripts&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;...
"scripts": {
  "start": "start-storybook",
  "build": "webpack -- mode production"
},
...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Finally we need to setup the Webpack config to build the components library. In the root directory create a file called webpack.config.js and add the following&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const path = require('path')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const nodeExternals = require('webpack-node-externals');

module.exports = {
  entry: './src/index.js',
  externals: [nodeExternals()],
  output: {
    filename: 'index.js',
    path: path.resolve(__dirname, 'dist'),
    library: '',
    libraryTarget: 'commonjs'
  },
  plugins: [new CleanWebpackPlugin()],
  module: {
    rules: [
     {
        test: /\.(js|jsx)$/,
        exclude: /node_modules/,
        use: ['babel-loader']
      },
      { 
        test: /\.scss$/,
        use: ['style-loader', 'css-loader', 'sass-loader'],
        include: path.resolve(__dirname, './src')
      }
    ]
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This config is telling Webpack to clean the dist directory (using CleanWebpackPlugin) before loading the JavaScript/Sass contents of src/index.js and outputting it to the dist directory.&lt;/p&gt;

&lt;h2&gt;
  
  
  Publishing our components library
&lt;/h2&gt;

&lt;p&gt;Publishing the components library we just created to NPM and importing it into other React apps is really straightforward. Once the code has been built using the yarn build command we created earlier, ensure you are logged into NPM and run npm publish, to publish the components library to NPM. &lt;/p&gt;

&lt;p&gt;Using the components in your other React apps is then as simple as running yarn add yourPackageName inside your other React apps and then importing it into your React app like this&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;import { Button } from 'yourPackageName'&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;If you don't want to publish your components library to NPM, you can &lt;a href="https://stackoverflow.com/questions/17509669/how-to-install-an-npm-package-from-github-directly"&gt;import it directly from Github instead&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;I have published my code from this guide &lt;a href="https://github.com/andypotts/components-library-template"&gt;on Github&lt;/a&gt;. If you found this useful, have any questions, or want more content like this, feel free to &lt;a href="https://twitter.com/AndyPotts_"&gt;follow me on twitter&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>beginners</category>
      <category>react</category>
      <category>webpack</category>
    </item>
  </channel>
</rss>
