Skip to content

Latest commit

 

History

History
159 lines (111 loc) · 7.89 KB

File metadata and controls

159 lines (111 loc) · 7.89 KB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Project Overview

FixIt is a modern, responsive theme for the Hugo static site generator. Built with Hugo templates, SCSS, UnoCSS, and TypeScript.

Development Commands

Prerequisites

  • Node.js >= 20
  • Hugo Extended >= 0.161.0 (Dart Sass required)
  • pnpm

Development

pnpm install           # Install dependencies
pnpm dev:demo          # Start demo site dev server
pnpm dev:test          # Start test site dev server
pnpm dev:docs          # Start docs dev server (requires fixit-docs as sibling directory)

Build

pnpm build:demo        # Build demo site
pnpm build:test        # Build test site
pnpm build             # Build all sites (demo + test, merged into public/)
pnpm preview           # Preview built site (requires build first)

Code Generation

pnpm gen:lexers        # Regenerate assets/scss/core/maps/_chroma-lexers.scss from Chroma source

Code Quality

pnpm lint              # Run ESLint
pnpm typecheck         # Run TypeScript type checking

There are no unit tests. Verify changes by building pnpm build:demo or pnpm build:test and inspecting the output.

Architecture

Monorepo Structure

Root package.json is @hugo-fixit/core. pnpm workspaces include apps/* and packages/*:

  • apps/demo/ — Demo site (deployed to demo.fixit.lruihao.cn)
  • apps/test/ — Test site for exercising theme features
  • packages/shared — Shared utilities (exports workspaceRoot, fromRoot, runCommand, capitalize, consola)
  • packages/versioning — Version management (auto-updates version in layouts/_partials/init/index.html during pre-commit)
  • packages/integration — Post-build: merges demo/test output into public/
  • packages/chroma-lexers — Generates Chroma lexer SCSS map from GitHub

JavaScript Module System (assets/js/)

Service-class architecture with direct constructor calls:

  • main.ts — Entry point. Instantiates all modules with direct constructor calls, builds the typed window.fixit public API facade, and runs the init sequence on DOMContentLoaded.
  • types/ — TypeScript type definitions:
    • config.tsFixItConfig and all config sub-types.
    • ui.tsFixItPublicAPI, global window augmentation for third-party libs.
    • third-party.ts — Types for vendored libraries.
  • core/ — Infrastructure layer:
    • event-bus.ts — Typed event bus singleton wrapping DOM CustomEvents. Exports eventBus (module-level singleton) and FixItEventMap type.
    • tokens.ts — Service interfaces (CoreService, ThemeService, CodeService, etc.) used for module constructor typing.
  • modules/ — Feature modules. Each is a class implementing its service interface. Dependencies are constructor-injected. Private state uses ES6 # fields. Modules: charts, code, content, core, encryption, events, menu, misc, search, theme, toc. pagefind.ts is a standalone factory consumed by SearchModule.
  • utils/ — Pure utility functions (no side effects, no DOM state). Re-exported from utils/index.ts.
  • lib/ — Third-party library wrappers (aplayer, echarts, file-tree, fixit-decryptor, lightgallery, mapbox, mathjax, mermaid, etc.). All import the shared eventBus singleton.
  • head/color-scheme.ts runs synchronously in <head> before body render to prevent flash of wrong theme.
  • pages/ — Page-specific scripts (e.g. link.ts for the link guard redirection page).

Cross-module communication uses the shared eventBus singleton, not direct module imports. The window.fixit facade exposes a typed public API for user custom scripts (custom.ts): theme control, scroll state, mask overlay management, content re-initialization, and the event bus.

Hugo Templates (layouts/)

  • _partials/ — Reusable template components (organized into init/, base/, function/, plugin/, single/, store/)
  • _shortcodes/ — 31 custom shortcodes (admonition, aplayer, echarts, file-tree, mermaid, tabs, timeline, etc.)
  • _markup/ — 15 render hooks (code blocks, headings, images, links, tables, blockquote alerts, passthrough for math)

Asset Pipeline

Hugo Pipes processes all assets. The key orchestration is in _partials/base/assets.html:

  • CSS: scss/main.scss is the entry point importing core/, pages/, widgets/, custom. SCSS variables are configured via hugo:vars (user-configurable from [params.appearance]) and hugo:vars/internal (theme system config). UnoCSS utility classes are pre-built to assets/css/unocss.css (via pnpm unocss), loaded before the main SCSS bundle.
  • JS: _partials/function/js-build.html wraps js.Build with minify-in-production defaults. Hugo's @params injection passes config values into TypeScript at build time.
  • Third-party libraries: Stored in assets/lib/ (vendored, not npm-managed). Tracked by librarybot.yml and updated weekly by the hugo-fixit/librarybot GitHub Action. Can be overridden via CDN config in assets/data/cdn/jsdelivr.yml or unpkg.yml.

Theme Configuration

  • hugo.toml — Default theme configuration (1700+ lines). Uses _merge = "shallow" to let user configs override without deep merging.
  • theme.toml — Theme metadata

Coding Standards

SCSS (assets/scss/)

  • CSS classes: BEM or semantic naming (header-desktop, menu-item)
  • SCSS variables: hyphen-separated, semantic ($global-font-family)
  • CSS custom properties: prefixed with fi- / --fi-
  • Use CSS variables for theme switching; SCSS variables for colors (no hardcoded values)
  • Prefer relative units (rem, em, %) over absolute units
  • Keep selector nesting shallow

UnoCSS (assets/css/unocss.css)

  • Pre-built utility classes generated by pnpm unocss (config: uno.config.ts)
  • Use atomic classes for common utilities (hidden, me-1, text-center, etc.)
  • Theme colors mapped via @theme: bg-primary, text-success, text-danger, etc.
  • Responsive breakpoints: sm: (>=680px), md: (>=960px), lg: (>=1200px), xl: (>=1440px). Use max-sm: for xs (<680px)
  • Wrap SVG elements with <!-- @unocss-skip-start --> / <!-- @unocss-skip-end --> to avoid false positives from d attribute values
  • safelist in uno.config.ts for dynamically generated classes (e.g., order-*, sm:hidden)

TypeScript

  • Use ES6 # private fields — not TypeScript private with _ prefix
  • One module per file, one service interface per module
  • Constructor injection for dependencies — no global state access
  • Import the shared eventBus singleton from core/event-bus — do not create new instances
  • Pure functions only in utils/ — no side effects, no DOM state
  • Comment style: follow TSDoc conventions

Hugo Templates

  • Variable naming: camelCase ($footerConfig, $fingerprint)
  • Translation: use T function ({{ T "header.switchTheme" }})
  • Whitespace: use {{- -}} trim markers
  • Use partialCached for expensive partials that don't change per page
  • Use .Site.Store for shared computed values (e.g. fingerprint)
  • Check hugo.IsProduction before adding analytics or minification
  • Minimize id attribute usage — prefer class selectors for styling and JS queries. Reserve id for: <label for>, aria-controls/aria-labelledby, fragment anchors, or third-party library requirements

Commit Convention

Follows Conventional Commits:

<type>(<scope>): <subject>

Types: feat, fix, refactor, chore, docs, perf, style, test, ci, build

Scopes: workflow, archetypes, assets, i18n, layouts, config, or specific directories.

Pre-commit Hooks

Pre-commit runs: versioning (dev mode), typecheck, lint-staged (eslint --fix on staged files).

ESLint

Uses @antfu/eslint-config with TypeScript support. Config at eslint.config.ts.