DevJong12

[OrientalUnity][React, Spring] React Quill의 바이트 코드이미지 삽입이슈와 해결법 본문

프로젝트/OrientalUnity

[OrientalUnity][React, Spring] React Quill의 바이트 코드이미지 삽입이슈와 해결법

Jong12 2023. 11. 20. 17:19
728x90

목차

     

    1️⃣ 글 작성에 앞서...

    해당 이슈는 우리 팀이 구현한 사용한 도구에 대한 이해가 필요하다.

     

    일단 FrontEnd의 경우 React를 기반으로 작성을 진행하였으며, 이슈가 발생한 장소는 게시물을 등록하는 곳에서 발생이 되었다.

     

    게시물을 등록시 필자의 팀의 경우에는 에디터를 사용하여 게시물을 등록할 수 있도록 기능 구현을 하였으며, 오픈소스중 하나인 React Quill을 활용하였다.

     

    Quill자체에는 이미지를 업로드하는 기능이 존재하였으나, 이미지를 업로드할때 발생이 되는 이슈사항에 대하여 기록을 해보고자 한다.


    2️⃣ ReactQuill와 Quill을 선정한 이유?

    1. ReactQuill이란?

    공식페이지에서 소개되어있는 내용으로, 긴 텍스트를 작성할 수 있는 에디터라고 설명이 되어있다.

    에디터를 작성하게 되면 TextArea와는 다르게 HTML마크업을 그대로 전달받을 수 있게 된다.

    https://quilljs.com/

     

    Quill - Your powerful rich text editor

    Sailec Light Sofia Pro Slabo 27px Roboto Slab Inconsolata Ubuntu Mono Quill Rich Text Editor Quill is a free, open source WYSIWYG editor built for the modern web. With its modular architecture and expressive API, it is completely customizable to fit any ne

    quilljs.com

     

    2. 필자가 생각하는 에디터를 사용해야 하는 이유

    에디터를 써야하는 이유는 필자가 생각함에 있어서는 일단 정보를 전달하는 글을 작성함에 있어 강조의 표현을 다르게 꾸며논다든가 등 글의 가독성을 높일 수 있기 위해서는 HTML언어를 적용 시킬 수 있어야 하는데, TextArea로는 작성자가 의도대로 작성하는지의 확인이 힘들다는 단점이 가장 큰 문제이지 않나 싶다.

     

    그 외에도 호환문제라든가 여러가지 사유가 존재하고, 각자가 다 다를 수 있으니 해당사항은 직접 생각해보면 좋을 듯 하다.

     

    3. 왜 Quill이었는가?

    딱히 큰 이유는 없었다. 오픈소스에 무료사용이 가능한점, Editor를 검색시 가장 먼저 나온점등이 이유였다.

    그저, 이미지를 넣을 수 있고, HTML로 Content를 받아올 수만 있었다면 자료가 많은것중 아무거나 가져와서 사용했을 것이다.

     

    Quill이 먼저 많이 나온 자료였고, 아래의 이미지 처럼 구현이 바로바로 가능했기때문에 빠르게 채택하였다. 

     

    그냥 에디터를 왜 써? 라고 묻는다면..한번 생각해보자.

     

    우리가 블로그에서 글을 작성하건, 커뮤니티 싸이트에서 글을 작성하건.. 사진을 못올리고, 게시물의 내용을 볼드나 이태릭처리를 못하는 그런 커뮤니티나 블로그를 본적이 있는가?

     

    이게 내가 생각했을때 커뮤니티 프로젝트를 하게 된 순간부터 에디터를 고려 할 수밖에 없단 사항이다.


    3️⃣ 이슈내용

    이미지를 업로드할 떄 문제가 된다고 처음에 말을 하였다.

    이미지는 굉장히 긴 바이트코드로 이루어져있다. FrontEnd Application레벨에서는 이미지를 어떻게 처리하는지를 나도 몰랐다.

     

    ReactQuill에서는 그 긴 바이트코드를 HTML태그로 img태그에 집어넣고 있었다.

     

    오른쪽의 코드가 IMG태그의 src속성에 직접 바이트코드로 넣고 있는것을 볼 수 있으며, 저 문자열을 그대로 Spring에서 받게 된다는 것이다. 그렇게 넘어오는 것 자체를 필자는 이슈라고 정의하였다.


    4️⃣ 해결 방안?

    해결의 최종점은 바이트코드를 대신해서 서버에 업로드된 이미지의 Path를 기록하게 하는 것이었다.

    그를 위해 어떻게 작업을 해야할까? 고민을 했고, Image를 업로드할 때 사용되는 Handler를 제작해서 적용하기로 마음먹었다.

     

    로직을 이해하기 쉽게 이미지로만 끝내면 다음과 같이 표현이 가능해진다.

    1. 기존에 React Quill을 사용시의 로직

    2. Server의 Path를 가져오는 로직


    5️⃣ BackEnd (Spring)의 작업내역

    1. Controller

    이미지를 업로드할 API를 제작한다.

    해당 요청은 MultiPart를 받아야 하기때문에 POST메소드를 사용해야 한다.

     

    2. DTO

    Request를 담당할 DTO와 Response를 담당할 DTO를 생성한다.

    필자의 경우 사용처를 Path에 집어넣고 있어서, 어느 기능에서 올린것인지 구분하기 위한 Enum이 존재한다.

    3. Service

    Service에서는 우선적으로 로그인한 사용자인지를 구분하며, 이후 테이블에 요청한 사용자의 정보를 바탕으로 올린 파일정보를 기록해두며, Response객체로 감싸서 Return을 한다.

    4. FileUpload Util

    해당 코드에서 실질적인 파일 업로드가 이뤄진다. 정말로 파일 업로드변경된 파일 명을 반환만한다.

     

    여기서 기억할 사항은 필자의 경우 spring.profiles.active의 Value에 따라 /dev~ 로 시작할지, /local~ 로 시작할 지를 구분하였다.

    또한 파일의 경우 실행위치 + 사용처 + 시간 + 파일명으로 저장이 되게 된다

     

    5. Amazon S3 Bean

    해당 코드에서는 FileUpload를 진행하는 Util에서 사용하는 S3의 Bean을 설정하는 코드만 존재한다.

    StorageProperties까지는 나열하지 않을 예정이므로, Git Repository를 참고해주기 바란다.

     


    6️⃣ FrontEnd (React)에서의 작업사항

    FrontEnd에서는 굉장히 간단한 작업이 된다.

     

    useMemo를 통해 사용할 Module을 선정한다. 이후 handlers에서 Image를 업로드하는 태그인 image의 함수를 제작해주면 작업이 완료된다.

     

    FormData로 Dto형식에 맞게 생성한 이후 받아온 Path를 InsertEmbed메소드를 통해 기록하면 된다.

    또한 useMemo를 통해 생성한 module를 ReactQuill에서는 당연히 참조를 해야한다.


    7️⃣ 결과물

    왼쪽의 이미지가 참조가 되지 않는 이유는 현재는 해당 Object Storage를 없앴기 떄문에 실제 업로드 기능을 BE에서 비활성화 해놓은 상황이다.

     

    실제 해당 경로에 올라가지 않았기 때문에 이미지를 못 불러 오는건 어쩔 수 없으며, 오른쪽의 경로를 자세히 봐주면 좋을 듯 하다.

     

    local~로 시작하면서 업로드한 Path 정보의 확인이 가능하다.

     

    위의 경우에는 작업이 완료된 이후의 src 속성의 값이며, 아래는 작업 전의 src 속성값이다.

    어떤것이 좋을 지는 게시물을 읽고있는 독자가 판단하면 좋을 듯 하다.


    8️⃣ 왜 이런 작업을 생각하게 되었나?

    필자의 프로젝트 컨셉에 들어가는 기능은 게시물의 자동번역이다.

     

    그러다 보니 저 바이트코드가 전부 번역기능(Papago)에 요청을 보낼 경우 문자열 한개로 인식을 하고 있었다.

    바이트코드의 길이가 수백자 수천자가 될 수 있는 상황인데, 이걸 전부 요청을 보내면 천문학적인 비용이 청부 될 수도 있겠다 생각하였다.

     

    또한 필자가 하던 생각이 맞다 보니 더 심각하게 해당 이슈를 바라 볼 수밖에 없었다.


    9️⃣ 글을 마치며

    파일 업로드를 Spring으로 제작한 선례의 자료가 찾기 힘들었다. (그냥 없었다 수준인듯..?)

     

    Image Handler를 컨트롤하는 방법만 알면 어렵진 않겠다 생각이 들었고, Next등으로 만든걸 올려준 사람이 많다보니 쉽게 할 수 있었다.

     

    항상 하는 생각이지만, 제작하면서 더 깊이 들은 생각은 "언어는 그냥 도구일 뿐이고, 어떤 언어든 실행로직을 이해하면 다른 언어로도 어느 정도는 구현할 줄 알아야 한다" 였다. (진짜로 불가능하거나 너무 효율이 안좋은 경우도 있겠지만 말이다.)

     

    실제 Reference에 기록을 해뒀지만, Quill의 ImageHandler를 어떻게 컨트롤 할 수 있는지 참조만하고 작업을 하였으니 말이다.

     

    ※ 진짜 작성하기 가장 무서웠던 글의 작성을 드디어 끝냈다... 내용이 많아서 언제하지 하면서 겁을 내고있었다.


    🔟 참고한 Reference

     

    Quill 에디터 - 이미지 처리하기

    깃허브에 작성한 ReadMe를 블로그로 옮겨왔다.(형식은 조금 수정..) 요새 너무 바빠서 글을 못올려서..^^ 팀 프로젝트에서 Quill 에디터를 사용했는 데, 이미지 업로드에 고생을 좀 해서 정리해봤다.

    12ahn22.tistory.com

     

    728x90
    Comments