DEV Community

Will Medina
Will Medina

Posted on

Complete React Setup with SSR, CSR, TailwindCSS, and Jest Using esbuild

This is a continuation of my first blog post:

In this post I will extend the setup adding TailwindCSS for styling, Jest for unit testing.

Configuring TailwindCSS

To enable TailwindCSS we need to add PostCSS and write a small esbuild plugin to enable TailwindCSS in our css file.

First we'll need to install the following dependencies:

npm i --save-dev postcss tailwindcss autoprefixer
Enter fullscreen mode Exit fullscreen mode

Now lets create a esbuild plugin that we can add to our scripts to enable postcss and tailwindcss:

import { readFile } from 'node:fs/promises';
import postcss from 'postcss';
// esbuild Plugin to process css files with postcss
export const postcssPlugin = ({
  plugins = []
} = {}) => {
  return {
    name: 'postcss',
    setup(build) {
      build.onLoad({ filter: /\.css$/ }, async (args) => {
        const raw = await readFile(args.path, 'utf8');
        const source = await postcss(plugins).process(raw.toString(), {
            from: args.path
          });
        return {
          contents: source.css,
          loader: 'css'
        };
      });
    }
  };
}

export default postcssPlugin;
Enter fullscreen mode Exit fullscreen mode

In your esbuild configuration now we can use the plugin:

{
  //...esbuildConfig,
  plugins: [
    postcssPlugin({
      plugins: [
        tailwindcss(),
        autoprefixer
      ]
    })
  ]
}
Enter fullscreen mode Exit fullscreen mode

And create our initial tailwindcss config tailwind.config.ts:

import type { Config } from 'tailwindcss';

const config: Config = {
  content: [
    './src/**/*.{ts,tsx,svg}'
  ],
  // Theme
  theme: {
    extend: {
      colors: {
        background: 'var(--background)',
        foreground: 'var(--foreground)',
      }
    }
  }
};

export default config;
Enter fullscreen mode Exit fullscreen mode

Configuring Jest

To enable Jest in our project we will use @testing-library as it will facilitate the configuration and testing utilities.

Install the following dependencies:

npm i --save-dev jest jest-environment-jsdom @testing-library/jest-dom @testing-library/react @types/jest
Enter fullscreen mode Exit fullscreen mode

To configure Jest with react and esbuild we'll need to create a transformer to transpile typescript and jsx.

import { transformSync } from 'esbuild';
export default {
  process(src, filename) {
    // Ensure only TypeScript and JavaScript files are processed
    if (/\.(ts|tsx|js|jsx)$/.test(filename)) {
      const result = transformSync(src, {
        loader: filename.endsWith('ts') || filename.endsWith('tsx') ? 'tsx' : 'jsx',
        format: 'esm',  // ESM format
        sourcemap: 'inline', // Inline sourcemaps for debugging
        target: 'esnext', // Set the target to latest ECMAScript
        tsconfigRaw: {
          compilerOptions: {
            jsx: 'react-jsx'
          },
        }
      });
      return { code: result.code, map: result.map };
    }
    return src;
  },
};
Enter fullscreen mode Exit fullscreen mode

We'll also need a environment setup file to import jest-dom from @testing-library that way we can use the library matches like toBeInTheDocument and toBeInTheDOM.

import '@testing-library/jest-dom';
Enter fullscreen mode Exit fullscreen mode

Lastly we can create a config file jest.config.json that will use our custom esbuild transformer and setup file.

{
  "testMatch": [
    "<rootDir>/**/?(*.)+(test).(ts|tsx)"
  ],
  "transform": {
    "^.+\\.(ts|tsx)$": "<rootDir>/scripts/testTransformer.js"
  },
  "setupFilesAfterEnv": [
    "<rootDir>/scripts/testSetup.ts"
  ],
  "moduleFileExtensions": ["ts", "tsx", "js", "jsx", "json", "node"],
  "extensionsToTreatAsEsm": [".ts", ".tsx", ".svg"],
  "transformIgnorePatterns": ["/node_modules/"],
  "testEnvironment": "jsdom"
}
Enter fullscreen mode Exit fullscreen mode

This will allow us to run jest test files in the project. since we are using esm we have to use node --experimental-vm-modules flag.

There are also others utilities that are commonly used in react projects like importing SVG as Components and auto reload on changes. I have included these in my repository:

GitHub logo willyelm / react-app-seed

A Simple react app setup with SSR, CSR, Jest, TailwindCSS and esbuild

A Simple react app setup with SSR and esbuild

This project leverages the latest features of react@19, react-router-dom@7, and others to configure SSR.

Depdendencies

  • react: Component-based and interactive UI library.
  • react-dom: Hydrates SSR content with React functionality.
  • react-router-dom: Handle Routes with React.
  • express: Node.js simple server for static and REST APIs.
  • esbuild: Transile TypeScript and bundle JS, CSS, SVG, and other files.
  • typescript: Adding Typing to our source code.
  • jest: Unit testing.
  • postcss: Preprocess css files.
  • tailwindcss: css utilities.
  • svgo: converting svg to JSX component modules.

Project Structure

react-app/             # This will be our workspace directory.
  - public/
  - scripts/           
    - build.js         # Bundle our server and client scripts.
    - config.js        # esbuild config to bundle.
    - dev.js           # Bundle on watch mode and run server.
  - src/
    - App/             # Our components will be here.
      - App.tsx        # The
Enter fullscreen mode Exit fullscreen mode

Top comments (0)