<?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: Milos</title>
    <description>The latest articles on DEV Community by Milos (@milosdukic).</description>
    <link>https://dev.to/milosdukic</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%2F180122%2F627c5afd-9e79-4998-8fb9-b6008493367d.png</url>
      <title>DEV Community: Milos</title>
      <link>https://dev.to/milosdukic</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/milosdukic"/>
    <language>en</language>
    <item>
      <title>RVM Ruby 2.6.0 — built with custom openssl version on Ubuntu 22.04</title>
      <dc:creator>Milos</dc:creator>
      <pubDate>Fri, 26 Apr 2024 12:11:45 +0000</pubDate>
      <link>https://dev.to/milosdukic/rvm-ruby-260-built-with-custom-openssl-version-on-ubuntu-2204-186l</link>
      <guid>https://dev.to/milosdukic/rvm-ruby-260-built-with-custom-openssl-version-on-ubuntu-2204-186l</guid>
      <description>&lt;p&gt;Setup: Ubuntu 22.04, rvm, RoR (4.2.X), Ruby 2.1.7&lt;/p&gt;

&lt;p&gt;Recently I had a task to update Ruby from &lt;code&gt;2.1.7&lt;/code&gt; to &lt;code&gt;2.6.0&lt;/code&gt; while keeping the RoR version to &lt;code&gt;4.2.X&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;After standard &lt;code&gt;rvm install 2.6.0&lt;/code&gt; and &lt;code&gt;bundle install&lt;/code&gt; command, I had to bump Rails to &lt;code&gt;4.2.8&lt;/code&gt; due some incompatibility with gems, and then &lt;code&gt;bundle install&lt;/code&gt; yielded some &lt;a href="https://stackoverflow.com/questions/49674564/package-configuration-for-libxml2-is-not-found"&gt;errors&lt;/a&gt; for gems, which I had to resolve by installing &lt;code&gt;sudo apt-get install libxml12-dev libcurl14-openssl-dev&lt;/code&gt; packages, which coincidently removed &lt;code&gt;libssl1&lt;/code&gt;, and the build passed.&lt;/p&gt;

&lt;p&gt;But when I ran the RoR app, I got SSL certification issue from the &lt;strong&gt;3rd party service&lt;/strong&gt;, which was working fine with previous versions of Ruby and Rails: &lt;code&gt;SSL_connect returned=1 errno=0 state=error: certificate verify failed (unable to get local issuer certificate)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;So I removed &lt;code&gt;Ruby 2.6.0&lt;/code&gt; and tried to build from scratch, and got issue during ruby install process, apparently I was missing &lt;code&gt;openssl&lt;/code&gt; library files. &lt;code&gt;Ruby 2.6.0&lt;/code&gt; was not compatible with the system &lt;code&gt;openssl&lt;/code&gt; libs, which was strange since the first time it passed.&lt;/p&gt;

&lt;p&gt;It turns out that &lt;code&gt;libssl1&lt;/code&gt; , which was removed was crucial, and the &lt;code&gt;2.6.0&lt;/code&gt; can’t be built with the new libs which were installed via &lt;code&gt;apt-get install&lt;/code&gt; command, but I needed those libs to do &lt;code&gt;bundle install&lt;/code&gt;. So it was closed loop.&lt;/p&gt;

&lt;h3&gt;
  
  
  Solution #1 (which didn’t work)
&lt;/h3&gt;

&lt;p&gt;After digging the web, the most common solution was to do following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rvm pkg install openssl
rvm install 2.6.0 --with-openssl-dir=/usr/local/rvm/usr
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that passed, Ruby was built, but the problem with the SSL certificate when Rails up was started &lt;strong&gt;was still present&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The issue was that version of &lt;code&gt;openssl&lt;/code&gt; that comes with &lt;code&gt;rvm&lt;/code&gt; is &lt;code&gt;1.0.1i&lt;/code&gt; and the &lt;code&gt;openssl&lt;/code&gt; in the &lt;code&gt;libssl1&lt;/code&gt; is &lt;code&gt;1.0.2n&lt;/code&gt; , which can be seen &lt;a href="https://launchpad.net/ubuntu/bionic/+package/libssl1.0-dev"&gt;here&lt;/a&gt; and &lt;a href="https://launchpad.net/ubuntu/+source/openssl1.0/1.0.2n-1ubuntu5.13"&gt;here&lt;/a&gt;. So there was some incompatibility with openssl version and the SSL certificate. By the way, SSL certificate was issued by &lt;strong&gt;Let’s Encrypt&lt;/strong&gt;, so it wasn’t some custom certificate.&lt;/p&gt;

