Astro로 만든 사이트를 하루 만에 Hugo로 갈아엎었습니다
이 사이트는 처음에 Astro로 만들었습니다. 그리고 같은 날 걷어내고 Hugo로 다시 만들었습니다.
부끄러운 쪽부터 적습니다. 갈아엎은 이유는 Astro가 나빠서가 아니라 제가 고를 때 대안을 나란히 놓고 따져보지 않았기 때문입니다.
처음 든 근거 셋, 전부 결정적이지 않았습니다
Astro를 고르면서 제가 든 이유는 세 개였습니다.
- Node가 이미 깔려 있다
- content collections의 스키마 검증이 편하다
- Cloudflare가 공식 지원한다
“다른 정적 생성기도 많지 않나"라는 말을 듣고서야 비교를 해봤는데, 셋 중에 결정적인 것이 하나도 없었습니다.
| 처음 든 근거 | 따져보니 |
|---|---|
| Node가 이미 있다 | 있으면 편한 것이지, 고를 이유는 아닙니다 |
| 스키마 검증 | Hugo도 빌드 스크립트로 됩니다. 직접 짜야 할 뿐입니다 |
| Cloudflare 공식 지원 | Hugo도 마찬가지입니다 |
“Node가 이미 있다"는 특히 이상한 근거였습니다. 이미 가진 것을 이유로 대면 뭘 골라도 그 이유가 성립합니다.
나란히 놓고 재보니
말로 따지는 것보다 재는 게 빨랐습니다. 같은 글 3편, 같은 내용으로 두 번 만들어봤습니다.
| Astro | Hugo | |
|---|---|---|
| 설치되는 npm 패키지 | 278개 | 0개 (단일 바이너리) |
| 빌드 시간 | 877ms | 10ms |
빌드 속도는 사실 신경 쓰지 않았습니다. 글 서너 편에서 무슨 차이가 나겠나 싶었습니다. 88배가 날 줄은 몰랐습니다. 물론 877ms도 기다릴 만한 시간이라 이게 결정타는 아니었습니다. 다만 “차이 없을 것"이라는 제 짐작이 틀렸다는 건 확인됐습니다.
덤으로 나온 실수 하나. astro@^5로 깔았더니 5.18.2가 설치됐는데,
그때 최신은 7.2.7이었습니다. 두 메이저 뒤처진 걸 깔아놓고 시작한 겁니다.
튜토리얼에 적힌 버전 범위를 그대로 복사한 결과였습니다.
“이거 계속 관리될까요”
진짜 물어야 했던 질문은 이거였습니다. 블로그는 몇 년을 굴릴 물건이니까요.
GitHub API로 두 프로젝트의 커밋을 기여자별로 집계해봤습니다.
Hugo
| 기여자 | 커밋 | 비중 |
|---|---|---|
bep | 5,821 | 70.7% |
| dependabot[bot] | 627 | 7.6% |
spf13 (창시자) | 466 | 5.7% |
jmooring | 406 | 4.9% |
Astro
| 기여자 | 커밋 | 비중 |
|---|---|---|
matthewp | 2,079 | 20.6% |
| astrobot | 1,631 | 16.1% |
ematipico | 1,178 | 11.7% |
FredKSchott | 1,084 | 10.7% |
이 표는 Hugo에 유리하지 않습니다. 오히려 반대입니다. 한 사람이 70%를 쓰고 있고, 2위는 봇이고, 창시자는 손을 뗐습니다. 버스 팩터 1입니다. Astro는 넷이 고르게 나눠 쓰고 있어서 이 축으로는 Astro가 낫습니다.
다만 Astro 쪽 기여자들은 Astro Technology Company 소속입니다. 분산돼 있지만 회사 하나에 묶여 있다는 뜻이라, 리스크가 없어진 게 아니라 종류가 다릅니다.
릴리스 패턴도 같이 봤습니다.
| 시작 | 그때 버전 | 읽히는 것 | |
|---|---|---|---|
| Hugo | 2013 | v0.165.0 | 12년째 0.x. semver를 안 쓰고 조금씩 갑니다 |
| Astro | 2021 | v7.2.7 | 5년에 메이저 7개 = 연 1~1.5회 breaking change |
“중간에 갈아엎을 일이 생기지 않을까"가 원래 Astro 쪽 걱정이 아니라 Hugo 쪽 걱정이었는데, 숫자로는 반대였습니다.
결정을 가른 질문
두 프로젝트 다 리스크가 있고 종류가 다르다는 것까지 왔습니다. 그래서 질문을 바꿨습니다. “개발이 멈추면 나는 어떻게 되나.”
| 개발이 멈추면 | |
|---|---|
| Hugo | 바이너리 하나 보관해두면 영구히 빌드됩니다. 인터넷 없이도 됩니다 |
| Astro | npm install이 3년 뒤에 깨질 수 있습니다. 278개 중 하나만 사라져도 |
이 축에서는 비교가 안 됐습니다. Hugo가 12년째 0.x인데도 살아있는 이유도 아마 이것일 겁니다.
그런데 이 결정은 되돌리기 쌉니다
마지막으로 확인한 게 하나 더 있습니다. 틀렸을 때 얼마나 손해인가.
글이 전부 마크다운이라 어느 생성기로든 그대로 옮겨갑니다. front matter 필드 이름만 맞추면 됩니다. 실제로 이번에 옮기는 데 든 건 글 1편 + CSS 1개 이식 + 레이아웃 다시 짜기 30분이었습니다. 글이 50편이어도 마크다운은 그대로 갑니다.
되돌리기 싼 결정에 오래 고민하는 게 더 손해라, 여기서 확정하고 넘어갔습니다.
옮기고 나서 밟은 것 넷
Hugo가 12년째 0.x라는 건, 오래된 튜토리얼이 그대로 안 먹는다는 뜻이기도 합니다. 검색해서 나온 대로 따라 하다 걸린 것들입니다.
1. v0.146.0에서 템플릿 시스템이 통째로 바뀌었습니다.
layouts/_default/가 없어지고, partials/ → _partials/, shortcodes/ → _shortcodes/로
바뀌었습니다. 검색 상위에 뜨는 글들은 대부분 이 이전 것이라 구조부터 안 맞습니다.
2. languageCode는 v0.158.0에서 locale로 바뀌었습니다.
경고만 뜨고 빌드는 되기 때문에 한동안 모르고 지나갑니다.
3. 본문에 raw HTML을 쓰려면 설정을 켜야 합니다.
[markup.goldmark.renderer]
unsafe = true
이 글에 있는 회색 박스가 그것 때문에 필요했습니다. 안 켜면 태그가 조용히 사라집니다.
4. disableKinds는 루트 레벨에 둬야 합니다.
이게 제일 오래 헤맸습니다. 태그 페이지를 끄려고 disableKinds를 넣었는데
태그 페이지가 계속 생성됐습니다. 오타도 아니고 오류도 없었습니다.
[params] 같은 섹션 안에 들어가 있으면 에러 없이 그냥 무시됩니다.
# 이건 동작합니다 — 루트 레벨
disableKinds = ['taxonomy', 'term']
[params]
description = '...'
왜 태그 페이지를 껐는가: 글이 적을 때 태그 분류를 켜두면 글 한 편짜리 페이지가 태그 수만큼 생깁니다. 목록에 제목 하나만 있는 페이지들이 사이트의 절반이 됩니다. 글이 쌓이면 그때 켜려고 합니다.
정리
- 고를 때 대안을 나란히 놓지 않으면 이유가 있어도 근거는 없습니다. 제가 그랬습니다
- “차이 없을 것"이라고 짐작한 항목이 88배 차이였습니다. 짐작한 것은 재봐야 압니다
- 유지보수 리스크는 없는 쪽을 고르는 게 아니라 종류를 고르는 것이었습니다
- 결정적이었던 질문은 성능도 생태계도 아니고 **“개발이 멈추면 나는 어떻게 되나”**였습니다
- 되돌리기 싼 결정에는 오래 고민하지 않는 편이 낫습니다. 글이 마크다운이면 이사는 언제든 됩니다