[kotlin] 인텔리제이 무료 버전으로 kotlin javascript 개발하기

개요

사내에서 안드로이드, 스프링에 이어 프론트엔드에도 코틀린을 도입하기로 결정했습니다. 이유는 되도록이면 언어를 통일해야 생산성이 늘어나기 때문이죠. 기존에는 자바, 코틀린, 자바스크립트, 스위프트를 사용하는 체계에서 이젠 코틀린, 스위프트로 단순화 된 셈이죠.

언어를 통합했을 뿐이지 코틀린 풀스택으로 개발하지는 않습니다. 그냥 안드로이드를 코틀린으로, 스프링은 스프링대로 코틀린을 사용하고 있습니다. 마찬가지로 프론트엔드를 위한 코틀린도 별도로 진행합니다.

블로그의 다른 여러 포스팅 시리즈처럼 이번에도 부담 없는 무료 인텔리제이 커뮤니티에디션으로 환경을 구축하고 진행해보겠습니다.

코틀린 js는 의외로 한글로 된 포스팅을 찾기 어렵고 제대로 된 튜토리얼이나 최신 버전에 맞춘 내용도 구하기 어렵습니다.
오늘(19년 3월 26일)기준으로 스샷을 찍어가며 포스팅해보죠.

프로젝트 기본설정하기

프로젝트를 하나 생성해봅니다. 아래 그림처럼 그냥 kotlin말고 gradle에 있는 kotlin을 고르세요.

주의할 점은 코틀린 모듈을 고르면 안되고 그래이들 모듈을 고른 뒤 코틀린 자바스크립트를 선택해야 한다는 점입니다. 이유는 여러가지가 있는데 가장 중요한 것은 DCE 때문입니다. 이 주제는 뒤에 다룹니다. 여튼 그래이들 기반으로 프로젝트가 진행되어야 얻는 잇점이 많기 때문에 SDK기반의 코틀린 프로젝트를 만드는 건 편리하지만 추천하지 않습니다.

아티펙트는 적당히 설정하시고 모듈 설정 화면은 다음과 같이 설정하겠습니다.

소스셋별로 자동 모듈을 만들게 하면 너무 모듈이 난잡해지는 경향이 있어 제 경우는 체크를 푸는 경우가 많습니다. 취향대로 하시면 되지만 이 포스팅에서는 푼 것을 기준으로 전개합니다. 프로젝트 설정을 마치고 잠시 기다리면 다음과 같은 형태를 볼 수 있습니다.

저 위의 kotlin폴더가 본격적으로 코드가 들어갈 위치가 됩니다. 다음 단계는 그래이들을 만져주는 것입니다.

DCE설정

먼저 DCE가 무엇인지 이해해야 합니다. 코틀린 공식 사이트의 링크는 다음과 같습니다.

https://kotlinlang.org/docs/reference/javascript-dce.html

DCE란 dead code elimination 즉 안 쓰는 코드는 죽이는 기능입니다. 왜 이게 필요하냐면 코틀린으로 제작된 자바스크립트는 반드시 kotlin.js라는 지원 라이브러리를 요구합니다.

이 kotlin.js는 풀사이즈가 1.7메가로 미니파이를 거쳐도 700k에 이르릅니다. 사실 부담스러운 크기죠. 파일 사이즈는 둘째치고 사이트 초기 로딩 시 저 크기가 파싱되는 비용을 치루기가 두렵습니다. 이렇게 지원 라이브러리의 크기가 큰 건 kotlin언어에서 지원하는 모든 기능에 대한 래퍼가 들어있기 때문입니다. 하지만 실제 코드에서는 모든 kotlin의 기능을 쓰는 것은 아니고 일부만 사용하죠. list는 사용하지만 map은 안쓸 수도 있는 것처럼요. 이렇게 딱 쓰는 코틀린의 코드만 분석해서 kotlin.js의 크기를 최적화하는 기능이 바로 DCE입니다.

