
LMIM 프로젝트에서 내가 진행했던 프로젝트를 작성하는데 이미지 업로드 구현이 필요했다.
우선 위지윅 에디터 가 필요했는데, 마크다운을 지원했으면 하는 마음에 여러 에디터들을 찾아봤다.
1. Ckeditor5
2. ToastEditor
3. Draft
4. TinyMouse
각각의 장단점이 있는데 결국엔 ToastEditor를 선택해서 사용하게 되었다.
처음엔 정말 많은 기능을 탑재한 Ckeditor5를 사용하려고 했는데, 툴바를 커스터마이징 하기 위해서는 webpack 을 다루거나, React 를 eject 하여 작업해야만 했다.
webpack 의 경우에는 지금 공부하고 다루기에는 양이 방대하기도 하고 난이도가 있어서 프로젝트 일정에 차질이 생길 것 같아 배제하였고, React eject를 하는 것은 한번 차출하게된다면 되돌릴 수 없기에 참았다, 물론 우회하는 방법인 craco등 라이브러리를 사용해보았지만, React v 18 로 넘어오면서 그마저도 정상적으로 작동하지 않았다.
그래서 차선으로 ToastEditor를 선택했다.
선택하게 된 이유로는
1. 자체적으로 한글을 지원한다. (개발사가 국내 기업인 NHN)
2. 위지윅, 마크다운을 전부 지원한다.
3. 이미지 업로드가 가능하다.
이러한 이유가 있다.
이미지를 상세하게 편집하기 위해서는 커스터마이징이 필요한데, 이 또한 간편해서 차후에 해볼만하다는 생각이 들었다.
<Editor
initialValue={defaultContent || ""}
placeholder="내용을 입력해주세요."
previewStyle="vertical"
height="600px"
initialEditType="wysiwyg"
useCommandShortcut={true}
language="ko"
ref={editorRef}
onChange={() => {
onchange();
}}
hooks={{
addImageBlobHook: async (blob, callback) => {
try {
const imageData = new FormData();
const file = new File([blob], encodeURI(blob.name), {
type: blob.type,
});
imageData.append("image", file);
const imageURI = await axios({
method: "POST",
headers: {
"Content-Type": "multipart/form-data",
},
url: `${process.env.REACT_APP_SERVER_URL}/api/v1/image/upload`,
data: imageData,
withCredentials: true,
});
callback(
`${
process.env.REACT_APP_SERVER_URL
}/api/v1/image/${encodeURIComponent(imageURI.data.fileName)}`,
"image"
);
} catch (error) {
console.log(error);
}
},
}}
/>
이미지 업로드까지 포함한 에디터와 관련된 전체 코드이다.
에디터를 여러곳에서 사용하게 될거니까 ( 글 작성, 수정, 댓글 ) 컴포넌트로 따로 만들고, 수정 시에는 기본값이 필요하니 defaultContent를 기본 내용으로 하되 수정이 아니라면 비어있도록 하였다.
이미지 업로드 또한 매우 간편하게 지원했던 것이,
Editor -> hook -> addImageBlobHook 이라는 메소드가 있는데, 이미지 첨부 시 blob 형태로 이미지의 정보를 받아온다.
이 받아온 정보를 토대로 처음에는 blob을 그대로 서버로 넘겨서 처리했는데 그렇게 하게 되면
이미지 한개당 약 1만줄 이상의 base64 문자열을 필요로 하기에 너무나도 비효율적이었다. 그래서 다른 방법을 찾다보니, blob을 기반으로 File 객체를 만들어서 서버로 전달하면 된다기에
const imageData = new FormData();
const file = new File([blob], encodeURI(blob.name), {
type: blob.type,
});
이런 형태의 FormData 를 만들어서 서버로 전달 했다,
특이한게 파일 객체를 생성하는 new File() 을 사용할때 blob객체에 저장된 파일이름을 그대로 사용하여 서버에 파일 객체를 전달하니, 서버측에서는 한글이 전부 깨지는 대참사가 일어났다.
그래서 어떻게 해야 안깨질까라는 우선 흔히 쓰는 UTF-8로 바꿔보자는 생각으로 구글링을 또 열심히 해보니 자바스크립트 내장 메소드인
encodeURI(string): string
encodeURI 를 사용하면 UTF-8로 변환해준다고 하길래 라이브러리도 안써도 되고 아주 좋군 싶어서 바로 적용해보니 서버에서도 아주 잘 받더라~ 했다.
하지만 여기서 꼭 해야 할 것은
encode를 했다면 decode를 해야한다는것!
decode를 깜빡해서 파일명이 전부 UTF-8로 저장 되었다.
다시 다날리고 서버측의 multer 설정에서 파일명을 decode 하여 저장 하였다.
막힌부분
1. ckeditor5 커스터마이징 -> 해결 못함.
2. toastUI 이미지 업로드시 blob 형태만을 지원하여 용량이 너무 크다. -> blob 을 가지고 File 객체를 만들어서 서버로 전달
3. 파일명 깨짐 -> encodeURI() 를 이용하여 utf-8로 전환
4. 파일명이 UTF-8로 저장됨 -> decodeURI() 를 이용하여 다시 한글로 변환
더 나아가며 생각해볼 문제
1. 이미지 파일 크기가 너무 크다.
구글 크롬에서 지원해주는 Light-house를 돌려서 성능을 테스트 해봤는데,
죄다 이미지에 관련된 문제를 제시했다..
성능면에서 40 / 100 점을 받았다..
나머지는 90점대인데 비해 문제가 심각하다는 생각이 들어
이미지 압축에 관해 알아보고 처리하려한다.
2. 이미지 크기 조절이 불가능한걸 해결해보고자 한다.
이미지를 업로드하는것 자체는 매우 이지하게 해결했지만, 그 이미지를 사용자가 커스텀할수가 없는 단점을 갖고 있었다.
ckeditor5를 사용하려던 이유중에 하나에 이것이 있었는데,, 커스텀이 너무 힘드니 어쩔 수 없지 뭐,,
아무튼 해결해보고자 한다.
3. 프로젝트 시연 영상을 유튜브에 업로드하고 그 영상을 미디어 임베디드 형식으로 글쓸때 같이 업로드 하고자 한다.
하지만 toastEditor에서는 이 것을 지원하지 않아 따로 커스텀이 필요하다 이것도 해보고자한다.
까먹기 전에 얼른 적어보자 싶어서 두서없이 썼다.
'B4 Junior' 카테고리의 다른 글
📁 File Upload to AWS S3 with multer-s3 Library (0) | 2023.01.07 |
---|---|
Image compress, Format convert with Sharp Library (0) | 2023.01.03 |
벱-영오-프로젝트 투 회고 📝 (0) | 2022.08.31 |
BEB 5기 첫 프로젝트 회고 🧐 (0) | 2022.08.16 |
코드스테이츠 블록체인 과정 27일 ~ 32일차 후기 💻 (0) | 2022.06.16 |
백엔드는 못말려
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!