레퍼런스도구자라는 중업데이트 2026.08읽는 데 약 5분
레퍼런스 · 도구

다섯 가지 검사

빌드가 초록이라고 페이지가 멀쩡하다는 뜻은 아닙니다. 이 도구 사슬은 계층마다 검사 하나를 세워 두고, "빌드는 초록, 페이지는 고장"인 조용한 실패를 부류별로 하나씩 잡습니다 — 그중 둘은 독자가 보는 방식 그대로, 진짜 브라우저에서 페이지를 봅니다.

검사 다섯 · 엔진이 셋, 이 패키지가 둘 · 전부 초록이어야 커밋

§1다섯 관문, 다섯 계층

검사배포 주체보는 것돌리는 시점
check-content엔진, scripts/check-content.mjs모든 md/mdx 소스 파일콘텐츠 저장소 CI, 또는 글을 쓴 직후
check-wikilinks엔진, scripts/check-wikilinks.mjs[[위키링크]] 그래프콘텐츠 저장소 CI, 또는 노트 이름을 바꾼 뒤
check-dist엔진, scripts/check-dist.mjsastro build 산출물매 빌드 후 (postbuild)
ui_probe이 패키지, scripts/ui_probe.mjs진짜 브라우저에서 렌더링된 페이지스타일/레이아웃 변경 후
contrast_probe이 패키지, scripts/contrast_probe.mjs모든 텍스트 노드의 대비, 두 테마토큰 변경 후

§2check-content: 소스 계층

페이지가 될 모든 md/mdx 파일을 사이트와 완전히 같은 방언으로 컴파일해 봅니다 — 문법 오류와 조용한 변형(짝을 맺지 못하는 강조 표시, MDX 평가에 삼켜진 중괄호, 줄바꿈이 낳은 목록 마커, 한 줄짜리 $$, KaTeX가 렌더링하지 못하는 수식 — 전 요소 시연이 끝에 나열한 바로 그 목록)이 전부 CI를 붉게 만듭니다.

이 스크립트가 반드시 엔진에서 와야 하는 이유: 플러그인 구성이 사이트와 다른 검사기는 검사기가 없느니만 못합니다 — 수식 플러그인이 빠지면 수식 중괄호를 JSX 표현식으로 오독하고, GFM이 없으면 표의 파이프를 통과시킵니다. 방언은 엔진 안에 한 번만 쓰이고, 사이트 렌더링, CMS 저장 검증, 그리고 이 스크립트가 소비하는 것은 언제나 같은 하나입니다.

콘텐츠 저장소 루트
node <engine>/scripts/check-content.mjs . --glob '**/index.{md,mdx}' --math

컴파일 너머로, frontmatter의 조용한 손실 두 부류도 잡습니다: 값 안에 따옴표 없이 들어간 #(YAML이 주석으로 읽어 나머지를 소리 없이 잘라 먹습니다), 그리고 아예 파싱되지 않는 YAML — 줄 번호와 함께 보고합니다.

죽은 [[위키링크]]는 의도적으로 빌드를 실패시키지 않습니다 — 정원에는 아직 자라지 않은 노트로 링크를 걸 자유가 있어야 하니까요. 그래도 링크 부패는 CI에서 드러나야 하므로, 엔진은 라이브러리 자신의 파서와 해석 규칙(별칭, brand, 제목, 로케일 미러)으로 모든 위키링크를 해석해 없는 것, 모호한 것, 의심스러운 앵커를 보고하는 린트를 싣고 있습니다. --strict 플래그는 죽은 링크를 실패 종료 코드로 바꿉니다 — 이 저장소의 CI가 도는 방식이 바로 그것입니다:

이 정원의 링크 검사, CI와 동일
node scripts/check-links.mjs

§4check-dist: 산출물 계층

빌드된 dist/ 안에서, 독자가 클릭할 수 있는 모든 내부 참조는 실제로 존재해야 합니다. 초록 빌드 밑의 조용한 구멍을 잡습니다:

  • 존재하지 않는 파일을 가리키는 내부 링크와 자산(라우트를 한 번 재배치하면 수십 개씩 쏟아지는 부류);
  • 존재하지 않는 id를 가리키는 페이지 내 앵커;
  • 경로에 겹쳐 쌓인 로케일 구간(/en/en/ — i18n 폴백이 이미 접두사가 붙은 라우트에 접두사를 또 얹은 고전적 결과);
  • <a> 안에 중첩된 <a>(HTML 파서가 바깥쪽을 일찍 닫아 버려, 버튼이 카드 밖으로 떨어져 나갑니다);
  • KaTeX 오류 잔여물(페이지의 수식은 이미 빨간 텍스트인데 빌드는 초록으로 남는 경우).