예를 들어 언어적인 요소 외에 kotlin은 코어 객체들을 전혀 사용하지 않는다면 kotlin.js의 용량을 압축 전 100k까지 줄여버립니다. 전혀 부담이 없는 사이즈가 되는 거죠(미니파이하면 30k내외입니다 ^^)
이걸 SDK에 기본으로 적용했으면 좋았을텐데 공식 링크에 가보시면

DCE tool is currently available from Gradle.

라고 명시되어있습니다. 무엇보다 이게 그래이들 기반으로 프로젝트를 만들어야만 하는 이유죠. 그 외에도 인텔리제이 무료 버전에서는 빌드에 관여할 다양한 SDK플러그인이 없으므로 이에 대응하는 kotlin-frontend-plugin을 적용하기 위해서라도 그래이들이 낫습니다.

적용방법은 매우 간단합니다. build.gradle에

apply plugin: 'kotlin-dce-js'

를 적용해주면 됩니다. 다음과 같은 화면이 될 것입니다.

여기까지 성공하셨다면 대부분 정리가 끝난 셈입니다.

hello world

이제 간단한 환경 설정이 끝났으니 진입점을 만들 차례입니다. src/main/kotlin 밑에 main.kt를 만들고 다음과 같이 코드를 작성합니다.

fun main(){
  println("hello world")
}

코틀린 자바스크립트는 자동으로 main이라는 함수를 찾아 진입점으로 사용합니다. 따라서 루트에 main함수를 만들면 진입점이 되죠.
이제 모든 준비는 끝났습니다. Gradle 패널을 열어 build 태스크를 아래 그림처럼 실행합니다.

그림처럼 빌드가 성공적으로 이뤄지면 우측 프로젝트 패널에 build폴더가 솟아납니다. 이 안을 살펴보면 DCE덕분에 kotlin-js-min 이라는 폴더가 생긴 걸 알 수 있습니다.

이제 빌드결과물이 나왔으므로 이를 브라우저에서 보기 위해 간단히 kotlin-js-min/index.html을 만들어줍니다.

에디터 우상단에 보이는 크롬아이콘을 눌러 로컬 서버로 띄워서 보면 다음과 같이 콘솔에 정상적으로 hello world를 볼 수 있습니다.

main폴더를 실제 탐색기에서 열어 용량을 확인해보죠.

미니파이 하기 전의 kotlin.js가 불과 113k로 줄어든 것을 확인할 수 있습니다.

빌드 과정에 미니파이를 추가하기

일단 빌드는 정상적을 됩니다만 미니파이를 안했습니다. 여기서는 간단히 클로저컴파일러를 이용하도록 하겠습니다.
우선 프로젝트 루트에서 노드 콘솔을 열어 클로저컴파일러를 설치합니다.

npm install npm install –save google-closure-compiler

설치가 무사히 완료되었다면 다음과 같은 npx실행이 먹게 됩니다.

npx google-closure-compiler --compilation_level=SIMPLE --env=BROWSER --language_in=ECMASCRIPT5 --language_out=ECMASCRIPT5 --js_output_file='build/kotlin-js-min/js/main.js' --js='build/kotlin-js-min/main/sample.js'

인자를 나눠서 살펴보겠습니다.

  • –compilation_level=SIMPLE : 압축레벨은 간단히(ADVANCE로 할 일을 이미 DCE가 다해줬습니다 ^^)
  • –env=BROWSER : 환경은 브라우저
  • –language_in=ECMASCRIPT5 :입출력 언어를 전부 ES5로 하는데 이는 코틀린 js의 기본 출력이 ES5이기 때문입니다.
  • –language_out=ECMASCRIPT5
  • –js_output_file=’build/kotlin-js-min/js/app.js’ : 압축결과물을 js/app.js로 저장했습니다.
  • –js=’build/kotlin-js-min/main/sample.js’ : 소스코드 원본은 sample.js죠.

마찬가지로 kotlin.js도 압축해줘야합니다. 인자는 대동소이하고 출력과 입력만 수정해주면 됩니다.

npx google-closure-compiler --compilation_level=SIMPLE --env=BROWSER --language_in=ECMASCRIPT5 --language_out=ECMASCRIPT5 --js_output_file='build/kotlin-js-min/js/base.js' --js='build/kotlin-js-min/main/kotlin.js'

