Google Chrome 에서 Grunt 사용하기

KStyleTrip 에서는 프론트엔드 영역에서 디자이너와 개발자가 협업하고 있다.

나는 사실 HTML CSS 를 어느 수준으로 다루기는 하지만 퍼블리셔는 아니어서 픽셀 단위의 디테일을 구현하는데는 어려움이 있다. 디자이너는 디자이너 대로 원하는 만큼의 디테일을 구현하기 어려워하는 내 모습을 보기 안타까워 했다. 그래서 현실적인 수준에서 협업을 시작했다.

개발자가 디자인을 보고 큰 덩이에 대해 마크업과 CSS 처리를 하면 디자이너가 원하는 수준의 디테일을 구현하는 방식이다.

그런데 역시 개발자와 비 개발자간의 협업은 환경구성에 어려움이 있기 마련이다. 예를들어 서버를 띄우거나 하는 일들 말이다. 물론 이것도 쉘 스크립트 등을 사용해 할 수 있는 한 단순하게 만들어 관리하고 있었지만 더 쉬운 방법을 찾게 되었다.

바로 크롬 개발자도구에서 Grunt 를 사용하는 것이다. 쉘스크립트로 관리되던 작업들을 Gruntfile 에 통합하고 grunt-devtools 를 사용해 여러 작업들을 GUI 로 작동할 수 있게 만들었다.

설치과정과 실행방법을 공유하고자 한다.

설치

크롬 익스텐션과 grunt-devtools npm 패키지를 설치해야 한다.

크롬 익스텐션 설치

크롬 익스텐션은 크롬 웹스토어에서 설치할 수 있다. 바로가기

익스텐션을 설치하고 크롬 개발자도구를 열어보면 Grunt 탭이 추가된 것을 알 수 있다.

abstract

grunt-devtools 명령어 설치

명령어를 실행할 것이므로 -g 옵션을 주어 패키지를 설치한다.

$ npm install -g grunt-devtools

사용방법

Gruntfile 이 있는 경로에서 grunt-devtools 를 실행하고 개발자 도구의 gruntjs 탭으로 이동하면 프로젝트가 추가된다.

$ grunt-devtools

여러 디렉토리를 옮겨가며 추가하면 상단 프로젝트 바에 여러 프로젝트들이 추가된다. 이 프로젝트들은 일시적인 것으로, grunt-devtools 와 크롬을 종료하면 사라진다. 따라서 크롬을 다시 시작하면 프로젝트마다 다시 실행해줘야 한다.

그리고 왼편에 위치한 태스크 리스트 아이템을 더블클릭하면 태스크가 실행된다.

태스크에는 Background Tasks, Alias Tasks, Tasks 가 있다.

Alias Tasks 나 Tasks 는 Grunt 의 기본기능이다. Background Tasks 가 생소한데, 간단히 말하면 콘솔을 점유하는 watch 같은 태스크를 Background 로 실행시킬 수 있는 기능이다. 콘솔을 점유하는 태스크들은 종료하지 않으면 다른 태스크를 사용할 수 없다. 이럴 때 Background Tasks 로 실행시켜두면 실행을 종료하지 않고 다른 태스크를 동시에 실행할 수 있다.

태스크를 일단 실행시키고 그 위에 B 아이콘을 클릭하면 Background Tasks 로 실행된다.

background-task

이제 디자이너는 grunt-devtools 라는 명령 하나만 외우면, 혹은 단축 아이콘을 더블클릭하는 것으로 서버를 띄우고 스프라이트 아이콘을 빌드하는 등의 작업을 할 수 있게 되었다. 더 쉽게 더 많은 권한을 드릴 수 있게 되어 기분이 매우 좋다 🙂

P.S. Gulp 에도 gulp-devtools 라는 프로그램이 있다.

페이스북에 Gruntjs 관심그룹을 운영 중입니다. 가입을 언제나 환영합니다 😀

Git Merging 과 Rebase 의 상황별 사용법

Git 을 사용하기 시작한지가 벌써 3년이다. 한번은 문상환님하고 Git 의 Merge branch 커밋에 대해 이야기를 한 적이 있다. 대화가 진행될 수록 Rebase 와 Merge 를 머리로만 알고 있을 뿐, 제대로 이해하지 못하단 걸 알게됐다. 일종의 산파법이랄까.

