<?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: GeekPlux</title>
    <description>The latest articles on DEV Community by GeekPlux (@geekplux).</description>
    <link>https://dev.to/geekplux</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%2F279091%2F09e9db25-5d0d-4d7a-aa8b-6efbb6b43dbd.jpeg</url>
      <title>DEV Community: GeekPlux</title>
      <link>https://dev.to/geekplux</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/geekplux"/>
    <language>en</language>
    <item>
      <title>Legacy code best practice: how to take over an existing project smoothly</title>
      <dc:creator>GeekPlux</dc:creator>
      <pubDate>Tue, 26 Jan 2021 16:35:34 +0000</pubDate>
      <link>https://dev.to/geekplux/legacy-code-best-practice-how-to-take-over-an-existing-project-smoothly-161e</link>
      <guid>https://dev.to/geekplux/legacy-code-best-practice-how-to-take-over-an-existing-project-smoothly-161e</guid>
      <description>&lt;p&gt;Every programmer, I guess, would meet the code from others that you have never contributed to. And one of the ways to distinguish experienced programmers from beginners is to see if they can quickly dive into the legacy code and maintain, develop, and refactor it in the right way.&lt;/p&gt;

&lt;p&gt;There is no silver bullet to approach it, I’ve also been caught in the nightmare of not being able to read the code at all. But I have some tips from my experience to guide you to master it step by step. Hope it would be helpful.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Ask for documentation or explanation
&lt;/h2&gt;

&lt;p&gt;It’s very lucky if there is some detailed documentation, or if the person who wrote the code is still around. This can save you a lot of time, but of course the best way is that the previous team can help you walk through the whole codebase.&lt;/p&gt;

&lt;p&gt;In this stage, you’d better know:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;how to &lt;strong&gt;run&lt;/strong&gt; the whole project code&lt;/li&gt;
&lt;li&gt;any easier way to &lt;strong&gt;test&lt;/strong&gt; or &lt;strong&gt;debug&lt;/strong&gt; during development&lt;/li&gt;
&lt;li&gt;the &lt;strong&gt;version control&lt;/strong&gt; tool they used&lt;/li&gt;
&lt;li&gt;how to &lt;strong&gt;release&lt;/strong&gt; and &lt;strong&gt;deploy&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;any &lt;strong&gt;dependent&lt;/strong&gt; library you should notice&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;if there are no docs and no person was responsible for it available, promise me, please do not get angry and smash your keyboard :)&lt;/p&gt;

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

&lt;h2&gt;
  
  
  2. Fix minor bugs
&lt;/h2&gt;

&lt;p&gt;Learn by doing is always the fastest way to master code. For instance, if the legacy code is for the front-end, you can just change the Button style, if it’s for the back-end, you can just replace the response, that’s the easy but effective method to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;know and practice how to &lt;strong&gt;debug&lt;/strong&gt; during developing&lt;/li&gt;
&lt;li&gt;know each function’s purpose and its &lt;strong&gt;scope&lt;/strong&gt;, roughly&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These small bugs or tweaks allow you to get better familiar with the code, especially if you are really confused and have no idea how to start.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Keep new code clean
&lt;/h2&gt;

&lt;p&gt;If you do not want to make things more complicated, then keep your new code clean. To follow the &lt;a href="https://www.wikiwand.com/en/Unix_philosophy"&gt;Unix philosophy&lt;/a&gt;, &lt;strong&gt;make each function do one thing and do it well&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;You can’t control the quality of the inherited code, but you can make sure the code you add is the style you love.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Only rewrite code when necessary
&lt;/h2&gt;

&lt;p&gt;I know every developer can’t help trying to rewrite the legacy code, but it usually brings much &lt;strong&gt;undesirable&lt;/strong&gt; behavior.&lt;/p&gt;

&lt;p&gt;Every time when I have to rewrite some functions, I will imagine the code taken over is a black box full of magic (and it always is!) so that I will be careful with each input and output.&lt;/p&gt;

&lt;p&gt;When it comes to interdependent functions, try to control the scope of their impact, change the code as little as possible, try to ensure that no new bugs are introduced, and keep smooth iterative development.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Modularize code to the minimum possible
&lt;/h2&gt;

&lt;p&gt;Maintaining and developing the legacy code is a progressive process. When you have to rewrite it, don’t rush to completely overturn the previous code first, try to take it apart first.&lt;/p&gt;

