<?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: Itsopensource</title>
    <description>The latest articles on DEV Community by Itsopensource (@itsopensource).</description>
    <link>https://dev.to/itsopensource</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%2F2580%2Fcd862d0c-9877-4bf2-ab6d-c7df14f1290b.png</url>
      <title>DEV Community: Itsopensource</title>
      <link>https://dev.to/itsopensource</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/itsopensource"/>
    <language>en</language>
    <item>
      <title>Rainbow text with CSS</title>
      <dc:creator>Trishul</dc:creator>
      <pubDate>Mon, 12 Feb 2024 07:39:18 +0000</pubDate>
      <link>https://dev.to/itsopensource/rainbow-text-with-css-1fmi</link>
      <guid>https://dev.to/itsopensource/rainbow-text-with-css-1fmi</guid>
      <description>&lt;p&gt;Some designers can not get enough of colors and want the text not to be in solid color but rainbow colors. Traditionally developers achieve this by using a PNG image, something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsrmfgbb2dl4746tgkrwi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsrmfgbb2dl4746tgkrwi.png" alt="Rainbow colored text" width="551" height="129"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But with modern day CSS, this can be achieved with just few CSS rules. &lt;/p&gt;

&lt;h3&gt;
  
  
  How
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Create a Div&lt;/li&gt;
&lt;li&gt;Add some text&lt;/li&gt;
&lt;li&gt;Add some basic styling like &lt;code&gt;font-size&lt;/code&gt;, &lt;code&gt;line-height&lt;/code&gt; etc.&lt;/li&gt;
&lt;li&gt;Add a background color &lt;code&gt;background: linear-gradient(45deg, red, orange, yellow, green, blue, indigo, violet, red);&lt;/code&gt;: Rainbow 🌈 &lt;/li&gt;
&lt;li&gt;Add this property to the div &lt;code&gt;background-clip: text&lt;/code&gt;: This makes sure the background is only used for the available text&lt;/li&gt;
&lt;li&gt;Add &lt;code&gt;color: transparent&lt;/code&gt;: This makes sure that the clipped background on text is completely visible.&lt;/li&gt;
&lt;li&gt;That's it 😎&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Code
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.rainbow-text&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;linear-gradient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;45deg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;red&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;orange&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;yellow&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;green&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;blue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;indigo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;violet&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;red&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
   &lt;span class="nl"&gt;background-clip&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;text&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;transparent&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;40px&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;h4&gt;
  
  
  DEMO
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://itsopensource.com/rainbow-text/#:%7E:text=DEMO"&gt;https://itsopensource.com/rainbow-text/#:~:text=DEMO&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hope this helps 😊&lt;/p&gt;

</description>
      <category>css</category>
      <category>design</category>
      <category>frontend</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Identifying non ES5 packages</title>
      <dc:creator>Trishul</dc:creator>
      <pubDate>Sun, 15 Aug 2021 17:39:31 +0000</pubDate>
      <link>https://dev.to/itsopensource/identifying-non-es5-packages-1lh5</link>
      <guid>https://dev.to/itsopensource/identifying-non-es5-packages-1lh5</guid>
      <description>&lt;p&gt;To the delight of Frontend developers around the globe, Microsoft finally decided to kill its dreaded browser Internet explorer. But it's not done yet, and still we need to support IE in  our Frontend builds, due to which almost all our JS bundles are transpiled in ES5 formats.&lt;br&gt;&lt;br&gt;
