구문 강조 개발 가이드라인 (리포지터리 blob 뷰어)
GitLab v19.2요약
이 가이드는 리포지터리 소스 코드 뷰어에서 구문 강조를 구현하는 모범 사례와 세부 구현 방법을 설명합니다. 소스 코드 뷰어는 이 두 가지 방식을 함께 사용하여 다양한 언어를 지원하고 리포지터리에서 파일을 볼 때 최적의 성능을 보장합니다.
이 가이드는 리포지터리 소스 코드 뷰어에서 구문 강조를 구현하는 모범 사례와 세부 구현 방법을 설명합니다. GitLab은 두 가지 구문 강조 라이브러리를 사용합니다:
- 소스 뷰어에서 클라이언트 측 강조를 위한 Highlight.js
지원 언어 전체 목록을 참조하세요.
- 서버 측 폴백으로 사용되는 Rouge
지원 언어 전체 목록을 참조하세요.
소스 코드 뷰어는 이 두 가지 방식을 함께 사용하여 다양한 언어를 지원하고 리포지터리에서 파일을 볼 때 최적의 성능을 보장합니다.
컴포넌트 개요#
구문 강조 구현은 다음과 같은 주요 컴포넌트로 구성됩니다:
-
blob_content_viewer.vue: 파일 콘텐츠를 표시하는 메인 컴포넌트 -
source_viewer.vue: 소스 코드 렌더링을 처리하는 컴포넌트 -
highlight_mixin.js: 강조 처리 및 WebWorker 통신을 관리하는 컴포넌트 -
highlight_utils.js: 콘텐츠 청크 분할 및 처리를 위한 유틸리티를 제공하는 컴포넌트
성능 원칙#
콘텐츠를 최대한 빠르게 표시하기#
단계적 렌더링 방식을 통해 콘텐츠 표시를 최적화합니다:
-
처음 70줄을 일반 텍스트로 즉시 렌더링합니다(강조 없이).
-
WebWorker에 처음 70줄의 강조 처리를 요청합니다.
-
WebWorker에 전체 파일의 강조 처리를 요청합니다.
최적의 브라우저 성능 유지하기#
최적의 브라우저 성능을 유지하기 위해:
-
메인 스레드를 차단하지 않도록 강조 작업에 WebWorker를 사용합니다.
-
강조된 콘텐츠를 청크로 나누고 IntersectionObserver API를 사용하여 사용자가 스크롤할 때 렌더링합니다.
구문 강조 지원 추가하기#
다음 방법으로 새로운 언어에 대한 구문 강조 지원을 추가할 수 있습니다:
-
기존 서드파티 언어 정의 사용.
-
코드베이스에 커스텀 언어 정의 생성.
선택하는 방법은 해당 언어에 Highlight.js 호환 정의가 이미 있는지 여부에 따라 달라집니다.
서드파티 정의가 있는 언어의 경우#
package.json에 서드파티 의존성을 추가하고 highlight_js_language_loader에서 해당 의존성을 import할 수 있습니다.
예시:
package.json에 의존성 추가:
// package.json
//...
"dependencies": {
"@gleam-lang/highlight.js-gleam": "^1.5.0",
//...
highlight_js_language_loader.js에서 언어 import:
// highlight_js_language_loader.js
//...
gleam: () => import(/* webpackChunkName: 'hl-gleam' */ '@gleam-lang/highlight.js-gleam'),
//...
언어가 여전히 일반 텍스트로 표시된다면 highlight_mixin.js에서 파일 확장자 기반의 언어 감지를 추가해야 할 수 있습니다:
if (name.endsWith('.gleam')) {
language = 'gleam';
}
기존 정의가 없는 언어의 경우#
새로운 언어 정의는 ~/vue_shared/components/source_viewer/languages/ 하위의 코드베이스에 추가할 수 있습니다.
새로운 언어 지원을 추가하려면:
-
Highlight.js 문법을 따라 새 언어 정의 파일을 생성합니다.
-
highlight_js_language_loader.js에 언어를 등록합니다. -
필요한 경우
highlight_mixin.js에 파일 확장자 매핑을 추가합니다.
다음은 커스텀 언어 구현의 두 가지 예시입니다:
색상 스킴 미리보기 썸네일#
사용자 환경설정의 각 구문 강조 색상 스킴에는 app/assets/images/<scheme>-scheme-preview.png에 미리보기 썸네일이 있습니다. 단일 HTML 템플릿이 GitLab Mono로 모든 썸네일을 렌더링하므로, 썸네일은 스킴 전반에서 일관성을 유지하며 각 스킴의 팔레트와 일치합니다.
스킴을 추가하거나 테마의 색상을 변경한 후에는 썸네일을 다시 생성합니다:
bundle exec rake gitlab:color_schemes:preview_images
이 작업은 Rouge 렉서로 샘플 스니펫을 토큰화합니다. 각 토큰은 스킴 스타일시트(app/assets/stylesheets/highlight/themes/<scheme>.scss)에서 해당 토큰의 클래스가 가지는 값으로 색이 지정되므로, 새 테마는 자신의 색상 맵으로부터 일치하는 미리보기를 얻습니다. 이 작업은 2배 크기로 렌더링한 뒤 결과를 축소하여 텍스트 가장자리가 매끄럽게 유지되도록 하고, 이어서 pngquant를 실행하여 각 썸네일을 작게 유지합니다.
이 작업에는 헤드리스 Chrome 또는 Chromium 바이너리가 필요합니다. 바이너리가 PATH에 없는 경우 CHROME_BIN을 설정하세요. 출력을 최적화하려면 pngquant를 설치하세요. pngquant가 없으면 이 작업은 경고와 함께 최적화를 건너뜁니다.