필자는 vuejs를 2버전 까지 사용해 보았고 angular는 1.5버전까지 사용해보았으며
현재 주로 사용하고 있는 reactjs는 typescript와 함께 사용하고 있다.
angular는 2이후 버전에 대해서 구글에 배신감(?)을 느끼고 사용하지는 않지만 vuejs를 쓰면서 angularjs의 장점을 이식했다는 말을 어느정도 이해할 수 있었다.
vuejs를 쓰면서 일단 가장 좋은 점은 반응형시스템의 상태변경이 object.defineProperty를 사용한 setter, getter로 상태변경 추적 인터페이스를 숨겼기 때문에 상당히 직관적이고 간편하다는 점이다.
react처럼 비동기 api setState를 사용하면서 컴포넌트간 상태관리에 대해서 고민이 적다는점이 초보자에게 확실히 러닝커브가 낮아서 좋다는 점도 있다.
또한 기존 html,css,js문법을 그대로 써도 되기때문에 팀원들의 학습러닝커브가 낮을 수 밖에 없다는 점이 도입하기도 쉽다.
게다가 좀더 디테일하게 들어가면 angular1을 차용한것이 많이 보였기때문에 개인적으로는 이런 비슷한 요소들도 사용하기 편했다.
그럼에도 불구하고 vuejs를 쓰고자할때 생태계 크기를 제외하고 편의성으로 꺼릴 수 밖에 없는 이유들이 있다.
vuejs에서 typescript지원이 잘된다고 누군가 그러지만 언어레벨에서 tsx포맷을 지원하는것과 vue포맷을 지원하지않는것은 차이가 있을 수 밖에 없다.
당장 vuejs에서 typescript가 잘된다고 하더라도 ide에서 언어자체를 지원하는 레벨과는 차이가 날 수 밖에 없다. 아이러니하게도 이 부분은 angular2 이후도 마찬가지라 html에서 angular-component를 ide가 인식하고 읽어들이려면 별도의 angular-plugin을 받아야 하지만 tsx는 언어레벨에서 지원하기 때문에 ide가 ts를 지원한다면 react는 그럴필요가 없다.
vuejs도 tsx를 쓸수있다고는 하지만 여러 방법중에 하나일뿐이고 사람들이 주로 쓰는 best practice가 아니다. 게다가 tsx를 쓸거면 리액트를 쓰지 vue를 쓸 이유가 없기도 하다.
그런데 react는 @types를 받아야함에도 불구하고 typescript가 jsx/tsx포맷을 지원하기 때문에 아이러니하게도 typescript가 제일 잘 어울리는 라이브러리다.
정말 hook을 만든 사람은 어떤 발상이었을지는 모르지만 정말 완벽하다고 생각하고 있다.
hook은 class에서의 mixin이나 상속에서 다중상속의 문제를 깔끔하게 날려버린 완벽한 재사용방식이다.
괜히 vuejs3.0부터 리액트를 따라 hook을 도입하는게 아니라는 생각이 들었다.
vuejs에서 컴포넌트의 기능을 재사용하기 위해서 mixin을 사용할때 mixin간의 메소드가 충돌할 수 있는 문제는 개발자의 인지에서 캡슐화를 깨뜨릴수 있는 문제가 있다.
하지만 hook은 그럴 걱정이 없다. 만약 두개의 같은 hook을 사용하고 hook내부의 구현에 대해서 신경쓰지 않아도 호출부에서 인터페이스를 변경할 수 있기 때문에 내부 구현에서 무엇을 호출하든 신경쓸 요소가 매우적다.
const useCount = () => {
const [count, setCount] = useState(0);
const addCount = () => {
setCount(count + 1);
}
return [count, addCount];
}
// 두개의 카운트를 사용하는 컴포넌트
const MyComp = () => {
// 호출부에서 이름을 변경했다.
const [count1, addCount1] = useCount();
const [count2, addCount2] = useCount();
return ...;
}
vuejs를 사용하면서 가장 이해할 수 없는게 어째서 상위컴포넌트 커스텀 이벤트 핸들링 방식으로 emit방식을 best practice로 차용했는지이다.
props에 function을 넣어서 인터페이스를 명확하게 하면 type hinting도 좋아지고 해당 컴포넌트를 사용하는 개발자가 문서를 뒤지거나 코드를 뒤질 필요없이 해당 코드의 인터페이스를 파악할 수 있는데 이 부분에서 굳이 캡슐화를 깨는 방식으로 best practice를 정해놨다는 점이다.
vue의 emit방식을 angular의 것을 차용한것은 잘못된것을 차용한게 아닌가 싶다. 분명히 단편적으로 봤을때는 좋다라고 생각할 수 도 있지만 vue-ts의 ide지원을 약하게 만드는 요소들중 하나이다.
컴포넌트를 정의할때 인터페이스에서 emit할 요소들을 정의하는게 아니라 emit을 하위 컴포넌트에서 호출하는게 곧 인터페이스이기 때문에 컴포넌트 사용자는 코드를 뒤지던가 문서를 볼 수 밖에 없다.
간단하게 함수의 parameter처럼 모든것을 props로 전달하도록 하는게 best-practice로 두지 않는 이유가 무엇인지는 구현상 성능문제때문일지는 비교해보지는 않았지만 이 부분이 정말 아쉬웠다.
이 부분은 angularjs의 transclude를 차용했지만 별로 좋다고 생각하지 않는다.
분명히 하위 돔을 주입할때 그 요소들을 flat하게 주입할수 있다는 점이 장점이지만 이 부분은 props로만 주입하게 해도 충분하지 않았나싶다.
컴포넌트,dom요소를 props와 분리하게 하고자함이 의도였을수는 있지만 slot도 vue의 ide지원을 어렵게 만드는 요소중 하나이다.
ts로 만들어져 있고 이런 컴포넌트를 주입하게 하면서 커스텀할 수 있는 여지를 열어 놓은 react의 잘 정의된 컴포넌트들은 있을법한 인터페이스의 단어만 잘 떠올려서 props를 적어도 무엇을 입력해야하는지 문서를 가지않고도 알 수 있으면서 직관적인 부분들이 굉장히 많지만 vuejs의 slot은 문서나 코드를 보지않고는 알 수 가없다.
vuejs만 하던분들에 비하면 깊이가 얕아 잘모르는 부분도 있어서 어그로를 끌었을 수 있다고 생각하지만
지극히 개인적인 편의성에 대한 비교로 reactjs를 더 선호하는 이유를 적었다.
이번 vue의 3.0이 어떤지는 아직 둘러보지는 않았지만 react의 hook방식을 차용한다고 하니 다음에 사용할때는 이 부분의 개선이 잘 일어났으면 좋겠다.