TypeScript 절대 경로 지정하기

정호진·2022년 9월 21일
0

프로젝트

목록 보기
2/9

프로젝트를 하는 도중에 파일들을 import 할 때 ../../ 형태의 경로 접근이 상당히 난잡해 보였습니다. 이에 절대 경로 설정을 통해 좀 더 직관적으로 파일들을 사용할 수 있도록 설정했습니다.

절대 경로 지정하기

처음에는 TypeScript에서 절대 경로를 지정하는 것은 나름 쉽다고 생각했습니다. 그냥 tsconfig.json 파일에 들어가서 절대 경로로 사용할 path들을 설정하면 되겠구나 생각했습니다.

{
  "baseUrl": "./src",
  "paths": {
    "@components/*": ["components/*"],
    "@pages/*": ["pages/*"]
  }
}

하지만 오류가 발생합니다. @pages의 파일을 읽어오지 Module not Found 에러를 계속해서 찍어냈습니다. 이에 무엇이 문제인지 확인하기 위해 열심히 구글링을 했습니다.

사건의 발단

사건의 발단은 CRA를 통해 React 프로젝트를 시작한 데서 비롯되었습니다. 위와 같은 현상은 CRA 내부의 Webpack 설정 때문에 tsconfig를 변경한 내용이 적용되지 않고 초기에 생성된 tsconfig.json설정으로 돌아가기 때문에 절대 경로 설정이 적용되지 않는 것이었습니다.
하지만, CRA는 Webpack 설정을 숨겨놓고 있으며, 이를 직접 수정하기 위해서는 eject 명령어를 쳐서 해결해야 하는데, CRA는 한 번 eject 하면 되돌릴 수 없는 강을 건너가 버립니다. 절대 경로 설정하자고 프로젝트 전체에 영향을 줄 수 있는 행위를 하는 것은 그다지 바람직한 상황은 아닙니다.

craco

eject 하지 않고도 Webpack 등 CRA 내부에 숨겨진 설정을 변경할 수 있도록 해주는 라이브러리 중에 craco가 있습니다. 즉 해당 라이브러리를 통해서 typescript 절대 경로 설정이 가능해집니다.
우선 라이브러리와 플러그인을 설치해 줍니다.

npm install @craco/craco	// 라이브러리
npm install -D craco-alias	// 플러그인

웁스. 근데 설치 와중에 다음과 같은 에러가 발생하게 됩니다.

또 다른 문제의 시작

보아하니 의존성 버전이 맞지 않는 것을 알 수 있습니다. 현재 프로젝트에서 사용하는 react-script의 버전은 5.0.1인데, carco 최신 버전이 의존하는 react-script 버전은 4.0.0이기 때문에 문제가 생기는 것입니다. 그리고 해결 방법으로 다음과 같은 두 가지 방법을 제시합니다.

해결

  1. --force
  2. --legacy-peer-dops

이것들이 의미하는게 뭔지 싶어 찾아보다가 다음과 같은 정보를 보게 되었습니다.

npm의 의존성 관리

조금 더 자세한 설명은 아래와 같다. npm은 아래 5가지 종류의 의존성을 제공하고 있다.

dependencies

프로젝트에서 실제로 의존하고 호출하는 의존성들

devDependencies

개발할 때만 의존하는 의존성들(예를 들면 코드 포맷팅을 예쁘게 해주는 라이브러리)

peerDependencies

내 패키지가 다른 패키지로부터 직접 불려지는(require) 것은 아니지만 특정 버전의 패키지와 호환된다는 것을 명시
즉, 내가 다른 패키지의 특정 버전과 호환된다는 것을 뜻한다
자세한 내용은 여기 참고

optionalDependencies

선택적인 의존성으로 없거나 설치에 실패해도 npm 패키지 설치 과정이 중단되지 않아 다른 라이브러리 설치에 영향을 주지 않는 의존성들

bundledDependencies

내 패키지와 함께 제공되는 일련의 패키지들. 타사 라이브러리가 NPM에 없거나 일부 프로젝트를 모듈에 포함하려는 경우 사용할 수 있다.
출처: https://www.korecmblog.com/ERESOLVE-unable-to-resolve-dependency-tree/

위에서 언급한 방법 중 2가지 방법에 대한 해석은 다음과 같습니다.

  • npm install --force
    로컬에 다운로드 복제본이 존재하더라도 다시 온라인에서 다운로드 받는다.

  • npm install --legacy-peer-deps
    마치 6버전 이하에서 동작하던 것처럼 peerDependencies를 무시한다.

