Angular ์ƒํƒœ๊ณ„

NgModule

์ค‘์š”: Angular ํŒ€์€ ์ƒˆ๋กœ ์ž‘์„ฑํ•˜๋Š” ๋ชจ๋“  ์ฝ”๋“œ์—์„œ NgModule ๋Œ€์‹  ๋…๋ฆฝํ˜• ์ปดํฌ๋„ŒํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ฐ€์ด๋“œ๋Š” @NgModule์„ ์‚ฌ์šฉํ•˜๋Š” ๊ธฐ์กด ์ฝ”๋“œ๋ฅผ ์ดํ•ดํ•  ๋•Œ ์ฐธ๊ณ ํ•˜์„ธ์š”.

NgModule์€ @NgModule ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ๋ถ™์ธ ํด๋ž˜์Šค์ž…๋‹ˆ๋‹ค. ์ด ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋Š” Angular๊ฐ€ ์ปดํฌ๋„ŒํŠธ ํ…œํ”Œ๋ฆฟ์„ ์ปดํŒŒ์ผํ•˜๊ณ  ์˜์กด์„ฑ ์ฃผ์ž…์„ ์„ค์ •ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ง€์ •ํ•˜๋Š” ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ ๋ฅผ ์ธ์ž๋กœ ๋ฐ›์Šต๋‹ˆ๋‹ค.

import {NgModule} from '@angular/core';

@NgModule({
  // ์ด๊ณณ์— ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค.
})
export class CustomMenuModule {}

NgModule์€ ํฌ๊ฒŒ ๋‘ ๊ฐ€์ง€ ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค:

  • NgModule์— ์†ํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ, ๋””๋ ‰ํ‹ฐ๋ธŒ, ํŒŒ์ดํ”„๋ฅผ ์„ ์–ธํ•ฉ๋‹ˆ๋‹ค.
  • ์ด NgModule์„ ๋กœ๋“œํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ, ๋””๋ ‰ํ‹ฐ๋ธŒ, ํŒŒ์ดํ”„์˜ ์ธ์ ํ„ฐ์— ํ”„๋กœ๋ฐ”์ด๋”๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

declarations

@NgModule ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ์˜ declarations ํ”„๋กœํผํ‹ฐ์—๋Š” NgModule์— ์†ํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ, ๋””๋ ‰ํ‹ฐ๋ธŒ, ํŒŒ์ดํ”„๋ฅผ ์„ ์–ธํ•ฉ๋‹ˆ๋‹ค.

@NgModule({
  /* ... */
  // CustomMenu์™€ CustomMenuItem์€ ์ปดํฌ๋„ŒํŠธ์ž…๋‹ˆ๋‹ค.
  declarations: [CustomMenu, CustomMenuItem],
})
export class CustomMenuModule {}

์œ„ ์˜ˆ์ œ์—์„œ CustomMenu์™€ CustomMenuItem ์ปดํฌ๋„ŒํŠธ๋Š” CustomMenuModule์— ์†ํ•ฉ๋‹ˆ๋‹ค.

declarations ํ”„๋กœํผํ‹ฐ์—๋Š” ์ปดํฌ๋„ŒํŠธ, ๋””๋ ‰ํ‹ฐ๋ธŒ, ํŒŒ์ดํ”„์˜ ๋ฐฐ์—ด ์„ ์ง€์ •ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๋ฐฐ์—ด ์•ˆ์— ๋‹ค๋ฅธ ๋ฐฐ์—ด์„ ํฌํ•จํ•ด๋„ ๋ฉ๋‹ˆ๋‹ค.

const MENU_COMPONENTS = [CustomMenu, CustomMenuItem];
const WIDGETS = [MENU_COMPONENTS, CustomSlider];

@NgModule({
  /* ... */
  // ์ด NgModule์—๋Š” CustomMenu, CustomMenuItem,
  // CustomSlider, CustomCheckbox๋ฅผ ๋ชจ๋‘ ์„ ์–ธํ•ฉ๋‹ˆ๋‹ค.
  declarations: [WIDGETS, CustomCheckbox],
})
export class CustomMenuModule {}

