Scala/ScalaJS

Scala.js 0.6.18을 사용해 보고.

partner_jun 2017. 6. 30. 16:03

Scala.JS는 프론트엔드에서도 스칼라를 사용할 수 있게 하는 라이브러리 프로젝트다. 커피스크립트나 다트같은 것들과 마찬가지로 .scala 파일이 js 파일로 변환되는 형식이다.



공식 홈페이지에서 자랑하는 몇 가지 특징을 살펴보자면



 

1. Correctness


스칼라의 강력한 타입 시스템을 이용하기 때문에 JS에서의 타입 문제(Number에 +를 했을 때 String으로 변환되는 등의)를 피해갈 수 있다. 또, 친숙한 Undefined, 호이스팅 문제도 해결해준다(사실 이미 let 등으로 피해갈 수 있다).




2. Performance



Scala.js는 컴파일할 때 'fast optimizing' 과정을 거치는데, 이 때 더 효율적인 JS로 최적화해준다. 생성되는 JS파일은 전체 어플리케이션 용으로 만들어지며, 최소 45kB의 용량을 가진다. 프로젝트에서 사용되는 모든 .scala 파일이 하나의 JS파일로 만들어지고 그 안에는 main 함수도 포함되어 있다. 설정에 따라 main을 사용하지 않을 수도 있지만 기본적으로 SPA에 적용하기 쉽다.




3. Interoperability

Scala.js에서도 React나 AngularJS같은 JS 라이브러리를 사용할 수 있다. 그대로 사용할 수도 있고 Scala.js용으로 변환된 라이브러리를 사용할 수도 있다. 다른 라이브러리처럼 SBT에 Dependency를 추가해서 사용한다.





내가 직접 Scala.js를 사용하며 느낀 몇 가지 장단점을 적어본다.



장점


1. 서버 사이드와 클라이언트 사이드 코드의 공유

Play Framework와 Scala.js를 함께 사용하는 프로젝트에서는 서버사이드 코드와 클라이언트 사이드 코드를 공유하는 'shared' 공간이 존재한다. 이 공간에 코드를 작성하면 한번 작성한 코드를 양쪽 모두에서 사용하는 아주 즐거운 경험을 할 수 있다.


2. 스칼라의 자료구조와 문법

스칼라(+자바)의 다양한 자료구조를 클라이언트 사이드에서 사용할 수 있다!


3. Fast optimizing

컴파일 타임에 최적화된 JS파일을 생성한다. 이 최적화가 얼마나 차이나는지는 직접 비교해볼 예정이다.


4. JSExport

.scala파일에 구현된 class나 object의 함수 중 사용할 함수에 어노테이션을 작성하면 JS나 HTML에서 사용할 수 있다.




단점


1. 어려운 시작

Scala.js의 자체는 어렵지 않다. 오히려 쉬운 편이다. 하지만 Scala.js 프로젝트를 '만드는' 과정은 어렵다. 일반 프로젝트 build.sbt 파일에 설정해야 할 것도 많은데, Play Framework와 사용하려고 하면 정말 복잡하다. Example들을 보며 열심히 따라서 해 보았지만 이상한 문제(실행중에 JS로 컴파일이 안되어 매번 다시 시작해야한다던가 하는)가 많았다. Play Framework와 사용할 것이라면 그냥 example 프로젝트를 클론떠서 사용하자.


2. Fast optimizing time

앞서 performance에서 언급한 것처럼, Scala.js는 fast optimizing 과정이 있다. 하지만 단순한 변경(+를 -로 바꾼다던가 하는)에도 이 과정이 필요하다. 그런데 그 때 걸리는 시간이 꽤나 길다. 한두번이라면 괜찮지만 테스트를 여러번 한다면 정말 골치아픈 문제가 된다. 이 기능을 켜고 끌 수 있을 것 같기는 한데, Play Framework와 사용하는 경우에는 설정이 달라서 검색해도 알 수가 없었다.


3. JS파일과의 연동, Dynamic 타입

JS파일로 작성된 함수나 변수도 Scala.js에서 사용할 수 있다. 하지만 타입에 문제가 있다. Scala.js에서 JS파일의 함수나 변수는 'JsDynamic' 타입으로 사용한다. 하지만 이 타입은 스칼라의 기본 타입과 다르다. 그래서 asInstanceOf나 isInstanceOf 함수로 타입을 변경(혹은 체크) 해야한다. 이건 절대 쉽게 넘어갈 문제가 아니다.


4. 런타임 예외

컴파일 타임에서 잡을 수 있는 예외가 아닌 Array Index Exception같은 런타임 시에 발생하는 예외는 코드 어느 부분에서 발생했는지 확인이 어렵다. 아직 왜 그런지는 모르겠지만, .scala 파일에서 예외 발생 라인을 잡아주기도 하지만 그렇지 않은, 그냥 에러가 났다고 알려주는 경우도 있었다. 모든 예외를 체크해가며 만들 수는 없기에 골치아픈 문제다.


5. Scala.js 라이브러리

Scala.js용으로 만들어진 라이브러리들이 있는데, 이 라이브러리들은 사용하는데 주의가 필요하다. 예를 들어 Akka.js는 ActorSystem을 만드는데 2.5초나 걸렸고, Scala.js용 Jquery는 셀렉터를 사용하면 대부분 Dynamic 형태를 반환하여 형변환을 신경써야 했다. 이런 전용 라이브러리 외에 기존에 사용하던 JS파일 형식의 라이브러리는 3번 문제와 마찬가지로 형변환을 조금 신경써야 한다. 




적어보니 단점이 더 많아졌다. 하지만 결코 나쁘지 않았다. 아니, 오히려 좋았다. 앞으로 개인적인 장난감 프로젝트의 서버사이드 언어가 스칼라라면 나는 별다른 고민없이 Scala.js를 사용할 것이다.


ECMA Script를 잘 다룬다면 서버사이드 언어로 스칼라를 선택하지 않고 Node나 Meteor를 사용할 것이고, Scala.js라는 이름조차 들어볼 이유가 없다. 하지만 스칼라를 더 잘 사용하거나 클라이언트 사이드에서 스칼라 라이브러리(혹은 자바)를 사용해야 한다면, 또 스칼라의 문법과 자료구조를 사용할 수 있다는 점으로도 충분히 사용해볼만 하다고 생각한다.