예제
KO

빌드 훅

빌드 훅으로 빌드 전후에 사용자 정의 셸 명령을 실행할 수 있습니다. 의존성 설치, 데이터 전처리, 에셋 최적화, 배포 트리거 같은 작업에 유용합니다.

설정

config.toml에 훅을 정의합니다.

[build]
hooks.pre = ["npm install", "npx tsc"]
hooks.post = ["npm run minify", "npx pagefind --site public"]
타입 기본값 설명
hooks.pre array [] 빌드 전에 실행할 명령
hooks.post array [] 빌드 후에 실행할 명령

동작 방식

빌드 전 훅

빌드 전 훅은 콘텐츠 처리가 시작되기 전에 실행됩니다. 다음 작업에 적합합니다.

[build]
hooks.pre = [
  "npm ci",
  "npx tailwindcss -i src/input.css -o static/assets/css/main.css",
  "python scripts/fetch-data.py"
]

빌드 전 훅이 실패하면(0이 아닌 상태로 종료) 빌드가 중단됩니다. 의존성이 빠졌거나 에셋이 깨진 상태로 빌드되는 일을 막기 위해서입니다.

빌드 후 훅

빌드 후 훅은 사이트가 출력 디렉터리에 생성된 후에 실행됩니다. 다음 작업에 적합합니다.

[build]
hooks.post = [
  "npx imagemin public/images/* --out-dir=public/images",
  "npx pagefind --site public",
  "./scripts/deploy.sh"
]

빌드 후 훅이 실패하면 경고만 표시되고 빌드 자체는 실패로 처리되지 않습니다. 생성된 사이트는 그대로 유지됩니다.

실행 순서

명령은 정의된 순서대로 차례로 실행됩니다.

[build]
hooks.pre = ["echo Step 1", "echo Step 2", "echo Step 3"]

출력:

Running pre-build hook: echo Step 1
Step 1
Running pre-build hook: echo Step 2
Step 2
Running pre-build hook: echo Step 3
Step 3

serve 모드

빌드 훅은 hwaro serve 중에도 실행되지만, 전체 재빌드에서만 실행됩니다.

덕분에 저장 후 새로고침이 빠르게 유지됩니다. 서버가 켜져 있는 동안 훅의 결과물을 갱신해야 한다면 config.toml을 건드리거나 hwaro serve를 재시작해 전체 재빌드를 유도하세요.

재빌드 루프

감시 대상 디렉터리(content/, templates/, static/, data/, i18n/)나 config.toml 자체에 쓰는 훅은 자기 결과물을 다시 감시자에게 흘려보냅니다. 무해한 경우는 하와로가 알아서 처리합니다. 빌드가 이미 읽은 것과 같은 바이트를 다시 쓰는 실행(변하지 않은 응답을 받아오는 curl -o data/team.json, 동일한 결과물을 다시 내보내는 번들러, config.toml의 시각만 건드리는 훅)은 무한 재빌드로 이어지지 않고 잦아듭니다. 파일 위치에 따라 그 변경은 아예 무시되거나, 훅을 다시 실행하지 않는 부분 재빌드로 흡수됩니다.

반면 다음 두 가지는 감시자 입장에서 실제 변경이므로 매번 재빌드를 유발합니다.

결과물을 결정적으로 만들거나, 감시하지 않는 위치에 쓰세요(.hwaro/는 무시되며, 위에 나열한 디렉터리 밖도 마찬가지입니다).

활용 사례

TypeScript 컴파일

[build]
hooks.pre = ["npx tsc --outDir static/assets/js"]

Tailwind CSS

[build]
hooks.pre = [
  "npx tailwindcss -i src/styles.css -o static/assets/css/styles.css --minify"
]

API에서 데이터 가져오기

가장 흔한 경우, 즉 GET 요청 하나의 페이로드를 site.data에 넣는 것이라면 훅이 필요 없습니다. config.toml[[data.remote]] 소스를 선언하면 Hwaro가 빌드당 한 번 가져오며, 디스크 캐싱과 명시적인 오류 처리가 내장되어 있습니다.

가져오기가 요청 하나로 끝나지 않을 때는 여전히 사전 빌드 훅이 맞는 도구입니다. load_data()는 디스크만 읽습니다. 따라서 원격 데이터는 빌드 전에 data/로 내려받아 정적으로 굽습니다. data/ 아래 파일은 그대로 site.data로 노출됩니다.

[build]
hooks.pre = ["curl -sfL https://api.example.com/team -o data/team.json"]
{% for member in site.data.team %}
  <li>{{ member.name }}</li>
{% endfor %}

curl -f는 HTTP 오류에서 0이 아닌 코드로 종료하므로, 데이터가 빠진 사이트를 배포하는 대신 빌드가 중단됩니다. 페이지네이션, 인증 헤더, 응답 가공처럼 요청 하나로 끝나지 않는 작업은 스크립트로 분리해 호출하세요.

[build]
hooks.pre = ["./scripts/fetch-data.sh"]

오프라인에서도 동일한 빌드를 원한다면 내려받은 파일을 커밋하고, 항상 최신 데이터를 원한다면 .gitignore에 추가하세요.

Pagefind 검색

빌드 후 클라이언트 사이드 검색 인덱스를 생성합니다.

[build]
hooks.post = ["npx pagefind --site public"]

이미지 최적화

[build]
hooks.post = [
  "npx imagemin public/**/*.{jpg,png} --out-dir=public"
]

사용자 정의 배포 스크립트

[build]
hooks.post = ["./scripts/deploy.sh"]

전체 파이프라인 예시

[build]
hooks.pre = [
  "npm ci",
  "npx tsc",
  "npx tailwindcss -i src/input.css -o static/assets/css/main.css --minify"
]
hooks.post = [
  "npx pagefind --site public",
  "npx imagemin public/images/* --out-dir=public/images",
  "echo 'Build complete!'"
]

오류 처리

훅 유형 실패 시
빌드 전 ❌ 빌드 중단 — 콘텐츠를 처리하지 않음
빌드 후 ⚠️ 경고 표시 — 생성된 사이트는 유지

필수 준비 작업(빌드 전)은 반드시 성공해야 하고, 선택적 최적화 작업(빌드 후)은 빌드 출력을 막지 않도록 설계되어 있습니다.

함께 보기