오르막길 잊기전에 기록하기

Vue는 왜 filter를 삭제하려고 했을까?

Photo by frank Jakub Kapusnak on Unsplash

지나가다 filter에 값이 변경될 때만 다시 랜더링하게 해달라는 이슈를 보았고, 그 댓글에 뷰의 메인테이너인 Evan Youfilter 를 3.0에서 삭제하고 싶었지만, 2.0에서 삭제되었다가 커뮤니티의 요청으로 가장 일반적인 문법만이 다시 추가되었다는 이야기를 남긴걸 보고 2.0 설계 쓰레드에서 왜 filter 가 삭제될 뻔 했는지를 따라가 보았다.

쓰레드 원글은 https://github.com/vuejs/vue/issues/2756 여기를 참고하면 된다. 추가로 본래 이슈는 https://github.com/vuejs/rfcs/pull/6 여기를 참고하면 된다.

Intro

무려 9개월간 논의된 이 쓰레드에는 v2.0 에서 filter의 삭제를 두고 의견이 팽팽히 대립되는걸 볼 수 있었다.

과거 (2.0 이전) 뷰의 필터는 다음과 같은 파이프 라인 문법과 기본 필터들을 지원하였다.

thing in things | filterBy 'foo' | orderBy 'bar' | limitBy 5

뷰 코어 팀이 필터를 삭제한 이유는 다음과 같다.

필터를 사용하는 대신 다음과 같은 방법을 권장하고 있다.

필터가 유용한것은 사실이지만 순수 javascript의 함수와 같은 일을 하면서도 함수처럼 유연한 사용이 불가능한점, 표준으로 파이프라인 문법이 draft로 올라와 있는점이 filter를 삭제하려는 가장 큰 이유라고 할 수 있다.

Discussion

하지만 커뮤니티의 반응은 사뭇 달랐다. 필터를 다시 복원해달라는 의견이 지배적이였다. 다음과 같은 논의들이 오고갔다.

Q1. 만약 필터를 사용하지 않으면 다음과 같이 코드를 작성해야 한다.

<ul>
    <li v-for="item in filteredItems"></li>
</ul>
new Vue({
    el: 'body',

    data: {
        items: [],
        filter: ''
    },

    computed: {
        filteredItems() {
            var self = this
            return this.items.filter(function(item) {
                return item.indexOf(self.filter) > -1
            })
        }
    }
})

매번 이렇게 쓸려면 얼마나 번거롭겠는가?

또한 파이프 라인 문법이 없으면 다음과 같은 코드를 작성해야 한다.

<ul v-for="word in filters.limitBy(filters.orderBy(filters.filterBy(words, userInput), column, -1), limit)">
    <li></li>
 </ul>

얼마나 번거롭겠는가?

본인도 그렇고, 이 의견을 본 많은 사람들도 그렇고 두번째 예제는 적절치 않은것 같다. 템플릿이 너무 많은 관심을 가지고 있기 때문인데, 해당 관심은 계산된 속성으로 분리하는게 더 나은 방법같아 보인다.

A1. 첫번째 예제에 대해선 매번 컴포넌트에 작성하는게 번거롭다면 global Mixin 을 쓰거나, 메소드를 모듈로 분리하거나, 계산된 속성 함수로 모듈을 분리하거나..

이 경우에도 매번 import 시켜주는것 또한 번거로운 일로 느껴지는것 같다.

Q2. 자바스크립트의 표준 문법과 헷갈릴 여지가 있다면 차라리 ES7 스타일로 필터의 파이프라인 문법을를 변경하는건?

A2. 그것도 2.0에 바벨을 통해 적용될 예정 렌더 함수 코드를 파이프를 통해 사용할 수 있게 할 것이다. 순수한 자바스크립트를 헤치지 않는 선에서

Q3. 객체지향적인 관점에서 보면 필터는 static한 순수함수에 가깝고 method는 그렇지 않다. 이런 이질적인 속성을 methods 안에 넣으라는건 조금 이상하지 않나?

이 질문에 대한 답은 딱히 없었던것 같다. 나도 이 의견에 동의한다.

Q4. 필터의 삭제를 반대하는 사람들이 이야기하는 필터의 주요 피처는 글로벌, 체이닝, 파이프라인 문법이다. 좀더 순수한 자바스크립트로 다가가는것은 인정하지만, 그것이 꼭 프레임워크에서 최우선적으로 고려해야 할 일인가? 리액트 대신 뷰를 선택하는 많은 이들이 고려하는 가치는 러닝커브이고, js를 잘 다루지 못하는 사람들도 쉽게 익혀서 쓸 수 있다는 점이다. lavarel이 프론트 프레임워크로 Vue를 채택한것도 비슷한 맥락일것.

