에디터의 데이터를 어떻게 저장해야 할지 걱정이었다.
에디터의 값을 받아보니 왠걸 태그까지 같이 저장해주고 있었다.
이걸로 어떻게 검색 기능을 넣지?라는 생각이 들었고 챗 지피티와 구글링을 열심히 했다.
챗 지피티에서는 (비록 좀 부실해보이지만) 해결방법은 있다는 것에 안도감을 느꼈고, 그로 인해 차분히 서칭할 수 있었다.
서칭하면서 구글링 해서 나온 issue 탭에 나와 비슷한 고민을 가진 사람들이 이미 적어둔 해결책을 보고 이 react-quill이라는 에디터의 데이터를 저장하기 위해서는 에디터에서 만들어둔 방법이 따로 없다는 것을 알았다. (이걸로 라이브러리 쓰다 바꾸는 유저들도 있더라) 하지만 에디터의 내장된 메서드인 delta라는 객체와 태그로된 문자열을 함께 저장하기를 추천했다. delta for editor, html for rendering이 최선의 아이디어 였다.
나는 이에 더해 나의 아이디어를 덧붙였다. 저렇게 저장하기에는 검색할 때 성능이 더딜 것 같다는 생각이 들었고 계속 시도해보니 에디터가 꼭 delta로만 렌더링 되지 않고 html 문자열로도 렌더링 되는 것을 알 수 있었다. 직접 넣어봐서 알 수 있었다. 덕분에 조금이라도 성능을 개선하기 위해 나는 글을 그대로 저장하는 문자열(\n이 들어가긴 한다)과 렌더링을 위한 html 문자열을 저장해두기로 했다.
이렇게 하기까지 많은 시간과 용기와 인내가 필요했다. 여기까지 하고도 나는 db에 잘 연결할 수 있을지 걱정했는데 생각보다 간단히 수정되어서 좋았다.
매번 걱정하는데 실제로 발을 넣어보면 그렇게 무서운 건 아닌 것 같다.
그냥 찾아보고 해보는 게 좋을 것 같다. 너무 두려워 하지말자.
그리고 앞으로도 issue탭을 먼저 활용하면 더 빨리 해결할 수 있을 것 같다. (챗 지피티는 간단한/직관적인 문제 해결 정도에 도움 되는 듯)
구현해야 될 것들은 많은데 예기치 못한 버그들이 자꾸만 생기고 생각보다 시간을 많이 쏟게 된다.
가급적 내가 혼자 해결해보고자 최소 3시간 이상은 찾아보는데 제자리 걸음 하는 것 같다고 느낄 때, 어떻게 해야될까.
시간은 없는데 버그는 계속 생긴다. 나는 이럴 때 멘토님이나 사수분한테 물어보는 게 맞을까. 토이 프로젝트만 그렇게 하면 되는 걸까?
잘 모르겠다. 일단 너무 오래 끌던 문제 3가지는 멘토님께 도움 요청을 드렸다.
지금 시간이 없는 것 같아 마음이 자꾸 조급해지는 것 같다. 일단 나홀로 생각이 많아지는 것 같아 상황을 알린 점은 괜찮은 것 같다. 답을 듣고 다시 생각해보자.
하면 시간가는 줄 모르고 한다. 적으면 1시간 길면 3시간 쭉 자리에 앉아 코딩 할 수 있다.
집중력에는 1시간 반~2시간이 베스트인 것 같다. (3시간은 좀 무리한 느낌)
집에가서도 생각한다. 어떻게 해결할 수 있을까? 근데 너무 안풀리는 버그면 고통스러움을 느낀다. 적당히 해결할 수 있는 것이나 조금이라도 해결되는 것이 가장 좋다. 계속 발전하는 느낌이라서.
코딩을 좋아해서 다행이다.
다만 이론 공부할 때, 흐트러지는 마음을 잘 잡는 것이 중요할 것 같다. 이론을 기반으로 코딩하는 것이라고 들었으니까 (멘토님 왈). 앞으로 이론공부와 코딩의 밸런스를 잘 맞추는 게 중요할 것 같다. 아니, 멘토님이 말해주셨던 3가지 분야에 대한 밸런스를 잘 맞추는 게 더 중요하겠지.
드디어 ReferenceError: document is not defined
에러를 해결했다.
해결 방법은 어이 없게도 nextjs 13과 상관 없이 2020년도에 올라온 한 블로그 글을 참고해서 해결할 수 있었다. (늘 그렇듯 이게 마지막으로 보는 레퍼런스이길 바라면서 들춰봤다.)
그냥 너무나 기본적인 dynamic import를 하고 ssr: false를 해주는 것이였다.
내가 그 레퍼런스를 참고하게끔 만든 문구는 아래와 같다.
This way your component won't even be rendered on the server-side at all.
전에 react-quill과 document is not defined
을 봤을 때, dynamic import는 무수히 봤고 비슷하게 시도도 해본 것 같은데 왜 그 땐 틀렸고 지금은 맞았을까?
아마 멘토님이 써준 글을 보고 차분히 그리고 골똘히 생각해본 것 같다. 그리고 몇 일 뒤에 다시 본 것이기 때문에 리프레시도 분명 되어있었을 것이다.
멘토님이 적어두신 리뷰
버그 1. (ReferenceError: document is not defined)
무지성 검색보다는 왜 이런 에러가 나는지, 그 원인을 알고 원인을 해결해야해요.
이 에러는 next가 빌드할 때 node 환경에서 빌드하기에 window.document 객체가 없어서 발생하는 에러에요.
react-quill 라이브러리 내부에서 document 객체에 접근하는 코드가 있는 것 같다고 추측할 수 있을 것 같아요.
따라서 window객체가 없다면(node 환경이라면) react-quill을 임포트 하는 컴포넌트를 렌더링하지 않도록 하면 문제가 해결될꺼에요.
이 리뷰를 처음 봤을 때는 이 문제를 해결하기 위해 많은 시간을 애쓰며 이 에러와 react-quill과 관련된 모든 레퍼런스를 들춰보고 시도해봤기에 무지성이라는 단어에 내심 속상하기도 했다.
그런데 지금 생각해보면 얼핏 맞는 말인 것 같기도 하다. 단지 좀 직설적이였을 뿐. 내가 에러를 스스로 찾는 습관이 능숙하지 않기 때문에 그냥 무작정 전에 개선했던 방법으로 시도 해봤다. 에러 문구와 관련 라이브러리를 열심히 검색을 해보았지만 원인을 몰랐기에 아쉬운 결과를 맞이했던 것 같다.
하지만 근본적으로 이 에러가 왜 났는지는 이해하지 못했다. (근데 한 편으로는 이런 생각을 어떻게 하지? 라는 생각도 든다. 하지만 해야 겠지?) 이해할 필요성이 있다는 것 조차 인지하지 못했다. 시간에 쫓겨 급급해 했다. 하지만 읽었던 레퍼런스들에는 스치듯 계속 document가 없다고 말했던 것 같다. 그 때 원인들을 캐치 했었으면 좋았을 것 같다. document가 없기 때문이구나 하고.
nextjs가 빌드 시, node환경에서 빌드한다는 것을 인지하거나 찾아내는 건 조금 난이도가 있었던 부분이었던 것 같다. 하지만 다음부터는 이런 부분들을 좀 더 찾아보고 근본 원인을 파악한 후에 해결하려고 하면 좋을 것 같다.
멘토님이 쓰신 에러 원인을 토대로 생각하며 찾아보니 결국 이전에 봤던 레퍼런스들과 비슷한 방법으로 해결해낼 수 있었다. 이번 트러블 슈팅이 앞으로 스스로 문제 해결을 하는 데 있어 적절한 방법을 깨닫는 새로운 자양분이 될 것 같다. 그리고 중간 중간 다른 걸 하면서 머리를 리프레시 하는 것도 많은 도움이 되는 것 같다.
어려웠던 부분은 아래의 코드였다.
// 제작하는 함수
export const convertModules = (
quillRef: MutableRefObject<ReactQuill | undefined>,
) => ({
toolbar: {
...생략
handlers: {
image: imageHandler(quillRef), // 1안
image: () => imageHandler(quillRef), // 2안
},
},
...생략
})
// 사용처
const modules = useMemo(() => convertModules(quillRef), [])
1안으로 하면 화면을 딱 띄우자 마자 imageHandler가 2번 실행 되는 것 같고
2안으로 하면 이미지 아이콘을 실행할 때마다 imageHandler가 실행되었다.
제가 원하는대로 동작하는 것은 2안인데, 왜 서로 다르게 동작하는지 이해를 하지 못했었다.
아직 확실하지는 않으나 주변 개발자에게도 물어보고 chatGPT한테도 물어본 결과, convertModules함수의 handlers.image()는 렌더링과 함께 즉시 실행이 되며 (2번 되는데 이 또한 strict mode를 원인으로 보고 있다.) 2안의 경우 익명함수로 한 번 감쌌지만 1안의 경우에는 함수가 바로 실행이 되어서 그 결괏값을 보여주게 된다고 판단했다.
조금 헤맸던 부분인데 익명함수에 대해서도 리마인드 하고 strict mode도 아주 오래전 봤던 것 같은데 리마인드 할 수 있는 시간이였다.
벨로그를 많이 참고 하면서 벨로그처럼 글 작성 시, 네비게이션 바를 없애고 싶었다.
하지만 도저히 전역적으로 사용되는 네비게이션 바를 어떻게 없애는 게 적절한지 모르겠어서 그냥 유지하기로 했다.
왜냐면 네비게이션 바가 있으나 없으나 기능 상 차이는 크게 없기 때문이다.
이를 위해 zustand 도입도 고민했으나 Provider 위에 상태를 끌어와야 할 것 같아서 이것도 의미 없는 방법이라고 생각되어 접었다.
지금 생각해보면 시간 관계상 잘한 선택 같다.
에디터 높이를 수정하려고 하는데 적절한 방법을 모르겠더라.
quill의 issue 탭에 들어가보니 내부의 class name을 통해서 조절하라고 하는 것 같은데 그렇게 적용하려고 하니 style-lint 에러가 났다.
그리고 여전히 아래에 있던 버튼이 에디터랑 겹쳐 보이는 문제가 있었다.
해결 방법을 모색하다가 일단 개발자 도구로 들어가서 에디터의 height를 조절해보고 display 문제 인 것 같아서 display를 하나씩 쭉 적용해보니 잘 적용되는 속성을 발견할 수 있었다. (inline-block)
그래서 그 방법으로 해결할 수 있었고 안도할 수 있었다.
끝까지 포기 하지 않고 해결한 나 칭찬해주고 싶다 👏