&lt;p&gt;Dividing code makes you understand the code logic totally. You could keep the input params and output as simple as possible. &lt;strong&gt;Roughly split first, and then split again on top of that until it is minimized&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The advantage of this step is that any future refactoring of your code will also bring minimal impact.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DuFrFcTq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/plfajgb78xgepebkk4m5.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DuFrFcTq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/plfajgb78xgepebkk4m5.jpg" alt="modularize like lego"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Refactor after modularization
&lt;/h2&gt;

&lt;p&gt;Best practices for refactoring are written in many books, but I still recommend doing it on top of completing the previous step. Which will take weeks, months or possibly years depending on the complexity.&lt;/p&gt;

&lt;p&gt;At the same time you need to keep up with the speed of developing new features, so it’s a &lt;strong&gt;trade-off&lt;/strong&gt;. I know that refactoring parts of the legacy code can improve the speed of writing new code, but it can also be more of a burden. It needs much patience to take your time and get the refactoring done.&lt;/p&gt;

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

&lt;p&gt;In short, &lt;strong&gt;don’t rush to overturn all the old code, but change it little by little, modularize and optimize it&lt;/strong&gt;. Which like eating a pie, starting from the edges and working your way to the core, little by little.&lt;/p&gt;

</description>
      <category>refactoring</category>
      <category>legacycode</category>
      <category>development</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>How to use tailwindcss with AMP in a Next.js project</title>
      <dc:creator>GeekPlux</dc:creator>
      <pubDate>Tue, 24 Mar 2020 15:43:56 +0000</pubDate>
      <link>https://dev.to/geekplux/how-to-use-tailwindcss-with-amp-in-a-next-js-project-1f97</link>
      <guid>https://dev.to/geekplux/how-to-use-tailwindcss-with-amp-in-a-next-js-project-1f97</guid>
      <description>&lt;p&gt;Recently, I was refactoring my blog using Next.js by a whim. There are 3 tech stacks I would use:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://nextjs.org/"&gt;Next.js&lt;/a&gt; , a popular React framework with SSG, SSR support naturally&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://tailwindcss.com/"&gt;Tailwindcss&lt;/a&gt; , a low-level CSS framework with the utility-first concept.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://amp.dev/"&gt;AMP&lt;/a&gt; , an HTML framework developed by Google to make your website fast and loading smoothly.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;However, There are so many restrictions in AMP for performance issues. At the beginning of the project, I found &lt;a href="https://github.com/zeit/next.js/issues/7121"&gt;this issue&lt;/a&gt;, which means you can NOT add a global CSS as &lt;a href="https://nextjs.org/docs/basic-features/built-in-css-support#adding-a-global-stylesheet"&gt;Next.js documented&lt;/a&gt;. So this article may be a guide for how to use tailwindcss with AMP in a Next.js project.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: How to add style in AMP
&lt;/h2&gt;

&lt;p&gt;First, we are supposed to know how to add style for a page in AMP. After look up their &lt;a href="https://amp.dev/documentation/guides-and-tutorials/develop/style_and_layout/?format=websites#add-styles-to-a-page"&gt;official documents&lt;/a&gt;, there are &lt;strong&gt;only two ways&lt;/strong&gt; to style your site:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://amp.dev/documentation/guides-and-tutorials/develop/style_and_layout/?format=websites#define-styles-in-head"&gt;Define styles in head&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://amp.dev/documentation/guides-and-tutorials/develop/style_and_layout/?format=websites#define-inline-styles"&gt;Define inline styles&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;React JSX syntax lets you add CSS inline intuitively, written as attributes and passed to elements. But it's pain to write pseudo-classes, add prefix and maintain. Besides, tailwindcss has already listed in our armoury, so I have to choose another method.&lt;/p&gt;

