Search
🚀

SpaceONE 의 영차영차 Vue2.7 업그레이드!

안녕하세요? SpaceONE 에서 프론트엔드 개발을 맡고있는 MS Genie   입니다.
저희는 고객분들과 밀접하게 접점을 만드는 Console디자인시스템 Mirinae 를 개발하고 있고, 더 나은 User Experience 를 제공하기 위하여 끊임없이 노력하고 있답니다.
UX 향상을 위한 많은 방법이 존재하지만, 저는 그 중에서도 디펜던시 업그레이드에 대해 이번 포스팅을 가져왔습니다.
개발환경 세팅 후 시간이 지날수록 코드는 낡아가기 마련입니다.
특히 Framework 와 Library 를 기반으로 작성된 프로그램은 내장된 Bug 및 취약점에 노출되기 쉽고 새로운 Feature 를 활용하지 못할 뿐더러, 생태계에서 뒤쳐지는 코드가 될 수 있습니다.

기존 상황과 Vue3 로의 migration 을 미룬 이유

SpaceONE 의 Console 과 Mirinae 는 Vue2 + CompositionAPI + Typescript 의 구성으로 개발되고 있습니다.
저희 또한 Vue2 내장 버그에 시달리고 있었고, 옆동네(Vue3) 의 새롭고 멋있는 기능들을 사용하고 싶었습니다.
하지만…
1.
Project 의 규모가 너무 방대하여 쉽게 건드릴 수 없는 단계에 위치하여 있었습니다.
左: Console | 右: Mirinae
Console 과 Mirinae 는 약 140만 lines 로 구성되어 있습니다. (September, 2022 기준)
또한 멀티레포의 특성 상 각 레포간의 코드를 유기적으로 접근하기 때문에 섣불리 업그레이드를 진행했다가는 수많은 side effect 에 시달릴 수 있습니다.
따라서 점진적으로 Vue3 에 맞게 refactoring 을 진행하며 업그레이드를 하는 방식을 채택했습니다.
2.
Vue2 의 의존성에 걸려있는 라이브러리가 많았습니다.
storybook/vue, vue-cli, vuexVue2 에 큼지막하게 의존하고 있는 라이브러리들부터 짜잘한 라이브러리들까지 전부 버전업을 하기에는 큰 시간이 소요될 것으로 예상되어 이러한 의존성을 걷어낸 후 Vue3 로 가는 방식을 고민하고 있었습니다.
3.
멀티클라우드 관리 플랫폼 SpaceONE 이 오랜 기간 연구개발 끝에 상용화되었습니다!
따라서 투입 가능한 인력/시간이 부족했습니다 🫠
그러던 중 .. Vue2.7 버전이 릴리즈되었습니다.

Vue2.7

Vue2.7 버전이 July, 2022 에 릴리즈되었습니다.
기존 2.6.14 버전은 June, 2021 에 배포되었으니, Vue2 버전으로써는 굉장히 반가운 소식입니다.
현재 Vue 3이 기본 버전임에도 불구하고 종속성 호환성, 브라우저 지원 요구 사항 또는 업그레이드 하기에 충분한 대역폭이 없기 때문에 Vue 2를 유지해야 하는 사용자가 여전히 많은 것으로 알고 있습니다. Vue 2.7에서는 Vue 3의 가장 중요한 기능 중 일부를 백포트하여 Vue 2 사용자도 이점을 누릴 수 있도록 했습니다.
저희와 같은 고민을 하고 계시는 분이라면 Vue2.7 이 적합한 차선책이 (최선책은 Vue3  ) 될 것 같습니다.

Backported Features

Methods
더 향상된 defineComponent() 의 type interface
h()useSlot()useAttrs()useCssModules(), set() , del() , nextTick()
2.7은 템플릿 식에서 ESNext 구문 사용도 지원합니다. 빌드 시스템을 사용할 때 컴파일된 템플릿 렌더링 함수는 일반 JavaScript에 대해 구성된 동일한 로더/플러그인을 통과합니다. 즉, .js 파일에 대해 Babel을 구성한 경우 SFC 템플릿의 식에도 적용됩니다.
Appendix
ViteVue2 에서 사용 가능하게 됩니다!!!
어쩌면 가장 중요한 기능이 될 수 있을 것 같습니다.
vue-cliwebpack 을, 특히 Vue2 를 사용 중이라면 vue-cli v4 버전을 사용해야하고, 이는 webpack4 를 참조하고 있습니다.
IE 의 공식 지원이 끝났을 뿐더러 (June, 2022), SpaceONE 또한 정책 상 IE 를 지원하지 않기 때문에, 불필요한 빌드시간 증가, 불필요한 빌드 파일의 용량을 차지합니다.
따라서 Vue2.7 을 올린 후, vue-cliVite 로 대체한 뒤 Vue3 마이그레이션 계획을 수립하게 되었습니다.
Vue2 의 공식 지원 날짜는 2023년 말까지로 fix 되었습니다.
그 외의 자세한 Vue2.7 에 대한 내용과 주의사항 등은 공식 홈페이지를 참고해주세요.

