개발자, 트렌드를 버리다.

easylogic
15 min readFeb 15, 2019

이 이야기는 css gradient editor 를 만들기까지의 과정에 대한 이야기이다. (이 글은 깁니다. ^^;;;;;;; 스크롤이 힘들면 안 읽으셔도 됩니다.)

나는 왜 트렌드를 버렸는가?

트렌드를 버렸다기 보다는 트렌드를 신경쓰지 않게 됐다가 맞을 것 같다.

나는 현재 프런트엔드 프로그래머로 일하고 있고 몇가지 프로젝트에 참여하고 있다. 그 중에 하나가 summernote 인데 지금은 업데이트를 많이 못하고 있지만 summernote 를 통해서 개발자체에 대한 공부를 많이 할 수 있었다.

플러그인 시스템을 만들고 멀티 UI 를 구성하고 Bootstrap 의 의존성을 없애고자 자체 UI 시스템을 만드는 등 기존의 트렌드와는 어쩌면 반대되는 형태로 작업했는지 모르겠다.

그럴 수 밖에 없었던 것이 점점 jquery 를 쓰지 않는 추세였고, bootstrap 기반이었던 summernote 에서 bootstrap 을 빼달라는 요구사항이 많이 생겨났기 때문에 하나씩 대응하다 보면 어쩔 수 없이 처음부터 다시 구상하게 된다.

summernote 는 bootstrap 기반 심플한 위지윅 에디터이다. 사이트는 https://summernote.org

심지어 많이 쓰던 font-awesome 이라는 폰트 아이콘도 용량이 크다고 줄여달라고 하는 바람에 자체 font 시스템을 만들기도 했다.

위지윅 에디터 하나를 만드는데 상당히 많은 시스템이 들어가고 거의 모든 UI 인터페이스들이 다 동원 되어야 한다. 덕분에 플러그인을 하나 만들 때에도 UI 를 쉽게 만들 수 있는 방법을 지속적으로 고민했었다.

FrontEnd 프레임워크들이 발전 하면서 React, Angular, VueJS 에서는 더 이상 jquery 를 사용하지 않아도 될 정도가 됐다. 하지만 summernote 는 jquery 기반이었고 그 3가지 프레임워크에서도 돌아가야 하는 문제들이 생기기 시작했다. 프레임워크를 사용하는 프로젝트들은 모두 jquery 를 빼기를 원했고 에디터 때문에 jquery 를 넣기를 원하지 않았다.

즉, editor 는 프레임워크에 상관 없이 동작을 해야하는 궁극의 UI 를 가져야 할지 모른다. jquery 라는 너무 큰 라이브러리도 허용이 안되는…..

그러는 동안 es6 를 시작으로 상당히 많은 기능들이 브라우저로 유입되면서 더 이상 jquery 를 안 써도 할 수 있겠다는 느낌이 들었다.

많은 js 라이브러리 들에서 자체 dom handler 를 가지고 라이브러리를 만들고 있다. CodeMirror 만 봐도 순수 js 로 되어 있고 CodeMirror 하나만 추가 해도 그 UI 를 쓸 수 있는 상태이다.

이렇게 생각을 나열하다 보니 몇가지 사실로 압축이 될 수 있는데

  1. FrontEnd 프레임워크에 독립적인 UI 만드는 방식이 필요하다.
  2. jquery 를 쓰지 않는다.
  3. bootstrap 같은 특정 css 프레임워크도 쓰지 않는다.

이 3가지만 하더라도 FrontEnd 개발자 입장에서는 상당히 고민이다. 3가지에 해당하는 것들을 다시 만들어야 하기 때문이다. 거기다가 현실적인 고민이 몇가지 더 추가된다.

  1. summernote 는 open source 이고 참여자가 많이 없기 때문에 만드는 방법이 심플해야 한다.
  2. 심플하지만 혼자서도 나름 완성도 있는 플러그인을 쉽게 만들 수 있어야 한다. (예를 들어 jquery 없이 파일업로드 컴포넌트 같은걸 만들 수 있어야 한다. )
  3. 쉽게 만드는 만큼 유지보수도 쉬워야 한다.

그 외에도 많지만 결국 외부 프레임워크를 사용하지 않으면서 자체 프레임워크가 그 만큼의 퀄리티를 가져야 한다는 말이다. 트렌드를 완전히 따라가기가 힘들어지는 상황이 된 것이다.

