본문 바로가기
WIKI 기술 지식 베이스

TechDocs Addons

원문 보기 위키 갱신

이 문서는 이전 프런트엔드 시스템을 기준으로 작성됐어요.

출처: 문서

본문

info

이 문서는 이전 프런트엔드 시스템을 위해 작성됐어요. 새 프런트엔드 시스템을 사용 중이라면 별도의 문서를 읽는 것이 좋아요.

개념(Concepts)

TechDocs는 조직 전체의 기술 문서를 게시·보기·발견하기 위한 중앙 집중식 플랫폼이에요. 탄탄한 기반이죠! 그런데 문서에 대한 더 높은 차원의 요구 문제를 스스로 해결하지는 못해요. 문서 문화를 어떻게 만들고 강화할까? 기술 문서의 품질에 대한 신뢰를 어떻게 구축할까?

TechDocs Addons는 이러한 더 높은 차원의 요구 중 일부를 해결하기 위해 TechDocs 경험을 커스터마이즈할 수 있는 메커니즘이에요.

Addons

Addon은 그저 react 컴포넌트예요. 다른 어떤 react 컴포넌트처럼, 일반적인 Backstage나 네이티브 훅, API, 컴포넌트를 사용해 데이터를 가져오고 렌더링할 수 있어요. Props로 그 동작을 구성할 수도 있어요(적절한 경우에).

장소(Locations)

Addon은 렌더링될 location을 선언해요. 대부분의 location은 TechDocs UI의 물리적 공간을 나타내요.

  • Header: 제목과 같은 줄에, 헤더를 오른쪽부터 채우는 Addon용.

  • Subheader: 헤더 아래이지만 모든 콘텐츠 위에 놓이는 Addon용. TechDocs 표시를 위한 도구/설정에 좋은 장소예요.

  • Settings: 이 Addon들은 설정 메뉴 목록에 추가되는 항목으로, 예를 들어 접근성 옵션처럼 읽는 사람의 경험을 커스터마이즈할 수 있게 설계된 것들이에요.

  • PrimarySidebar: 콘텐츠 왼쪽, 내비게이션 위.

  • SecondarySidebar: 콘텐츠 오른쪽, 목차 위.

  • Content: 문서 자체의 정적으로 생성된 콘텐츠를 보강하는 Addon을 위한 특수 장소.

  • Component: 제안됐지만 아직 구현되지 않은 가상의 location으로, 일반적인 유형의 Addon을 단순화하는 것을 목표로 해요.

Addon 레지스트리

Addon의 설치와 구성은 Backstage 앱의 프런트엔드 안에서 이뤄져요. Addon은 플러그인에서 임포트되어 <TechDocsAddons>라는 레지스트리 컴포넌트 아래에 추가돼요. 이 레지스트리는 TechDocs Reader 페이지와 Entity 문서 페이지 양쪽에 대해 구성할 수 있어요.

Addon은 등록된 순서대로 렌더링돼요.

Addon 설치 및 사용

Addon을 사용하려면 @backstage/plugin-techdocs-module-addons-contrib 패키지를 앱에 추가해야 해요. 프로젝트 루트에서 yarn --cwd packages/app add @backstage/plugin-techdocs-module-addons-contrib 명령을 실행하면 돼요.

Addon은 다른 Backstage 플러그인의 확장과 거의 같은 방식으로 설치·구성할 수 있어요. App.tsx에서 TechDocs Reader 페이지를 나타내는 route 아래의 확장 레지스트리 컴포넌트(<TechDocsAddons>) 아래에 추가하면 돼요.

// packages/app/src/App.tsx
import { TechDocsReaderPage } from '@backstage/plugin-techdocs';
import { TechDocsAddons } from '@backstage/plugin-techdocs-react';
import { ReportIssue } from '@backstage/plugin-techdocs-module-addons-contrib';

// ...
<Route path="/docs/:namespace/:kind/:name/*" element={<TechDocsReaderPage />}>
  <TechDocsAddons>
    <ReportIssue />
    {/* Other addons can be added here. */}
  </TechDocsAddons>
</Route>;

커스텀 TechDocs reader 페이지를 사용한다면 설정이 아주 비슷할 거예요. 예시는 다음과 같아요.

<Route path="/docs/:namespace/:kind/:name/*" element={<TechDocsReaderPage />}>
  <TechDocsAddons>
    <ReportIssue />
    {/* Other addons can be added here. */}
  </TechDocsAddons>
  {techDocsPage} // This is your custom TechDocs reader page
</Route>

엔티티 페이지의 문서 탭에서 Addon을 구성하는 과정도 아주 비슷해요. <TechDocsAddons> 레지스트리를 <Route> 아래가 아니라 <EntityTechdocsContent />의 자식으로 추가해요.

// packages/app/src/components/catalog/EntityPage.tsx
import { EntityLayout } from '@backstage/plugin-catalog';
import { EntityTechdocsContent } from '@backstage/plugin-techdocs';
import { TechDocsAddons } from '@backstage/plugin-techdocs-react';
import { ReportIssue } from '@backstage/plugin-techdocs-module-addons-contrib';

// ...
<EntityLayout.Route path="/docs" title="Docs">
  <EntityTechdocsContent>
    <TechDocsAddons>
      <ReportIssue />
      {/* Other addons can be added here. */}
    </TechDocsAddons>
  </EntityTechdocsContent>
</EntityLayout.Route>;

엔티티 페이지에서는 Catalog 플러그인이 페이지 헤더를 담당하기 때문에, location이 Header인 TechDocs Addons는 렌더링되지 않는다는 점을 알아두세요.

사용 가능한 Addons