&lt;p&gt;Define CSS within the &lt;code&gt;&amp;lt;style amp-custom&amp;gt;&lt;/code&gt; tag, then add the class name to where you wanna style. The only one thing is different from your usual CSS writing is to write it in the &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt; &lt;code&gt;&amp;lt;style&amp;gt;&lt;/code&gt; tag.&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="cp"&gt;&amp;lt;!doctype html&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    ...
    &lt;span class="nt"&gt;&amp;lt;style &lt;/span&gt;&lt;span class="na"&gt;amp-custom&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="c"&gt;/* any custom styles go here. */&lt;/span&gt;
      &lt;span class="nt"&gt;amp-img&lt;/span&gt;&lt;span class="nc"&gt;.grey-placeholder&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;grey&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;
    ...
  &lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;amp-img&lt;/span&gt;
        &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"grey-placeholder"&lt;/span&gt;
        &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://..."&lt;/span&gt;
        &lt;span class="na"&gt;srcset=&lt;/span&gt;&lt;span class="s"&gt;"..."&lt;/span&gt;
        &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"500"&lt;/span&gt;
        &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"300"&lt;/span&gt;
        &lt;span class="na"&gt;layout=&lt;/span&gt;&lt;span class="s"&gt;"responsive"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/amp-img&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://jjsweb.site/"&gt;JJ Kasper&lt;/a&gt; provided a way to implement this in Next.js: &lt;a href="https://github.com/zeit/next.js/issues/7121#issuecomment-487329715"&gt;to overwrite _document&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// pages/_document.js&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;MyDocument&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;Document&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nx"&gt;getInitialProps&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;initialProps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;Document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getInitialProps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;initialProps&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;initialProps&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt; &lt;span class="nx"&gt;dangerouslySetInnerHTML&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;
            &lt;span class="na"&gt;__html&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`body{ background: orange; }`&lt;/span&gt;
          &lt;span class="p"&gt;}}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So the &lt;strong&gt;next step&lt;/strong&gt; is how to add tailwind CSS as a string into &lt;code&gt;&amp;lt;style&amp;gt;&lt;/code&gt; tag.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: How to add a CSS file as String into style tag
&lt;/h2&gt;

&lt;p&gt;This step is too simple to just add a loader the &lt;a href="https://nextjs.org/docs/api-reference/next.config.js/custom-webpack-config"&gt;Webpack config&lt;/a&gt; in &lt;code&gt;next.config.js&lt;/code&gt;.  &lt;strong&gt;&lt;a href="https://webpack.js.org/loaders/raw-loader/"&gt;raw-loader&lt;/a&gt;&lt;/strong&gt; allows importing files as a String, you could add it following &lt;a href="https://nextjs.org/docs/api-reference/next.config.js/custom-webpack-config"&gt;Webpack customing doc&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// next.config.js&lt;/span&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;webpack&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rules&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&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;css$/&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;use&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;raw-loader&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;config&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;Then download the &lt;code&gt;tailwind.min.css&lt;/code&gt; to your &lt;code&gt;styles&lt;/code&gt; folder at root directory, try to import it in &lt;code&gt;pages/_document.js&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// pages/_document.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;tailwindcss&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;!raw-loader!../styles/tailwind.min.css&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it! But when you run &lt;code&gt;next start&lt;/code&gt; again after these steps, you would encounter a warning (if your pages are set to AMP):&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; warn &lt;span class="o"&gt;]&lt;/span&gt;  Amp Validation

/  error  The author stylesheet specified &lt;span class="k"&gt;in &lt;/span&gt;tag &lt;span class="s1"&gt;'style amp-custom (transformed)'&lt;/span&gt; is too long - document contains 725366 bytes whereas the limit is 75000 bytes.  https://amp.dev/documentation/guides-and-tutorials/learn/spec/amphtml#maximum-size
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Don't worry, we all know warning is not error. We can ignore this warning message during development until you wanna build a production version.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3 How to build and deploy
&lt;/h2&gt;

&lt;p&gt;Not only is it because of AMP validation error, but to add entire tailwindcss package into the final bundle is too big, so we need to process tailwindcss, leaving only the classes we actually use.&lt;/p&gt;

&lt;p&gt;If your project was created by an &lt;a href="https://github.com/zeit/next.js/tree/canary/examples/with-tailwindcss"&gt;official example&lt;/a&gt;, you would see the &lt;code&gt;postcss.config.js&lt;/code&gt; under root folder, and tailwindcss was imported in &lt;code&gt;styles/index.css&lt;/code&gt;&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;/* styles/index.css */&lt;/span&gt;