UI 를 쉽게 만드는 고민을 하다.

UI 를 쉽게 만들려는 고민은 summernote 의 플러그인을 연구하면서 시작되었다.

파일업로드 컴포넌트를 하나 만들고 싶었는데 이걸 기존 플러그인 구조로 만들면 너무 복잡해지는 느낌이 있었다.

파일 업로드 컴포넌트의 기획을 좀 크게 해서하나의 플러그인이 이정도의 규모를 가질 수 있는가에 대한 고민이 시작되었다. https://fineuploader.com/

사실 저정도면 따로 라이브러리로 만드는게 맞긴 한데 에디터가 커지면 기능이 어디까지 갈지 알 수 없기 때문에 충분히 가능한 시나리오가 된다.

그래서 계속 연구하다가 몇가지 패턴을 만들어 내었다.

HTML 기반 UI 를 만들 때 가장 고민을 많이 해야 하는 영역을 다시 구성하는 것이다. 어떤 것이 있을까?

  1. html 관리 (요즘 다 Virtual DOM 쓰는데 여전히 그냥 DOM 을 써도 되나? )
  2. dom event 관리
  3. 그로 인한 성능 이슈
  4. 컴포넌트 기반 개발
  5. 테스트하기 쉬운가?

여기있는 것 말고도 많은 일들이 있을 수 있는데

  • 가장 중요한 것은 html 을 통한 DOM 을 관리 하는 방식이다.

성능을 위해 Virtual DOM 으로 대변되는 여러가지 프레임워크 들이 있는데 현 시점에서 Virtual DOM 을 도입하게 되면 위에 전제했던 모든 것들이 깨지게 된다.

그래서 순수 HTML 형태로 template 을 정의한다.

그럼 이런 질문이 올 수 있다.

Virtual DOM 안 쓰면 느리지 않나요?

물론 Virtual DOM 을 안 쓰면 느릴 수는 있다. 왜냐하면 결국은 또 jquery 형태로 핸들링을 해야 하는 이슈가 있기 때문이다. 그런데 잘 생각해보면 Virtual DOM 도 결국은 DOM 을 핸들링 해야 하는 이슈가 있다.

기본 컨셉은 데이타를 잘 핸들링 해서 이전 데이타와 현재 데이타의 차이점만 DOM 에 적용한다가 핵심이기 때문에 이전과 현재데이타를 내가 알고 있고 그 차이점을 쉽게 구성할 수 있으면 DOM 조작도 쉬워질 수 있다.

  • 두번째로 중요한 것은 Event Handling 이다.

event 를 정의 하는 방식은 많이 있는데 , jquery 처럼 dom 에 직접적으로 on, off 메소드를 통해 설정해도 되고 , html tag 에 onClick=”” 처럼 실제로 코드로 적용해도 된다. 나는 전자와 후자를 약간 섞은 타입을 구상했다.

  • 세번째로 이로 인한 성능 이슈가 나올 수 있다.

현대 많은 프레임워크들이 기존 jquery 로 만든 것보다 빨라요가 핵심이다.

그 핵심을 몇가지 짚어보면

  1. jquery 로 하는 Dom 조작이 가장 큰 부분을 차지한다.
  2. Selector 를 사용하지 않도록 한다.
  3. reflow, repaint 를 최소한으로 일어나게 해서 rendering 성능을 극대화 한다.

위와 같은 몇가지만 해결해도 사실 브라우저의 성능 이슈는 잡을 수 있다. 이걸 Virtual DOM 으로 해서 잡아야 하느냐? 하면 그건 아니다.

부끄럽지만 예전에 이런 글도 적었었다. https://easylogic.gitbooks.io/js_performance/content/

사실 성능을 끌어올리는건 몇가지 없다. 가장 중요한 컨셉은 어떤 행위가 일어났을 때 변화를 최소화 하는게 가장 핵심이다.

특히나 DOM 에 있어서 reflow, repaint 라는 렌더링 시점에 나타날 수 있는 여러가지 요소를 안하도록 설계만 할 수 있다면 사실 성능은 그리 문제가 되지 않는다.

물론 이게 어려우니 Virtual DOM 이 나오긴 했지만 막상 만들고 보면 우리가 변화의 시점만 알면 굳이 그렇게 고민할 필요가 없는 영역이기도 하다.

  • 네번째로 중요한 지점은 Component 기반 개발

