본 글은 create-react-app으로 프로젝트를 생성하고, 이미지가 아래와 같이 존재하는 환경을 기반으로 작성되었습니다.
⎼⎼⎼ public
⌙ asset
⌙ logo.png
react-script 3.4.x의 경우, css나 jsx 폴더의 절대 경로가 public 으로 동일하기 때문에 다음과 같이 설정할 수 있습니다.
.test {
background-image: url(/assets/logo.png);
}
export default function App() {
return (
<div>
<img src="/assets/logo.png" />
<div>
)
}
위와 같이 작성하면 react-script 3.4.x에서는 css, jsx 둘 다 /public/assets/logo.png
에 접근하므로 문제가 발생하지 않습니다.
하지만 react-script 4.0.0 부터 css의 절대 경로가 src로 바뀌게 되어 아래와 같이 logo.png
가 존재하지 않는다고 에러가 발생하게 됩니다.
즉, react-script 4.0.0은 css와 jsx의 절대 경로가 달라 경로에 문제가 발생하게 됩니다.
절대경로 설정시 루트 폴더 기준 (
/assets/logo.png
)
jsx
파일에서 절대경로는 public 폴더를 기준으로 한다.(/public/assets/logo.png
)css
파일에서 절대경로는 src 폴더를 기준으로 한다. (/src/assets/logo.png
)
CRA Repo에도 이 이슈가 등록되어 있습니다.(https://github.com/facebook/create-react-app/issues/9937) 이 이슈에서 많은 사람들이 css와 jsx의 절대 경로가 달라서 생기는 문제들에 불편함을 호소하고 있습니다. 하지만 contributor의 댓글을 살펴보면 'src에 asset 폴더를 포함시키세요'를 해법으로 알려주고 있습니다. 그리고 이 이슈가 등록된 지 1년이 넘었고, CRA V5가 21년 12월 14일에 나왔음에도 해당 이슈가 해결되지 않은 걸로 봐서는 CRA에서 바꿔줄 것 같지 않습니다. 그렇다면 이 이슈를 어떻게 해결해야 할까요?
위의 이슈에 댓글을 살펴보면 다음과 같은 해결책이 나와 있습니다.
이 댓글처럼 craco를 사용하여 이슈를 해결해보려고 합니다.
CRACO(Create React App Configuration Override)는 말 그대로 CRA에 config 설정을 덮어쓰기위한 라이브러리입니다. 즉, CRA에서 eject
를 하지 않아도 eslint, babel, postcss 등을 customize할 수 있게 도와줍니다.
아래의 명령어를 입력하여 설치해줍니다.
$ npm install @craco/craco
하지만 react-script 5.x.x 의 경우, 설치 시, 다음의 에러가 발생합니다.
이러한 에러가 발생하는 이유는 현재(22.08.18 기준) CRACO가 CRA V4.* 까지 지원을 하고 있기 때문입니다.
https://github.com/gsoft-inc/craco/issues/378 이 이슈를 보면 CRACO도 CRA V5에 맞춰 업데이트를 진행하고 있는 것을 확인할 수 있습니다. 또한, 아직 완전하진 않지만 CRA 5를 지원하는 7.0.0-alpha
버전을 사용할 수 있습니다. 따라서 다음을 설치하면 react-script 5.x.x에서도 CRACO를 사용할 수 있게 됩니다.
$ npm install @craco/craco@7.0.0-alpha.3
물론, 추후 stable한 버전이 나오게 되면 바꿔주는 작업이 필요합니다.
루트 디렉토리에 craco.config.js
을 생성해주고 다음과 같이 설정해줍니다.
module.exports = {
reactScriptsVersion: 'react-scripts',
style: {
css: {
loaderOptions: () => {
return { url: false };
},
},
},
};
url을 false로 설정하면 css-loader는 url 또는 image-set에 지정된 경로를 parse하지 않습니다. (참조: 웹팩 css loader )
package.json
에 script 부분을 다음과 같이 수정해주면 됩니다.
// package.json
"scripts": {
"start": "craco start",
"build": "craco build",
"test": "craco test"
}
그리고 실행을 해보면 경로 에러없이 실행되는 것을 확인할 수 있습니다.
$ npm start