그래서 저는 일단 --force를 통해 라이브러리와 플러그인을 다운받았고, 작동이 되지 않을 경우 --legacy-peer-deps를 통해 덮어 씌울 생각을 하고 있었지만, --force만 사용해서 라이브러리를 설치했는데 문제없이 작동하는 것을 확인했습니다.

carco 설정

설치에서 오는 문제를 해결했습니다. 이제 TypeScript에서 carco 설정만 해주면 됩니다. 위에 tsconfig파일에 보면 절대 경로를 파일 안에 작성했는데, carco를 사용하면서 외부 파일로 분리해야 합니다. 해당 파일을 carco에서 처리하도록 남겨주고, carco는 리액트 실행 시 웹 팩 기본 설정에게 이 옵션을 제대로 인식할 수 있도록 전달하는 역할을 수행하게 됩니다. 따라서 경로 옵션만 담고 있는 tsconfig.paths.json 파일을 tsconfig.json 파일과 동일 레벨에서 하나 생성해 줍니다.

// tsconfig.paths.json
{
  "compilerOptions":{
    "baseUrl": "./src",
    "paths": {
      "@components/*": ["components/*"],
      "@pages/*": ["pages/*"]
    }
  }
}

경로 옵션 설정이 외부 파일로 분리되어 있기 때문에 다시 tsconfig.json에서 인식할 수 있도록 extends 키워드를 통해 파일 설정을 상속받도록 설정합니다.

// tsconfig.json
{
  "extends": "./tsconfig.paths.json",
  "compilerOptions": {
    "target": "es5",
    ...// webpack 기본 설정
  }
}

이제 해당 TypeScript 설정을 carco가 다룰 수 있도록 만져줘야 합니다. 이는 carco.config.js라는 라이브러리 설정 파일을 통해 작업할 수 있습니다.

const CracoAlias = require("craco-alias");

module.exports = {
  plugins: [
    {
      plugin: CracoAlias,
      options: {
        source: 'tsconfig',
        baseUrl: "./src",
        tsConfigPath: "tsconfig.paths.json",
      },
    }
  ]
};

craco 라이브러리 설정에서 웹 팩을 위한 자동 alias 생성 플러그인 craco-alias를 지정해 주고 있습니다. 우리가 필요한 기능은 해당 플러그인이 전부 지원하기 때문에 별다른 설정을 건들지 필요가 없습니다. craco에서는 웹 팩을 비롯한 다양한 설정 파일을 다룰 수 있는데 자세한 점은 npm 문서를 참고하면 됩니다.

플러그인에서 지정할 수 있는 options에는 다음의 값들이 있습니다. 저는 3개의 프로퍼티만 지정해 주었지만 각자 서비스에 맞게 설정해 주시면 됩니다.

  • source : options | jsconfig | tsconfig 중 하나, 디폴트는 options이지만 타입스크립트를 사용한다면 tsconfig를 선택
  • baseUrl : 타입 스크립트 경로에서 기본 출발점이 되는 경로와 동일
  • aliases : source: 'options' 일때만 필요한 프로퍼티로, 별칭 이름과 경로를 가진 객체를 지정
  • tsConfigPath : source: 'tsconfig' 일때 지정하는 프로퍼티로, 여기선 우리가 만든 경로 관련 tsconfig.paths.json 파일을 지정
  • filter : 필터링 함수를 넘겨주며, 별칭 중 특정 기준으로 사용할 것과 사용하지 않을 것을 필터링하고자 할 때 사용
  • unsafeAllowModulesOutsideOfSrc : ./src 디렉토리 외부에 있는 모듈 역시 import/export를 가능하게 하는 설정으로, 이는 기본 웹팩 설정의 ModuleScopePlugin과 상충되는 옵션이기에 사용 시 판단근거 마련이 필요
  • debug : 디버그 관련 정보를 로그로 출력

이제 pakage.json에 있는 script를 다음과 같이 변경시켜주면 됩니다.

"scripts": {
  "start": "craco start",
  "build": "craco build",
  "test": "craco test",
  "eject": "react-scripts eject"
},

지금까지의 작업들이 모드 carco 라이브러리가 커스텀 설정들을 인식하기 위한 작업들이었습니다. 따라서 React 앱을 실행/빌드 할 때 설정 정보를 가지고 carco를 통해 이루어질 수 있도록 명령어를 변경해야 합니다.
해당 과정들을 마치고 npm start를 실행한다면 절대 경로 설정이 되었음을 확인할 수 있습니다.


참조

CRA TypeScript 절대 경로 설정 w carco
--force와 --legacy-peer-deps의 차이
carco npm

0개의 댓글