- Replace helpers dispatcher pattern with standalone chroma-lexers package - Add runCommand, fromRoot, consola re-export to shared - Update versioning and integration to use shared utilities - Shorten dev version format: base36 timestamp, no hash - Rename eslint.config.js to eslint.config.ts (add jiti) - Add README.md to each package
6.8 KiB
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, and TypeScript.
Development Commands
Prerequisites
- Node.js >= 20
- Hugo Extended >= 0.158.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 todemo.fixit.lruihao.cn)apps/test/— Test site for exercising theme featurespackages/shared— Shared utilities (exportsworkspaceRoot,fromRoot,runCommand,capitalize,consola)packages/versioning— Version management (auto-updates version inlayouts/_partials/init/index.htmlduring pre-commit)packages/integration— Post-build: merges demo/test output intopublic/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 typedwindow.fixitpublic API facade, and runs the init sequence onDOMContentLoaded.types/— TypeScript type definitions:config.ts—FixItConfigand all config sub-types.ui.ts—FixItPublicAPI, globalwindowaugmentation for third-party libs.third-party.ts— Types for vendored libraries.
core/— Infrastructure layer:event-bus.ts— Typed event bus singleton wrapping DOMCustomEvents. ExportseventBus(module-level singleton) andFixItEventMaptype.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.tsis a standalone factory consumed bySearchModule.utils/— Pure utility functions (no side effects, no DOM state). Re-exported fromutils/index.ts.lib/— Third-party library wrappers (aplayer, echarts, file-tree, fixit-decryptor, lightgallery, mapbox, mathjax, mermaid, etc.). All import the sharedeventBussingleton.head/—color-scheme.tsruns synchronously in<head>before body render to prevent flash of wrong theme.pages/— Page-specific scripts (e.g.link.tsfor 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 intoinit/,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/config.template.scssgenerates runtime CSS custom properties from Hugo config.scss/main.scssis the entry point importingcore/,pages/,widgets/,custom. - JS:
_partials/function/js-build.htmlwrapsjs.Buildwith minify-in-production defaults. Hugo's@paramsinjection passes config values into TypeScript at build time. - Third-party libraries: Stored in
assets/lib/(vendored, not npm-managed). Tracked bylibrarybot.ymland updated weekly by thehugo-fixit/librarybotGitHub Action. Can be overridden via CDN config inassets/data/cdn/jsdelivr.ymlorunpkg.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
TypeScript
- Use ES6
#private fields — not TypeScriptprivatewith_prefix - One module per file, one service interface per module
- Constructor injection for dependencies — no global state access
- Import the shared
eventBussingleton fromcore/event-bus— do not create new instances - Pure functions only in
utils/— no side effects, no DOM state
Hugo Templates
- Variable naming: camelCase (
$footerConfig,$fingerprint) - Translation: use
Tfunction ({{ T "header.switchTheme" }}) - Whitespace: use
{{- -}}trim markers - Use
partialCachedfor expensive partials that don't change per page - Use
.Site.Storefor shared computed values (e.g. fingerprint) - Check
hugo.IsProductionbefore adding analytics or minification
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.