티스토리 뷰
Angular2(이하 Angular) 개발시 Service에 선언한 Interface를 export를 하고 다른 컴퍼넌트에서 import를 할려고하니 아래와 같은 에러 메세지가 발생하였습니다.
WARNING in ./src/app/core/sidenav/sidenav-item/sidenav-item.component.ts
21:83-92 "export 'ISideItem' was not found in '../sidenav.service'
at HarmonyImportSpecifierDependency._getErrors (/Users/david/work/resume/client/node_modules/webpack/lib/dependencies/HarmonyImportSpecifierDependency.js:65:15)
at HarmonyImportSpecifierDependency.getWarnings (/Users/david/work/resume/client/node_modules/webpack/lib/dependencies/HarmonyImportSpecifierDependency.js:39:15)
at Compilation.reportDependencyErrorsAndWarnings (/Users/david/work/resume/client/node_modules/webpack/lib/Compilation.js:677:24)
at Compilation.finish (/Users/david/work/resume/client/node_modules/webpack/lib/Compilation.js:535:9)
at applyPluginsParallel.err (/Users/david/work/resume/client/node_modules/webpack/lib/Compiler.js:512:17)
at /Users/david/work/resume/client/node_modules/tapable/lib/Tapable.js:289:11
at _addModuleChain (/Users/david/work/resume/client/node_modules/webpack/lib/Compilation.js:481:11)
at processModuleDependencies.err (/Users/david/work/resume/client/node_modules/webpack/lib/Compilation.js:452:13)
at _combinedTickCallback (internal/process/next_tick.js:67:7)
at process._tickCallback (internal/process/next_tick.js:98:9)
ISideItem 을 sidenav.service에서 찾을 수 없다는데 export 잘 선언되어있고 작동도 잘하고 있었습니다.
waring이지만 뭔가 찜찜합니다. 일단 문제되던 코드를 살펴보겠습니다.
//sidenav-item.component.ts
import {Component, Input, OnInit} from '@angular/core';
import {ISideItem, SideItemTypes} from '../sidenav.service';
@Component({
selector: 'app-sidenav-item',
templateUrl: './sidenav-item.component.html',
styleUrls: ['./sidenav-item.component.scss']
})
export class SidenavItemComponent implements OnInit {
@Input('item') item: ISideItem;
@Input('index') index: number;
menuTypes = SideItemTypes;
constructor() {}
ngOnInit() {}
}
아래는 sidenav.service.ts 입니다.
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
/**
* sidenav 메뉴 type
* (link/dropDown/icon/separator/extLink)
*/
export enum SideItemTypes {
link,
dropDown,
icon,
separator,
extLink
}
/**
* sidenav 메뉴 인터페이스
*/
export interface ISideItem {
type: SideItemTypes; // menu의 type:
name?: string; // menu 노출될 이름
path?: string; // 라우터 경로
icon?: string; // 메뉴 아이콘
tooltip?: string; // 메뉴 툴팁
disabled?: boolean; // 메뉴 숨김여부
sub?: ISideSub[]; // 하위 메뉴(Array)
}
/**
* sidenav 하위 메뉴
*/
export interface ISideSub {
name: string; // 하위메뉴 이름
path: string; // 라우터 경로
}
@Injectable()
export class SidenavService {
constructor() { }
menu: ISideItem[] = [
//....
];
// 메뉴 subject
menuItems = new BehaviorSubject(this.menu);
// 메뉴 스트림
menuItems$ = this.menuItems.asObservable();
}
분명히 Interface들이 선언이 잘되어있습니다. 구글링을 조금 해보니 해당 이슈가 발견되었습니다.
그리고 기존의 다른 개발자분들은 interface를 어떻게 export하고 import하고 있는지 확인해봤습니다.
angular.io/src/app/navigation/navigation.service.ts
// Import and re-export the Navigation model types
import { CurrentNodes, NavigationNode, NavigationResponse, NavigationViews, VersionInfo } from './navigation.model';
export { CurrentNodes, CurrentNode, NavigationNode, NavigationResponse, NavigationViews, VersionInfo } from './navigation.model';
Interface용 파일을 별도로 빼서 service에서 export로 from 구문으로 내보내고 있습니다.
그래서 아래와 같이 수정하였습니다.
//sidenav.service.ts
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
// import 하고 export하는 이유는 https://github.com/angular/angular-cli/issues/2034#issuecomment-302666897 참고
import { ISideItem, SideItemTypes} from './sidenav.model';
export { ISideItem, ISideSub, SideItemTypes } from './sidenav.model';
@Injectable()
export class SidenavService {
constructor() { }
menu: ISideItem[] = [
//...
];
// 메뉴 subject
menuItems = new BehaviorSubject(this.menu);
// 메뉴 스트림
menuItems$ = this.menuItems.asObservable();
}
// sidenav.model.ts
/**
* sidenav 메뉴 type
* (link/dropDown/icon/separator/extLink)
*/
export enum SideItemTypes {
link,
dropDown,
icon,
separator,
extLink
}
/**
* sidenav 메뉴 인터페이스
*/
export interface ISideItem {
type: SideItemTypes; // menu의 type:
name?: string; // menu 노출될 이름
path?: string; // 라우터 경로
icon?: string; // 메뉴 아이콘
tooltip?: string; // 메뉴 툴팁
disabled?: boolean; // 메뉴 숨김여부
sub?: ISideSub[]; // 하위 메뉴(Array)
}
/**
* sidenav 하위 메뉴
*/
export interface ISideSub {
name: string; // 하위메뉴 이름
path: string; // 라우터 경로
}
Interface 선언용 파일 sidenav.model.ts를 별도로 분리하여 serivce에서 불러와 포함시키도록 하니 waring이 사라졌습니다.
Typescript에서 @(Decorator)를 사용한 경우 발생되는 문제라고 하니 참고하시면 좋을듯 합니다.
'Angular > Angular 2' 카테고리의 다른 글
[ Angular ] Angular 에 Parcel bundler 를 적용해 보았다. (7) | 2017.12.16 |
---|---|
[ Angular / Rxjs ] Angular에서 unsubscribe(구독취소)은 언제 어떻게 해야하는가? (1) | 2017.09.14 |
[ Angular ] angular2를 이용하여 HNPWA 만들기 ( 1. Angular 프로젝트 작업 ) (0) | 2017.08.15 |
[ Angular ] angular-cli.json의 Schema로 알아보는 angular-cli 기능들 (3) | 2017.07.25 |
[ Angular ] Angular 4.0 정식 release (4.0에서 달라진점) (2) | 2017.03.27 |