프로젝트 20일: 회사의 합병 소식

개인 프로젝트 20일째, 오늘은 내가 근무하는 회사가 다른 회사와 합병한다고 공시가 났다.

겉으로야 합병이지만, 사실상 내용을 열어보면 우리가 인수당하는 입장이고, 앞으로 어떻게 될지는 알 수 없다. 당장 직속상관이 바뀌어도 업무가 확 바뀌는 것이 당연한데, 심지어 최대 주주가 바뀌는 일이니, 변화가 없을 수야 없겠지. 10년간 우리 회사가 다른 회사를 인수하거나 분사하는 것을 지켜봐 왔지만, 피인수는 처음이다. 나름 다채로운 근로자 생활이 되려나 보다.

회사 분위기도 살피고, 사장님 발표도 들으러 잠시 출근했다. 출근한 김에, 팀원들에게 어제 알아본 RequireJS와, Async와 Promise에 대해서도 물어봤다. 팀원들도 다행히 아직은 큰 동요가 없다, 아직 뭐 실감 날 일은 없으니까. 나도 아직은 멍하니 잘 모르겠고 말이다.

AMD 잘 쓰고 있나?

합병 관련해서야 내가 할 수 있는 일은 따로 없을 테고, 개인 프로젝트 얘기로 돌아오자. 이미 Node.js로 사내 서비스를 개발하고 있는 팀원들에게 물어보니, 아직 RequireJS같은 AMD를 쓰고 있지는 않았고, Promise 역시 스펙 정도만 보고, 실제로 써보지는 않은 단계였다.

“minify 해서 다 로드해놓으면 되죠. JS 파일 다 합쳐봐야 얼마나 되나요? 그걸 굳이 나눠서 로드할 필요 있나요?”

맞는 말이다. 그래 봐야 텍스트 파일 아닌가? 신속한 네트워크 환경에서 텍스트 파일, 그것도 gzip으로 묶으면 이미지 파일 크기 정도인데, 그걸 어렵사리 lazy loading 하겠다고 노력하는 것도 지나친 수고일 수 있다.

Promise는?

10일차에 알아본 Async.js로 콜백 중첩을 푸는 방법에 대해서도 찜찜한 구석이 있어서, 다른 대안인 Promise에 대해서도 물어봤다. 한 명은 Promise는 오버엔지니어링인 것 같고, Async.js를 만족스럽게 쓰고 있다 했고, 한 명은, Promise를 써보지는 않고 스펙만 보았으나, 괜찮아 보인다고 했다.

아직 모르는 입장에서는 남의 의견이 궁금하고, 또 중요하지만, 스스로 느끼기에도 async.waterfall도 아직 콜백 지옥을 완전히 해결해주지 못하는 것 같아서, Promise 관련해서도 조금 더 봤다. 스펙이 정리되고 있는 단계인데, 아직 지원하지 않는 JS엔진들이 더러 있어서, 그걸 메꿔주는 모듈들이 있었다.

http://promisejs.org/

nodegit = require("nodegit")
Promise = require("promise")

nodegitPath = ".git/modules/git/nodegit/"

openRepo = Promise.denodeify(nodegit.Repo.open)

describe '[CoffeeScript w/promise.js] nodegit 저장소', () ->
  it '열어서 커밋 찾아보기', (done) ->
    sha = "e9ec116a8fb2ea051a4c2d46cba637b3fba30575"
    openRepo(nodegitPath).then((repo) ->
      expect(repo.path()).toMatch /\/git\/nodegit\/$/

nodegit.Repoopen이 일반 콜백 방식의 함수이고, 이걸 Promise 식으로 바꿔서 호출하면, then()에서 성공했을 경우의 결과 값으로 그다음 진행을 할 수 있다.

이렇게 한 단계의 콜백은 쉽게 Promise.then() 으로 풀어쓰는 걸 알겠는데, waterfall을 해결하는 방법은 아직 와 닿지 않는다.

http://trevorburnham.com/presentations/flow-control-with-promises/

여기에 괜찮은 슬라이드 자료를 찾았다. 틈날 때 다시 공을 들여 읽어봐야겠다.

[CoffeeScript]

또 한가지, 물어봤다. 커피스크립트는 어떻게 쓰고 있는지. 클라이언트 측 JS를 위해서야 컴파일도 미리 해놓고 최소화하는 것도 중요할 테니 미리미리 컴파일한다고 하더라도, 서버 측에서까지 매번 미리 컴파일하며, 각 커피 소스마다 JS파일 따로 만들어 놓는 게 여간 번거롭지 않았다. Ruby로 개발할 때야 신경 쓰지 않았다, 클라이언트 측 커피 코드만 컴파일했었으니까.

어쨌건, 커피를 즐겨 쓰는 팀원 분의 의견은, 그냥 서버 실행을 node가 아닌 coffee로 한다는 것. 노드로 했을 경우에도, 한 줄의 설정으로 그다음 require부터는 커피스크립트 소스를 그대로 읽을 수 있으니, 최초 진입 소스만 JS로 해도 되고, 아니면 최초 실행부터 아예 coffee로 하면 최초 진입 소스와 그 후 require 모두 커피스크립트를 그대로 활용할 수 있다. 그래 그게 낫겠다. 서버 측이야, 떠 있는 애플리케이션이 계속 재활용되니까, 클라이언트 측처럼 매 클라이언트가 매번 컴파일 해야하는 것도 아니고 큰 부담 없겠다.

지금까지 프로젝트 소스에는 커피스크립트와 JS를 혼용했는데, 오늘부로, 서버 측 코드는 커피스크립트로 통일했다. js2coffee로 변환하고, 눈으로 직접보고 아주 약간씩만 손봤다.

클라이언트 측 소스는 원래 하던 대로 커피스크립트 파일을 asset 디렉터리에 두고, 그때그때 JS 파일로 변환하는 방식을 유지하기로 한다.

프로젝트는 지지부진

오늘의 성과는, 커피스크립트로 통일 전환한 것이 전부다. Promise라도 조금 더 이해할 수 있었으면 정리할 내용이 있었을 것 같은데 아쉽다. 합병 소식에 어수선했다고 얘기하면 핑계겠지.

아! 그래서 결국 AMD를 쓰는 것에 대한 오늘의 방안은, D3.js를 비롯한 대부분은 AMD 방식으로 로딩하고, AngularJS만 일반 동기식으로 로딩하자는 것이다. AngularJS도 익숙하지 않고, AMD방식의 RequireJS도 익숙치 않아서, 어딘가 문제가 발생하면, 두 부분 중 어디서 잘못했는지 파악하기가 어렵다. 따라서 Angular만이라도 일반적(!)으로 로딩해서, 우선 문제 범위를 줄여놓고 진행하다가, 익숙해지면, 다시 비동기 로딩으로 전환하는 방법을 택하겠다.

어떤 개발이든 마찬가지다. 무언가를 변경하거나 새로 할 때는, 불투명한 범위를 최소화해놓고, 부분과 단계별로 Divide & Conquer하는 것이 기본이다.

다행히, 오늘 작업 중에야 RequireJS가 조금 파악이 되어, 조만간 AnguarJS도 비동기 로딩할 수 있을 것 같은 기대가 든다.

오늘은 여기까지.

[CoffeeScript]: http://coffeescript.org/

30일 프로젝트 글목록