Node.js Project 설정 가이드 (5) - alias

alias는 별명으로 번역될 수 있다.

프로젝트가 커지다 보면 상대경로로 import를 하는것이 점점 더 부담스러워진다.

가령 src/controller/user/userTest.ts 에서 src/utils/str/printName.ts 속의 어떤 것이 필요하다고 해보자. 지금까지 진행한 프로젝트에 폴더를 몇개 더 만들었다. printName.ts도 이동시켰다.

src
├── controller
│   └── user
│       └── userTest.ts
├── index.ts
└── utils
    └── str
        └── printName.ts

userTest.ts 파일을 다음과 같이 작성해보자. 여기서 printName을 include 해보면 ../를 두번 써서 src까지 올라간 다음 다시 utils 폴더 내의 파일을 지칭하게 된다.

import printName from '../../utils/str/printName';

const userTest = (name: string) => {
  console.log('this is userTest controller');
  printName(name);
};

export default userTest;
userTest.ts

테스트를 위해 index.ts에서는 이 함수를 호출하자.

import userTest from './controller/user/userTest';
import printName from './utils/str/printName';

console.log('hello world');
printName('dave');
userTest('jessica');
index.ts

목표

우리의 목표는 프로젝트 내의 어떤 위치에서건 다음과 같이 쓰는 것이다. 현재 위치가 하위의 깊은 위치라도 ../가 여러번 등장하지 않는다.

import userTest from 'controller/user/userTest';
import printName from 'utils/str/printName';

tsconfig.json 수정

tsconfig의 complierOptions 내에 다음 paths 항목을 추가하자. (root는 필요없으면 안해도 된다. 최상위 폴더 자체도 지정할 수 있다는 뜻으로 넣어두었다. )

"paths" : {
      "utils/*": ["./src/utils/*"],
      "controller/*": ["./src/controller/*"],
      "root/*": ["./src/*"], 
    }

그리고 userTest.ts 에서 import구문을 없애고 다시 추가해보자. (빨간줄 쳐진 printName 위에서 cmd+. 을 누르면 quickfix가 뜬다.)

import printName from 'utils/str/printName';

const userTest = (name: string) => {
  console.log('this is userTest controller');
  printName(name);
};

export default userTest;

이제 상대경로가 아닌 alias를 이용한 절대 경로가 잘 지정된 것이다. 빨간줄도 모두 없어졌다. test를 해보자.

➜  my-nodejs-proj npm start

> my-nodejs-proj@1.0.0 start
> npm run build && node dist/index.js


> my-nodejs-proj@1.0.0 build
> babel src --out-dir dist --extensions '.ts,.js'

Successfully compiled 3 files with Babel (204ms).
node:internal/modules/cjs/loader:1078
  throw err;
  ^

Error: Cannot find module 'utils/str/printName'
:
:

음.. 실행은 되지 않는다.

.babelrc 수정

eslint가 tsconfig.json을 보고 어디에서 파일을 가져와야 할지, 적혀있는 경로가 맞는지 판단은 할 수 있게 되었지만, babel이 주도하는 컴파일 과정에서는 이를 다시 알려주어야 한다.

우선 babel 플러그인 하나를 설치하자.

npm i --save-dev babel-plugin-module-resolver 

그리고 .babelrc 를 열어 다음을 추가하자.

"plugins": [
	["module-resolver", {
        "alias": {
          "utils" : "./dist/utils",
          "controller" : "./dist/controller",
        }
      }]
]

이제 다 잘 되는것을 확인할 수 있다.

➜  my-nodejs-proj npm start                                     

> my-nodejs-proj@1.0.0 start
> npm run build && node dist/index.js


> my-nodejs-proj@1.0.0 build
> babel src --out-dir dist --extensions '.ts,.js'

Successfully compiled 3 files with Babel (201ms).
hello world
My name is dave
this is userTest controller
My name is jessica
➜  my-nodejs-proj 

결론

우리는 지금까지 typescript로 nodejs 개발환경을 구축하는 것을 차근차근 진행했다. 벌써 이 프로젝트에 pacakage.json을 포함해 6개나 되는 설정파일이 생겼다.

기존에 쓰던 세팅 혹은 퍼온 세팅을 베이스로 해서 각각의 플러그인, 프리셋, 설정의 의미를 모른 채 프로젝트를 구성하기도 하는데 이는 시대에 뒤떨어진 레거시 세팅을 남겨서 나중에 오히려 더 귀찮게 될 수도 있다.

최대한 각 설정들의 의미를 챙기면서 프로젝트를 구축하는 습관을 들이자.