기존의 jQuery 는 jquery 플러그인 형태로 동작했고 DOM 자체만 중점적으로 관리했기 때문에 Component 에 대한 규칙이 없었다. 그래서 만드는 사람마다 제 각각의 시점이 존재했고 유지보수가 어려운 지점이 생긴다.

그러는 와중에 NodeJS 가 나오면서 FrontEnd 의 개발환경이 급변 했는데 그중에 가장 중요한건 Component 기반으로 빌드가 가능해졌다는 것이다.

import, require 등으로 특정 컴포넌트를 가지고 와서 실행할 수 있게 되고 빌드를 관리할 수 있게 되면서 많은 이점들이 생기고 있다.

여기서도 기본적으로 Component 기반으로 개발할 수 있도록 설계한다. 컴포넌트 끼리 중첩도 가능하도록 하고 있다.

  • 다섯번째로 중요한 지점은 Test 의 용이성

이건 아직 고민중이긴 한데 기본 스펙이 template 을 통한 문자열만 쓰는 구조라 별다른 이슈가 없으면 기존 Test Framework 들도 다 커버될거라 생각한다.

이쯤되면 최신 프레임워크가 없어도 만들 수 있을 것 같아 보인다. 하지만 해보기 전까지는 모르는 일…

더군다나 실제로 개발이 자연스럽게 이어져야 하기 때문에 쉽지 않을 수도 있다.

실제 UI 를 만들다

위에 정의 했던 몇가지 컨셉들을 가지고 실제로 동작하는 코드를 정의 해본다. 예를 들어 코드는 아래와 같이 된다.

template 은 순수하게 html 의 문자열만 지정한다. 거기에는 스크립트를 넣지 않는다.

대신 이벤트를 지정할 메소드를 만든다. 이 때도 메소드 이름을 지정하지 않고 실제로 메소드가 하는 행위에 집중한다.

[CLICK()] (e) { }

보통은 메소드에 clickButton 이라는 이름을 지정하고 이벤트 핸들러에서 on이나 onClick 을 통해서 그 메소드를 다시 연결하는 작업을 해야 하는데 중간 연결고리를 메타데이타 형태로 구성했다.

[CLICK(‘$range .real-value’)] (e) { console.log(e.$delegateTarget.val()) }

jquery 에서 많이 쓰던 delegate 방식도 쉽게 쓸 수 있도록 적용이 되어 있다. element 가 많아 이벤트 핸들러를 많이 연결해야 하는 경우 부모를 통해서 하나의 이벤트 설정만 해도 같은 효과를 볼 수 있다.

[CLICK(‘$range’) + ALT] (e) { console.log(‘clicked alt key’) }

이런 식으로 ALT 키를 눌러야만 동작하는 메소드로도 만들 수 있다.

Decorator 같은 느낌도 들 수 있는데 Decorator 를 쓰게 되면 컴파일러를 재구성해야해서 일단은 스펙에 넣지 않는다.

이 메소드는 이름을 가지지 않아도 행위로서 자신을 명확히 표현할 수 있게 된다. 좀 더 복잡하게 구성하면 아래와 같이 될 수도 있다.

몇가지 구조를 설명하면

  1. template 은 html 만 정의한다. 스크립트를 넣지 않는다.
  2. 이벤트 정의는 모두 메소드로 한다.
  3. DOM 이벤트에 대응하는 CLICK, CHANGE 같은 prefix 를 미리 정의해서 사용한다. 그렇게 해서 메소드의 목적에 대해서 명확히 한다.
  4. jQuery 와 유사한 DOM 라이브러리 패턴을 사용해서 실제 DOM 을 핸들링 한다.
  5. refs 를 둬서 element 를 바로 참조 할 수 있게 한다. 이렇게 하면 selector 를 써서 가지고 필요가 없기 때문에 dom 핸들링하는게 느리지 않다.
  6. 모델 바인딩은 사용하지 않고 특정 DOM 이벤트가 실행 될 때 그 행위를 그대로 정의한다.

this.refs.$number.val(this.refs.$range.val())

UIElement 를 기반으로 만들어진 것을 하나의 Component 로 본다. Component 들은 합쳐질 수 있는데 아래의 예제를 보자.