&lt;h3&gt;
  
  
  Solution #2 (which worked)
&lt;/h3&gt;

&lt;p&gt;I had to download &lt;code&gt;1.0.2n&lt;/code&gt; openssl from Github and build it, install it and then rebuilt Ruby against it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note here I was using Docker, but this can be done outside of the Docker of course.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here are the steps for building Ruby via &lt;code&gt;rvm&lt;/code&gt; against custom version of openssl:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We will need 2 locations&lt;/li&gt;
&lt;li&gt;One where we &lt;code&gt;git clone&lt;/code&gt; openssl.&lt;/li&gt;
&lt;li&gt;One where we will &lt;code&gt;install&lt;/code&gt; the cloned version to (we will 
install it but not for system, just for our usage).&lt;/li&gt;
&lt;li&gt;For &lt;code&gt;git clone&lt;/code&gt; we will use &lt;code&gt;/tmp&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;For &lt;code&gt;install&lt;/code&gt; location we will use a/opt/openssla (for 
this you can create &lt;code&gt;tmp&lt;/code&gt; folder somewhere e.g. &lt;code&gt;~/tmp&lt;/code&gt;, or you can use &lt;code&gt;/opt/tmp&lt;/code&gt; or &lt;code&gt;/opt&lt;/code&gt;, just don’t use something that the system would use)&lt;/li&gt;
&lt;li&gt;Run/Add following commands in Dockerfile:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ENV OPENSSL_PREFIX=/opt/openssl
ENV SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt

WORKDIR /tmp
RUN git clone --branch OpenSSL_1_0_2n https://github.com/openssl/openssl.git
RUN cd openssl
RUN ./config shared --prefix=$OPENSSL_PREFIX --openssldir=$OPENSSL_PREFIX/ssl
RUN make
RUN make install

RUN rvm install 2.6.0 -C --with-openssl-dir=$OPENSSL_PREFIX
ENV PATH /usr/local/rvm/bin:$PATH
RUN rvm --default use ruby-2.6.0
ENV PATH /usr/local/rvm/bin:/usr/local/rvm/rubies/ruby-2.6.0/bin:$PATH
ENV GEM_HOME /usr/local/rvm/rubies/ruby-2.6.0/lib/ruby/gems/2.6.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that’s it. If that was successful you have Ruby complied against custom &lt;code&gt;openssl&lt;/code&gt; library.&lt;/p&gt;

&lt;h3&gt;
  
  
  Important notes:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;If you omit &lt;code&gt;ENV SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt&lt;/code&gt; the build process will not fail, but when you do bundle install it will give you:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Fetching source index from https://rubygems.org/
Could not verify the SSL certificate for
https://rubygems.org/quick/Marshal.4.8/nokogiri-1.13.10-x86_64-linux.gemspec.rz.
There is a chance you are experiencing a man-in-the-middle attack, but most
likely your system doesn't have the CA certificates needed for verification. For
information about OpenSSL certificates, see http://bit.ly/ruby-ssl. To connect
without using SSL, edit your Gemfile sources and change 'https' to 'http'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And you would try to fix this by doing &lt;code&gt;gem update — system&lt;/code&gt; or whatever, but the problem is that it needs path to certs.&lt;/p&gt;

&lt;p&gt;So don’t forget to add &lt;code&gt;ENV SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt&lt;/code&gt;.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You have to build/compile openssl as &lt;code&gt;shared&lt;/code&gt; library, otherwise &lt;code&gt;rvm&lt;/code&gt; will complain. And for that we have &lt;code&gt;shared&lt;/code&gt; option in line: &lt;code&gt;RUN ./config shared — prefix=$OPENSSL_PREFIX — openssldir=$OPENSSL_PREFIX/ssl&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;You can do build against a bit higher version of &lt;code&gt;openssl&lt;/code&gt; like &lt;code&gt;1.1.1&lt;/code&gt; , in that case just do &lt;code&gt;RUN git clone — branch OpenSSL_1_1_1 https://github.com/openssl/openssl.git&lt;/code&gt; instead.&lt;/li&gt;
&lt;/ol&gt;

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