We generally exclude all the node modules from the transpilation process as we believe all the npm packages serve ES5 packages, which is not true for every package (learned that hard 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="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;test&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\.(&lt;/span&gt;&lt;span class="sr"&gt;ts|tsx|js&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="sr"&gt;$/&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;loader&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;babel-loader&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;exclude&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;node_modules&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example, I am working with an e-commerce app and we have to support IE11 atleast for this app, one fine day our app stopped working on IE and we spent almost 2 days figuring out what's wrong. Turned out a developer introduced new state management library &lt;code&gt;recoil&lt;/code&gt;, which is an amazing tool. But, it does not serve ES5 build. This broke our application on IE.&lt;br&gt;&lt;br&gt;
To fix this all we need to do is, not exclude these packages from our transpilation and done.&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="nl"&gt;test&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\.(&lt;/span&gt;&lt;span class="sr"&gt;ts|tsx|js&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="sr"&gt;$/&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;loader&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;babel-loader&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;exclude&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;\\&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="nx"&gt;node_modules&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;\\&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;](?&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="nx"&gt;recoil&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="err"&gt;\\&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But still, we need to find manually which packages are not being served as ES5. While figuring out this problem I stumbled upon an amazing tool that automatically identifies all non-ES5 packages for us in the node modules &lt;a href="https://www.npmjs.com/package/are-you-es5"&gt;are-you-es5&lt;/a&gt;. And in bonus, it provides a regex to exclude these packages from our excluding node modules from transpilation. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvbbybotfdl5j1g3q24yp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvbbybotfdl5j1g3q24yp.png" alt="usage" width="800" height="321"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>es5</category>
      <category>webpack</category>
      <category>ie</category>
    </item>
    <item>
      <title>ReadabilityJS - adding Reader View Mode to websites</title>
      <dc:creator>Trishul</dc:creator>
      <pubDate>Mon, 18 Jan 2021 09:03:59 +0000</pubDate>
      <link>https://dev.to/itsopensource/readabilityjs-adding-reader-view-mode-to-websites-4ma3</link>
      <guid>https://dev.to/itsopensource/readabilityjs-adding-reader-view-mode-to-websites-4ma3</guid>
      <description>&lt;p&gt;One of the features I absolutely love in Firefox is &lt;code&gt;Firefox Reader View&lt;/code&gt;. This removes all the clutter and present the content in text format for better readability and relief for eyes(It also removes the ad banners 😉 ).&lt;/p&gt;

&lt;p&gt;Not all the browsers (Chrome needs special flag to enable this 😐 ) have a readability mode thus, providing an option for reader mode within your website would be a huge help to your users and would make your webpage more accessible.  &lt;/p&gt;

&lt;p&gt;The good news is you do not have to implement this on your own, Mozilla has a standalone version of the readability library used for Firefox Reader View - &lt;a href="https://github.com/mozilla/readability" rel="noopener noreferrer"&gt;&lt;strong&gt;Readability.js&lt;/strong&gt;&lt;/a&gt;.&lt;br&gt;&lt;br&gt;
The usage is pretty simple and straight forward:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We need to include the readability.js in our code in either of 2 ways:

&lt;ol&gt;
&lt;li&gt;Download the file via &lt;a href="https://github.com/mozilla/readability/releases" rel="noopener noreferrer"&gt;https://github.com/mozilla/readability/releases&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Install npm package - &lt;a href="https://www.npmjs.com/package/@mozilla/readability" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/@mozilla/readability&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create a new &lt;code&gt;Readabilty&lt;/code&gt; object from DOM document node&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight javascript"&gt;&lt;code&gt;  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;article&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;Readability&lt;/span&gt;&lt;span class="p"&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;parse&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;This article object will have following properties&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;title&lt;/code&gt;: article title&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;content&lt;/code&gt;: HTML string of processed article content&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;textContent&lt;/code&gt;: text content of the article (all HTML removed)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;length&lt;/code&gt;: length of an article, in characters&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;excerpt&lt;/code&gt;: article description, or short excerpt from the content&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;byline&lt;/code&gt;: author metadata&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;dir&lt;/code&gt;: content direction (LTR or RTL)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Note&lt;/em&gt; Readability morphs the actual object so better to pass a clone node.&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;documentClone&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;cloneNode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;article&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;Readability&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;documentClone&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;




&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Substitute this &lt;code&gt;article.textContent&lt;/code&gt; in the desired div and done 😎&lt;/p&gt;&lt;/li&gt;

&lt;/ol&gt;

&lt;p&gt;See this in action here - &lt;a href="https://itsopensource.com/demos/readability" rel="noopener noreferrer"&gt;https://itsopensource.com/demos/readability&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;center&gt;HTML View&lt;/center&gt;&lt;/strong&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F0dfbuo7cra43f1iaobd5.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%2F0dfbuo7cra43f1iaobd5.png" alt="HTML view" width="800" height="479"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;center&gt;Text View&lt;/center&gt;&lt;/strong&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F5twfljccl5texasy6cbq.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%2F5twfljccl5texasy6cbq.png" alt="text view" width="800" height="467"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Reference: &lt;a href="https://github.com/mozilla/readability" rel="noopener noreferrer"&gt;https://github.com/mozilla/readability&lt;/a&gt;&lt;/p&gt;

</description>
      <category>a11y</category>
      <category>javascript</category>
      <category>firefox</category>
      <category>readermode</category>
    </item>
    <item>
      <title>Publish GitHub pages with GitHub Actions</title>
      <dc:creator>Trishul</dc:creator>
      <pubDate>Sun, 13 Dec 2020 11:22:13 +0000</pubDate>
      <link>https://dev.to/itsopensource/publish-github-pages-with-github-actions-e1g</link>
      <guid>https://dev.to/itsopensource/publish-github-pages-with-github-actions-e1g</guid>
      <description>&lt;p&gt;GitHub pages are the best way to host static blogs like &lt;code&gt;Gatsby&lt;/code&gt;. One of the most common ways to do this is, maintain your code in main/master branch, build it, and then push the code to &lt;code&gt;gh-pages&lt;/code&gt; branch.&lt;br&gt;
There are various CI that easily automate this process like Travis CI, CircleCI, etc.&lt;br&gt;
With GitHub actions, this would be a piece of cake, and without depending on any third-party provider. From the docs: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Automate, customize, and execute your software development workflows right in your repository with GitHub Actions  &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you are not sure what are GitHub actions please visit &lt;a href="https://github.com/features/actions"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;center&gt; Workflow &lt;/center&gt;
&lt;/h2&gt;
&lt;h4&gt;
  
  
  Prerequisites
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;You have a static blog(let's say gatsby) setup, the code for your blog is in master branch.&lt;/li&gt;
&lt;li&gt;You have a build script in your package.json&lt;/li&gt;
&lt;li&gt;You have setup your GitHub pages (or pointed to your custom domain) in &lt;code&gt;gh-pages&lt;/code&gt; branch.&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;
  
  
  Process
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;&lt;center&gt; Step 1 &lt;/center&gt;&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Install &lt;a href="https://www.npmjs.com/package/gh-pages"&gt;gh-pages npm package&lt;/a&gt; in your project, this is a small utility package which helps to publish your code to gh-pages branch.&lt;br&gt;
You can skip this step in case you want to push all contents from master to &lt;code&gt;gh-pages&lt;/code&gt; branch.  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;center&gt;Step 2 &lt;/center&gt;&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Add a deploy script in your &lt;code&gt;package.json&lt;/code&gt;. This script should do 2 jobs&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Build the project, make it ready for being published.&lt;/li&gt;
&lt;li&gt;Push the changes to the &lt;code&gt;gh-pages&lt;/code&gt; branch.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For example, this pushes the code to &lt;code&gt;gh-pages&lt;/code&gt; via npm package.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"deploy": "gatsby build &amp;amp;&amp;amp; gh-pages -d public -r https://$GH_TOKEN@github.com/&amp;lt;username&amp;gt;/&amp;lt;repository_name&amp;gt;.git"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;center&gt;Step 3 &lt;/center&gt;&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Generate an access token and add it to secret of your repository.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create an access token: goto &lt;a href="https://github.com/settings/tokens"&gt;https://github.com/settings/tokens&lt;/a&gt;, create a new token, give it access for repo and workflow.
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fh2gyliyu9cm6k9jnn349.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fh2gyliyu9cm6k9jnn349.png" alt="access token" width="754" height="489"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Add this token to secret of your repository: goto &lt;code&gt;https://github.com/&amp;lt;username&amp;gt;/&amp;lt;repository_name&amp;gt;/settings/secrets/actions&lt;/code&gt;, click &lt;code&gt;new repository secret&lt;/code&gt;.
&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;&lt;strong&gt;&lt;center&gt;Step 4 &lt;/center&gt;&lt;/strong&gt;  &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a workflow file, you need to create a file in following path: &lt;code&gt;.github/workflows/&amp;lt;some-name-you-like&amp;gt;.yml&lt;/code&gt;, its important to have &lt;code&gt;.yml&lt;/code&gt; extension and have exact same path.&lt;/li&gt;
&lt;li&gt;Following action file is complete enough to publish &lt;code&gt;gh-pages&lt;/code&gt;, every time a new commit is merged in master branch. ✅
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;   &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;gh-pages publisher 🚀&lt;/span&gt;

   &lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
   &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;master&lt;/span&gt; &lt;span class="pi"&gt;]&lt;/span&gt;

   &lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
   &lt;span class="na"&gt;publish-gh-pages&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
      &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
         &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v2&lt;/span&gt;
         &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-node@v1&lt;/span&gt;
         &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;node-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;12&lt;/span&gt;
         &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm ci&lt;/span&gt;
         &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;git config user.name "&amp;lt;user name&amp;gt;" &amp;amp;&amp;amp; git config user.email "user email"&lt;/span&gt;
         &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm run deploy&lt;/span&gt;
         &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;GH_TOKEN&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{secrets.SECRET_GITHUB_TOKEN}}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This script is pretty self-explanatory, it performs the following tasks.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It specifies to work only on &lt;code&gt;push&lt;/code&gt; on &lt;code&gt;master&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Sets up a &lt;code&gt;node 12&lt;/code&gt; environment&lt;/li&gt;
&lt;li&gt;Installs dependencies via &lt;code&gt;npm ci&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Sets up git requirements for username and email (required to do a push to branch)&lt;/li&gt;
&lt;li&gt;Run the deploy script&lt;/li&gt;
&lt;li&gt;In case you don't use gh-pages npm package, you can write another step for git push to gh-pages branch.&lt;/li&gt;
&lt;li&gt;At last, we set up env variable &lt;code&gt;GH_TOKEN&lt;/code&gt; from our action secret (which you set up in step 3), this env variable would be available in &lt;code&gt;package.json&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;&lt;center&gt;Step 5 &lt;/center&gt;&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Commit this file and see your first &lt;code&gt;action&lt;/code&gt; in action (sorry for the pun 🙈 )&lt;/p&gt;




&lt;center&gt;Hope this helps 🙏🙏🙏&lt;/center&gt;






&lt;ul&gt;
&lt;li&gt;&lt;p&gt;You can see the actions running here: &lt;code&gt;https://github.com/&amp;lt;username&amp;gt;/&amp;lt;repository_name&amp;gt;/actions&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Workflow file for &lt;a href="https://itsopensource.com"&gt;itsopensource.com&lt;/a&gt; can be viewed &lt;a href="https://github.com/tsl143/itsopensource/blob/master/.github/workflows/gh-pages-publish.yml"&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>github</category>
      <category>ci</category>
      <category>automation</category>
      <category>actions</category>
    </item>
    <item>
      <title>Creating accordions with native HTML
</title>
      <dc:creator>Shivam Singhal</dc:creator>
      <pubDate>Sat, 12 Dec 2020 12:43:24 +0000</pubDate>
      <link>https://dev.to/itsopensource/creating-accordions-with-native-html-1mgi</link>
      <guid>https://dev.to/itsopensource/creating-accordions-with-native-html-1mgi</guid>
      <description>&lt;p&gt;Accordions are one of the most commonly used UI components for any website. For example FAQs section of the website, where only the question is shown, and when clicked the answer just opens up.&lt;br&gt;
Generally, we handle this by creating 2 &lt;code&gt;divs&lt;/code&gt; and adding some javascript to handle the open and close of the accordion. But recently I stumbled upon this hidden gem in HTML that eliminates the need of all this - &lt;a href="https://developer.mozilla.org/docs/Web/HTML/Element/details"&gt;&lt;code&gt;&amp;lt;details&amp;gt;&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can simply design a simple FAQ or summary section with &lt;code&gt;&amp;lt;details&amp;gt;&lt;/code&gt; HTML tag without using Javascript!!! 🤯🤯🤯.&lt;br&gt;
And the best part... it is supported by all the modern browsers (obviously except IE :( ) - &lt;a href="https://caniuse.com/?search=details"&gt;browser compatibility&lt;/a&gt;.  &lt;/p&gt;
&lt;h3&gt;
  
  
  Using &lt;code&gt;&amp;lt;details&amp;gt;&lt;/code&gt; tag
&lt;/h3&gt;

&lt;p&gt;There are two elements here: &lt;code&gt;&amp;lt;details&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;summary&amp;gt;&lt;/code&gt;. &lt;code&gt;&amp;lt;details&amp;gt;&lt;/code&gt; is the wrapper for all the content you want to show and hide, and  contains the — well, the summary and title of the section. &lt;code&gt;&amp;lt;summary&amp;gt;&lt;/code&gt; is optional, if you do not add it, the browser will use some default text. For example, in Firefox and Chrome, it is &lt;code&gt;Details&lt;/code&gt;. Below is a sample HTML markup:&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;details&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;Details&lt;span class="nt"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Something small enough to escape casual notice.&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/details&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And it will render like:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--TrZYOQZC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/vgjgg43x944mbadpks72.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--TrZYOQZC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/vgjgg43x944mbadpks72.gif" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This markup can be designed with CSS as any other HTML element. Now for creating beautiful accordions all you need is just HTML and CSS (and a will to let go of IE).&lt;/p&gt;

&lt;p&gt;Demo: &lt;a href="https://bit.ly/htmldetails"&gt;https://itsopensource.com/demos/details/&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  References
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/details"&gt;MDN: details&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cheers.&lt;/p&gt;

</description>
      <category>html</category>
      <category>beginners</category>
      <category>webdev</category>
      <category>frontend</category>
    </item>
    <item>
      <title>Content Security Policy - protect your website from XSS attacks</title>
      <dc:creator>Trishul</dc:creator>
      <pubDate>Sat, 31 Oct 2020 11:05:30 +0000</pubDate>
      <link>https://dev.to/itsopensource/content-security-policy-protect-your-website-from-xss-attacks-13h9</link>
      <guid>https://dev.to/itsopensource/content-security-policy-protect-your-website-from-xss-attacks-13h9</guid>
      <description>&lt;h3&gt;
  
  
  Problem
&lt;/h3&gt;

&lt;p&gt;It's very common while building any project we use certain third party libraries, in the case of Javascript; &lt;code&gt;npm packages&lt;/code&gt;, which recursively use more packages, and eventually your code includes a huge chunk of third party code.&lt;br&gt;&lt;br&gt;
There is nothing wrong with it, there is no point re-inventing the wheel. We include the required library, make our code work, write tests. Deploy to a staging environment, pass through automation and finally deploy to production.  &lt;/p&gt;

&lt;p&gt;The problem is when a library tries to load remote content on our website. It can be an image, font, style, or even Javascript. This content bypasses all our tests, checks, and is executed directly on production. Even worse we don't know where the content is being served from.&lt;/p&gt;
&lt;h3&gt;
  
  
  Content Security Policy
&lt;/h3&gt;

&lt;p&gt;Content Security Policy (CSP) is a &lt;a href="https://www.w3.org/TR/CSP3/"&gt;W3C specification&lt;/a&gt; that helps to avoid &lt;code&gt;XSS&lt;/code&gt; attacks. CSP enables developers to define rules for fetching the resources(images, javascript, fonts, etc.) on the client browser. Developers can define policies to allow/restrict loading any resource, restrict resources to load only from certain domains, and disallow from any other domain. For example, you can write a CSP to restrict browsers to load images only from &lt;code&gt;example.com&lt;/code&gt;, any images from other domains will be not loaded and would throw errors. In addition to resources, CSP also offers control over the embeds.&lt;br&gt;&lt;br&gt;
In the following example, the CSP forces to load images/scripts only from self domain and prevents the loading of images from other domains.&lt;/p&gt;

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

&lt;p&gt;&lt;em&gt;From the &lt;a href="https://www.w3.org/TR/CSP3/"&gt;W3c specification&lt;/a&gt; docs:&lt;/em&gt; &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;One of the CSP goal is to mitigate the risk of content-injection attacks by giving developers fairly granular control over&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The resources which can be requested (and subsequently embedded or executed) on behalf of a specific Document or Worker&lt;/li&gt;
&lt;li&gt;The execution of inline script&lt;/li&gt;
&lt;li&gt;Dynamic code execution (via eval() and similar constructs)&lt;/li&gt;
&lt;li&gt;The application of inline style&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h3&gt;
  
  
  How
&lt;/h3&gt;

&lt;p&gt;CSP can be implemented in following two ways:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Specify in &lt;strong&gt;HTTP headers&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   Content-Security-Policy: __Policy__
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ol&gt;
&lt;li&gt;Specify in &lt;strong&gt;META tags&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&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;meta&lt;/span&gt; &lt;span class="na"&gt;http-equiv=&lt;/span&gt;&lt;span class="s"&gt;"Content-Security-Policy"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;" __Policy__ "&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h4&gt;
  
  
  Defining a policy
&lt;/h4&gt;

&lt;p&gt;The Policy is the accumulation of directives which defines the allowed location of each resource, no directive means allowed for all. Some of the useful directives are the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;default-src&lt;/em&gt; : This defines the loading policy for all types of resources.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;script-src&lt;/em&gt; : This defines the loading policy for all javascript, from where javascript can be loaded.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;img-src&lt;/em&gt; : This defines the loading policy for all images, from where images can be loaded. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;List of directives for the other resources is &lt;a href="https://developers.google.com/web/fundamentals/security/csp#policy_applies_to_a_wide_variety_of_resources"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Some examples of policies are:&lt;br&gt;
1.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   Content-Security-Policy: default-src 'self';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This would allow resources only from the same domain, and all other resources will fail to load.&lt;br&gt;
2.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   Content-Security-Policy: img-src example.com;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This would allow images only from &lt;code&gt;example.com&lt;/code&gt;, and all other images will fail to load.&lt;br&gt;
2.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   Content-Security-Policy: default-src 'self'; img-src example.com;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This would allow any resources to load only if from the same domain, except images which can be from &lt;code&gt;example.com&lt;/code&gt; too.&lt;/p&gt;

&lt;h4&gt;
  
  
  Reporting
&lt;/h4&gt;

&lt;p&gt;CSP also provides a way to send violation reports, in case any logging is required, via &lt;code&gt;report-uri&lt;/code&gt; directive.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`Content-Security-Policy: default-src 'self'; report-uri http://example.com/cspfails` 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The reports will be sent as POST request and with following JSON:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"csp-report"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="nl"&gt;"document-uri"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"http://example.com/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="nl"&gt;"referrer"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="nl"&gt;"blocked-uri"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"http://example.com/some_malware.js"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="nl"&gt;"violated-directive"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"default-src self"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="nl"&gt;"original-policy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"default-src 'self'; report-uri http://example.com/cspfails"&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;h3&gt;
  
  
  Risks
&lt;/h3&gt;

&lt;p&gt;Before defining a CSP you should be completely aware of all the resources and respective origin required for your webapp, else some vital resources may be blocked and eventually random bugs. &lt;br&gt;
In case you are not sure what all resources are being required for running your web page smoothly, you can implement the CSP in reporting mode, in this way the violations will be reported but no resource will be blocked, once you are sure what are the resources really required, you can implement CSP. To do this instead of &lt;code&gt;Content-Security-Policy&lt;/code&gt; we need to use &lt;code&gt;Content-Security-Policy-Report-Only&lt;/code&gt; header.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Content-Security-Policy-Report-Only: __Policy__ + report-uri
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Resources
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP"&gt;https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://owasp.org/www-community/attacks/Content_Security_Policy"&gt;https://owasp.org/www-community/attacks/Content_Security_Policy&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>javascript</category>
      <category>security</category>
      <category>bestpractices</category>
    </item>
    <item>
      <title>How to checkout github pull requests locally like Pro
</title>
      <dc:creator>Shivam Singhal</dc:creator>
      <pubDate>Thu, 01 Oct 2020 18:57:16 +0000</pubDate>
      <link>https://dev.to/itsopensource/how-to-checkout-github-pull-requests-locally-like-pro-1f22</link>
      <guid>https://dev.to/itsopensource/how-to-checkout-github-pull-requests-locally-like-pro-1f22</guid>
      <description>&lt;p&gt;If you work with the repositories hosted on Github , you have to deal with lot of Pull requests daily generally, and the process to checkout the PR's locally in your machine is quite not easy, you have to see the PR's id and also the branch name.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git fetch origin pull/ID/head:BRANCHNAME
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And if the PR is in upstream repository, first you need to add that particular user as remote in your local copy of the project and then pull the particular branch of the contributor. For example&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git remote add fayem git@github.com:fayepal/itsopensource.git
git checkout &lt;span class="nt"&gt;-b&lt;/span&gt; fayem fayepal/blog-docker-vm
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As we see its quite long process and you will have lot of remote added in your repository as well.&lt;/p&gt;

&lt;p&gt;To solve this there is a awesome &lt;a href="https://gist.github.com/gnarf/5406589" rel="noopener noreferrer"&gt;git alias&lt;/a&gt; by gnarf:&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="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;alias&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
  &lt;span class="nb"&gt;pr&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"!f() { git fetch -fu &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;2&lt;/span&gt;&lt;span class="k"&gt;:-&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;git remote |grep ^upstream &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;echo &lt;/span&gt;origin&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; refs/pull/&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="s2"&gt;/head:pr/&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="s2"&gt; &amp;amp;&amp;amp; git checkout pr/&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="s2"&gt;; }; f"&lt;/span&gt;
  pr-clean &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"!git for-each-ref refs/heads/pr/* --format='%(refname)' | while read ref ; do branch=&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;#refs/heads/&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; ; git branch -D &lt;/span&gt;&lt;span class="nv"&gt;$branch&lt;/span&gt;&lt;span class="s2"&gt; ; done"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Either you can add them directly in your &lt;code&gt;.gitconfig&lt;/code&gt; file or by doing so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git config &lt;span class="nt"&gt;--global&lt;/span&gt; alias.pr &lt;span class="s1"&gt;'!f() { git fetch -fu ${2:-$(git remote |grep ^upstream || echo origin)} refs/pull/$1/head:pr/$1 &amp;amp;&amp;amp; git checkout pr/$1; }; f'&lt;/span&gt;
git config &lt;span class="nt"&gt;--global&lt;/span&gt; alias.pr-clean &lt;span class="s1"&gt;'!git for-each-ref refs/heads/pr/* --format="%(refname)" | while read ref ; do branch=${ref#refs/heads/} ; git branch -D $branch ; done'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you simply do &lt;code&gt;git pr x&lt;/code&gt; and it will do the magic for you:&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F8epzbjljjo7t49wiaf3h.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%2F8epzbjljjo7t49wiaf3h.jpg" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cheers&lt;/p&gt;

</description>
      <category>github</category>
      <category>git</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Decoupled DRUPAL 8 With JSON API</title>
      <dc:creator>Dipali Goel</dc:creator>
      <pubDate>Wed, 09 Sep 2020 14:42:11 +0000</pubDate>
      <link>https://dev.to/itsopensource/decoupled-drupal-8-with-json-api-59ma</link>
      <guid>https://dev.to/itsopensource/decoupled-drupal-8-with-json-api-59ma</guid>
      <description>&lt;h3&gt;
  
  
  Benefits of decoupled architecture
&lt;/h3&gt;

&lt;p&gt;A decoupled architecture does great work in reducing or completely eliminating problems that are a part of the monolithic content management systems.&lt;br&gt;
CMS data is exposed to and consumed by a front-end JavaScript framework. The framework can be React.js, Angular.js, and many more.&lt;/p&gt;
&lt;h3&gt;
  
  
  Json API
&lt;/h3&gt;

&lt;p&gt;In JSON API, the consumer can get all the data with a single query, tracing relationships between objects and returning the desired output in a single shot.&lt;br&gt;
A single request from a consumer can return multiple entities. For the same API, different consumers may use different embedding patterns, depending on the requirement.&lt;br&gt;
All API can be customized according to the requirement which we can achieve by downloading and enabling JSONAPI Extras module.&lt;/p&gt;
&lt;h3&gt;
  
  
  Enable json API
&lt;/h3&gt;


&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;Using Drush
&lt;span class="nv"&gt;$ &lt;/span&gt;drush en serialization &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;drush en jsonapi &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;drush dl jsonapi_extras &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; drush en jsonapi_extras &lt;span class="nt"&gt;-y&lt;/span&gt;

Using Drupal Console
&lt;span class="nv"&gt;$ &lt;/span&gt;drupal module:install serialization
&lt;span class="nv"&gt;$ &lt;/span&gt;drupal module:install jsonapi
&lt;span class="nv"&gt;$ &lt;/span&gt;drupal module:download jsonapi_extras &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; drupal module:install jsonapi_extras
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Configuration
&lt;/h3&gt;

&lt;p&gt;JSONAPI is a zero-configuration module that gives access to all Drupal entities for reading out of the box.&lt;br&gt;
You need to go to the module settings page &lt;em&gt;&lt;code&gt;(/admin/config/services/jsonapi)&lt;/code&gt;&lt;/em&gt; and make the changes according to the requirement.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--R-Lqp6ca--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/e3z4tdbcu5m4ot6pya00.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--R-Lqp6ca--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/e3z4tdbcu5m4ot6pya00.png" alt="Json API"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Retrieving resources with JSON API
&lt;/h3&gt;

&lt;p&gt;JSON API specification recommends that all requests include an Accept header with the correct MIME type for JSON API, &lt;br&gt;
the JSON API module accepts requests without any request headers present.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Retrieving resource collections&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Key motivations for using JSON API instead of REST is the possibility of retrieving multiple resources using JSON API collections. &lt;br&gt;
There is only Views rest export to get the collection entities can be retrieved. In JSON API, simply issue a GET request against the following URL to retrieve a collection of entities eg for articles:&lt;br&gt;
&lt;code&gt;/jsonapi/node/article&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Using JSON API specification, you can use certain query parameters to operate on the collections retrieved through the API. &lt;br&gt;
Eg  &lt;code&gt;page[limlit],sort&lt;/code&gt;&lt;br&gt;
&lt;code&gt;/jsonapi/node/article?sort=nid&lt;/code&gt;&lt;br&gt;
&lt;code&gt;/jsonapi/node/article?page[limit]=30&amp;amp;page[offset]=25&lt;/code&gt;&lt;br&gt;
&lt;code&gt;/jsonapi/node/article?page[limit]=30&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Retrieving limited subsets of fields&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
To capture only the title, created and modified timestamps, and body of the entity, you can provide fields query parameter.&lt;br&gt;
Note that with the parameter, the type and bundle must be included as well.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;/jsonapi/node/article?fields[node--article]=title,created&lt;/code&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Creating resources with JSON API
&lt;/h3&gt;

&lt;p&gt;The JSON API specification allows for individual resources to be created through an API.&lt;br&gt;
The following request headers are obligatory on all POST requests in order to generate a standard response:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Accept: application/vnd.api+json&lt;/code&gt;&lt;br&gt;
&lt;code&gt;Content-Type: application/vnd.api+json&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;To POST request that creates an article, use the same URL that we used to retrieve collections of articles:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;/jsonapi/node/article&lt;/code&gt;&lt;br&gt;
For creating an article, you can include a relationship to a user to indicate that they were the one to create the article.&lt;br&gt;
The following payload reflects a relationship that connects the entity to an existing user &lt;code&gt;({{user_uuid}})&lt;/code&gt; &lt;br&gt;
whose authorship is assigned in this POST request.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"node--article"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"attributes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"My snazzy new article"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"body"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Hello world! Lorem ipsum dolor sit amet consectetur adipiscing elit"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"format"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"plain_text"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"relationships"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"uid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"user--user"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"{{user_uuid}}"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This request will result in a 201 Created response code with the JSON API response of the created entity.&lt;br&gt;
Sample response from postman&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--fp-PIgMT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/wc69vi6ygwzc95fw31m9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fp-PIgMT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/wc69vi6ygwzc95fw31m9.png" alt="postman image 1"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--eAYjrW2y--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/zagvn8ua4fitbdd6sfcf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--eAYjrW2y--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/zagvn8ua4fitbdd6sfcf.png" alt="postman image 2"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Updating resources with JSON API
&lt;/h3&gt;

&lt;p&gt;PATCH requests also require the following headers.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Accept: application/vnd.api+json&lt;br&gt;
Content-Type: application/vnd.api+json&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;We use &lt;code&gt;PATCH&lt;/code&gt; to modifies an article, find the UUID of the article in question and append it to the end of the &lt;br&gt;
URL, as follows:&lt;br&gt;
&lt;code&gt;/jsonapi/node/article/{{node_uuid}}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;And include a request payload that contains only the fields that you intend to modify and the UUID of the entity in question:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"node--article"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"{{node_uuid}}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"attributes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Change in article"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--T6nYpZ_l--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/4smtjmsmgiqd0z15dfgn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--T6nYpZ_l--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/4smtjmsmgiqd0z15dfgn.png" alt="Patch 1"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--yhzbL5l2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/zh10aacu5yf7nbubgygx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--yhzbL5l2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/zh10aacu5yf7nbubgygx.png" alt="patch 2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Deleting resources with JSON API
&lt;/h3&gt;

&lt;p&gt;We can delete the artcile which we have created using &lt;code&gt;DELETE&lt;/code&gt; method&lt;br&gt;
Headers :&lt;br&gt;
&lt;code&gt;Content-Type: application/vnd.api+json&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;With DELETE requests no payload is required. We need to add the correct resource using its UUID and use the &lt;code&gt;Delete&lt;/code&gt; method for that URL.&lt;br&gt;
&lt;code&gt;/jsonapi/node/article/{{node_uuid}}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;It will result in a 204 No Content response code .&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zAg1_YR_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/djx9hit3txgb3gkj6hd9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zAg1_YR_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/djx9hit3txgb3gkj6hd9.png" alt="Delete Content"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;With the evolution of web-based APIs, this json format is a better approach than XML. &lt;br&gt;
JSONAPI has a great experience by making the Drupal entities (users, comments and more) available via a web service API. &lt;br&gt;
URLs can be manipulated as per the requirement to access the entity types and bundles using HTTP methods.&lt;/p&gt;

</description>
      <category>php</category>
      <category>drupal</category>
      <category>jsonapi</category>
    </item>
    <item>
      <title>Conversion of SSH2 private key to openSSH format using PuTTYgen</title>
      <dc:creator>palgoel</dc:creator>
      <pubDate>Sun, 06 Sep 2020 07:31:19 +0000</pubDate>
      <link>https://dev.to/itsopensource/conversion-of-ssh2-private-key-to-openssh-format-using-puttygen-3i70</link>
      <guid>https://dev.to/itsopensource/conversion-of-ssh2-private-key-to-openssh-format-using-puttygen-3i70</guid>
      <description>&lt;h3&gt;
  
  
  Problem Statement
&lt;/h3&gt;

&lt;p&gt;While working on mercurial(Version Control System), we need to generate different public/private keys for windows &amp;amp; Linux, which leads to have multiple keys for single user.&lt;/p&gt;

&lt;h3&gt;
  
  
  Solution
&lt;/h3&gt;

&lt;p&gt;If we want to access mercurial through Linux with your same key as Windows, then instead of generating a new rsa key pair ,we can reuse same public/private key pair to access mercurial from linux.&lt;br&gt;
Hence same repository you can access via windows or linux without creating separate public/private key pair for both.&lt;/p&gt;

&lt;h3&gt;
  
  
  STEPS :
&lt;/h3&gt;

&lt;p&gt;Pre-requisite: There must a key pair existing in SSH2 format to access mercurial`&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open the PuTTY Key Generator&lt;/li&gt;
&lt;li&gt;On the menu bar, click "File" -&amp;gt; "Load private key"&lt;/li&gt;
&lt;li&gt;Select your .ppk file&lt;/li&gt;
&lt;li&gt;On the menu bar, click "Conversions" -&amp;gt; "Export OpenSSH key"&lt;/li&gt;
&lt;li&gt;Save the file as  (without an extension) e.g. mercurial_rsa
`&lt;code&gt;&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You are all done. Same private key on windows can be reused(with above steps) with Linux.&lt;/p&gt;

</description>
      <category>mercurial</category>
      <category>hg</category>
    </item>
    <item>
      <title>How to move forward and backward between commits in git</title>
      <dc:creator>Shivam Singhal</dc:creator>
      <pubDate>Thu, 03 Sep 2020 16:31:52 +0000</pubDate>
      <link>https://dev.to/itsopensource/how-to-move-forward-and-backward-between-commits-in-git-16i3</link>
      <guid>https://dev.to/itsopensource/how-to-move-forward-and-backward-between-commits-in-git-16i3</guid>
      <description>&lt;p&gt;We always keep moving forward and backward between commits in &lt;code&gt;git&lt;/code&gt;. Once you checked out a previous hash &lt;code&gt;git log&lt;/code&gt; no more shows the next commits, we end up rebasing or resetting, but git provides a way to see all the commits, and we can checkout the next commits too from a previous state.&lt;/p&gt;

&lt;p&gt;The simple and easiest way to do this is:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

git log &lt;span class="nt"&gt;--online&lt;/span&gt; &lt;span class="nt"&gt;--all&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Consider this example:&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ffw8f8g61scfz14m3mj85.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%2Ffw8f8g61scfz14m3mj85.jpg" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here if we check out to commit id &lt;code&gt;95613ab Fix more TOC links&lt;/code&gt; and then see the git history with &lt;code&gt;git log&lt;/code&gt; or &lt;code&gt;git log --oneline&lt;/code&gt; you will only see:&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fbiwtwx5i8q3sx9edmsr5.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%2Fbiwtwx5i8q3sx9edmsr5.jpg" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As we see here we missed the commits ahead of &lt;code&gt;95613ab&lt;/code&gt;. You can see the HEAD with &lt;code&gt;git show-ref --head&lt;/code&gt; but it will not show the commits in between the &lt;code&gt;HEAD&lt;/code&gt; and the commit you checked out. So if you do &lt;code&gt;git log --oneline --all&lt;/code&gt; you will get the whole history with the commit where the &lt;code&gt;HEAD&lt;/code&gt; is right now.&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fbprablapi53w3g8ehdjz.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%2Fbprablapi53w3g8ehdjz.jpg" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let us know if you know the better solution for this problem.&lt;/p&gt;

&lt;p&gt;Cheers.&lt;/p&gt;

</description>
      <category>git</category>
      <category>github</category>
      <category>beginners</category>
      <category>howto</category>
    </item>
    <item>
      <title>Best way to keep users safe while using Google Analytics</title>
      <dc:creator>Trishul</dc:creator>
      <pubDate>Sun, 12 Jul 2020 15:54:17 +0000</pubDate>
      <link>https://dev.to/itsopensource/best-way-to-keep-users-safe-while-using-google-analytics-16c2</link>
      <guid>https://dev.to/itsopensource/best-way-to-keep-users-safe-while-using-google-analytics-16c2</guid>
      <description>&lt;p&gt;Google Analytics is the most used web analytics service over the web, Google has made it pretty easy and effective in terms of implementation and dashboard UI. It gives detailed demographic data and many other features that justify its vast usage.&lt;br&gt;
The most common and easiest way to enable google analytics on any website is by adding the tag manager (the code snippet provided) to the website.&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="c"&gt;&amp;lt;!-- Global site tag (gtag.js) - Google Analytics --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;async&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://www.googletagmanager.com/gtag/js?id=UA-XXXXXXXXX-1"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
  &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dataLayer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dataLayer&lt;/span&gt; &lt;span class="o"&gt;||&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;gtag&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;&lt;span class="nx"&gt;dataLayer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;);}&lt;/span&gt;
  &lt;span class="nf"&gt;gtag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

  &lt;span class="nf"&gt;gtag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;config&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;UA-XXXXXXXXX-1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Problem
