InfoGrab DocsInfoGrab Docs

구문 강조 개발 가이드라인 (리포지터리 blob 뷰어)

요약

이 가이드는 리포지터리 소스 코드 뷰어의 구문 강조에 대한 모범 사례와 구현 세부 사항을 설명합니다. 소스 코드 뷰어는 이 두 가지 방식을 함께 사용해 폭넓은 언어 지원과 리포지터리 파일 조회 성능을 확보합니다. 구문 강조 구현은 다음 주요 컴포넌트로 이루어집니다.

이 가이드는 리포지터리 소스 코드 뷰어의 구문 강조에 대한 모범 사례와 구현 세부 사항을 설명합니다. GitLab은 두 가지 구문 강조 라이브러리를 사용합니다.

소스 코드 뷰어는 이 두 가지 방식을 함께 사용해 폭넓은 언어 지원과 리포지터리 파일 조회 성능을 확보합니다.

컴포넌트 개요#

구문 강조 구현은 다음 주요 컴포넌트로 이루어집니다.

  • blob_content_viewer.vue: 파일 콘텐츠를 표시하는 기본 컴포넌트입니다.
  • source_viewer.vue: 소스 코드 렌더링을 담당합니다.
  • highlight_mixin.js: 강조 처리와 WebWorker 통신을 관리합니다.
  • highlight_utils.js: 콘텐츠 청크 분할과 처리를 위한 유틸리티를 제공합니다.

성능 원칙#

콘텐츠를 최대한 빠르게 표시#

단계적 렌더링 방식으로 콘텐츠 표시를 최적화합니다.

  1. 처음 70줄을 강조 없이 평문으로 즉시 렌더링합니다.
  2. WebWorker에 처음 70줄의 강조를 요청합니다.
  3. WebWorker에 파일 전체의 강조를 요청합니다.

브라우저 성능 유지#

브라우저 성능을 양호하게 유지하는 방법은 다음과 같습니다.

  • 강조 작업이 메인 스레드를 막지 않도록 WebWorker를 사용합니다.
  • 강조된 콘텐츠를 청크로 나누고 IntersectionObserver API로 사용자가 스크롤할 때 렌더링합니다.

구문 강조 지원 추가#

새 언어의 구문 강조 지원은 다음 방법으로 추가할 수 있습니다.

  1. 기존 서드파티 언어 정의를 사용합니다.
  2. GitLab 코드베이스에 사용자 지정 언어 정의를 만듭니다.

어떤 방법을 선택할지는 해당 언어에 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/ 아래에 코드베이스로 추가할 수 있습니다.

새 언어 지원을 추가하는 방법은 다음과 같습니다.

  1. Highlight.js 문법에 따라 새 언어 정의 파일을 만듭니다.
  2. highlight_js_language_loader.js에 해당 언어를 등록합니다.
  3. 필요하다면 highlight_mixin.js에 파일 확장자 매핑을 추가합니다.

사용자 지정 언어 구현 예시는 다음 두 가지입니다.

  1. Svelte
  2. CODEOWNERS

색상 스킴 미리보기 썸네일#

사용자 환경 설정의 구문 강조 색상 스킴마다 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가 없으면 이 작업은 경고를 남기고 최적화를 건너뜁니다.

구문 강조 개발 가이드라인 (리포지터리 blob 뷰어)

GitLab v19.4
원문 보기

요약

이 가이드는 리포지터리 소스 코드 뷰어의 구문 강조에 대한 모범 사례와 구현 세부 사항을 설명합니다. 소스 코드 뷰어는 이 두 가지 방식을 함께 사용해 폭넓은 언어 지원과 리포지터리 파일 조회 성능을 확보합니다. 구문 강조 구현은 다음 주요 컴포넌트로 이루어집니다.

이 가이드는 리포지터리 소스 코드 뷰어의 구문 강조에 대한 모범 사례와 구현 세부 사항을 설명합니다. GitLab은 두 가지 구문 강조 라이브러리를 사용합니다.

소스 코드 뷰어는 이 두 가지 방식을 함께 사용해 폭넓은 언어 지원과 리포지터리 파일 조회 성능을 확보합니다.

컴포넌트 개요#

구문 강조 구현은 다음 주요 컴포넌트로 이루어집니다.

  • blob_content_viewer.vue: 파일 콘텐츠를 표시하는 기본 컴포넌트입니다.
  • source_viewer.vue: 소스 코드 렌더링을 담당합니다.
  • highlight_mixin.js: 강조 처리와 WebWorker 통신을 관리합니다.
  • highlight_utils.js: 콘텐츠 청크 분할과 처리를 위한 유틸리티를 제공합니다.

성능 원칙#

콘텐츠를 최대한 빠르게 표시#

단계적 렌더링 방식으로 콘텐츠 표시를 최적화합니다.

  1. 처음 70줄을 강조 없이 평문으로 즉시 렌더링합니다.
  2. WebWorker에 처음 70줄의 강조를 요청합니다.
  3. WebWorker에 파일 전체의 강조를 요청합니다.

브라우저 성능 유지#

브라우저 성능을 양호하게 유지하는 방법은 다음과 같습니다.

  • 강조 작업이 메인 스레드를 막지 않도록 WebWorker를 사용합니다.
  • 강조된 콘텐츠를 청크로 나누고 IntersectionObserver API로 사용자가 스크롤할 때 렌더링합니다.

구문 강조 지원 추가#

새 언어의 구문 강조 지원은 다음 방법으로 추가할 수 있습니다.

  1. 기존 서드파티 언어 정의를 사용합니다.
  2. GitLab 코드베이스에 사용자 지정 언어 정의를 만듭니다.

어떤 방법을 선택할지는 해당 언어에 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/ 아래에 코드베이스로 추가할 수 있습니다.

새 언어 지원을 추가하는 방법은 다음과 같습니다.

  1. Highlight.js 문법에 따라 새 언어 정의 파일을 만듭니다.
  2. highlight_js_language_loader.js에 해당 언어를 등록합니다.
  3. 필요하다면 highlight_mixin.js에 파일 확장자 매핑을 추가합니다.

사용자 지정 언어 구현 예시는 다음 두 가지입니다.

  1. Svelte
  2. CODEOWNERS

색상 스킴 미리보기 썸네일#

사용자 환경 설정의 구문 강조 색상 스킴마다 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가 없으면 이 작업은 경고를 남기고 최적화를 건너뜁니다.