Mục lục

Config Strategy: TypeScript, ESLint & Tailwind

Thiết lập môi trường phát triển đồng nhất. Chia sẻ config Tailwind để đảm bảo Design System nhất quán.

Trong Monorepo, cơn ác mộng lớn nhất là mỗi dự án lại có một config khác nhau.

  • App A dùng Tailwind v3.3, App B dùng v3.4.
  • App A dùng rule ESLint airbnb, App B dùng standard.

Chúng ta cần Centralized Configuration.

1. Shared Tailwind Config

Tất cả dự án phải dùng chung một bảng màu (Color Palette).

javascript:
// packages/config/tailwind-preset.js
module.exports = {
  darkMode: ["class"],
  theme: {
    container: {
      center: true,
      padding: "2rem",
      screens: {
        "2xl": "1400px",
      },
    },
    extend: {
      colors: {
        border: "hsl(var(--border))",
        input: "hsl(var(--input))",
        ring: "hsl(var(--ring))",
        background: "hsl(var(--background))",
        foreground: "hsl(var(--foreground))",
        primary: {
          DEFAULT: "hsl(var(--primary))",
          foreground: "hsl(var(--primary-foreground))",
        },
        secondary: {
          DEFAULT: "hsl(var(--secondary))",
          foreground: "hsl(var(--secondary-foreground))",
        },
        destructive: {
          DEFAULT: "hsl(var(--destructive))",
          foreground: "hsl(var(--destructive-foreground))",
        },
        muted: {
          DEFAULT: "hsl(var(--muted))",
          foreground: "hsl(var(--muted-foreground))",
        },
        accent: {
          DEFAULT: "hsl(var(--accent))",
          foreground: "hsl(var(--accent-foreground))",
        },
        popover: {
          DEFAULT: "hsl(var(--popover))",
          foreground: "hsl(var(--popover-foreground))",
        },
        card: {
          DEFAULT: "hsl(var(--card))",
          foreground: "hsl(var(--card-foreground))",
        },
      },
      borderRadius: {
        lg: "var(--radius)",
        md: "calc(var(--radius) - 2px)",
        sm: "calc(var(--radius) - 4px)",
      },
      fontFamily: {
        sans: ['var(--font-inter)', 'sans-serif'],
      }
    },
  },
  plugins: [require("tailwindcss-animate")],
};

Cách sử dụng ở App:

javascript:
// apps/store/tailwind.config.js
module.exports = {
  presets: [require("@repo/config/tailwind-preset")],
  content: [
    "./app/**/*.{ts,tsx}",
    "../../packages/ui/components/**/*.{ts,tsx}" // Quan trọng: Scan cả file trong package UI
  ],
};

2. Shared TypeScript Config

Tạo một file base tsconfig mà tất cả đều kế thừa.

json:
// packages/config/tsconfig.base.json
{
  "compilerOptions": {
    "target": "ESNext",
    "module": "ESNext",
    "moduleResolution": "Bundler",
    "strict": true,
    "skipLibCheck": true,
    "jsx": "preserve"
  }
}

Sử dụng:

json:
// apps/admin/tsconfig.json
{
  "extends": "@repo/config/tsconfig.base.json",
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@/*": ["./src/*"]
    }
  },
  "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"]
}

3. Shared ESLint

Đảm bảo coding style giống nhau.

javascript:
// packages/config/eslint-preset.js
module.exports = {
  extends: ["next/core-web-vitals", "prettier"],
  rules: {
    "no-console": "warn",
    "@next/next/no-html-link-for-pages": "off"
  }
};

Lợi ích

  1. Brand Consistency: Không bao giờ bị lệch màu giữa các app.
  2. Maintenance: Muốn bật rule no-any? Chỉ cần sửa 1 file config, cả 3 app đều văng lỗi ngay lập tức.
  3. Setup nhanh: New app apps/marketing chỉ mất 5 phút setup thay vì 1 tiếng copy config.
Quảng cáo
mdhorizontal