&lt;/h3&gt;

&lt;p&gt;Adding a Tag manager is &lt;strong&gt;allowing google to run some code on your website&lt;/strong&gt; whenever someone visits the website or do some action (I would request to read this line once more). Based on the options selected on the analytics UI, Google inserts the scripts into the website, sends the data back with &lt;code&gt;HTTP requests&lt;/code&gt;. Data includes the complete URL(with query params) and many other details that may be classified as &lt;code&gt;Personal Identifiable Information(PII)&lt;/code&gt;. &lt;a href="https://twitter.com/konarkmodi"&gt;Konark Modi&lt;/a&gt;, a privacy advocate, has written a detailed case study on how sensitive user data or PII is getting leaked to third parties, including Google Analytics, in &lt;a href="https://medium.com/free-code-camp/how-airlines-dont-care-about-your-privacy-case-study-emirates-com-6271b3b8474b"&gt;this blog&lt;/a&gt;.&lt;br&gt;
As a developer, we always want to have complete control over whatever is being served on our website. Google tag managers kind of blow this up.&lt;br&gt;&lt;br&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fs44ovlswrsfseb4v5cvt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fs44ovlswrsfseb4v5cvt.png" alt="Leak 1" width="800" height="303"&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fuxlsfqhhvp8am27794h4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fuxlsfqhhvp8am27794h4.png" alt="Leak 2" width="800" height="25"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Solution
&lt;/h3&gt;

