최근에 진행중인 프로젝트에서 create-react-app을 이용해 생성한 리액트 프로젝트에서 path alias설정을 하려다 삽질을 많이 해서 누군가는 도움이 되라는 의미에서 글을 작성합니다.
프로젝트 환경
create-react-app의 typescript 템플릿으로 생성한 프로젝트입니다. 정석대로 여기서 path alias를 설정하려면 eject 명령어를 사용해야 하지만 craco(Create React App Configuration Override)를 사용하면 eject 없이 path alias를 설정할 수 있습니다.
프로젝트의 디렉토리 구조는 아래와 같고 $components, $contexts, $hooks를 각각 path alias에 추가하고 싶다고 가정해보겠습니다.
root/
src/
components/
contexts/
hooks/craco 설정
우선 아래 명령어를 통해 craco를 설치해줍니다.
npm install @craco/craco설치가 완료되면 package.json 파일의 scripts의 react-scripts를 craco로 바꿔줍니다.
"scripts": {
"start": "craco start",
"build": "craco build",
"test": "craco test"
}그 후에 루트 디렉토리에 아래와 같이 craco.config.js파일을 생성해줍니다.
/* craco.config.js */
const path = require('path/posix');
module.exports = {
webpack: {},
jest: {}
};tsconfig 설정하기
path alias가 잘 작동하도록 설정하기 위해서는 총 3가지 설정을 수정해줘야 합니다. 그 중 두 가지는 craco.config.js파일에서 수정이 가능하고 나머지 한 가지는 tsconfig.json파일에서 수정을 해줘야합니다.
tsconfig.json 파일에서 compilerOptions 옵션의 path 설정을 아래와 같이 해줘야 합니다.
{
"compilerOptions": {
"baseUrl": "src",
"paths": {
"$components/*": ["components/*"],
"$contexts/*": ["contexts/*"],
"$hooks/*": ["hooks/*"]
}
}
}히지만 여기까지 설정하면 괴상하게도 CRA가 스크립트를 실행할 때마다 tsconfig.json파일을 초기화시켜 위 설정을 지워버립니다. (여기서 삽질을 한참 했습니다...) 이를 해결하기 위해서 루트 디렉토리에 tsconfig.paths.json파일을 새로 만들어주고 위 설정을 옮겨줍니다. 그리고 기존의 tsconfig.json파일에 아래 줄을 추가해줍니다.
{
"extends": "./tsconfig.paths.json"
}이렇게 하면 CRA가 path 설정을 지우지 않는 것을 방지할 수 있습니다.
Webpack, Jest 설정
이제 craco.config.js파일을 열어서 webpack과 jest 설정을 추가해줘야합니다.
webpack 설정은 아래와 같이 해줍니다.
webpack: {
alias: {
$components: path.resolve(__dirname, 'src/components'),
$contexts: path.resolve(__dirname, 'src/contexts'),
$hooks: path.resolve(__dirname, 'src/hooks'),
},
},여기까지 설정하면 애플리케이션은 정상적으로 동작하지만 테스트를 실행했을 때 jest가 path alias를 인식하지 못하기 때문에 jest에도 추가적인 설정을 해줘야합니다.
jest: {
configure: {
moduleNameMapper: {
'^\$components/(.*)$': '<rootDir>/src/components/$1',
'^\$contexts/(.*)$': '<rootDir>/src/contexts/$1',
'^\$hooks/(.*)$': '<rootDir>/src/hooks/$1',
},
},
},이렇게 하면 테스트도 정상적으로 동작하는 것을 확인할 수 있습니다.
주의사항
만약 path alias에 @를 사용하는데 types폴더가 존재하면 충돌이 발생합니다. 타입스크립트가 타입 선언 라이브러리(@types/node)와 혼동하기 때문에 폴더 이름을 바꾸거나 다른 문자를 사용해야 합니다.
만약 $components와 같이 폴더에 path alias를 설정하는 것이 아니라 src폴더에 $를 매핑하려고 하면 $가 아닌 다른 문자를 사용해야 합니다. Webpack에서 $를 다른 목적으로 사용하기 때문에 @와 같은 다른 문자를 사용해야 합니다.