</description>
      <category>ruby</category>
      <category>rails</category>
      <category>openssl</category>
      <category>sslcertificate</category>
    </item>
    <item>
      <title>Ruby on Rails 4.2.X upgrade issue with meta_request — undefined method normalize_key</title>
      <dc:creator>Milos</dc:creator>
      <pubDate>Fri, 26 Apr 2024 09:39:32 +0000</pubDate>
      <link>https://dev.to/milosdukic/ruby-on-rails-42x-upgrade-issue-with-metarequest-undefined-method-normalizekey-1cal</link>
      <guid>https://dev.to/milosdukic/ruby-on-rails-42x-upgrade-issue-with-metarequest-undefined-method-normalizekey-1cal</guid>
      <description>&lt;p&gt;You may find yourself in need to migrate from &lt;strong&gt;RoR 4.2.X&lt;/strong&gt; to the latest version, and that can be quite a task. Facing the same problem, I would like to point out the issue that bugged me for quite a bit, and that is gem &lt;strong&gt;meta_request&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Now if you are not using it, this text is not for you, but if you are, you might find this post helpful.&lt;/p&gt;

&lt;p&gt;So, initial situation: very old Ruby, very old Rails.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Next step(s)&lt;/strong&gt;: &lt;strong&gt;keep&lt;/strong&gt; the Rails version, &lt;strong&gt;update&lt;/strong&gt; Ruby (in this case to 2.6.0 or at least to 2.3.0)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Last step(s)&lt;/strong&gt;: &lt;strong&gt;update&lt;/strong&gt; Rails to 5.0 and then to 6.0 and so on, by the book.&lt;/p&gt;

&lt;p&gt;Updating Ruby went fine more or less, keep in mind that the Rails is still the &lt;strong&gt;same version&lt;/strong&gt;, also &lt;code&gt;bundle install&lt;/code&gt; yielded minor hiccups/errors but nothing that can’t be resolved.&lt;/p&gt;

&lt;p&gt;But upon landing/opening home page I got&lt;/p&gt;

&lt;p&gt;&lt;code&gt;NoMethodError: undefined method normalize_key ActiveSupport::Cache::Store&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now &lt;code&gt;normalize_key&lt;/code&gt; is Rails 5+ function, and I had &lt;strong&gt;4.2.X&lt;/strong&gt;, how the hell is that being called then?&lt;/p&gt;

&lt;h3&gt;
  
  
  The answer is meta_request!
&lt;/h3&gt;

&lt;p&gt;Yes, bundler picked up latest possible version, since it says it is &lt;a href="https://rubygems.org/gems/meta_request/versions/0.4.0?locale=en"&gt;compatible&lt;/a&gt; with Rails(i.e. railties &amp;gt;= 3.0.0) and in it, meta_request on &lt;a href="https://github.com/dejan/rails_panel/blob/master/meta_request/lib/meta_request/event.rb#L61"&gt;line&lt;/a&gt; uses &lt;code&gt;normalize_key&lt;/code&gt; call, which is &lt;a href="https://apidock.com/rails/v5.0.0.1/ActiveSupport/Cache/Store/normalize_key"&gt;Rails 5 feature&lt;/a&gt;(from v5.0.0.1).&lt;/p&gt;

&lt;p&gt;So to fix this issue just do:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;gem 'meta_request', '~&amp;gt; 0.7.4'&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;until you bump your Rails to 5+.&lt;/p&gt;

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

</description>
      <category>ruby</category>
      <category>rails</category>
      <category>bundler</category>
      <category>upgrade</category>
    </item>
    <item>
      <title>Angular Material Datepicker Icon + TailwindCSS</title>
      <dc:creator>Milos</dc:creator>
      <pubDate>Mon, 30 Dec 2019 10:42:48 +0000</pubDate>
      <link>https://dev.to/milosdukic/angular-material-datepicker-icon-tailwindcss-11p1</link>
      <guid>https://dev.to/milosdukic/angular-material-datepicker-icon-tailwindcss-11p1</guid>
      <description>&lt;p&gt;This is a quick note/fix for any1 who uses Angular Material Datepicker and TailwindCSS. I have faced small cosmetic issue when trying to use Angular Material Calendar in my TailwindCSS based application.&lt;/p&gt;