&lt;p&gt;This can be avoided by using &lt;strong&gt;Google Measurement protocol&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;From the &lt;a href="https://developers.google.com/analytics/devguides/collection/protocol/v1"&gt;docs&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The Google Analytics Measurement Protocol allows developers to make HTTP requests to send raw user interaction data directly to Google Analytics servers&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;TLDR; Do not load google scripts but, create and send HTTP requests by yourself. This gives way more control over what you want to send to google and ensures your complete control over your website. You can send Requests for whatever action needs to be recorded for analytics. It can be just page visits, clicks, or any event.&lt;/p&gt;
&lt;h4&gt;
  
  
  How
&lt;/h4&gt;

&lt;p&gt;Analytics tool receives the data via query parameters of the request, a typical request looks like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;POST /collect HTTP/1.1
Host: www.google-analytics.com

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

&lt;/div&gt;



&lt;p&gt;Mandatory parameters are&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;v=1              // Version of the tool.
&amp;amp;tid=UA-XXXXX-Y  // Tracking ID / Property ID.
&amp;amp;cid=555         // Anonymous Client ID.
&amp;amp;t=              // Hit Type
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Google provides a number of parameters in case you want more detailed analytics say for e-commerce, check the parameter guide &lt;a href="https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters"&gt;here&lt;/a&gt;, some interesting parameters which can be controlled are&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;dr&lt;/code&gt; - Document referrer //  = document.referrer&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;dl&lt;/code&gt; - Location URL // = document.location.origin + document.location.pathname (also may be document.location.search)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;aip&lt;/code&gt; - Anonymize IP, if present the IP address of the sender will be anonymized // = 1&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;npa&lt;/code&gt; - Disable advertising personalization - if enabled  it won't be used when populating a remarketing audience for "past purchasers" // = 1&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Lesser&lt;/strong&gt; the parameters, &lt;strong&gt;lesser&lt;/strong&gt; the data sent, &lt;strong&gt;better&lt;/strong&gt; the privacy.&lt;/p&gt;