์ปดํฌ๋„ŒํŠธ, ๋””๋ ‰ํ‹ฐ๋ธŒ, ํŒŒ์ดํ”„๊ฐ€ ์—ฌ๋Ÿฌ NgModule์— ์ค‘๋ณต์œผ๋กœ ์„ ์–ธ๋˜์–ด ์žˆ์œผ๋ฉด Angular๋Š” ์˜ค๋ฅ˜๋ฅผ ๋ฐœ์ƒ์‹œํ‚ต๋‹ˆ๋‹ค.

NgModule์— ์„ ์–ธํ•  ์ปดํฌ๋„ŒํŠธ, ๋””๋ ‰ํ‹ฐ๋ธŒ, ํŒŒ์ดํ”„์—๋Š” ๋ฐ˜๋“œ์‹œ standalone: false๋ฅผ ๋ช…์‹œํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

@Component({
  // NgModule์— ์„ ์–ธํ•  ์ˆ˜ ์žˆ๋„๋ก ์ปดํฌ๋„ŒํŠธ์— `standalone: false`๋ฅผ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.
  standalone: false,
  /* ... */
})
export class CustomMenu {
  /* ... */
}

imports

NgModule์— ์„ ์–ธํ•œ ์ปดํฌ๋„ŒํŠธ๋Š” ๋‹ค๋ฅธ ์ปดํฌ๋„ŒํŠธ, ๋””๋ ‰ํ‹ฐ๋ธŒ, ํŒŒ์ดํ”„์— ์˜์กดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฐ ์˜์กด์„ฑ์€ @NgModule ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ์˜ imports ํ”„๋กœํผํ‹ฐ์— ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

@NgModule({
  /* ... */
  // CustomMenu์™€ CustomMenuItem์€ PopupTrigger์™€ SelectorIndicator ์ปดํฌ๋„ŒํŠธ์— ์˜์กดํ•ฉ๋‹ˆ๋‹ค.
  imports: [PopupTrigger, SelectionIndicator],
  declarations: [CustomMenu, CustomMenuItem],
})
export class CustomMenuModule {}

imports ๋ฐฐ์—ด์—๋Š” ๋‹ค๋ฅธ NgModule๋ฟ ์•„๋‹ˆ๋ผ ๋…๋ฆฝํ˜• ์ปดํฌ๋„ŒํŠธ, ๋””๋ ‰ํ‹ฐ๋ธŒ, ํŒŒ์ดํ”„๋„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

exports

NgModule์— ์„ ์–ธํ•œ ์ปดํฌ๋„ŒํŠธ, ๋””๋ ‰ํ‹ฐ๋ธŒ, ํŒŒ์ดํ”„๋ฅผ ์™ธ๋ถ€๋กœ ๊ณต๊ฐœ(export) ํ•˜๋ฉด ๋‹ค๋ฅธ ์ปดํฌ๋„ŒํŠธ์™€ NgModule์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@NgModule({
  imports: [PopupTrigger, SelectionIndicator],
  declarations: [CustomMenu, CustomMenuItem],

  // CustomMenuModule์„ ๋กœ๋“œํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ์™€ NgModule์—์„œ
  // CustomMenu์™€ CustomMenuItem์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.
  exports: [CustomMenu, CustomMenuItem],
})
export class CustomMenuModule {}

exports ํ”„๋กœํผํ‹ฐ์—๋Š” ์ง์ ‘ ์„ ์–ธํ•œ ํ•ญ๋ชฉ๋งŒ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์€ ์•„๋‹™๋‹ˆ๋‹ค. NgModule์—์„œ ๋กœ๋“œํ•œ ๋‹ค๋ฅธ ์ปดํฌ๋„ŒํŠธ, ๋””๋ ‰ํ‹ฐ๋ธŒ, ํŒŒ์ดํ”„, NgModule๋„ ์™ธ๋ถ€๋กœ ๊ณต๊ฐœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@NgModule({
  imports: [PopupTrigger, SelectionIndicator],
  declarations: [CustomMenu, CustomMenuItem],

  // CustomMenuModule์„ ๋กœ๋“œํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ์™€ NgModule์—์„œ PopupTrigger๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.
  exports: [CustomMenu, CustomMenuItem, PopupTrigger],
})
export class CustomMenuModule {}