&lt;span class="c"&gt;/* purgecss start ignore */&lt;/span&gt;
&lt;span class="k"&gt;@tailwind&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;@tailwind&lt;/span&gt; &lt;span class="n"&gt;components&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c"&gt;/* purgecss end ignore */&lt;/span&gt;
&lt;span class="k"&gt;@tailwind&lt;/span&gt; &lt;span class="n"&gt;utilities&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next.js compiles CSS using PostCSS, so you can just create a &lt;code&gt;postcss.config.js&lt;/code&gt; without other config then it works. And as you know, &lt;code&gt;postcss.config.js&lt;/code&gt; also is able to used by &lt;a href="https://github.com/postcss/postcss-cli"&gt;PostCSS CLI&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You need to add 2 steps before building process:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Compile a &lt;code&gt;output.css&lt;/code&gt; file to &lt;code&gt;styles&lt;/code&gt; folder.&lt;/li&gt;
&lt;li&gt;Import &lt;code&gt;styles/output.css&lt;/code&gt; as String in &lt;code&gt;pages/_document.js&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So first, let's tweak &lt;code&gt;postcss.config.js&lt;/code&gt; for CLI using because of &lt;code&gt;require()&lt;/code&gt; function syntax.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// postcss.config.js&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;purgecssOption&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Specify the paths to all of the template files in your project&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;./pages/**/*.{js,jsx,ts,tsx}&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;./components/**/*.{js,jsx,ts,tsx}&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;

  &lt;span class="c1"&gt;// Include any special characters you're using in this regular expression&lt;/span&gt;
  &lt;span class="na"&gt;defaultExtractor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;content&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="nx"&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;[\w&lt;/span&gt;&lt;span class="sr"&gt;-&lt;/span&gt;&lt;span class="se"&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;+&lt;/span&gt;&lt;span class="se"&gt;(?&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;!:&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="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="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;CSS_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;build&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="nx"&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="nx"&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="nx"&gt;purgecssOption&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
          &lt;span class="nx"&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-preset-env&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
          &lt;span class="nx"&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;cssnano&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)({&lt;/span&gt;
            &lt;span class="na"&gt;preset&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;default&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
          &lt;span class="p"&gt;})&lt;/span&gt;
        &lt;span class="p"&gt;]&lt;/span&gt;
      &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
          &lt;span class="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="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="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;@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="nx"&gt;purgecssOption&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
            &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;undefined&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-preset-env&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Please notice a &lt;strong&gt;env variable&lt;/strong&gt; called &lt;code&gt;CSS_ENV&lt;/code&gt;, it is going to use in future steps.&lt;/p&gt;

&lt;p&gt;Second, importing &lt;code&gt;styles/output.css&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// pages/_document.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;outputcss&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;!raw-loader!../styles/output.css&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;tailwindcss&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;!raw-loader!../styles/tailwind.min.css&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cssFile&lt;/span&gt; &lt;span class="o"&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="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;outputcss&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;tailwindcss&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;MyDocument&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;Document&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nx"&gt;getInitialProps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;initialProps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;Document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getInitialProps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;initialProps&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;
            &lt;span class="nx"&gt;dangerouslySetInnerHTML&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;
              &lt;span class="na"&gt;__html&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;cssFile&lt;/span&gt;
            &lt;span class="p"&gt;}}&lt;/span&gt;
          &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;          &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;initialProps&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nx"&gt;render&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;When you run command here:&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="nv"&gt;CSS_ENV&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;build postcss styles/index.css &lt;span class="nt"&gt;--config&lt;/span&gt; postcss.config.js &lt;span class="nt"&gt;-o&lt;/span&gt; styles/output.css
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;you would see &lt;code&gt;output.css&lt;/code&gt; is generated. That's convenient if you add this line to your &lt;code&gt;package.json&lt;/code&gt; scripts.&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;package.json&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"scripts"&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;"dev"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"next"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"build"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"yarn build-css &amp;amp;&amp;amp; next build"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"build-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;"CSS_ENV=build postcss styles/index.css --config postcss.config.js -o styles/output.css"&lt;/span&gt;&lt;span class="p"&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="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;Then you run &lt;code&gt;yarn build&lt;/code&gt; or &lt;code&gt;npm run build&lt;/code&gt; every time, it would compile CSS automatically.&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="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-al&lt;/span&gt; styles
&lt;span class="nt"&gt;-rw-r--r--&lt;/span&gt;  1 geekplux  staff   7.7K Mar 24 01:54 output.css
&lt;span class="nt"&gt;-rw-r--r--&lt;/span&gt;@ 1 geekplux  staff   694K Mar 23 06:48 tailwind.min.css
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After completing all the steps, you can now use tailwindcss well in both development and production environments.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;OK finally, in a summary, you should NOT use tailwind in your Next.js project, because when you define a custom PostCSS configuration file, Next.js &lt;strong&gt;completely disables&lt;/strong&gt; the built-in &lt;a href="https://nextjs.org/docs/advanced-features/customizing-postcss-config#default-behavior"&gt;default behavior&lt;/a&gt;......it's a joke.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://geekplux.com/2020/03/24/how-to-use-tailwindcss-with-amp-in-a-next.js-project/"&gt;https://geekplux.com/2020/03/24/how-to-use-tailwindcss-with-amp-in-a-next.js-project/&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