Upgrade Guide

1.
@vue/cli-xxx 최신 버전으로 업그레이드 합니다. (가능하다면)
a.
~4.5.19 or ~5.0.6
2.
vue2.7.10 (or latest) 으로 업그레이드합니다.
3.
@vue/test-utils 를 사용하지 않고 계시면, vue-template-compiler 를 제거해주세요. 만약 사용중이시라면, 아직 제거할 수 없습니다.
4.
vue-loader: ^15.10.0 , vue-demi: ^0.13.1 의 버전이 lock 파일에서 또한 버전이 맞아야 합니다. 버전이 다르다면, lock 파일과 node_modules 를 삭제 후 진행해주세요.
5.
@vue/composition-api 를 제거합니다. 기존의 @vue/composition-api 에서 import 하던 것들은 vue 에서 import 해야합니다.
6.
<script setup> 에서 lint error 가 발생할 경우, eslint-plugin-vue 을 (9+) 버전 이상으로 업그레이드합니다. 저의 경우, lint 에러가 나지 않고, 오히려 (vue/max-attributes-per-line should be number (0/1/2) ⇒ 1 line 에 작성 가능한 prop 개수 제한) 규칙에 걸려, 업그레이드 하지 않았습니다.
7.
postcss 를 (8+) 버전으로 업그레이드 합니다.

Error Resolve Guides

디펜던시 업그레이드를 완료했다면, IDE 와 개발자도구에서 Type / Lint / Warning 등이 뿜어져 나올 수 있습니다.
1.
Instance 를 가져오기 위해 사용하는 getCurrentInstance().proxy 의 타입은 ComponentRenderProxy 가 아닌, Vue 으로 사용합니다.
2.
@vue/ 관련 Typescript 디펜던시를 업그레이드 했다면, Typescript 의 업그레이드도 염두해주세요. 생각보다 많은 에러가 해결될 수 있습니다. //@ts-ignore 는 신입니다
3.
vue 를 참조하는 라이브러리가 있을 경우, 업그레이드 후 instance 가 null 이 return 되는 현상이 있었습니다.
// vue.config.js module.exports: { ... configureWebpack: { ... resolve: { alias: { ... vue: path.resolve('./node_modules/vue'), } } }
TypeScript
다음과 같은 구문을 추가함으로써 각 라이브러리가 vue 를 참조하는 부분에서 발생한 충돌을 억제시킬 수 있습니다.
4.
더 이상 SetupContext 에서 root 를 제공하지 않습니다.
따라서 다음과 같이 getCurrentInstance() 를 활용하여 해결하였습니다.
5.
props 에 대한 타입
a.
setup() 내의 props 타입 명시를 제거해주세요. vue의 향상된 타입추론으로 더 이상 필요하지 않을 뿐더러, 오히려 lint 와 typescript 에러가 발생합니다.
1.
Object, Array 에 대해 default type 을 PropType 으로 명시해주세요. 더욱 구체적으로 타입을 명시해주는 것이 좋습니다.
업그레이드의 모든 커밋로그는 아래 링크에서 확인 가능합니다 (!!! SpaceONE 은 오픈소스입니다 !!!)

마치며

사실 외관적으로 디펜던시 관리가 인풋 대비 아웃풋이 크지 않다고 생각합니다.
큰 차이가 보이지도 않을 뿐더러, 수많은 서치와 삽질, 리팩토링이 수반되기도 하고요.
야크 털 깎기에 대해 아시나요?
1. 나무를 베기 위해 도끼를 구했다. 2. 도끼날이 너무 무뎌 날을 갈기 위한 돌을 구하려 한다. 3. 그런데 어떤 마을에 정말 좋은 돌이 있다는 이야기를 듣는다. 4. 그 마을에 가기 위해 야크를 구한다. 5. 야크 털이 너무 길어서 털을 깎기 시작한다. // 출처: https://parksb.github.io/article/32.html
TypeScript
목표는 분명 업그레이드 하는 것이지만, 이를 위해 라이브러리의 코드를 읽어야 하고,
Webpack / VueCLI / Vite 등 번들러에 대한 공부를 해야하고, Typescript / Lint 등 툴에 대한 활용법과
기초적인 Javascript 동작 방식까지 이해를 해야합니다
수많은 공부를 하게되고, 버전을 올렸다는 뿌듯함까지 얻는 디펜던시 관리에 대해 저 개인적으로는 상당히 매력적인 업무라고 생각합니다.
다음 스프린트에는 버전 업그레이드 한 스푼 어떠신가요?
멀티클라우드 관리 랫폼 SpaceONE 에 대해 관심이 있으시다면? ⇒ SpaceONE 공식 홈페이지
SpaceONE 을 뚝딱뚝딱 만드는 CloudONE 팀에 관심이 있으시다면? ⇒ CloudONE 🚀
프론트엔드 개발자분을 채용 중에 있습니다. 저희와 함께 재밌게 일해요!