이제 index.html이 js폴더의 출력물을 가리키도록 수정합니다.

<html>
<head></head>
<body>
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-preserve="%3Cscript%20src%3D%22js%2Fbase.js%22%3E%3C%2Fscript%3E" data-mce-resize="false" data-mce-placeholder="1" class="mce-object" width="20" height="20" alt="&lt;script&gt;" title="&lt;script&gt;" />
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-preserve="%3Cscript%20src%3D%22js%2Fapp.js%22%3E%3C%2Fscript%3E" data-mce-resize="false" data-mce-placeholder="1" class="mce-object" width="20" height="20" alt="&lt;script&gt;" title="&lt;script&gt;" />
</body>
</html>

이제부터가 좀 귀찮은데 build.gradle에 태스크를 정의하고 run스크립트를 작성하는 과정입니다.
우선 build.gradle 두 개의 태스크를 추가합니다.

task packKotlin(type: Exec) {
    executable = 'npx.cmd'
    args = [
        'google-closure-compiler',
        '--compilation_level=SIMPLE',
        '--env=BROWSER',
        '--language_in=ECMASCRIPT5',
        '--language_out=ECMASCRIPT5',
        '--js_output_file=build/kotlin-js-min/js/kotlin.js',
        '--js=build/kotlin-js-min/main/kotlin.js'
    ]
}
task packMain(type: Exec) {
    executable = 'npx.cmd'
    args = [
            'google-closure-compiler',
            '--compilation_level=SIMPLE',
            '--env=BROWSER',
            '--language_in=ECMASCRIPT5',
            '--language_out=ECMASCRIPT5',
            '--js_output_file=build/kotlin-js-min/js/app.js',
            '--js=build/kotlin-js-min/main/sample.js'
    ]
}

태스크 제작이 끝났으니 run스크립트를 작성해보죠.

우선 run/debug 설정에서 +를 눌러 Gradle을 선택합니다. 하나의 태스크에 앞에 before launch를 선택할 수 있기 때문에 우선 packMain을 고르고 그 앞에 build와 packKotlin이 일어나게 셋팅하면 됩니다.

우선 1단계로 packMain에 대한 태스크 셋팅을 합니다. 그림을 참고하여 프로젝트와 태스크를 잘 선택해주고 하단의 before launch의 +를 선택합니다.

여기서도 유형 중에 그래이들 태스크를 골라서 추가해갑니다.

전부 추가하면 다음과 같은 상태가 될 것입니다.

이제 이 run스크립트가 build후에 차근차근 과정을 진행해 줄 것입니다.

run실행후 모든 과정이 성공적으로 잘 진행되었다면 위와 같이 js폴더가 생겼을 것입니다. html을 실행해보면 여전히 잘 작동하는 것을 확인할 수 있습니다.

실제 미니파이 이후의 용량은 다음과 같습니다.

kotlin.js의 기본 용량이 51k로 크게 줄어 거의 부담되지 않는다는 사실을 알 수 있습니다.

결론

이상 간단히 코틀린을 통한 자바스크립트 개발을 알아봤습니다.

많은 사람들의 오해가 kotlin.js가 1메가가 넘는 것이 부담스럽다 라는 점이 있었습니다. 코틀린은 정적 언어이므로 당연히 의존성 분석이 되고 DCE라는 전용 플러그인을 통해 kotlin.js의 의존성에 따른 조정도 됩니다.

단지 기본 SDK를 통한 kotlin개발에서는 이를 자동으로 지원하지 않아 불편합니다. 대부분의 튜토리얼이 기본 SDK기반의 프로젝트로 진행하다보니 오히려 오해가 많이 쌓입니다. 저도 처음에는 SDK기반으로 만들고 클로저 ADVANCE모드로 kotlin.js의 용량을 줄일려고 시도하는 등의 미친 뻘 짓을 많이 했습니다.

부디 이후 코틀린 기반의 프론트엔드 개발에 입문하실 분들에게 작은 보탬이 되길 바라며 정리했습니다. 무료만세~