&lt;p&gt;Google also provides a tool to check and create a proper hit via &lt;a href="https://ga-dev-tools.appspot.com/hit-builder/"&gt;Hit Builder&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you find this a bit exhausting, then at least follow the best practices to make sure you are not sending the user's personal data to google.&lt;br&gt;
&lt;a href="https://support.google.com/analytics/answer/6366371"&gt;https://support.google.com/analytics/answer/6366371&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;center&gt;--- Keep your users safe ---&lt;/center&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>privacy</category>
      <category>javascript</category>
      <category>analytics</category>
    </item>
    <item>
      <title>How to Reduce Node Docker Image Size by 10X</title>
      <dc:creator>Shivam Singhal</dc:creator>
      <pubDate>Sat, 04 Jul 2020 09:35:29 +0000</pubDate>
      <link>https://dev.to/itsopensource/how-to-reduce-node-docker-image-size-by-10x-1h81</link>
      <guid>https://dev.to/itsopensource/how-to-reduce-node-docker-image-size-by-10x-1h81</guid>
      <description>&lt;p&gt;Dockerizing an application is simple, effective, but optimizing the size of Docker Image is the tricky part. Docker is easy to use but once the application starts scaling, the image size inflates exponentially. In general, the node docker image size of the applications is over 1 GB most of the time.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why the Size matters
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Large docker image sizes - Bigger image size requires more space means increased expense.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Long build durations - It takes a longer time to push the images over the network and results in CI Pipeline delays.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Let’s Start The Optimization
&lt;/h3&gt;