&lt;p&gt;Problem was that the Datepicker icon had an offset, and it was really annoying. Like so:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4n_EMV1s--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/ebd1xc4a2nfxx5iss4nx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4n_EMV1s--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/ebd1xc4a2nfxx5iss4nx.png" alt="calendar-image-offset" width="327" height="119"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So the fix for it is to set:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;svg&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;inline&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But I had to set it before "tailwindcss/utilities" are loaded or after the components are loaded :).&lt;br&gt;
So my &lt;strong&gt;tailwind-build.css&lt;/strong&gt; (this file can be named whatever you want) looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="k"&gt;@import&lt;/span&gt; &lt;span class="s1"&gt;"tailwindcss/base"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;@import&lt;/span&gt; &lt;span class="s1"&gt;"tailwindcss/components"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c"&gt;/* Custom component styling goes here*/&lt;/span&gt;
&lt;span class="k"&gt;@import&lt;/span&gt; &lt;span class="s1"&gt;"./app/some_path_blah_blah/common.css"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;@import&lt;/span&gt; &lt;span class="s1"&gt;"tailwindcss/utilities"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And in my common.css I added:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="nt"&gt;svg&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;inline&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So the Datepicker should look like this:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--aaJlx1X0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/j5hc8qrji2jaciaxl3mz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--aaJlx1X0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/j5hc8qrji2jaciaxl3mz.png" alt="calendar-icon-fix" width="325" height="127"&gt;&lt;/a&gt;&lt;/p&gt;

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

</description>
      <category>angular</category>
      <category>tailwindcss</category>
      <category>angularmaterial</category>
      <category>datepicker</category>
    </item>
    <item>
      <title>TailwindCSS &amp; Angular8</title>
      <dc:creator>Milos</dc:creator>
      <pubDate>Wed, 11 Dec 2019 15:13:54 +0000</pubDate>
      <link>https://dev.to/milosdukic/tailwindcss-angular8-134b</link>
      <guid>https://dev.to/milosdukic/tailwindcss-angular8-134b</guid>
      <description>&lt;p&gt;This is a simple tutorial about integrating TailwindCSS library into the Angular8 application.&lt;/p&gt;

&lt;p&gt;If you haven't heard of TailwindCSS you can check it out &lt;a href="https://tailwindcss.com/"&gt;here&lt;/a&gt;. In a nutshell TailwindCSS is the upcoming CSS library, which I hope will eventually replace the Bootstrap in the near future. Why would you use TailwindCSS you may wonder? Well first of all it is great for responsive applications, highly customisable, preloaded with, I would say 90% of CSS classes you would normally use to build a web application, etc.&lt;br&gt;
So lets get cracking :)&lt;/p&gt;

&lt;p&gt;The complete code can be found on GitHub repo: &lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--A9-wwsHG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/LaptopTheOne"&gt;
        LaptopTheOne
      &lt;/a&gt; / &lt;a href="https://github.com/LaptopTheOne/tailwindcss-angular-demo"&gt;
        tailwindcss-angular-demo
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      This is a simple demo on how to integrate TailwindCSS library into the Angular8 application
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;First of all you need to create simple Angular8 app and install some additional NPM packages:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ng new tailwindcss-demo
...IMPORTANT! select CSS when asked...

cd tailwindcss-demo
npm i -D tailwindcss postcss-import autoprefixer postcss-cli @fullhuman/postcss-purgecss
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After that run following command from the root of the application:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx tailwind init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will create new file called &lt;em&gt;tailwind.config.js&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Then create new file, also in the root of the application called &lt;em&gt;postcss.config.js&lt;/em&gt; and add this code into it:&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="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;postcss-import&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;tailwindcss&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;autoprefixer&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;NODE_ENV&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;production&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@fullhuman/postcss-purgecss&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)({&lt;/span&gt;
      &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./src/**/*.html&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;./src/index.html&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="na"&gt;defaultExtractor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match&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;A-Za-z0-9-_:&lt;/span&gt;&lt;span class="se"&gt;/]&lt;/span&gt;&lt;span class="sr"&gt;+/g&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="p"&gt;}),&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What this code effectively do is it strips the unused CSS from you application leaving only used TailwindCSS classes.&lt;/p&gt;

&lt;p&gt;After this create also one new file in &lt;em&gt;./src/tailwind-build.css&lt;/em&gt; and put this code in:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="c"&gt;/* ./src/tailwind.css */&lt;/span&gt;

