error일지

[TS] SVG Import Error

rachel_13 2022. 9. 9. 15:49

CRA로 타입스크립트와 emotion을 사용하고 있는데,

public 디렉토리에서 이미지들을 import 하지 않고, src/assets 디렉토리에서 이미지를 import 하려고 했다.

 

🤔 public vs assets

- public : 정적 디렉토리, 컴파일 시 경량화 되지 않음.

                 웹팩이 아니라 build 폴더에 복사 되므로 경로 오입력 등의 이유로 에러가 났을 경우, 위치를 찾기 힘들다.

                 경로에 '%PUBLIC_URL%' 사용

- assets : 웹팩으로 처리됨. 컴파일 에러시 경로 추적가능. 대부분의 이미지들은 여기에서 관리한다.

 

기존에 public/images 폴더에서 이미지 경로를 호출할 때는 아무 문제 없이 잘 되었다. (너무나도 당연함)

<img src="/images/face.svg"/>

그런데...

src/assets 으로 이미지 경로를 변경했더니, 브라우저에서 이미지의 경로를 불러오지 못하는 현상이 발생하였다.

(에러는 안남. 경로만 못불러옴.. 이것도 이유를 잘 모르곘지만..;;)

 

1. <Image/> 컴포넌트를 별도로 생성해서 타입 설정

-> 이 방법을 사용한 이유 : CRA 로 만든 프로젝트라서 webpack.config 설정을 따로 하지 않고, 타입이 설정된 이미지 컴포넌트를 사용하기 위해서였다.

(참고 : https://stackoverflow.com/questions/69775746/typescript-expected-type-comes-from-property-children-which-is-declared-on-i )

  • Styles/Image.tsx
import { Interpolation, Theme } from "@emotion/react";
import React, { ImgHTMLAttributes } from "react";

type Props = Pick<ImgHTMLAttributes<HTMLImageElement>, "src" | "alt"> & {
  css?: Interpolation<Theme>;
  className?: string;
};

export const Image = ({ src, alt, css, className }: Props) => {
  return (
    <picture>
      <img src={src} alt={alt} css={css} className={className} />
    </picture>
  );
};
  • import 해서 사용 (style - emotion 적용)
 <Image src="../../assets/face.svg" alt="timer" css={styles.timeStyle} />

❗️But... 동일하게 경로를 불러오지 못한다.. 아마도 이미지 경로에 대한 type 설정이 되어 있지 않은 것 같다.

 

2. tsconfig에 img 경로에 대해 설정할 수 있는 방법을 찾아보았다.

(1) custom.d.ts 파일 만들기

- 저 any타입이 너무 거슬리지만, 일단 만들어본다.

//custom.d.ts

declare module "*.svg" {
  const content: any;
  export default content;
}

(2) tsconfig.json include에 경로 추가하기

//tsconfig.json

  "include": ["src", "src/custom.d.ts"]

(3) svg import 해서 사용하기

 import face from "../../assets/face.svg";

 // (중략)
 <Image src={face} alt="timer" css={styles.timeStyle} />

 

정상적으로 이미지 경로를 불러오는 것을 확인할 수 있었다.

그런데, 경로를 보니 왜 처음에 못불러왔는지 알것만 같은... 전혀 다른 경로로 연결되고 있음을 확인해볼 수 있다.

그 이유에 대해서는 차차 찾아서 적어보도록 할 예정이다.

 

(아시는 분은 댓글로 알려주세요)