뷰를 사용하는 사람이 모두 훌륭한 자바스크립트 개발자는 아니다. 심지어 디자이너들도 있다. 뷰는 템플릿엔진/시스템 그 이상이지만 템플릿엔진/시스템의 역할도 가지고 있다. 다른 템플릿엔진들이 자바스크립트가 아닌 프레임워크만 익혀서 사용할 수 있도록 기본적인 내장필터를 가진것처럼 뷰도 이와 비슷한 맥락으로 쉽게 익혀서 사용할 수 있었던 필터를 유지해주었으면 좋겟다.

뷰를 자바스크립트를 배우지 않고 사용할 수 없지만, 기본적으로 충실하게 동작하게 하면 비개발자들 (디자이너를 포함해서)도 쉽게 접근할 수 있고, 그들이 뷰를 사용하다가 기본적인 동작만으로 부족하게 되면 그때 자바스크립트를 익히고 best practice를 찾아 학습할 것이다

A4. 파이프라인 문법이 필요한거라면 TC39의 스펙이 표준으로 정의되기전 바벨을 통해 사용할 수 있다. 그건 바벨의 관심이고 UI의 관심은 아닌것같다. 만약 뷰가 필터가 처음부터 없었더라면 javascript 문법을 확장해서 새로운 문법을 만들어달라고 요청했을 것인가?

개발자가 아닌 사람들, 그리고 초심자들에 대한 이야기를 했는데 물론 이들의 관점도 고려를 하고 있다. (실제로 뷰 코어팀에는 디자이너들도 존재하고, 매일 업무로 뷰를 사용하고 있다) 이 사람들에게 필터는 처음에는 마법같아 보일지 모르지만 곧 배우는데 더 복잡하고 한계를 마주치게 될 것이다.

Q5. 장고에도있고 twig에도 있는 필터를 왜 없애려고하냐! {} 안의 영역은 html도 javascript도 아닌 템플릿의 영역인데! 왜! 자꾸! js! 를!

A5. 템플릿 프레임워크의 특징들은 서버사이드 템플릿 언어에서는 필요한 기능이다 (계산된 속성도 없고 표현도 한계가 있으니) 하지만 뷰와 같은 유연성 높은 프론트 사이드 템플릿에서는 별로 필요하지 않은것 같다. 뷰가 생각하는 템플릿은 DOM과의 상호작용을 나타내고 있다. 앞서말한 서버사이드 템플릿 엔진이 정적인 문자열 출력을 만들어 내는것과는 달리. 양반향 바인딩이나, 이벤트를 핸들링하거나 등등.. 필터는 뷰의 환경에서 특수한 한정된 유즈 케이스에 맞춰저 있는 문법이다. 필터를 유지하는 한가지 대안은 {{ }} 안에서만 텍스트를 변형하기 위해 사용하는것이야.

Q6. 배열을 정렬하는등 조작하는건 계산된 속성이 하는게 명확하기 때문에 더 낫다. 하지만 데이터를 여러 포맷으로 보여주는건? 이걸 매번 메소드에 정의하는게 맞아? 성능상으로도 더 안좋잖아? 모든 객체에 프로퍼티로 포함되어야 할테니?

이 부분이 2.0 이후에 filter를 남기는 결정적인 이유가 된듯 하다.

— 그래서 최종적으로 Vue는 filter를 다시 되돌리게 된다. 다만 기능이 많이 간소화되었다.

오로지 {{ }} 내부에서만 사용해야하고, 논리적인 로직은 자바스크립트영역에서 하면서 텍스트를 포맷팅 하는 용도로만 사용해야 한다. 빌트인 필터는 삭제된다. 필요하다면 커뮤니티에서 플러그인이나 라이브러리를 만들어 배포할 수 있다. 필터 구문은 공백으로 인자를 받지 않고, 함수 호출 구문을 사용하여 표시한다.

마치며

오픈소스 프로젝트가 어떻게 커뮤니티와 상생하며 발전해나가는지 볼 수 있어서 좋았던 경험이였다. 특히 메인테이너인 Evan You가 커뮤니케이션 하는 모습은 인상깊었다. 토론에 참여하는 사람들이 차분해질 수 있도록, 그들이 사용하는 워딩을 환기시키며 대화를 이끌어 가는 모습이 앞으로 협업하는데 좋은 참고가 될 것 같다.

comments powered by Disqus