외부 컴포넌트를 가지고 와서 결합하기 위해서는 components() 라는 메소드에 해당 컴포넌트 리스트를 정의 하고 template 에 태그 처럼 적어주면 된다.

여기서 사용하는 태그는 custom element 규격이 아닌 문자열로만 존재하고 실제로는 YourUI 가 실행될때 나온 <div > 태그로 대체되어 들어간다.

영역만 구분 해 놓으면 개별 컴포넌트에서 행위를 정의하면 되기 때문에 개발의 이점이 있다.

다만 이 시점에 몇가지 문제가 발생할 수 있는데

  • 중첩 컴포넌트에서 이름이 같을 때 이벤트나 다른 DOM 핸들링에 문제가 있을 수 있다.
  • - 이벤트 정의가 중첩이 될 수 있다.

사실 아직 고민 중에 있다. 무엇이 좋은지….

일단은 의식적으로 dom 에 들어가는 class 이름이라던가 Component 이름을 같은 형태로 정의하지 않고 있다.

어플리케이션을 만들 수 있는가?

이렇게 만들어진 컨셉들이 정말로 어플리케이션을 만들 수 있는 구조가 되는가는 또 다른 문제이다.

즉, 가장 위에 설명 했던 summernote 의 플러그인 하나가 어플리케이션 정도로 커지는 거다. 그걸 감당할 자신이 있는지 확인 해봐야 한다.

그래서 그걸 하기 위해서 처음에는 ColorPicker 프로젝트를 도전했다.

이것을 만들면서 많은 부분을 테스트 했는데 실제로 위에 정리했던 몇가지 컨셉들이 잘 동작하는지, 그게 정말로 외부 라이브러리 없이 자연스럽게 되는지를 끊임없이 생각하고 다시 맞췄다.

일단은 나름 성공적이라고 자평한다. 위의 컬러 피커는 하나의 구조로 여러 가지로 확장 할 수 있고 기본 UI 는 공통으로 적용 할 수 있다. 컴포넌트 기반으로 template 형태만 구성하면 생각보다 쉽게 적용할 수 있다.

하나의 ColorPicker 는 이 정도의 기본 컨셉으로 정리 될 수 있다.

개별 컴포넌트의 소스코드는 길어서 실제코드를 보는게 도움이 될 수 있다. https://github.com/easylogic/css/blob/master/src/colorpicker/chromedevtool/index.js

ColorPicker 를 만들면서 몇가지 확인 한 것과 아직 가야할 길을 발견 했다.

확인 한 것

  1. html String 으로 DOM 을 넣어도 느리지 않다.
  2. refs 를 통해서 개별 element 의 속성만 제어 해도 느리지 않다.
  3. 컴포넌트 형태로 관리하니 확실히 편하다.
  4. html 기반이라 기타 다른 지식이 필요 없어서 접근하기 쉽다.
  5. 기존의 jquery 지식을 활용해도 무방하다.

가야할 길

  1. 이벤트 핸들링은 쉬워졌지만 drag 를 좀 더 정교하게 할 수 있는 장치가 필요하다.
  2. Component 에 property 를 정의하고 핸들링 하기 위한 규약이 필요하다.
  3. 더 큰 어플리케이션 만들기 위해서는 데이타를 관리하는 구조가 필요하다. Store 와 Action, Getter 등의 개념이 필요하다.

이러한 것들도 실제 결과물을 만들면서 나오고 있는 중이다.

더 큰 곳을 향해서

colorpicker 를 통해서 하나의 라이브러리를 만드는 것은 성공했고 실제로 다른 프로젝트에서도 나름 사용하고 있는 중이라 그 정도 수준에서 할 수 있는건 했다고 본다.

이제부터는 정말 거대한 것을 만들 준비를 해야한다. 일명 SPA …

저 정도를 만들 수 있어야 어느정도 UI 만드는 체계로서 모습을 갖출 수 있을 것 같다.

그래서 시작한 프로젝트가 CSS Gradient Editor 이다.

처음에는 ColorPicker 의 확장으로 만들다가 완전히 구조를 바꿔서 실제로 어플리케이션 처럼 만들고 있다.

처음에는 대략 이정도 수준에서 만들고 있다가

현재는 하나의 프로토타이핑 툴 수준으로 끌어 올려서 구성해보고 있다. 어디까지 할 수 있을지는 모르겠지만 적어도 내가 만들려던 UI 코드 형태의 증명은 되지 않을까 한다.