&lt;p&gt;Here is our &lt;a href="https://github.com/championshuttler/fluentbit-dashboard"&gt;demo application&lt;/a&gt; built using the VueJS Application. &lt;/p&gt;

&lt;p&gt;Here is the initial Dockerfile.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;FROM node:10

WORKDIR /app

COPY &lt;span class="nb"&gt;.&lt;/span&gt; /app

EXPOSE 8080

RUN npm &lt;span class="nb"&gt;install &lt;/span&gt;http-server &lt;span class="nt"&gt;-g&lt;/span&gt;

RUN npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; npm run build

CMD http-server ./dist
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The size of this image is:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_aM9nfwM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ta1hdfyjshvo3o2stzz6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_aM9nfwM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ta1hdfyjshvo3o2stzz6.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It is 1.34GB! Whoops!&lt;/p&gt;

&lt;p&gt;Let's start optimizing step by step&lt;/p&gt;

&lt;p&gt;1) Use &lt;strong&gt;Multi-Stage&lt;/strong&gt; Docker Builds&lt;/p&gt;

&lt;p&gt;Multi-stage builds make it easy to optimize Docker images by using multiple &lt;strong&gt;intermediate&lt;/strong&gt; images in a single Dockerfile. Read more about it &lt;a href="https://docs.docker.com/develop/develop-images/multistage-build/"&gt;here&lt;/a&gt;. By using multi-stage builds, we can install all dependencies in the build image and copy them to the leaner runtime image.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;FROM node:10 AS BUILD_IMAGE

