Quill + Hightlight 적용하기
Quill이란?
Quill은 텍스트 에디터로, 줄바꿈, 글꼴, 글자색, 사진, 영상을 쉽게 적용할 수 있습니다.
기존에 <textarea>
가 존재하고 있지만, 서비스에서 '리마인더'를 생성할 때 단순 텍스트에서부터 사진, 코드블럭까지 같이 제공하는 것이 좋겠다고 판단해 도입하였습니다.
1. Quill 설치하기
- 우선 패키지를 설치합니다.
pnpm add react-quill
- 패키지 설치가 끝나면, 에디터를 사용하는 페이지에 quill style을 임포트합니다.
import 'react-quill/dist/quill.snow.css';
2. Quill을 dynamic하게 가져오기
- Quill은 SSR 지원이 되지 않기 때문에 단순히 import를 하게 되면
document is not defined
에러가 발생합니다.
document가 정의되기 전에 react-quill이 로드되고, 정의되지 않은 document를 조작하려고 해서 발생하는 에러입니다.
- 그래서 Next에서 지원하는
dynamic import()
을 사용해 모듈을 동적으로 import합니다.
dynamic import를 통해 런타임시 필요한 module을 import하는데, 이를 게으른 로딩(lazy-load)이라고 합니다.
{ssr: false}
로 세팅해 임포트하는QuillWrapper
컴포넌트를 생성한 후, 해당 컴포넌트를 사용할 때는 아래와 같이 커스터마이징합니다.
export const QuillWrapper = dynamic(() => import('react-quill'), {
ssr: false,
loading: () => (
<div className='flex justify-center py-10 items-center gap-4'>
<Spinner />
<p>로딩 중...</p>
</div>
),
});
export default function CreateReminder () {
return <QuillWrapper theme='snow' />
}
3. hightlight.js
와 함께 코드 블록 기능 추가하기
hightlight.js란, 코드를 감지하여 코드를 읽기 쉽도록 도와주는 라이브러리입니다.
(1) hightlight.js 설치하기
- 우선 패키지를 설치합니다.
pnpm add highlight.js
(2) highlight를 적용시키고 싶은 언어를 선택하기
import hljs from 'highlight.js';
hljs.configure({ languages: ['javascript', 'python', 'typescript'] });
(3) Quill에 전달할 module 파일 생성하기
- syntax에서
hljs.highlightAuto(text)
을 통해, 자동으로 언어를 감지해 그에 맞는 css를 적용합니다. - toolbar에 'code-block' 버튼을 클릭합니다.
import 'highlight.js/styles/monokai.css';
export const editorModule = {
syntax: {
highlight: (text: string) => hljs.highlightAuto(text).value,
},
toolbar: [
[{ header: [1, 2, false] }],
['bold', 'italic', 'underline'],
[{ list: 'ordered' }, { list: 'bullet' }],
['link', 'image', 'code-block'],
],
};
(4) Quill + Hightlight 적용 확인하기
- Quill 에디터를 사용하고자 하는 페이지에 아래와 같이 컴포넌트를 불러옵니다.
'use client';
import { editorModule, QuillWrapper } from '@/components/QuillWrapper';
export default function CreateReminder() {
return (
<QuillWrapper theme='snow' modules={editorModule} />
);
}
- 이렇게 작성된 코드는 아래와 같이 잘 적용된 것을 확인할 수 있습니다.