CSS Gradient Editor 의 소개는 https://medium.com/@easylogic/easiest-css-gradient-editor-42af278714c1 여기를 보면 된다.

최종 소스 코드는 오픈소스로 되어 있고 누구든지 코드를 볼 수 있다. https://github.com/easylogic/css

마무리

특정한 제약이 생기고 그로 인해서 만드는 방식을 완전히 바꾸는 것은 나름 모험이다. 이미 잘 갖춰진 라이브러나 프레임워크들은 계속 나오고 있다.

특히나 트렌드에 뒤쳐지면 안 된다는 생각으로 인해서 나 스스로를 그동안 가둬 둔 것이 아닌가 하는 생각이 든다. 프런트 엔드 개발은 지금 하고 있는 모든 개발 방식을 다시 생각해봐야 할 시점이다.

React 가 처음 나왔을 때 제일 눈길을 끈건 JSX 를 통한 Virtual DOM 이었다. 이건 페이스북이 처음 만든 것도 아니고 이미 몇년 전부터 구현된 것들이 있던 것들이다.

특히 JSX 처럼 기존 JS 컴파일 영역의 상식을 엎을 생각을 어떻게 했을까?

페이스북에서 만든 HHVM 에서 php 의 XML객체를 php 코드 안에 태그 형태로 적으면 객체로 변환시켜 준다. 컴파일러를 다시 만들었기에 가능한 이야기다. 그 기술이 나오고 나서 JSX 도 차용되었다.

이러한 방식들은 jquery 의 방식을 철저히 무너뜨렸고 엄청난 발전을 이루었다.

이 지점에서 생각해야할게 몇 가지 있다.

  1. 우리가 알고 있던 과거 또는 현재의 방식은 최선의 도구가 아닐 수 있다.

2. 그 들은 왜 끊임없이 새로운 것을 만드는가? (왜 바퀴를 다시 만들까? )

3. 그 들은 왜 기존 방식으로 코딩하면서 발전시키지 못 했는가?

4. 그렇다면 그 들은 왜 처음부터 다시 만들어야 했는가?

5. 어째서 그 것을 과감히 실행할 수 있는가?

결국은 필요성인 것 같다.

페이스북 처럼 동적으로 여러 element 상태를 여러 번 변경하는 사이트들은 거의 없다. 이건 애초에 페이스북 페이지 자체가 그런 구조로 돌아갈 수 없는 상태였기도 하다.

보통은 바퀴의 재발명이 될 수 있는 이러한 라이브러리나 프레임워크들이 현재는 끊임 없이 나온다. 하지만 나에게 발생한 문제는 결국은 내가 해결해야하는 영역에 있다.

그 해결점을 찾기 위해 프로그래머가 존재한다고 생각한다. 좋은 방법을 계속 찾고 시도를 계속 해봐야 한다.

필요하면 컴파일러 조차도 엎어야 한다. 컴파일러를 엎으면, 예를 들어 Virtual scroll 같은 것도 라이브러리가 아니라 언어랑 브라우저 차원에서 지원할 수도 있다.

그러면 나한테 물어보자.

  1. 내가 지금 하고자 하는 것들이 남들이 만들어 놓은 프레임워크가 해결책인가?
  2. 그렇지 않다면 나는 그것을 만들 수 있는가?
  3. 나는 왜 남들이 만들어 놓은 것들만 써야 하는가?
  4. 나는 왜 새로운 개념을 만들지 못하는가?
  5. 새로운 개념은 경력이 많아야 생기는가?
  6. 경력이 10년이 되도 왜 React, VueJS 같은 개념을 생각하지 못하는가?

이런 저런 질문들을 할 때마다 정말로 많은 것들을 그 동안 놓치고 살았구나라는 생각이 든다.

경력만 쌓았지 개념을 쌓지 않은 거다. 뭔가 제대로된 나만의 개념을 만들어 보지 못했다. 스스로도 체계적이지 못한 사고 방식으로 인해서 언제나 트렌드만 쫓아간다.

하지만 새로움에 현혹되지 말고 현 상황에서 최선의 방식을 더 깊이 연구해야한다.프런트라는 영역은 고정된 영역이 아니니 더욱 더 기초를 튼튼히 해야한다.

아마도 지금이 개발자로서 가장 큰 터닝 포인트가 아닐까 한다.

--

--