Angular 6 업그레이드 후 RxJS 6 마이그레이션 작업

배경

회사 프로젝트가 Angular 5.2에서 6.0으로 업그레이드하면서 RxJS도 5.5에서 6.0으로 올라갔다. Angular CLI의 ng update 명령어가 자동으로 많은 부분을 처리해주긴 했지만, 수동으로 수정해야 할 부분들이 꽤 있었다.

주요 변경 사항

import 경로 변경

기존에는 개별 연산자를 각각 import 했다.

import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/filter';

이제는 통합된 경로에서 가져온다.

import { Observable } from 'rxjs';
import { map, filter } from 'rxjs/operators';

pipe 연산자 필수

기존 체이닝 방식이 모두 pipe로 변경되었다.

// Before
this.userService.getUsers()
  .map(users => users.filter(u => u.active))
  .catch(err => Observable.of([]))
  .subscribe(...);

// After
this.userService.getUsers().pipe(
  map(users => users.filter(u => u.active)),
  catchError(err => of([]))
).subscribe(...);

마이그레이션 도구

rxjs-tslint 패키지를 사용하면 자동 변환이 가능하다.

npm install -g rxjs-tslint
rxjs-5-to-6-migrate -p src/tsconfig.app.json

약 80% 정도는 자동으로 처리되었고, 나머지는 수동으로 수정했다. 특히 커스텀 연산자를 사용하는 부분에서 타입 에러가 많이 발생했다.

트러블슈팅

do 연산자가 tap으로 변경되면서 일부 디버깅 코드를 찾지 못하는 문제가 있었다. 전역 검색으로 .do( 패턴을 찾아 모두 수정했다.

빌드 크기는 약 15KB 정도 줄어들었다. tree-shaking이 제대로 작동하는 것으로 보인다.

결론

하루 반 정도 소요된 작업이었다. pipe 방식이 처음엔 번거로워 보였지만, 연산자 조합이 더 명확해져서 가독성은 오히려 나아진 것 같다. TypeScript 컴파일러의 타입 체크 덕분에 런타임 에러 없이 마이그레이션을 완료할 수 있었다.