&lt;span class="k"&gt;@import&lt;/span&gt; &lt;span class="s1"&gt;"tailwindcss/base"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;@import&lt;/span&gt; &lt;span class="s1"&gt;"tailwindcss/components"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;@import&lt;/span&gt; &lt;span class="s1"&gt;"tailwindcss/utilities"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open angular.json file and edit like so (there are 2 occurrences that need to be edited one under build other under test key):&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="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;this&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;is&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;under&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;build&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;key&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"styles"&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="s2"&gt;"src/styles.css"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"src/styles-tailwind.css"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;add&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;only&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;this&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;line&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;this&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;is&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;under&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;test&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;key&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"styles"&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="s2"&gt;"src/styles.css"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"src/styles-tailwind.css"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;add&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;only&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;this&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;line&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;

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

&lt;/div&gt;



&lt;p&gt;In package.json file, add under scripts section following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;scripts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;tailwind-build&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;postcss ./src/tailwind-build.css  -o ./src/styles-tailwind.css&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;tailwind-watch&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;postcss ./src/tailwind-build.css  -o ./src/styles-tailwind.css --watch&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm run tailwind-build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and notice that the new file has been created under &lt;em&gt;./src/styles-tailwind.css&lt;/em&gt;. That file is the final output of the tailwind build process and it contains &lt;strong&gt;ALL&lt;/strong&gt; the CSS elements from TailwindCSS. If you investigate a bit, you will notice that this file is ~ 787KiB&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;+--------------------------------------------------------------+
| Size         | 787.36 KiB                                    |
|--------------------------------------------------------------|
| Gzipped      | 85.43 KiB                                     |
|--------------------------------------------------------------|
| Mime type    | text/css                                      |
|--------------------------------------------------------------|
| Created      | December 11th 2019, 11:49:28                  |
|--------------------------------------------------------------|
| Changed      | December 11th 2019, 11:51:05                  |
+--------------------------------------------------------------+
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;which is a lot btw. This will be reduces as we progress, don't worry :). And remember we did not even used TailwindCSS anywhere in our project yet, so let's start using it :)&lt;/p&gt;

&lt;p&gt;In our app.component.html you can remove everything or add following line at the end of the file (this is just for testing purposes, and to se if we have integrated TailswindCSS properly):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"text-4xl text-center text-blue-500 bg-red-200 mt-8"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;TailwindCSS Example Works&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now run&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
 and you should be able to see 'TailwindCSS Example Works' text styled using TailwindCSS.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Hi23tk-i--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/v51zhrehe9uzae9x5uh2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Hi23tk-i--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/v51zhrehe9uzae9x5uh2.png" alt="Alt Text" width="800" height="338"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Also you can run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm run tailwind-watch
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;from another terminal window, and whenever you modify &lt;em&gt;./src/tailwind-build.css&lt;/em&gt; file build process will be triggered automatically, and fresh &lt;em&gt;./src/styles-tailwind.css&lt;/em&gt; file will be created.&lt;/p&gt;

&lt;h2&gt;
  
  
  What about that size ~ 787KiB?
&lt;/h2&gt;

&lt;p&gt;If you look closer in postcss.config.js file you will notice that when the env is production purgecss will remove any unused css code from all .html files, and therefore the size of &lt;em&gt;./src/styles-tailwind.css&lt;/em&gt; will be significantly reduced. If you run your code in the production environment:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;NODE_ENV=production npm run tailwind-build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;you will notice that &lt;em&gt;./src/styles-tailwind.css&lt;/em&gt; is now ~ 9KiB which is nice:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;+--------------------------------------------------------------+
| Size         | 8.99 KiB                                      |
|--------------------------------------------------------------|
| Gzipped      | 2.86 KiB                                      |
|--------------------------------------------------------------|
| Mime type    | text/css                                      |
|--------------------------------------------------------------|
| Created      | December 11th 2019, 11:49:28                  |
|--------------------------------------------------------------|
| Changed      | December 11th 2019, 13:06:37                  |
+--------------------------------------------------------------+
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So make sure that you use this approach when deploying to production.&lt;/p&gt;

&lt;p&gt;And that makes the end of this article. I hope you found it useful.&lt;br&gt;
Give TailwindCSS a try, and you will see why it so well accepted by community.&lt;/p&gt;

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

</description>
      <category>angular</category>
      <category>tailwindcss</category>
      <category>css</category>
    </item>
  </channel>
</rss>
