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

교체 가능한 컴포넌트

원문 보기 위키 갱신

교체 가능한 컴포넌트 (Swappable components)

교체 가능한 컴포넌트(Swappable Components)는 프론트엔드 시스템의 기능으로, Backstage 앱에서 사용되는 컴포넌트의 구현을 교체할 수 있게 해줘요.

출처: 문서

본문

교체 가능한 컴포넌트(Swappable Components)는 프론트엔드 시스템의 기능으로, Backstage 앱에서 사용되는 컴포넌트의 구현을 교체할 수 있게 해줘요. 이 교체 가능한 컴포넌트는 createSwappableComponent을 사용해 정의된 뒤 플러그인의 -react 패키지에서 export되어, 다른 플러그인에서 사용되거나 Backstage 통합자가 새 구현으로 다시 바인딩할 수 있게 해요.

교체 가능한 컴포넌트 만들기

교체 가능한 컴포넌트를 만들려면 @backstage/frontend-plugin-api 패키지의 createSwappableComponent 함수를 사용해야 해요. 컴포넌트의 기본 구현과 외부 컴포넌트의 props를 컴포넌트 구현이 사용하는 props에서 분리하는 방법을 제공할 수 있어요.

in @internal/plugin-example-react

import { createSwappableComponent } from '@backstage/frontend-plugin-api';export const ExampleSwappableComponent = createSwappableComponent({  name: 'example',  // This is a loader for loading the default implementation of the component when there's no overriding  // implementation created with `SwappableComponentBlueprint`.  // It can be sync like below, but it can also be async like `loader: () => import('./DefaultImplementation').then(m => m.DefaultImplementation)`.  loader: () => (props: { name: string }) =>    <div>Your name is {props.name}</div>,  // This is an optional function that can be used to transform the props of the external component.  // If it's not provided, the props of the external component will be passed through unchanged.  // Typically this wouldn't be used and you don't need to define this initially,  // this is a nice API to evolve the Swappable Component internal API without breaking usages of it in existing plugins.  transformProps: (props: { lastName: string; firstName: string }) => ({    name: `${props.firstName} ${props.lastName}`,  }),});

교체 가능한 컴포넌트 사용하기

교체 가능한 컴포넌트를 사용하는 것은 다른 React 컴포넌트를 사용하는 것과 같아요. createSwappableComponent의 반환 값은 플러그인에서 직접, 또는 -react 패키지를 소비할 플러그인에서 렌더링할 수 있어요.

in @internal/plugin-example

import { ExampleSwappableComponent } from '@internal/plugin-example-react';<ExampleSwappableComponent firstName="John" lastName="Doe" />;

교체 가능한 컴포넌트 재정의하기

교체 가능한 컴포넌트를 재정의하려면 SwappableComponentBlueprint를 만들고 app 플러그인과 함께 설치해야 해요. app 플러그인에 확장을 추가하는 방법은 두 가지가 있으며, 둘 다 아래에서 Progress 교체 가능한 컴포넌트를 재정의하는 예시로 문서화돼 있어요.

in packages/app/src/App.tsx

import { Progress, createFrontendModule } from '@backstage/frontend-plugin-api';import { SwappableComponentBlueprint } from '@backstage/plugin-app-react';import { MyCustomProgress } from './CustomProgress';import { createApp } from '@backstage/frontend-defaults';import appPlugin from '@backstage/plugin-app';const app = createApp({  features: [    // Using a module to provide the extension to the app    createFrontendModule({      pluginId: 'app',      extensions: [        SwappableComponentBlueprint.make({          name: 'core-progress',          params: defineParams =>            defineParams({              component: Progress,              loader: () => MyCustomProgress,            }),        }),      ],    }),    // Core components that already ship with the app plugin can be overridden using getExtension()    appPlugin.withOverrides({      extensions: [        appPlugin.getExtension('component:app/core-progress').override({          params: defineParams =>            defineParams({              component: Progress,              loader: () => MyCustomProgress,            }),        }),      ],    }),  ],});

기본 교체 가능한 컴포넌트 (Default Swappable Components)

현재 구현을 교체할 수 있는 내장 교체 가능한 컴포넌트는 세 개뿐이며, 이들은 @backstage/frontend-plugin-api에 있어요. 다음과 같아요.

  • <Progress />

  • <ErrorDisplay />

  • <NotFoundErrorPage />

이 컴포넌트에 대한 자세한 내용은 정의에서 볼 수 있고, 기본 구현은 app-plugin 내부에 함께 제공돼요.

테스트에서의 구현 (Implementations in tests)

기본적으로 createSwappableComponent에 loader를 전달하지 않으면 기본 대체 컴포넌트가 렌더링되며, 이는 주로 테스트에서 유용해요. loader가 없는 교체 가능한 컴포넌트의 기본 구현은 다음과 같아요.

props => <div data-testid={swappableComponentRef.id} {...props} />;

즉, 테스트에서 getByTestId를 사용해 이러한 컴포넌트가 페이지에 렌더링되었는지 검증할 수 있어요.

더 알아보기 (Learn more)