파일명 컨벤션과 웹팩/노드 오류

내가 파일 이름을 만들때 사용했던 방식은 이런 순서대로 거쳐왔다.

스네이크 케이스(snake_case) → 케밥 케이스(cabab-case) → 카멜 케이스(camelCase)

가령 "foo bar"라는 의미를 가진 파일을 만든다면,

  • 스네이크 케이스: foo_bar
  • 케밥 케이스: foo-bar
  • 카멜 케이스: fooBar

단어 중간에 언더 스코어를 넣은 방식은 학생 시절에 주로 사용했다. 공부할 때 c 언어를 사용한 탓인 것 같다. 대부분 교과서도 이런 표기법을 사용했다. 자바 책만 제외하면 말이지.

일을 시작하면서부터 케밥 케이스를 사용하기 시작했는데 html 코드의 영향인 것 같다. 게다가 하이픈은 언더 스코어보다 입력하기가 비교적 간단하다. 시프트 키를 누르지 않아도 되니깐 말이다.

컴포넌트 방식으로 웹 개발을 하면서부터 다시 카멜케이스를 사용하게 되었다. 컴포넌트와 같은 이름으로 파일명을 사용하기 때문이다. 가령 UserPage.js 처럼 말이다. 컴포넌트 혹은 클래스와 같은 이름의 파일을 에디터에서 검색하기도 쉽다.

가끔 문제가 발생한다

이러한 방식의 파일명 표기법은 배포하는 과정에서 이따금 문제를 야기한다.

internal/modules/cjs/loader.js:955
  throw err;
  ^

Error: Cannot find module './FooBar'

모듈을 찾을 수 없다는 오류 메시지다. FooBar라는 파일을 찾는 노드(Node.js) 코드에서 발생한 현상이다. 비단 노드뿐만 아니라 웹팩의 빌드 과정에서도 발생한다. MacOS를 사용하는 개발환경에서는 전혀 문제가 되지 않지만, 리눅스를 사용하는 배포 환경에서는 그렇다.

한편 MacOS에서도 비슷한 문제를 마주할 경우가 있는데 바로 깃(git)을 사용할 때 발생한다. 파일명을 변경해도 깃이 변화를 감지하지 못하는 현상이다. 가령 fooBar.js를 FooBar.js로 변경하면 깃이 이 변화를 감지하지 못한다.

이 두 가지 현상이 혼재된 상태는 개발 단계에서는 아무렇지 않다. 하지만 어플리케이션 배포 단계에 가서야 문제가 드러나는데 그 원인과 해결 방법을 정리해 보자.

원인: Git과 MacOS의 특성 때문

먼저 Git과 관련한 현상을 짚어 보자.

가끔 변경된 파일명을 추적하지 못하는 원인은 "깃은 대소문자를 무시"하기 때문이다. 파일명에 대소문자를 아무리 변경해도 인지하지 못한다.

fooBar.js를 FooBar.js로 변경하고 이 모듈을 사용하는 코드에서는 require("./FooBar") 로 고치고 커밋한다. 이렇게 수정된 코드를 다른 곳에서 가져와(클론해서) 사용한다고 치자. 깃은 변경된 FooBar.js를 모르기 때문에 여전히 fooBar.js만 알고 있다. 따라서 require("./FooBar") 코드를 만나면 모듈을 찾을 수 없는 오류에 봉착하게 되는 것이다.

MacOS 관련한 현상도 짚어 보자.

개발 환경인 MacOS에서는 잘 돌아가던 코드가 리눅스 환경에서 안되는 현상이다. 이유는 "MacOS는 파일명을 다룰 때 대소문자를 무시"하기 때문이다. 실제 파일이 fooBar.js가 되었든 FooBar.js가 되었든 모듈을 찾는 쪽에서 require("FooBar.js")로 해도 무방하다. 좀 관대한 편이다.

하지만 리눅스 환경에서는 다르다. 대소문자에 따라 다른 파일로 식별하기 때문에 정확한 파일명으로 호출해야 한다. 대부분 개발 환경은 MacOS이고 배포 환경이 리눅스라면 이런 문제의 가능성을 항상 가지고 있었던 것이다.

해결 방법

깃 관련된 문제는 수월하게 해결할 수 있다. 변경된 파일명을 깃에게 직접 알려주는 방식을 사용할 수 있다(참고).

git mv fooBar.js FooBar

운영체제에 따른 파일 대소문자 관련 문제는 처음엔 웹팩 플러그인으로 해결했다. 웹팩이 모듈을 빌드할때 대소문자를 식별하도록하는 플러그인(CaseSensitiveWebpackPlugin)인데 MacOS 환경인 개발환경에서 빌드할 때 이를 미리 체크해 주는 방식으로 문제를 예방한다.

웹팩을 사용하지 않는 환경에서는 어떻게 해결할 수 있을까? 좀 고민하다가 그냥 모든 파일의 컨벤션을 바꿔버렸다.

카멜케이스 → 케밥케이스로

소문자만 사용하는 방식으로 사용하면 운영체제 상관없이 변경된 파일명을 제대로 추적할 수 있을 것이다. 그동안 사용했던 npm 패키지들의 이름을 유심히 살펴 보면 모두 이런 표기법을 사용한다. 이러한 문제를 몇번 겪고보니 이 패키지들의 네이밍이 이제야 눈에 들어오는 것 같다.