[Vue2] 동적으로 Img 경로 입력 시 Require() 사용해야하는 이유

Castle_Junny·2023년 8월 15일
0

프로젝트 이슈

목록 보기
4/4
post-thumbnail

1. 서론

Vue2.0을 사용하다보면 여러가지 문제를 많이 직면하곤 했지만 이번에는 까먹을만 하면 겪는 image 경로를 읽어오지 못하는 문제가 있었다.

지난번 스타벅스 프로젝트 할 때 겪었던 것을 이번에 POSCO 프로젝트 내용을 이관하면서 또 겪게 되면서
원인을 파악해보고자 한번 여러가지 방면으로 찾아봐았다. 하지만 해결방법은 나와있지만 왜 사용해야하는지에 대해서 시원하게 긁어주는 글이 없었기에 한번 이렇게 저렇게 해보았다.

2. 본론

반영하고자 했던 내용
d3.js를 이용해서 동적(dynamic)으로 이미지를 추가하려고 했다.

문제의 코드

        circleGroup.append('image')
            .attr('width', d => d.imgSize)
            .attr('height', d => d.imgSize)
            .attr('x', d => d.cx - (d.imgSize / 2))
            .attr('y', d => d.cy - (d.imgSize / 2))
            .attr('class', 'amount-img')
        // 문제의 동적으로 이미지 경로 추가하는 부분
            .attr('xlink:href', d => `../../assets/posco/images/item_${d.item_grp_cd}.png`))

2.1 webpack의 문제인가?

처음에는 Webpack이 문제일까? 라고 생각을 했었다.
그래서 webpack으로 모듈들을 bundling을 할 때 이미지의 용량이 커서 제대로 읽지 못한건가?
아니면 파일명이랑 확장자 명이 이상한가?? 막 오만가지 생각이 다 들었다.

그래서 지푸라기라도 잡는 심정으로 vue.config.js의 설정도 변경해 보고
영문으로 된 vue랑 webpack의 문서를 떠듬 떠듬.. 한글로 변역해서 읽어도 봤다.

* 추가한 vue.config.js 내용


        config.module
            .rule('images')
            .use('url-loader')
            .loader('url-loader')
            .tap(options => {
                options.limit = 900000; // 이미지 크기 제한 없애기
                return options;
            });

        // 이미지 파일의 이름과 확장자가 해시값으로 변경되지 않도록 설정
        config.module
            .rule('images')
            .use('url-loader')
            .tap(options => {
                options.name = '[name].[ext]';
                return options;
            });

하지만 역시나 해결되는건 없었고...

그러고 곰곰히 생각을 해보았다.

.
.

아니, 정적으로 <img> 태그에 경로를 입력하면 되면서 왜 동적으로 하면 안되는거지?

.
.

2.2 webpack의 문제가 아니었다.

한 두 세시간을 이러고 있으니까 너무 짜증이나서 그냥 새 화면에다가 정적, 동적 두 방법으로 이미지를 불러보았다.

위와 같이 7개의 이미지를 준비하고 정적 , 동적으로 한번 화면을 구성해봤다.

<template>
  <div>
    <div v-for="d of [1,2,3,4,5,6,7]" :key="d">
    <img type="정적" src="@/assets/images/item_A010.png">
    <img type="동적" :src="(`@/assets/images/item_A0${d}0.png`)">
    </div>
  </div>
</template>

나는 사실 결과를 보고 너무 어이가 없었다.
기본적인 내용일 수 있는데, 정적인 Img의 경우 렌더링 시 data-url로 변환을 해주었고
동적으로 구성했을 때는 String으로만 인식을해서 그런지 Local 경로그대로 들어가 있었다.

3. 결론

그러니까 해당 코드에서는 백틱(`` ) 을 사용해서 동적으로 경로를 지정할 경우에는 해당 경로를 String으로만 인식을 하기 때문에 그 경로는 require()를 통해 data-url로 변경을 수동으로 해주는 작업이 필요한 것이었다.

그리고 이 내용은 공식 문서에도 명시가 되어 있었다.(링크)
이걸 이제 발견한 내가 바보였다 ㅋㅅㅋ

이번에 이 문제를 직면하고 디버깅 시 "경로도 맞는데 왜 안되는거야 ㅡㅡ" 라고 생각했었는데, 경로가 맞았으면 안됐던 것이었다...

알고보니 너무 기본적인 내용이라고 생각이들고 나처럼 시원하게 긁어주는 글이 없어서 간지러워하는 사람을 위해서 이렇게 기록을 남겨본다.

<template>
  <div>
    <div v-for="d of [1,2,3,4,5,6,7]" :key="d">
    <img type="정적" src="@/assets/images/item_A010.png">
    <img type="동적" :src="(require(`@/assets/images/item_A0${d}0.png`))">
    </div>
  </div>
</template>

0개의 댓글