rockyourcode

Subscribe
Archives
September 28, 2021

rockyourcode: Create a PostCSS Pipe With Hugo, How to Setup React Typescript With Snowpack and Daisy UI

Hello 👋! Thanks for subscribing.

Here are my last two articles. I've been busy onboarding into my new work as a software developer, so my writing has been slow.

On the positive side: my blog has a new theme, so check it out at some point!

Create a PostCSS Pipe With Hugo

Published on: 2021-09-24

tags: Hugo

I'm trying to create a new theme for Hugo.

Hugo offers powerful features, for example, Hugo pipes. Pipes allow you to transform data in your Hugo templates.

I want to use PurgeCSS to remove unused CSS from my production bundle.

The official website has a guide for using PostCSS with Hugo, but it was not 100% clear to me how to use the instructions.

1. Template

You will have a html template in your themes folder. Mine has the folllowing path: themes/<name-of-theme>/layouts/partials/head.html:

- $critical := resources.Get &quot;scss/critical.scss&quot; | resources.ToCSS
- $fonts := resources.Get &quot;scss/fonts.scss&quot; | resources.ToCSS | resources.Minify | resources.Fingerprint
- if hugo.IsProduction
- $critical = resources.Get &quot;scss/critical.scss&quot; | resources.ToCSS |  resources.PostProcess | resources.Minify | resources.Fingerprint
- end
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <meta http-equiv="X-UA-Compatible" content="ie=edge" />
  <link rel="stylesheet" href="$critical.RelPermalink" />
  <link rel="stylesheet" media="print" href="$fonts.RelPermalink" onload="this.media='all'" />
  <title>
    if not .IsHomewith .Title | {{
    .Site.Title }}
  </title>
  <meta
    name="description"
    content="with .Descriptionwith .Summary "
  />
  template &quot;_internal/opengraph.html&quot; .
  template &quot;_internal/twitter_cards.html&quot; .
  template &quot;_internal/schema.html&quot; .
</head>

If we make a production build with the command hugo, we will process the Sass SCSS file with several transformations.

2. Main Folder

The above code sits in the theme folder, nested in your main Hugo project.

Example folder structure:

├── archetypes
│   └── default.md
├── config.toml
├── content
│   ├── about.md
│   └── blog
│       ├── 2021
│       │   ├── hipsum.md
│       │   └── lorem-ipsum.md
│       └── _index.md
├── data
├── layouts
├── static
└── themes
    └── sample-hugo-theme
        ├── archetypes
        │   └── default.md
        ├── assets
        │   └── scss
        │       ├── _config.scss
        │       ├── critical.scss
        │       └── _reset.scss
        ├── layouts
        │   ├── 404.html
        │   ├── blog
        │   │   └── single.html
        │   ├── _default
        │   │   ├── about.html
        │   │   ├── baseof.html
        │   │   ├── list.html
        │   │   └── single.html
        │   ├── index.html
        │   └── partials
        │       ├── footer.html
        │       ├── header.html
        │       ├── head.html
        │       ├── page-header.html
        │       ├── pagination.html
        │       └── post_pagination.html
        ├── LICENSE
        └── theme.toml

We run the necessary commands from the main folder. For development mode, we use hugo server, for production mode, we use hugo.

Depending on which command you run, Hugo will recognize the mode.

That means that you'll need to set configuration settings from guide in the main folder (not the themes folder where your HTML template resides).