WORKDIR /app

COPY &lt;span class="nb"&gt;.&lt;/span&gt; /app

EXPOSE 8080

RUN npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; npm run build

FROM node:10

WORKDIR /app

&lt;span class="c"&gt;# copy from build image&lt;/span&gt;
COPY &lt;span class="nt"&gt;--from&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;BUILD_IMAGE /app/dist ./dist
COPY &lt;span class="nt"&gt;--from&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;BUILD_IMAGE /app/node_modules ./node_modules

RUN npm i &lt;span class="nt"&gt;-g&lt;/span&gt; http-server

CMD http-server ./dist
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the size of this image is 1.24GB:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gviww1fS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/n6uityca4i5u1ib2yjd4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gviww1fS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/n6uityca4i5u1ib2yjd4.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;2) Remove Development Dependencies and use &lt;strong&gt;Node Prune&lt;/strong&gt; Tool&lt;/p&gt;

&lt;p&gt;node-prune is an open-source tool for removing unnecessary files from the node_modules folder. Test files, markdown files, typing files and *.map files in Npm packages are not required at all in the production environment generally, most of the developers do not remove them from the production package. By using node-prune it can safely be removed.&lt;/p&gt;

&lt;p&gt;We can use this to remove Development Dependencies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm prune &lt;span class="nt"&gt;--production&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After making these changes &lt;code&gt;Dockerfile&lt;/code&gt; will look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;FROM node:10 AS BUILD_IMAGE

