Tiptap Editor - Headless WYSIWG 에디터
(github.com/ueberdosis)- UI를 제공하지 않는 Headless 프레임워크로 스타일링에 유리함
- React, Vue, Svelte, Alpine.js, Next.js, Nuxt.js, 바닐라 JS와 아주 잘 작동함
- ProseMirror 기반
개인적으로 써본중에 제일 편하고 확장하기 쉽게 구성되어있던 것 같아요.
Slate 로 에디터를 만들다가 느꼈던 불편함들이 여기서 정말 많이 해결되었습니다.
혹시 Slate 에디터 사용하셨을 때 불편함이 어떤 게 있었을지 공유해 주실 수 있을까요?
저는 Tiptap만 써봤는데, Slate가 괜찮다는 얘기 들어서 관심이 생긴 상태라서요!!
외부 컴포넌트 만드는 부분이 훨씬 편리합니다. 특히 react 같이 자체 dom 을 사용할 경우, html 이 아닌 컴포넌트로서의 렌더가 필요한데 애초에 모듈화를 고려해서 만든 tiptap이 고치기 더 편하더라고요.
전반적으로 Slate 문서가 어렵다고 느껴졌고, 너무 raw 해서 제가 원하는 기능을 구현하기에 배워야할 부분이 더 많다고 느꼈습니다.
2년 전 쯤의 기억이라 조금 다를 수 있는데 이런 문제들을 겪었어요.
- 모바일 환경에서 한글입력 문제: 이건 어디서 발생한지 찾기가 너무 어려웠는데, 커스텀하다가 발생해서 정확히 기억이 안나네요.
- select 관련 컨트롤 어려움: 선택된 문자들에 속성을 처리하는 기능을 추가하는데 굉장히 까다로웠습니다. (객체 자체가 복잡함)
- 플러그인 개발의 어려움: 지도 등의 플러그인을 직접 개발하려했는데, tiptap 이 플러그인을 추가개발하기 좋게 구성되어서 편했습니다.
https://tiptap.dev/docs/editor/installation/react#7-the-complete-setup 에서 작동하는 에디터 예시를 확인할 수 있습니다.
개인적으로 문서화가 꽤 잘 되어있다고 생각합니다만, 유료 구독이 필요한 요소들이 중간에 섞여있습니다.
문서를 읽는데 불편함을 주는 정도는 아니지만, 필요도 없는데 뽐뿌 오게 만들어 대단하기도 하고 얄밉기도 하고.. 복잡미묘하네요.
문서화가 나름 잘 되어있다고 하시는 말에 동의하기가 어렵습니다. 제가 느끼기에는 시작하기 문서와 API 문서 사이에 간극이 너무 커서 학습 곡선이 높습니다. 저희가 진행하는 리액트 프로젝트에서는 Prosemirror와 react-prosemirror 의 문서화 스타일이 좀더 사용자 친화적이고 완성도 있다고 판단해서, react-prosemirror를 선택하고 tiptap을 선택하지 않았습니다.
저희의 요구사항에 대한 poc용 샘플코드를 만들기 위해 리액트 예제를 파악하는 동안 다음과 같은 문제가 있었습니다.
- StarterKit을 추가했을 때 사용 가능한 요소는 무엇일까요? 패키지 이름으로 별도 문서를 찾아야 합니다. tiptap 예제를 실행해보던 집중상태에서 벗어나게 됩니다.
- ListItem은 StarterKit에 포함되어 있는데 예제에서는 왜 또 ListItem을 프로젝트에 포함시킨걸까요? extension에 대한 환경설정을 하기 위해서 입니다.
- 왜 editor().chain().focus() 같은 구문을 써야 하나요? 메소드 체이닝에 대한 설계 원리나 설명이 없습니다
- Bubble menu와 Floating menu는 리액트 예제에 빠져있습니다. Try it live 페이지 (https://templates.tiptap.dev/pjrwkQtNpq)에서 본 기능과 다르게 동작하므로 왜 기능이 빠져있는지 문서를 살펴봐야 합니다.
- 표 기능이 없어서 Extensions 페이지에서 table 키워드로 검색을 합니다. Table, TableCell, TableHeader, TableRow 가 검색결과에 나옵니다. 이것들을 다 추가해야 할까요?
- Table과 갖가지 extension을 어찌저찌 추가했습니다. 기능이 제대로 동작하는지 알아보려면 표 삽입부터 해야 합니다. 툴바 커맨드는 어떻게 작성해야 하나요? editor 툴바의 어디에 해당 커맨드들에 대한 함수가 추가될까요? 전혀 힌트가 없습니다
- 표 안에 다른 표를 중첩시키지 못해야 한다는 요구사항이 있습니다. 커서가 표 안에 있는지 판단하는 로직은 어떻게 구현해야 할까요? 전혀 힌트가 없습니다.
- Color가 extension으로 패키징되어 있던 것을 기억하고 궁금증이 생겨 소스코드를 열어봅니다. src 디렉토리에 파일이 단 두 개 있는 것을 보고 탄식이 나옵니다. 왜 이렇게 자잘한 모듈을 만들었는지 의도를 이해할 수 없습니다. 이렇게 작은 기능도 패키지로 만들면 재사용성보다는 의존성 버전 관리에 부담이 있지 않을까요?
1-3, 4-6, 8은 의문이나 불편함을 전혀 느끼지 못해 저는 동의하기 어렵네요.
1-2
StarterKit은 말그대로 Starter를 위한 Kit인 만큼, 실사용 시점에는 별 의미가 없어보입니다.
ListItem의 경우 말씀하신대로요. Color 익스텐션의 설정을 위한 요소입니다. 마찬가지로 StarterKit을 사용하지 않으면 그만인 부분이라고 생각해요.
3
chain().something().run() 은 단순 신택스 슈거와 같은 존재지만, 배터리 포함 라이브러리의 컨셉에 알맞는 기능을 제공한다고 생각합니다.
볼드 후 포커스 같은 액션이 사실상 필수인 모바일 환경에서 아주 유용하게 쓰고 있습니다.
4
해당 기능을 사용하지 않아 잘 모르겠네요.
(내가 사용하지 않을 기능에 대한 정보를 굳이 보지 않아도 된다는 점에서 1번의 집중상태에서 벗어나게 된다고 언급하신 단점의 반대급부로 오는 장점이라고 생각합니다.)
5-6
각 익스텐션의 문서에 잘 나와있을 뿐더러, 일반적으로 에디터를 구현하는 것과 다를게 전혀 없습니다.
솔직히 6번에서 말씀하신 부분은 제가 savvykang님의 말씀을 제대로 이해한게 맞는지도 잘 모르겠습니다... '이게 왜 의문이지...? 대체 어떤 힌트가 필요한거지...?' 라는 생각이 계속 드네요ㅎㅎ...
7
"다른 노드들의 것과 같이" editor.isActive('table') 으로 포커스를 확인할 수 있습니다.
다만, 단순히 포커스 노드만 파악한다고 해결될 문제가 아닌거 같아요. 붙여넣기에 대한 필터링, 개발자도구를 통한 삽입 등 많은 부분을 고려해야 하는 요구사항인 것 같습니다.
8
의존성 버전 관리에 부담이 된다는 부분에는 동의합니다만, 필요하지 않은 기능의 코드를 가지고 있지 않아도 된다는 점에서 장점을 가져가는 부분이라고 생각합니다.
딱 저희 케이스에서 언급하신 Color 익스텐션을 사용하지 않을 상황이었거든요. 각자의 장단점이 있는 것 같습니다.
.
언급하신 react-prosemirror와 tiptap은 컨셉이 완전히 다른 친구라고 생각합니다.
prosemirror를 리액트스럽게 쓸 수 있게 하는 친구
vs
prosemirror 기반인지 아닌지는 중요하지 않고, 아무튼 내 서비스에 어울리는 에디터를 구현하는데 필요한 것들을 몽땅 모아둔 친구