Hi, I'm Abdulfetah Suudi

GitHub Logo

Software Engineer based in Ethiopia, with a passion for open source and hands-on work. Currently shipping software as a part-time software engineer and working on Rivo and Notra.

profile picture
Your Name

The Many Faces of CSS

I started with vanilla CSS – inline styles, <style> tags in the head, and dedicated .css files. It worked, but repetition was killing me.

Then I discovered preprocessors: Less, Sass, and Stylus. They reduced boilerplate dramatically. Nesting, variables, mixins – I loved them.

Bootstrap: The First Library I Truly Hated

When I tried Bootstrap, something snapped. It wasn't flexible. I wanted to customize everything, but Bootstrap fought me at every turn. That was the first time I genuinely hated a library in my frontend journey.

Tailwind CSS: The One That Fits My Brain

Then I touched Tailwind CSS – utility‑class based. It clicked immediately. No more context switching between files. No more inventing class names. I never used another styling library after that. I've stuck with Tailwind to this day.

The Webpack Configuration Pain

Back then, to integrate these libraries I had to mess with Webpack – install loaders, edit configs, and pray. I learned some Webpack configuration from their docs and even made my own template. It was a pain.

Here's are of the configs I used to write:

  1. webpack.common.js - common config that i.e imported and used in both dev and prod
// webpack.common.js
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
 
module.exports = {
  entry: {
    index: {
      import: "./src/index.js",
    },
  },
  output: {
    filename: "[name].[contenthash].js",
    path: path.resolve(__dirname, "dist"),
    clean: true,
  },
  module: {
    rules: [
      {
        test: /\.less$/i,
        use: ["style-loader", "css-loader", "less-loader"],
      },
      {
        test: /\.styl$/i,
        use: ["style-loader", "css-loader", "stylus-loader"],
      },
      {
        test: /\.s[ac]ss$/i,
        use: ["style-loader", "css-loader", "sass-loader"],
      },
      {
        test: /\.(css)$/i,
        use: ["style-loader", "css-loader"],
      },
      {
        test: /\.(png|gif|jpg|jepg|svg|woff|woff2|eot|ttf|otf)$/i,
        type: "asset/resource",
      },
      {
        test: /\.(?:js|mjs|cjs)$/,
        exclude: /node_modules/,
        use: {
          loader: "babel-loader",
          options: {
            presets: [["@babel/preset-env", { targets: "> 0.25%, not dead" }]],
          },
        },
      },
    ],
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: "./src/index.html",
    }),
  ],
  optimization: {
    moduleIds: "deterministic",
    runtimeChunk: "single",
    splitChunks: {
      cacheGroups: {
        vendor: {
          test: /[\\/]node_modules[\\/]/,
          name: "vendors",
          chunks: "all",
        },
      },
    },
  },
};
  1. webpack.dev.js - development config overriding
// webpack.dev.js
const { merge } = require("webpack-merge");
const common = require("./webpack.common");
 
module.exports = merge(common, {
  mode: "development",
  devtool: "inline-source-map",
  devServer: {
    static: "src",
  },
});
  1. webpack.prod.js - production side config overriding
// webpack.prod.js
const { merge } = require("webpack-merge");
const common = require("./webpack.common");
 
module.exports = merge(common, {
  mode: "production",
  devtool: "source-map",
});

Major Projects From My Journey

These are the key projects I built while working through The Odin Project:

  1. Todo App (Vanilla JS)
  2. Blog App

And there are many more in my projects gallery!


Now Thanks to Evan You, I use vite and configure it as much as I want with ease!

No sponsors yet. Be the first!

Become a Sponsor