이 데모는 postbuild 단계에 연결해 둡니다: npm run build 명령이 초록이면 산출물 검사도 통과한 것입니다.

사이트 루트, 빌드 후 (하위 경로에 배포하는 사이트는 --base를 넘깁니다)
node vendor/astro-inkbrush/scripts/check-dist.mjs dist --base ${DEMO_BASE:-/}

§5렌더링 프로브

소스도 산출물도 옳은데 페이지는 여전히 고장일 수 있습니다 — 고전적 사례가, 어떤 스타일시트 규칙도 명중하지 않아 맨글자 한 줄로 짜부라져 렌더링되는 랜딩 카드입니다: 링크 검사와 앵커 검사는 렌더링된 페이지를 한 번도 보지 않으니 여전히 초록입니다. ui_probe 도구는 진짜 브라우저를 몰아 dist의 모든 페이지를 네 가지 뷰포트 너비(1440/1024/768/430)로 훑으며 측정합니다: 페이지의 가로 넘침, 스크롤 상자 없이 컨테이너보다 넓어진 요소, 어떤 스타일 규칙도 입혀 주지 않는 클래스, 건너뛴 제목 레벨, 중복된 id, alt 속성 없는 이미지, 허공을 가리키는 페이지 내 앵커와 aria-controls. 기계가 증명할 수 있는 것만 보고합니다 — 미적 판단은 하지 않습니다.

로컬에 Chrome/Chromium 필요
npm run build
node ../scripts/ui_probe.mjs dist   # dist를 직접 서빙합니다. 떠 있는 서버를 재려면 baseUrl을 넘기십시오

문서 전체를 들여다봅니다 — 크롬, 사이드바, 대화 상자까지 포함해서. 초록의 기준은 하나입니다: 보고서 마지막 줄이 SAMPLES WITH FINDINGS: 0일 것(샘플 하나는 라우트 하나를 너비 하나에서 본 것입니다).

§6대비 프로브

토큰이 AA를 주장하니, 그 주장은 단언 대신 측정으로 뒷받침합니다. contrast_probe 도구는 dist의 모든 페이지를 진짜 브라우저에 띄우고 — 라이트와 다크 테마, 데스크톱과 휴대폰 너비 — 기본 상태로 렌더링된 모든 텍스트 런을 측정합니다: HTML 텍스트, SVG 텍스트, ::before / ::after가 만든 텍스트까지. 대표 페이지에서는 <dialog data-probe-open> 표시가 붙은 오버레이를 모두 열어서 재고(검색창이 있으면 질의어도 쳐 넣습니다) — 이 표시는 "이 대화 상자는 쓰인 그대로가 완성형"이라는 사이트의 선언입니다. 바탕색은 스타일시트에서 읽지 않습니다. 모든 글리프를 투명하게 만든 채 페이지를 렌더링해 스크린샷을 찍고, 각 텍스트 런 밑의 픽셀이 곧 그 바탕이 됩니다 — 그래서 그러데이션, color-mix() 틴트, 반투명 레이어, 야간 팔레트가 전부 실제 렌더링되는 모습 그대로 측정됩니다. 전경색은 요소와 조상들에 누적된 opacity 값을 짊어지므로, 흐리게 처리된 텍스트도 독자가 실제로 보는 농도로 측정됩니다. hover와 focus 상태는 프로브 대신 사람 눈으로 검토합니다. 작은 글자의 기준선은 4.5:1, 큰 글자(24px, 또는 18.66px 굵게)는 3:1입니다. 색을 파싱할 수 없거나 바탕을 샘플링할 수 없는 런은 그 자체로 문제로 셉니다. 기준 미달인 런 하나하나에 대해, 보고서는 페이지, 테마, 너비, 선택자, 두 색상, 그리고 실측 비율을 지목합니다:

빌드 후, 두 테마 모두
node ../scripts/contrast_probe.mjs dist   # PROBE_THEMES / PROBE_WIDTHS로 측정 범위를 좁힐 수 있습니다

스타일 변경의 고정 루틴
패키지의 스타일시트나 컴포넌트를 손대는 모든 변경은 먼저 이 데모의 빌드를 지나고, 이어서 ui_probecontrast_probe가 산출물을 훑습니다 — 전부 초록이어야 커밋합니다. 데모가 곧 이 패키지의 시험대입니다.

제목, 섹션, 본문을 현재 언어에서 검색합니다.
    ↑↓ · Enter · Escastro-inkstone