Addon은 원칙적으로 어떤 플러그인이든 제공할 수 있어요! 사용 가능한 Addon을 더 쉽게 발견할 수 있도록 여기에 목록을 정리했어요.

| Addon | Package/Plugin | Description | | <ExpandableNavigation /> | @backstage/plugin-techdocs-module-addons-contrib | TechDocs 사용자가 TechDocs의 전체 주요 내비게이션을 펼치거나 접을 수 있게 하고, 문서 사이트 사이에서 사용자가 선호하는 상태를 유지함 | | <ReportIssue /> | @backstage/plugin-techdocs-module-addons-contrib | TechDocs 사용자가 TechDocs 페이지의 텍스트 일부를 선택하고 문서를 담고 있는 저장소에 대해 이슈를 열 수 있게 하며, 구성 가능한 템플릿에 따라 선택된 텍스트로 이슈 설명을 채움 | | <TextSize /> | @backstage/plugin-techdocs-module-addons-contrib | 이 TechDocs addon은 사용자가 문서 페이지의 텍스트 크기를 커스터마이즈할 수 있게 해 주고, 슬라이더나 버튼으로 글꼴 크기를 얼마나 늘리거나 줄일지 선택할 수 있음. 글꼴 크기의 기본값은 100%이고, 이 설정은 변경될 때마다 브라우저의 로컬 저장소에 보관됨 | | <LightBox /> | @backstage/plugin-techdocs-module-addons-contrib | 이 TechDocs addon은 사용자가 문서 페이지의 이미지를 라이트박스로 열 수 있게 해 주고, 한 페이지에 여러 장이 있으면 이미지 사이를 탐색할 수 있음. 라이트박스 이미지의 크기는 문서 페이지의 이미지 크기와 같음. 확대 아이콘을 클릭하면 이미지가 화면에 맞게 확대됨(background-size: contain과 유사) |

기여할 Addon이 있나요? 위에 행을 추가해 주세요!

Addon 만들기

가장 단순한 Addon은 TechDocs 사이트 내 특정 위치에 렌더링되는 평범한 react 컴포넌트예요. 그런 react 컴포넌트를 Addon으로 패키징하려면 다음 단계를 따르세요.

  • 플러그인에서 다른 컴포넌트처럼 컴포넌트를 작성하기

  • 플러그인에서 컴포넌트를 만들고 제공(provide)하고 내보내기

// plugins/your-plugin/src/plugin.ts
import {
  createTechDocsAddonExtension,
  TechDocsAddonLocations,
} from '@backstage/plugin-techdocs-react';
import { CatGifComponent, CatGifComponentProps } from './addons';

// ...
// You must "provide" your Addon, just like any extension, via your plugin.
export const CatGif = yourPlugin.provide(
  // This function "creates" the Addon given a component and location. If your
  // component can be configured via props, pass the prop type here too.
  createTechDocsAddonExtension<CatGifComponentProps>({
    name: 'CatGif',
    location: TechDocsAddonLocations.Header,
    component: CatGifComponent,
  }),
);

Content location의 Addons

"지역에 컴포넌트 렌더링" 사용 사례를 넘어, Addon이 TechDocs 사이트의 DOM에 접근하고 조작하는 것도 가능해요. 예를 들어 클라이언트 측 다이어그램 라이브러리를 로드하고 인스턴스화하거나, 요소를 동적으로 로드된 콘텐츠로 교체하는 데 쓰일 수 있어요.

이런 유형의 Addon도 여전히 react 컴포넌트로 표현되지만, 렌더링할 react 요소를 반환하는 대신 부수 효과(side-effect, 예: useEffect)로 DOM을 업데이트해요. DOM 접근은 Addon 프레임워크가 제공하는 유틸리티 훅으로 가능해요.

// plugins/your-plugin/src/addons/MakeAllImagesCatGifs.tsx
import { useEffect } from 'react';
import { useShadowRootElements } from '@backstage/plugin-techdocs-react';

// This is a normal react component; in order to make it an Addon, you would
// still create and provide it via your plugin as described above. The only
// difference is that you'd set `location` to `TechDocsAddonLocations.Content`.
export const MakeAllImagesCatGifsAddon = () => {
  // This hook can be used to get references to specific elements. If you need
  // access to the whole shadow DOM, use the underlying useShadowRoot()
  // hook instead.
  const images = useShadowRootElements<HTMLImageElement>(['img']);

  useEffect(() => {
    images.forEach(img => {
      if (img.src !== 'https://example.com/cat.gif') {
        img.src = 'https://example.com/cat.gif';
      }
    });
  }, [images]);

  // Nothing to render directly, so we can just return null.
  return null;
};

Addon 테스트하기

플러그인에 @backstage/plugin-techdocs-addons-test-utils를 devDependency로 설치하면 그런 Addon을 더 쉽게 테스트할 수 있는 유틸리티를 쓸 수 있어요.

위 Addon에 대한 테스트는 다음과 같은 모습일 수 있어요.

// plugins/your-plugin/src/addons/MakeAllImagesCatGifs.test.tsx
import { TechDocsAddonTester } from '@backstage/plugin-techdocs-addons-test-utils';
// Note: import your actual addon (the one provided by your plugin).
import { MakeAllImagesCatGifs } from '../plugin.ts';

describe('MakeAllImagesCatGifs', () => {
  it('replaces img srcs with cat gif', async () => {
    const { getByTestId } = await TechDocsAddonTester.buildAddonsInTechDocs([
      <MakeAllImagesCatGifs />,
    ])
      .withDom(<img data-testid="fixture" src="http://example.com/dog.jpg" />)
      .renderWithEffects();

    expect(getByTestId('fixture')).toHaveAttribute(
      'src',
      'https://example.com/cat.gif',
    );
  });
});

더 알아보기 (Learn more)