NgModule ํ”„๋กœ๋ฐ”์ด๋”

ํŒ: ์˜์กด์„ฑ ์ฃผ์ž…๊ณผ ํ”„๋กœ๋ฐ”์ด๋”์— ๋Œ€ํ•ด ์•Œ์•„๋ณด๋ ค๋ฉด ์˜์กด์„ฑ ์ฃผ์ž… ๊ฐ€์ด๋“œ๋ฅผ ์ฐธ๊ณ ํ•˜์„ธ์š”.

NgModule์—๋Š” ์˜์กด์„ฑ ์ฃผ์ž…์— ์‚ฌ์šฉํ•  providers๋ฅผ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ํ”„๋กœ๋ฐ”์ด๋”๋Š” ๋‹ค์Œ ์œ„์น˜์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

  • ํ•ด๋‹น NgModule์„ ๋กœ๋“œํ•˜๋Š” ๋ชจ๋“  ๋…๋ฆฝํ˜• ์ปดํฌ๋„ŒํŠธ, ๋””๋ ‰ํ‹ฐ๋ธŒ, ํŒŒ์ดํ”„
  • ํ•ด๋‹น NgModule์„ ๋กœ๋“œํ•˜๋Š” ๋‹ค๋ฅธ NgModule์˜ declarations์™€ providers
@NgModule({
  imports: [PopupTrigger, SelectionIndicator],
  declarations: [CustomMenu, CustomMenuItem],

  // OverlayManager ์„œ๋น„์Šค๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
  providers: [OverlayManager],
  /* ... */
})
export class CustomMenuModule {}

@NgModule({
  imports: [CustomMenuModule],
  declarations: [UserProfile],
  providers: [UserDataClient],
})
export class UserProfileModule {}

์œ„ ์˜ˆ์ œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค:

  • CustomMenuModule์€ OverlayManager๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
  • CustomMenu์™€ CustomMenuItem ์ปดํฌ๋„ŒํŠธ๋Š” CustomMenuModule์— ์„ ์–ธ๋˜์–ด ์žˆ์œผ๋ฏ€๋กœ OverlayManager๋ฅผ ์ฃผ์ž…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • UserProfile์ด ์†ํ•œ NgModule์—์„œ CustomMenuModule์„ ๋กœ๋“œํ•˜๋ฏ€๋กœ UserProfile์— OverlayManager๋ฅผ ์ฃผ์ž…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • UserDataClient๊ฐ€ ์†ํ•œ NgModule์—์„œ CustomMenuModule์„ ๋กœ๋“œํ•˜๋ฏ€๋กœ UserDataClient์— OverlayManager๋ฅผ ์ฃผ์ž…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

forRoot์™€ forChild ํŒจํ„ด

์ผ๋ถ€ NgModule์€ ์„ค์ •์„ ์ธ์ž๋กœ ๋ฐ›๊ณ  ํ”„๋กœ๋ฐ”์ด๋” ๋ฐฐ์—ด์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ์ •์  forRoot ๋ฉ”์„œ๋“œ๋ฅผ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. forRoot๋ผ๋Š” ์ด๋ฆ„์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋ถ€ํŠธ์ŠคํŠธ๋žฉํ•  ๋•Œ ์ด ํ”„๋กœ๋ฐ”์ด๋”๋ฅผ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์ตœ์ƒ์œ„ ์—๋งŒ ์ถ”๊ฐ€ํ•œ๋‹ค๋Š” ์˜๋ฏธ๋กœ ์‚ฌ์šฉํ•˜๋Š” ๊ด€๋ก€์ž…๋‹ˆ๋‹ค.

