프론트엔드 시스템 명명 패턴
프론트엔드 시스템 명명 패턴 (Frontend System Naming Patterns)
프론트엔드 시스템 내에서 준수해야 할 명명 패턴들이에요. 이를 통해 패키지 전반에서 export와 ID를 일관되게 유지하고, export와 ID의 용도와 의도를 더 이해하기 쉽게 만들어 줘요.
출처: 문서
본문
프론트엔드 시스템 내에서 준수해야 할 명명 패턴들이에요. 이를 통해 패키지 전반에서 export와 ID를 일관되게 유지하고, export와 ID의 용도와 의도를 더 이해하기 쉽게 만들어 줘요.
원칙적으로 모든 이름은 camel case여야 하며, kebab case를 사용해야 하는 플러그인과 확장 ID는 예외예요.
플러그인 (Plugins)
| 구분 | 설명 | 패턴 | 예시 |
|---|---|---|---|
| ID | '<id>' |
'catalog', 'user-settings' |
|
| Symbol | <id>Plugin |
catalogPlugin, userSettingsPlugin |
예시:
// This declaration is only for internal usage in tests. This could also be a direct default export.export const userSettingsPlugin = createFrontendPlugin({ pluginId: 'user-settings', ...})// The plugin instance should be the default export of the package, typically this is placed in src/index.tsexport { userSettingsPlugin as default } from './plugin';
플러그인 인스턴스에 대해 이 명명 패턴을 사용하지만 이는 패키지 내부에서만 사용하는 것이라는 점에 유의하세요. 플러그인은 항상 플러그인 패키지의 기본(default) export로 내보내져요.
확장 (Extensions)
| 구분 | 설명 | 패턴 | 예시 |
|---|---|---|---|
| Blueprint | <Kind>Blueprint |
PageBlueprint, EntityCardBlueprint |
|
| ID | [<kind>:]<namespace>[/<name>] |
'core.nav', 'page:user-settings', 'entity-card:catalog/about' |
|
| Symbol | <namespace>[<Name>][<Kind>] |
coreNav, userSettingsPage, catalogAboutEntityCard |
새 확장을 만들 때는 ID를 직접 제공하지 않아요. 대신 ID를 구성하는 kind, namespace, name 부분을 간접적 또는 직접적으로 제공해요. kind는 항상 확장 블루프린트가 제공하며, 유일한 예외는 createExtension을 직접 사용할 때예요. 플러그인이 제공하는 확장은 기본적으로 namespace가 플러그인 ID로 설정되므로, 기존 확장을 재정의하려는 경우가 아니면 일반적으로 명시적 namespace를 제공할 필요가 없어요. name도 선택 사항이며 주로 같은 kind와 namespace의 여러 확장을 구분하는 데 사용돼요. 플러그인이 같은 kind의 다른 확장을 구분할 필요가 없다면 name은 생략할 수 있어요.
예시:
// This is an extension blueprint that is used to create an extension of the 'page' kind.export const PageBlueprint = createExtensionBlueprint({ kind: 'page', // ...});// The namespace is inferred from the plugin ID, in this case 'catalog'// The final ID for this extension will be 'page:catalog/entity'const catalogEntityPage = PageBlueprint.make({ name: 'entity', // ...});// The name is omitted, because the catalog plugin only provides a single extension of this kind// The final ID for this extension will be 'search-result-list-item:catalog'const catalogSearchResultListItem = SearchResultListItemBlueprint.make({ // ...});// Note that the extensions themselves are not exported, only the plugin instanceexport const catalogPlugin = createFrontendPlugin({ pluginId: 'catalog', extensions: [catalogEntityPage, catalogSearchResultListItem /* ... */],});
확장 데이터 (Extension Data)
| 구분 | 설명 | 패턴 | 예시 |
|---|---|---|---|
| Interface | <Name>ExtensionData |
SearchResultItemExtensionData |
|
| Standalone Reference | <name>ExtensionDataRef |
searchResultItemExtensionDataRef |
|
| Standalone ID | <namespace>.<name> |
'search.search-result-item' |
|
| Grouped Reference | <group>ExtensionData.<name> |
coreExtensionData.reactElement, catalogFilterExtensionData.functionFilter |
|
| Grouped ID | <group>.<name> |
'core.react-element', 'catalog-filter.function-filter' |
|
| Creator Reference | create<Kind>Extension.<name>DataRef |
createGraphiQLEndpointExtension.endpointDataRef |
|
| Creator ID | <namespace>.<kind>.<name> |
'graphiql.graphiql-endpoint.endpoint' |
확장 데이터 참조는 의도된 용도에 따라 몇 가지 다른 방식으로 정의될 수 있으며, 모두 아래에서 다룰 거예요.
독립형 확장 데이터 (Standalone Extension Data)
확장 데이터를 정의하는 가장 간단한 방법은 독립형 참조예요. 이는 특정 kind의 확장에 밀접하게 연결되지 않은 단일 참조를 export하고 싶을 때 유용해요. 각 참조에 대한 추가 export를 만들기 때문에, 가능하면 확장 데이터를 정의하는 다른 두 가지 방식을 선호해요.
// A separate named type declaration is only needed for bespoke complex extension data typesexport interface SearchResultItemExtensionData { /* ... */}export const searchResultItemExtensionDataRef = createExtensionDataRef<SearchResultItemExtensionData>().with({ id: 'search.search-result-item', });
그룹 확장 데이터 (Grouped Extension Data)
이 방식의 확장 데이터 정의는 독립형 방식과 유사하지만, 일반 용도로 그룹화된 확장 데이터의 여러 조각을 export하고 싶을 때 사용돼요. 이는 별도 export를 피하고 관련 확장 데이터 참조를 더 찾기 쉽게 만들어줘요. 그룹 이름은 일반적으로 export하는 패키지의 namespace, 보통 플러그인 ID와 같아야 해요. 그룹이 더 구체적이어야 한다면 namespace를 접두어로 붙여야 해요.
export const coreExtensionData = { reactElement: createExtensionDataRef<ReactElement>().with({ id: 'core.react-element', }), routePath: createExtensionDataRef<string>().with({ id: 'core.route-path', }),};
확장 생성자 확장 데이터 (Extension Creator Extension Data)
이는 데이터가 특정 확장 생성자에 의해서만 생성되도록 의도된 경우 확장 데이터를 정의하는 편리한 방법이에요. 추가 export를 피하고 이 데이터 조각이 이 특정 kind의 확장에 속한다는 것을 명확히 알려줘요.
export function createGraphiQLEndpointExtension(options) { /* ... */}// Use a TypeScript namespace to merge the extension data references with the extension creatorexport namespace createGraphiQLEndpointExtension { export const endpointDataRef = createExtensionDataRef</* ... */>().with({ id: 'graphiql.graphiql-endpoint.endpoint', });}
확장 입력 (Extension Inputs)
확장 입력은 모든 유형의 입력에 대한 명명 패턴이 있는 것은 아니지만, 알아볼 수 있는 입력 이름을 사용할 것을 권장하는 특정 사용 사례가 몇 가지 있어요.
| 이름 | 설명 |
|---|---|
children |
coreExtensionData.reactElement 데이터만 수용하고 React의 children 속성과 동등한 방식으로 사용되는 확장 입력예요. |