이맥스에서 JavaScript 정적 분석기 Tern 사용법
들어가며
텍스트 에디터는 IDE에 비해서 매우 가볍고 편리한 기능들을 가진 도구입니다만, 기능적인 면의 열세에 대해서 많이 이야기되곤 합니다. 특히 정적 분석을 통한 질 높은 자동 완성이 어렵다는 부분은 아주 큰 약점입니다. 이러한 한계를 극복하기 위한 흥미로운 시도가 있습니다. 자바스크립트 정적 분석기인 턴Tern은 서버로 동작하면서 자바스크립트 코드를 분석합니다. 이맥스에서는 패키지를 통해 턴 서버와 통신하면서 문법 체크와 자동완성과 같은 고도화된 기능을 사용할 수 있습니다. 이 글에서는 자바스크립트 정적 분석기인 턴Tern과 이맥스와 연동하는 방법을 소개합니다.
자바스크립트 정적 분석 도구 턴(Tern)
턴은 코드미러CodeMirror라는 에디터를 만들었던 Marijn Haverbeke의 또다른 오픈소스 프로젝트로 자바스크립트 코드 정적 분석기입니다. 지금 바로 데모 페이지에서 코드 미러 위에서 동작하는 턴의 기능들을 확인해보시기 바랍니다. 정적 코드 분석의 결과는 질높은 문법 체크 및 자동완성을 비롯한 다양한 부가 기능을 제공하는데 이용될 수 있습니다.
특히 턴은 특정 에디터에 종속되지 않는다는 점에서 봤을 때, 마츠야마 토모히로(松山朋洋) 씨가 Emacs는 죽었다는 글에서 이야기했던 외부 프로그램에 의한 잠재적인 사회적 가치를 극대화해야한다는 사상에 잘 들어맞는 프로그램입니다. 턴은 어떤 에디터에 종속적이지 않습니다. 독자적인 서버로 실행되며 에디터에서 보내오는 내용에 대한 적절한 분석 결과를 되돌려 줄 뿐입니다. 리눅스에서 명령어들의 결과를 파이프라인으로 보내는데 익숙하다면 이러한 개념이 합리적이고 적절히 확장 가능한지 금방 이해할 수 있을 것입니다. 분석 결과는 에디터의 플러그인이나 패키지가 적절히 처리해줍니다.
턴 저장소에는 이맥스Emacs, 빔Vim, 서브라임 텍스트Sublime Text, 이클립스Eclipse를 플러그인으로 지원하고 있으면 브레킷Brackets, 엣지 코드Edge Code에서는 빌트인으로 지원하고 있다고 소개하고 있습니다.
노드js(node.js) 패키지 관리자 npm을 사용해 턴 설치하기
턴을 사용하려면 먼저 설치를 해야합니다. 여기서는 npm을 사용해서 설치해보겠습니다.
$ npm install -g tern
npm http GET https://registry.npmjs.org/tern
npm http 200 https://registry.npmjs.org/tern
...
[email protected] /home/myhome/.nvm/v0.10.24/lib/node_modules/tern
├── [email protected]
├── [email protected] ([email protected])
└── [email protected] ([email protected], [email protected])
설치가 끝나면 tern
명령어로 서버를 실행해봅니다.
$ tern
Listening on port 60805
^c(종료)
랜덤한 포트에서 턴 서버가 실행되는 것을 확인할 수 있습니다.
턴과 이맥스 연동하기
이제 이맥스와 연동할 차례입니다. 턴은 이맥스 24 이상을 지원하고 있습니다. 먼저 설치된 이맥스 버전을 확인하고, 필요한 경우 업데이트를 해줍니다.
$ emacs --version
GNU Emacs 24.3.1
Copyright (C) 2013 Free Software Foundation, Inc.
GNU Emacs comes with ABSOLUTELY NO WARRANTY.
You may redistribute copies of Emacs
under the terms of the GNU General Public License.
For more information about these matters, see the file named COPYING.
이맥스 24에는 강력한 패키지 관리자가 기본으로 포함되어있습니다. tern
과 tern-auto-complete
패키지를 설치합니다.
M-x package-install <enter> tern <enter>
M-x package-install <enter> tern-auto-complate <enter>
만약 패키지를 찾을 수 없다면 ~/.emacs.d/init.el
이나 이에 준하는 이맥스 설정 파일에 다음 내용을 추가합니다.
다시 위로 돌아가 package-install
을 하면 정상적으로 설치가 가능할 것입니다. 이렇게해도 패키지가 나타나지 않는다면 턴 저장소의 내용을 클론해서 이맥스 디렉토리 아래의 el
들을 .emacs.d
디렉토리 아래로 복사합니다. 복사한 후 자신의 설정 파일(기본적으로 ~/.emacs.d/init.el
)에 아래 내용을 적절히 수정해서 추가해줍니다.
(add-to-list 'load-path "~/.emacs.d/tern/")
(autoload 'tern-mode "tern.el" nil t)
(add-hook 'js2-mode-hook (lambda () (tern-mode t)))
(eval-after-load 'tern
'(progn
(require 'tern-auto-complete)
(setq tern-ac-on-dot t)
(tern-ac-setup)))
이걸로 기본적인 설정은 끝났습니다. M-x load-file
명령어나 이맥스를 종료 후 다시 실행시켜 설정을 적용합니다. 이제 자바스크립트 메이저 모드일 때 턴 마이너 모드가 실행됩니다.
자바스크립트 프로젝트 설정
턴 마이너 모드가 실행 되면 자동적으로 턴 서버가 실행되고, 이 서버와 통신하면서 자동 완성을 비롯한 몇 가지 부가 기능들을 사용할 수 있습니다. 하지만 이 상태에선 자동완성이 될만한 표현식을 입력해봐도 자동으로 완성되는 게 거의 없습니다. 이는 턴 서버가 현재 자바스크립트가 어떤 맥락에서 평가 해야할 지 판단할 수 없기 때문입니다. 이를 위해서는 자바스크립트 프로젝트 단위로 .tern-project
파일을 만들어야합니다.
프로젝트 설정 파일의 대략적인 구조는 다음과 같습니다.
{
"libs": [
"browser",
"jquery"
],
"loadEagerly": [
],
"plugins": {
}
}
libs
에는 tern에서 미리 정의해놓고 있는 JSON 타입 정의 형식을 따르는 라이브러리 정의 파일을 지정할 수 있습니다. 턴 저장소에서 확인할 수 있는 바로는 browser
, chai
, ecma5
, jquery
, underscore
다섯가지를 기본적으로 사용할 수 있습니다.
예를 들어 underscore
를 사용하면 다음과 같이 자동 완성이 되는 것을 볼 수 있습니다.

loadEagerly
옵션을 통해 프로젝트 아래에서 미리 읽어둘 파일을 지정할 수 있습니다. 예를 들어 D3.js를 바우어bower로 설치하고 다음과 같이 프로젝트 설정 파일을 수정합니다.
{
"libs": [
"browser",
"jquery"
],
"loadEagerly": [
"bower_components/d3js/build/d3.v3.js"
],
"plugins": {
}
}
이를 통해서 D3.js 라이브러리에 관련된 자동 완성이나 tern-find-definition
과 같은 기능을 사용할 수 있게됩니다. 라이브러리를 지정할 때는 **
와 같은 패턴 매치도 사용가능하니 자바스크립트를 모아놓는 디렉토리를 미리 불러오는 것도 가능합니다.

이외에도 노드jsNode.js 플러그인, 리콰이어JSRequireJS 플러그인, 앵귤러JSAngularJS 플러그인 등 추가적인 확장을 사용할 수 있습니다. 이에 대한 자세한 설명은 공식 문서의 서버 플러그인 섹션을 참조하시기 바랍니다.
턴(Tern) 사용하기 : M-x 명령어 및 단축키
턴의 이맥스 확장에는 다음과 같은 명령어들이 정의되어있습니다. 괄호 안에 키는 기본 단축키 입니다.
- tern-get-docs(
C-c C-d
) : 커서 위치의 문서를 찾습니다. - tern-find-definition(M-. , 되돌아가기:
C-c C-r
) : 커서 위치의 정의를 찾아갑니다. - tern-rename-variable(
C-c C-c
) : 커서 위치의 변수 이름을 변경합니다. - tern-use-server : 특정 tern 서버를 지정합니다.
- tern-get-type : 커서 위치의 타입을 출력해줍니다.
- tern-highlight-refs : 커서 위치와 같은 것들을 하이라이트해줍니다.
- tern-find-definition-by-name : 지정한 이름의 정의를 찾아갑니다.
결론
턴과 함께 이맥스에서도 즐거운 자바스크립트 코딩을 즐기시기 바랍니다.