์ด ๋ฐฉ์‹์œผ๋กœ ํฌํ•จํ•œ ํ”„๋กœ๋ฐ”์ด๋”๋Š” ๋ชจ๋‘ ์ฆ‰์‹œ ๋กœ๋“œ๋˜๋ฏ€๋กœ, ํŽ˜์ด์ง€๋ฅผ ์ฒ˜์Œ ๋กœ๋“œํ•  ๋•Œ ํ•„์š”ํ•œ JavaScript ๋ฒˆ๋“ค ํฌ๊ธฐ๊ฐ€ ์ปค์ง‘๋‹ˆ๋‹ค.

bootstrapApplication(MyApplicationRoot, {
  providers: [CustomMenuModule.forRoot(/* some config */)],
});

๋น„์Šทํ•˜๊ฒŒ ์ผ๋ถ€ NgModule์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ณ„์ธต ์•ˆ์˜ ์ปดํฌ๋„ŒํŠธ์— ํ”„๋กœ๋ฐ”์ด๋”๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค๋Š” ์˜๋ฏธ๋กœ ์ •์  forChild ๋ฉ”์„œ๋“œ๋ฅผ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.

@Component({
  /* ... */
  providers: [CustomMenuModule.forChild(/* some config */)],
})
export class UserProfile {
  /* ... */
}

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ถ€ํŠธ์ŠคํŠธ๋žฉํ•˜๊ธฐ

์ค‘์š”: Angular ํŒ€์€ ์ƒˆ๋กœ ์ž‘์„ฑํ•˜๋Š” ๋ชจ๋“  ์ฝ”๋“œ์—์„œ bootstrapModule ๋Œ€์‹  bootstrapApplication์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ฐ€์ด๋“œ๋Š” @NgModule๋กœ ๋ถ€ํŠธ์ŠคํŠธ๋žฉํ•˜๋Š” ๊ธฐ์กด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์ดํ•ดํ•  ๋•Œ ์ฐธ๊ณ ํ•˜์„ธ์š”.

@NgModule ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ์—๋Š” ํ•˜๋‚˜ ์ด์ƒ์˜ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋‹ด๋Š” bootstrap ๋ฐฐ์—ด์„ ์„ ํƒ์ ์œผ๋กœ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

platformBrowser๋‚˜ platformServer์˜ bootstrapModule ๋ฉ”์„œ๋“œ๋กœ Angular ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์‹œ์ž‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ๋“ฑ๋กํ•œ ์ปดํฌ๋„ŒํŠธ์˜ CSS ์…€๋ ‰ํ„ฐ์™€ ์ผ์น˜ํ•˜๋Š” ์—˜๋ฆฌ๋จผํŠธ๋ฅผ ํŽ˜์ด์ง€์—์„œ ์ฐพ์•„ ํ•ด๋‹น ์œ„์น˜์— ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค.

import {platformBrowser} from '@angular/platform-browser';
import {NgModule} from '@angular/core';

@NgModule({
  bootstrap: [MyApplication],
})
export class MyApplicationModule {}

platformBrowser().bootstrapModule(MyApplicationModule);

bootstrap์— ๋“ฑ๋กํ•œ ์ปดํฌ๋„ŒํŠธ๋Š” NgModule์˜ ์„ ์–ธ์— ์ž๋™์œผ๋กœ ํฌํ•จ๋ฉ๋‹ˆ๋‹ค.

NgModule๋กœ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋ถ€ํŠธ์ŠคํŠธ๋žฉํ•˜๋ฉด ํ•ด๋‹น ๋ชจ๋“ˆ์˜ providers์™€ imports๋กœ ๋กœ๋“œํ•œ ๋ชจ๋“  ํ”„๋กœ๋ฐ”์ด๋”๋ฅผ ์ฆ‰์‹œ ๋กœ๋“œํ•˜๋ฉฐ, ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ „์ฒด์—์„œ ์ด ํ”„๋กœ๋ฐ”์ด๋”๋ฅผ ์ฃผ์ž…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.