RUN curl &lt;span class="nt"&gt;-sfL&lt;/span&gt; https://install.goreleaser.com/github.com/tj/node-prune.sh | bash &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="nt"&gt;-b&lt;/span&gt; /usr/local/bin

WORKDIR /app

COPY &lt;span class="nb"&gt;.&lt;/span&gt; /app

EXPOSE 8080

RUN npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; npm run build

&lt;span class="c"&gt;# remove development dependencies&lt;/span&gt;
RUN npm prune &lt;span class="nt"&gt;--production&lt;/span&gt;

&lt;span class="c"&gt;# run node prune&lt;/span&gt;
RUN /usr/local/bin/node-prune

FROM node:10

WORKDIR /app

&lt;span class="c"&gt;# copy from build image&lt;/span&gt;
COPY &lt;span class="nt"&gt;--from&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;BUILD_IMAGE /app/dist ./dist
COPY &lt;span class="nt"&gt;--from&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;BUILD_IMAGE /app/node_modules ./node_modules

RUN npm i &lt;span class="nt"&gt;-g&lt;/span&gt; http-server

CMD http-server ./dist
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By using this we reduced the overall size to 1.09GB&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jMocakz0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/r87f0ip9ctrdgvt08yb1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jMocakz0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/r87f0ip9ctrdgvt08yb1.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;3) Choose &lt;strong&gt;Smaller Final Base Image&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When dockerizing a node application, there are lots of &lt;a href="https://hub.docker.com/_/node/"&gt;base images&lt;/a&gt; available to choose from.&lt;/p&gt;

&lt;p&gt;Here we will use &lt;strong&gt;alpine&lt;/strong&gt; image; alpine is a lean docker image with minimum packages but enough to run node applications.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;FROM node:10 AS BUILD_IMAGE

RUN curl -sfL https://install.goreleaser.com/github.com/tj/node-prune.sh | bash -s -- -b /usr/local/bin

WORKDIR /app

COPY . /app

EXPOSE 8080

RUN npm install &amp;amp;&amp;amp; npm run build

&lt;/span&gt;&lt;span class="gp"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;remove development dependencies
&lt;span class="go"&gt;RUN npm prune --production

&lt;/span&gt;&lt;span class="gp"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;run node prune
&lt;span class="go"&gt;RUN /usr/local/bin/node-prune

FROM node:10-alpine

WORKDIR /app

&lt;/span&gt;&lt;span class="gp"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;copy from build image
&lt;span class="go"&gt;COPY --from=BUILD_IMAGE /app/dist ./dist
COPY --from=BUILD_IMAGE /app/node_modules ./node_modules

RUN npm i -g http-server

CMD http-server ./dist
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By using this &lt;code&gt;Dockerfile&lt;/code&gt; the image size dropped to &lt;code&gt;157MB&lt;/code&gt; \o/&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_8lcgFKg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/o9rypq0k50co2w2betrl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_8lcgFKg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/o9rypq0k50co2w2betrl.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;By applying these 3 simple steps, we reduced our docker image size by 10 times.&lt;/p&gt;

&lt;p&gt;Cheers!&lt;/p&gt;

</description>
      <category>docker</category>
      <category>beginners</category>
      <category>howto</category>
      <category>devops</category>
    </item>
  </channel>
</rss>
