저는 주로 작업을 neovim으로 하는데요, 상황에 따라 VSCode나 IntelliJ IDEA를 사용하기도 합니다. 이전에 coc.nvim을 활용해 Elixir 개발환경 세팅하는 글을 쓴 적이 있는데 대부분의 개발자분들은 VSCode나 IntelliJ같은 IDE를 선호하십니다. elixir를 사용하는 많은 분들이 주로 VSCode를 쓰기 때문에 관련 자료가 많지만 IntelliJ에 대한 자료는 잘 없는 것 같습니다. 이번에 IntelliJ로 잠깐 써봤는데 IntelliJ도 elixir 지원을 꽤 잘해주네요. 다만 2023.7.28 현재 IDEA 최신버전으로의 업데이트가 이루어지지 않아 2022.3.3 이하의 버전을 사용해야합니다. elixir와 erlang은 기본 세팅돼있다는걸 전제로 IntelliJ에서 elixir 개발환경을 세팅하고 간단한 커스텀 태스크를 만들어 mix 활용방법도 다뤄보도록 하겠습니다.
플러그인 설치
먼저, 플러그인을 받아야겠죠. 다른 언어나 프레임워크와는 달리 elixir는 한 가지 플러그인만 설치하면 됩니다. 플러그인 마켓플레이스에 elixir로 검색을 해 나오는 elixir 로고 모양의 플러그인을 설치해주시면 됩니다. 플러그인 링크
끝!
프로젝트 세팅
Hello World를 출력하는 간단한 프로그램 하나를 만들어보겠습니다. 새로운 프로젝트 만들기 화면에서 언어를 elixir로 선택해주고 원하는 버전의 elixir를 선택합니다.
저는 asdf로 elixir를 설치했는데 IDEA가 알아서 버전들을 찾아줬습니다. 현재 최신버전인 1.15.3을 선택하도록 하겠습니다.
아래 화면에서 옵션을 설정할 수 있는데, 터미널에서 설정하는 앱이나 모듈 이름, 슈퍼바이저 모듈, umbrella와 같은 모듈을 설정할 수 있습니다.
저는 딱히 필요 없기 때문에 그냥 넘어가겠습니다.
Create 버튼을 누르면 이렇게 프로젝트가 세팅되고 프로젝트 루트에 [프로젝트이름].iml
파일이 생성된 것을 볼 수 있습니다.
기본으로 생성된 파일을 열어보겠습니다. 플러그인 덕분에 syntax highlighting이 잘 되고 있습니다.
개발환경 세팅
SDK
elixir는 기본적으로 erlang 위에서 동작합니다. elixir를 사용하려면 erlang도 설치해줘야합니다. 이 때, elixir와 erlang, 혹은 OTP 버전이 맞지 않으면 오류가 발생합니다. [File]메뉴의 [Project Structure]를 열어보면 현재 프로젝트의 SDK 버전을 알 수 있습니다.
SDKs 메뉴에 들어가보면 해당 버전이 어떤 버전의 Erlang OTP를 사용하고 있는지 확인할 수 있습니다.
mix 오류가 erlang을 실행시키지 못해 발생하는 오류라면 설치한 버전에 맞는 erlang이 설치되었는지 확인해보고 여기서 해당 버전으로 변경해주면 됩니다. 많약 설치한 버전을 발견할 수 없다면 왼쪽 상단의 + 버튼을 눌러 추가해줄 수 있습니다.
IDEA가 자동으로 찾아주기도 하지만 찾지 못한다면 수동으로 경로를 지정해 가져올 수도 있습니다. 처음 elixir를 설치하실 때 버전에 맞게 elixir와 erlang을 잘 설치하셨다면 이 부분은 큰 문제가 안될테지만 버전을 마이그레이션하는 등의 경우에는 여기서 설정을 해줘야합니다. 저도 이전 버전인 25버전으로 설정돼 오류가 발생했고, 지금은 25버전을 지우고 26.0.2버전으로 설정해서 잘 실행됩니다.
포맷팅
방금 만들어진 프로젝트에는 .formatter.exs
라는 파일이 있는 걸 볼 수 있었습니다. elixir는 mix format이라는 자체 문범 포맷팅 기능을 제공합니다. 설정에서 확인할 수 있습니다.
정적 코드 분석
elixir 생태계에는 credo라는 정적 코드 분석 툴이 있는데 이것 역시 플러그인에 내장되어있습니다. javascript의 eslint와 비슷하다고 볼 수 있습니다. 코드를 정적으로 분석해 보다 깔끔한 코드를 만들 수 있게 해주는데 기본 옵션에는 꺼져있고, 라이브러리이기 때문에 credo 의존성을 설치해서 사용해야합니다.
또, 얼랭에서 사용되던 dyalizer라는 타입 분석 툴을 변형시킨 dyalixer라는 라이브러리가 있습니다. 코드를 실행시키지 않고 타입 오류 등을 분석해 경고문구를 띄워주는데 이 옵션은 기본으로 켜져있습니다.
새 모듈 만들기
플러그인의 도움으로 새 모듈도 쉽게 만들 수 있습니다.
프로젝트 루트의 lib폴더에 우클릭을 하고 New에 커서를 갖다대보면 New Elixir Module 메뉴를 볼 수 있습니다. 클릭해보겠습니다.
모듈의 이름과 종류를 설정할 수 있습니다. 어플리케이션부터 슈퍼바이저, 젠서버, 테스트까지 다양한 모듈의 기본 템플릿을 지원합니다. 이름은 defmodule의 이름이기 때문에 엘릭서 규칙에 맞춰 PascalCase로 작성해야합니다. 파일이름은 모듈을 snake_case로 변환해 지정됩니다.
단순히 출력하는 간단한 함수를 만들기 위해 일반 템플릿으로 Hello 모듈을 만들어 Hello World 문구를 출력하도록 해보겠습니다.
defmodule Hello do
@moduledoc false
IO.puts("Hello World")
end
실행
이제 만든 모듈을 실행시키는데, IntelliJ의 기능을 이용해 실행시켜보겠습니다. 메뉴의 [Run] > [Edit Configuration]을 들어가 명령어 설정을 켜고 새로운 커맨드를 만듭니다. node 처럼 파일 하나를 실행시킬 수 있는 명령어와 npm 처럼 프로젝트 스크립트를 실행시킬 수 있는 명령어 등을 만들 수 있습니다.
Hello모듈이 들어있는 hello.ex파일을 실행시키기 위해 Elixir 커맨드를 만들겠습니다.
이름은 hello로 하고 실행시킬 파일의 이름을 지정합니다. 이 때, 파일의 위치를 찾을 수 있도록 디렉토리를 지정해주는 것도 잊지 않아야합니다. 실행 전 수행할 작업에 디폴트로 빌드가 있네요. OK를 누르고 실행시켜보면 실행화면에서 Hello World가 출력되는 걸 볼 수 있습니다.
Mix
node.js에 npm
이 있다면 elixir에는 mix
가 있습니다. 다만 npm 명령어의 방식은 cli의 alias를 만드는 느낌이지만, mix는 cli 커맨드를 프로그래밍하는 느낌에 가깝습니다. Phoenix 프레임워크를 사용하면 phx.
로 시작하는 여러 명령어들이 있지만, 설치하고 세팅하는게 번거롭고 mix 커맨드를 이용하는 방법만 알면 되기 때문에 직접 Mix 태스크를 만들어 사용해보겠습니다.
기존의 Hello 모듈의 기능을 하나의 함수에 담아 외부에서 가져와 실행시킬 수 있도록 변경합니다.
# lib/hello.ex
defmodule Hello do
@moduledoc false
def world do
IO.puts("Hello World")
end
end
그리고 lib
디렉토리에 tasks
디렉토리를 만들고 Mix.Tasks.Hello
모듈을 만들어주도록 하겠습니다.
# lib/mix/tasks/hello.ex
defmodule Mix.Tasks.Hello do
@moduledoc false
use Mix.Task
def run(_) do
Hello.world()
end
end
use
같은 문법 설명은 생략하겠습니다.
이제 다시 커맨드 설정을 열어 기존의 hello 커맨드를 삭제하고, mix 커맨드로 다시 만들어보겠습니다.
mix arguments에 사용할 커맨드를 입력해줍니다. 이 때 주의할 점은 모듈 이름(Pascal Case)이 아닌 파일 이름(snake_case)으로 전달해야한다는 점입니다. 그리고 실행시켜보면 아까와 같이 Hello World를 출력하는 것을 볼 수 있습니다.
만약 Phoenix 서버를 실행시키고 싶다면 mix arguments에 phx.server
를 입력해서 쉽게 실행시킬 수 있습니다.