Git 에서 코드를 합치는 방법에 대해 탕수육의 뿌먹파와 찍먹파처럼 Rebase 파와 Merging 파가 있다. 나는 Merging 파였다. Rebase 에 대해서 알고는 있지만 그저 “충돌나면 머리아프니 안써” 라며 배제 했었는데 좋은 글을 찾아 요약하게 되었다.

개인적으로 중요한 내용인, 각각의 장단점과 활용방법에 대해서만 요약했다. 원문은 소스트리 블로그 에서 볼 수 있다.

각 기능의 장단점

Merging 장점

  • 이해하기 쉬움
  • 원래 브랜치의 컨텍스트를 유지함.
  • Fast-Forward Merge 를 하지 않는다면 브랜치 별로 커밋을 분리해 유지. 특히 이런 분리는 기능 브랜치에 유용.
  • 원래 브랜치의 커밋들은 변경되지 않고 계속 유지되어 다른 개발자들의 작업과 공유되는 것에 대해 신경쓸 필요가 없음.

Merging 단점

  • 단순히 모든 사람들이 같은 브랜치에서 작업하기 때문에 머지해야할 때는 merge 가 커밋 히스토리상으로 전혀 유용하지 않고 어지럽기만 하다.

Rebase 장점

  • 단순한 히스토리
  • 여러 개발자들이 같은 브랜치를 공유할 때 커밋을 합치는 가장 직관적이고 깔끔한 방법.

Rebase 단점

  • 충돌상황에서 다소 복잡. 커밋 순서대로 Rebase 를 하는데, 각 커밋마다 충돌해소를 순서대로 해주어야 한다. SourceTree 가 가이드하기는 하지만, 역시 복잡한 것은 사실이다.
  • 해당 커밋들을 다른 곳에 푸시한 적이 있다면 히스토리를 다시쓰는 것에 부작용이 발생한다. Mercurial 에서는 간단히 푸시를 할 수 없다. Git 에서는 Push 할 수 있으나 당신 혼자 쓰는 리모트 브랜치에만 가능하다. 만약 다른 사람이 그 브랜치를 체크아웃 받은 후 당신이 리베이스 한다면 꽤 혼란스럽게 될 것이다.

결론

Rebase 와 Merging 모두 나름의 가치가 있는 것으로, 논란의 대상이 아니고 상황에 따라 사용해야할 것이 다른것이다.

  1. 여러 개발자들이 같은 브랜치를 공유할 때는 Pull & Rebase 가 히스토리를 깔끔하게 유지하는데 좋음.
  2. 완료된 기능 브랜치를 다시 합칠 때는 머지를 사용.
  3. 기능 브랜치에 부모 브랜치의 변경 내용을 반영하고 싶을 때는
    1. 아래 상황에서는 리베이스가 낫다.
      • 이 브랜치를 다른 곳에 푸시한 적 없는 경우.
      • (Mercurial 이 아닌) Git을 사용하고 다른 사람이 이 기능브랜치를 체크아웃할 일이 없을 것이라 확신하는 경우.
    2. 이 외의 상황에는 머지가 낫다.

따라서 KStyleTrip 는 Git 그라운드 룰을 다음처럼 정하기로 했다.

  • Remote 와 Local 에 동시에 존재하는 브랜치를 Pull 할 때에는 Rebase 를 사용하도록 한다.
  • 기능 브랜치에 대해서는 Merge 를 사용, Rebase 와 비슷한 동작을 하게되는 Fast-Forward Merge 를 사용하지 않는다.
  • 기능 브랜치에 그 부모 브랜치의 내용을 합칠 때는 로컬 브랜치일 때만 Rebase 로 합침.

p.s. Github 클라이언트는 Pull 시 자동으로 Rebase 한다, Sourcetree 도 해당 기능을 설정할 수 있다. 설정법은 원문 참조.

핸드스튜디오 사내강의 “Git+, Git 조금 더 배워보기”