Install the necessary Node.js dependencies in the main Hugo directory (same folder as config.{toml,yaml,json}:

npm i -D @fullhuman/postcss-purgecss postcss postcss-cli

The next parts are identical to the documentation:

Adjust the configuration. If you use toml, here's the example config.toml:

[build]
  writeStats = true

Create a postcss.config.js:

const purgecss = require('@fullhuman/postcss-purgecss')({
  content: ['./hugo_stats.json'],
  defaultExtractor: (content) => {
    let els = JSON.parse(content).htmlElements
    return els.tags.concat(els.classes, els.ids)
  },
})

module.exports = {
  plugins: [
    ...(process.env.HUGO_ENVIRONMENT === 'production' ? [purgecss] : []),
  ],
}

3. Production Build

Run the following command inside your terminal:

hugo

The command will create a public folder which contains the static website that you built with Hugo. Your CSS assets should work.

Thoughts

If you share your theme for others to use, they will have to go through the steps of installing the Node.js dependencies in their Hugo project.

I find that less than ideal, as I prefer to manage my assets from the themes folder.

Links

  • PurgeCSS
  • Hugo Pipes Introduction
  • Asset Management with Hugo: PostProcess
  • How I can implement Purgecss, Uncss, or PurifyCSS in Hugo?

How to Setup React Typescript With Snowpack and Daisy UI

Published on: 2021-08-31

tags: React.js, TypeScript

This weekend I wanted to setup a new playground for testing out some React concepts.

I've decided to use Snowpack and Daisy UI.

Snowpack is a new build tool and bundler for JavaScript web applications. Under the hood it uses esbuild. esbuild was written in Go and is very fast.

Snowpack offers a development server and hot module replacement. It comes with a few plugins and templates to speed up setup, but its far from a zero-config tool.

DaisyUI is a wrapper around Tailwind CSS, the utility-first CSS framework. DaisyUI offers convenient components that remind of the well-known Bootstrap framework. For example, you can style a button with a simple btn btn-primary class in your HTML instead of stringing together several utility classes like inline-block px-4 py-3 text-sm font-semibold text-center text-white uppercase transition duration-200 ease-in-out bg-indigo-500 rounded-md cursor-pointer hover:bg-indigo-600.

In this article, I'll offer a "Getting started" for React with TypeScript and Daisy UI, using Snowpack.

The blog post borrows from Adding Tailwind CSS to React Snowpack Project which helped me bring all parts together.

Snowpack Setup

Use the snowpack template for creating a new app. You'll need Node.js. Node.js comes with the command line utility npx.

Type the following command into your terminal:

npx create-snowpack-app react-daisyui \
--template @snowpack/app-template-react-typescript \
--use-pnpm

Here we create a new application called react-daiyui with the template for React and TypeScript.

I use pnpm as the package manager of my choice, but you can use npm or yarn if you want.

Tailwind CSS

Navigate into the project directory:

cd daisy-ui

Sanity check! Try to start the project:

pnpm run start # or npm run start

It should now work.

Let's install Tailwind CSS, Daisy UI and its needed companions as development dependencies:

pnpm add -D @snowpack/plugin-postcss postcss postcss-cli \
tailwindcss autoprefixer daisyui

Now we need to configure all parts so that they work together.

Adjust the snowpack.config.mjs file in your project:

/** @type {import('snowpack').SnowpackUserConfig } */
export default {
  mount: {
    public: { url: '/', static: true },
    src: { url: '/dist' },
  },
  plugins: [
+    '@snowpack/plugin-postcss',
   /* ... */
   ],
  devOptions: {
+     tailwindConfig: './tailwind.config.js',
  },
  buildOptions: {
    /* ... */
  },
};

Create a new file called postcss.config.js with the following content:

const tailwindcss = require('tailwindcss')
const autoprefixer = require('autoprefixer')

const plugins = [tailwindcss, autoprefixer]

module.exports = { plugins }

Optional: cssnano

Sung Kim uses the package cssnano to optimize the production build. I hadn't heard of the tool before, but it looks useful.

Install via pnpm/npm:

pnpm add -D cssnano

Use this postcss.config.js:

const cssnano = require("cssnano")
const tailwindcss = require("tailwindcss")
const autoprefixer = require("autoprefixer")

const plugins =
  process.env.NODE_ENV === "production"
    ? [tailwindcss, autoprefixer, cssnano]
    : [tailwindcss, autoprefixer]

module.exports = { plugins }

Tailwind Configuration

Now we need to create a configuration file for Tailwind CSS. Create a new file called tailwind.config.js:

module.exports = {
  mode: 'jit',
  purge: ['./public/**/*.html', './src/**/*.{js,jsx,ts,tsx,vue}'],
  plugins: [require('daisyui')],
}

If you want, you can configure Daisy UI in this file, too. See the config section ofthe Daisy UI docs.

Now open the src/index.css file that snowpack generated for us. At the beginning of the file, add the following lines:

@tailwind base;
@tailwind components;
@tailwind utilities;

Sanity check! We can now add a new button that's styled with Daisy UI to our src/App.tsx file:

interface AppProps {}

function App({}: AppProps) {
  return <button class="btn btn-primary">DaisyUI Button</button>
}

export default App

It should now work!

Links

  • Daisy UI
  • Comparing the New Generation of Build Tools by Hugh Haworth
  • Adding Tailwind CSS to React Snowpack Project by Sung M. Kim
  • Snowpack: Tailwind Setup

Thank you for reading my blog.

Don't hesitate to reach out via email or Twitter!

Don't miss what's next. Subscribe to rockyourcode:
GitHub X
Powered by Buttondown, the easiest way to start and grow your newsletter.