2013년 핸드스튜디오와 연이 닿아 프로젝트를 함께 진행한 적이 있었다. 개인적으로 매우 잘 아는 유명한 회사이다 🙂

당시 핸드스튜디오는 Git 을 사내 버전 관리시스템으로 도입한 초기였고, 그 과정에서 도움이 되고싶어 사내강의를 자처했다.

당시 “svn 능력자를 위한 git 개념 가이드” 라는 아주 좋은 슬라이드가 있어 도입초기에는 이 슬라이드를 교안으로 강의를 진행했고, 이후 조금 더 잘 사용해보자는 의미에서 아래 슬라이드를 제작했다.

강의 이후 까맣게 잊고 지내다 며칠 전 함께 일했던 동료로부터 git flow 도입과 관련한 문의를 받고 생각난 김에 슬라이드쉐어에 업로드 했다.

아래 슬라이드는 git-blame, git-log, git-rebase, git-flow 에 대해 간단히 알아보는 정도로 내용이 구성되어 있어 능력자들께는 부족할 수도 있겠다 🙂

혹시라도 사내 강의가 필요하시면 연락주세요(소곤소곤)

Undefine:D 에서 발표한 “GruntJS로 개발프로세스 구축하기”

페이스북의 Undefine:D 정기세미나에서 “GruntJS로 개발프로세스 구축하기” 를 발표하게 되었다.

GruntJS 는 어떤 플러그인을 어떻게 사용하는지에 성패가 달려있다고 생각하기 때문에 기초보다는 사용하고 있는 플러그인 위주로 발표했다. 기초에 대해서는 이전에 많은 분들이 소개를 하셨기 때문에 발표로서의 차별화도 고려했다.

조직에서 사용하기 위해서는 구성원을 납득시킬 수 있어야 하기 때문에 도입에 대해 확신을 가질 수 있도록 장점을 보여줄 수 있는 데모를 골랐다.

첫 데모는 grunt-contrib-watch 를 골랐는데 그다지 반응이 없었다. 아마도 한번쯤은 봤던 데모여서 그럴지도 모르겠다. 오히려 grunt-injector 가 데모 중에 실수가 있었음에도 더 많은 관심을 받았다. 이외에도 grunt-imagesprite 에 대해 관심을 보여주셨다.

발표 이후에 반응을 종합해보면 현재 GruntJS 도입 초기에 있는 경우가 많다. 그리고 플러그인 하나씩을 이해하고 적용해가는 과정에 어려움을 가지고 있다. 그래서 그런 과정을 공유하면 어떨까 하는 마음에 페이스북에 GruntJS 관심그룹 을 만들었다. 이런 그룹을 만드는 것이 처음이라 어찌 잘 될지는 모르겠지만..

발표자로 서는 것이 오랫만이라 긴장했지만 발표 후에는 보람을 느꼈다. 앞으로도 공유할 것이 많아야 할텐데.. ^^

Dockerfile – ADD 를 통해 build 캐시막기

Dockerfile 을 수정하고 다시 빌드할 때 cache 덕분에 빠르게 재실행이 가능하다.

Dockerfile 의 명령라인이 변경되지 않으면 자동으로 캐시가 작동하게 되는데 가끔 이 기능이 불편할 때가 있다.

Node 개발용 서버를 구축하는 중에 이런 경우를 만났다.

git pull 을 하고, 의존성 해결을 위해 npm install 을 하는 플로우인데, RUN git pull 행이 변경되지 않으니 계속 캐시가 작동했다.

캐시를 작동하지 않게 하는 명령을 추가하는 것에 대해 이 곳에서 계속 논의가 진행중인데, 이 이슈를 살펴보다 랜덤스트링을 추가하는 괜찮은 방법을 알게되었다.

ADD http://www.random.org/strings/?num=10&len=8&digits=on&upperalpha=on&loweralpha=on&unique=on&format=plain&rnd=new /var/tmp/uuid

이 명령을 더이상 캐시가 필요하지 않는 곳에 추가해주면 된다. 이렇게 추가해주면 build 할 때마다 랜덤스트링을 다운받고 컨테이너의 파일이 변경되기 때문에 이후의 명령들은 캐시가 동작하지 않게된다.