ปี 2025 ควรเลือกเฟรมเวิร์กตัวไหนสำหรับ Rich Text Editor?
(liveblocks.io)- ตัวแก้ไขข้อความแบบ Rich Text (WYSIWYG) ซึ่งเป็นสิ่งจำเป็นในแอปสมัยนี้ ถูกใช้อย่างแพร่หลายในบริการอย่าง Linear, Notion และ Google Docs
- ตลอด 1 ปีที่ผ่านมา Liveblocks ได้วิเคราะห์ตัวแก้ไขยอดนิยมหลายตัว พร้อมสรุปข้อดีข้อเสียของแต่ละตัวไว้
- โดยทั่วไปตัวแก้ไขแบ่งได้เป็น 2 กลุ่ม คือแบบ “core” และแบบ “battery-included” ที่มีฟีเจอร์มาให้พร้อม
- ถ้าต้องการเพียงตัวแก้ไขแบบเรียบง่าย ตัวเลือกที่เบากว่าจะเหมาะกว่า แต่ถ้าจะสร้างตัวแก้ไขที่ซับซ้อนและมีฟีเจอร์ด้านการทำงานร่วมกันมาก ควรพิจารณาตัวที่ขยายต่อได้สูง
- โดยรวมแล้ว ตัวเลือกที่ปลอดภัยที่สุดคือ Tiptap ซึ่งถูกประเมินว่ามีความสมดุลระหว่างฟีเจอร์ที่ครบถ้วนกับความไม่ยัดเยียดแนวทางเกินไป
- การทำงานร่วมกัน
- เรา (Liveblocks) มุ่งเน้นด้านฟีเจอร์การทำงานร่วมกันมาโดยตลอด และในตัวแก้ไขส่วนใหญ่สามารถทำงานร่วมกันแบบเรียลไทม์ได้ผ่านไลบรารี CRDT ชื่อ Yjs
- เมื่อใช้ Yjs จำเป็นต้องมีบริการแบ็กเอนด์สำหรับจัดเก็บเอกสารและคงการเชื่อมต่อแบบเรียลไทม์ไว้
- Liveblocks มี general Yjs backend ที่ใช้งานได้กับหลายตัวแก้ไขที่รองรับ Yjs และยังมีโซลูชันแบบรวมสำหรับ Tiptap และ Lexical ด้วย
- ตัวแก้ไขบางตัวใช้โซลูชันของตัวเองที่อิง OT (Operational Transform) หรือใช้บริการคลาวด์แบบ closed-source
- ข้อควรระวังก่อนเริ่ม
- บทความนี้ตัดตัวแก้ไขที่เลิกบำรุงรักษาแล้วอย่าง Draft.js, ตัวแก้ไขที่มีคอมมูนิตี้ขนาดเล็ก, หรือโปรแกรมแก้ไขแบบ private source (เช่น Froala) ออกไป
- เรื่องการเข้าถึง (a11y) ยังต้องลงมือทำเพิ่มไม่มากก็น้อยในตัวแก้ไขส่วนใหญ่ และควรอ้างอิงเอกสารของแต่ละตัวแก้ไข
Tiptap
- เป็นตัวแก้ไขที่ทำงานอยู่บน ProseMirror โดยช่วยซ่อนความซับซ้อนของ ProseMirror เพื่อให้ประสบการณ์นักพัฒนาดีขึ้น
- ส่วนใหญ่ให้ใช้งานภายใต้ไลเซนส์ MIT และสามารถใช้ฟีเจอร์การทำงานร่วมกันแบบเรียลไทม์ได้ทันทีผ่าน Tiptap Cloud หรือ Liveblocks
- แม้มีฟีเจอร์จำนวนมาก แต่โครงสร้างถูกออกแบบให้ tree-shaking ได้ ทำให้ขนาด core bundle เล็กกว่า Quill, Slate และ Lexical ได้
- การขยายความสามารถ
- Tiptap ถูกออกแบบมาให้เพิ่ม node, mark, command และ extension แบบง่าย ๆ ได้สะดวก
- หากจำเป็น ยังสามารถ override พฤติกรรมของ extension เดิมเพื่อปรับแต่งได้ตามต้องการ
- extension ระดับ “pro” บางส่วนมีให้ใช้งานแบบเสียเงิน
- การปรับแต่งขั้นสูง
- อาจมีกรณีที่ต้องจัดการกับโครงสร้างของ ProseMirror โดยตรง
- ต้องใช้เวลาทำความคุ้นเคยกับ abstraction เฉพาะของ Tiptap เช่น command chain อยู่บ้าง
- โมเดลข้อมูลเป็นแบบอิง schema โดยส่วนใหญ่จะสร้างให้อัตโนมัติ แต่ในฟีเจอร์ขั้นสูงอาจต้องจัดการ schema เอง
- ข้อจำกัด (Drawbacks)
- ต้องสลับอ้างอิงเอกสารของ ProseMirror และ Tiptap ไปมา จนอาจทำให้แนวทางใช้งานสับสนได้
- เนื้อหาเกี่ยวกับการเข้าถึง (a11y) ยังพึ่งพาผู้พัฒนาในการลงมือทำค่อนข้างมาก
- หากมีการวนตรวจสถานะเอกสารโดยไม่จำเป็นระหว่าง transaction อาจทำให้ประสิทธิภาพลดลง
- การเปลี่ยนแปลงฝั่งเซิร์ฟเวอร์
- การจัดการเอกสารฝั่งเซิร์ฟเวอร์ด้วย Tiptap เพียงอย่างเดียวทำได้ไม่ง่ายนัก
- ควรพิจารณาใช้ ProseMirror โดยตรงหรือแก้ไขเอกสาร JSON โดยตรงแทน
- Liveblocks มีไลบรารีที่ช่วยให้แก้ไขเอกสาร ProseMirror ได้ง่ายขึ้น
- การทำงานร่วมกันแบบเรียลไทม์
- Tiptap มี extension สำหรับการทำงานร่วมกันแบบเรียลไทม์ด้วย Yjs
- สามารถเชื่อมต่อกับโซลูชันคลาวด์ได้หลายแบบ เช่น Tiptap Cloud และ Liveblocks
- Liveblocks Text Editor ยังเพิ่มฟีเจอร์อื่นนอกจากการทำงานร่วมกันแบบเรียลไทม์ เช่น การแสดงเคอร์เซอร์ คอมเมนต์ เมนชัน และประวัติเวอร์ชัน
- ข้อดี (Pros)
- เอกสารประกอบยอดเยี่ยม
- มีฟีเจอร์การทำงานร่วมกันแบบเรียลไทม์ที่ดีมาก
- ไม่ยึดติดกับเฟรมเวิร์ก และมีแพ็กเกจสำหรับ React โดยเฉพาะ
- ขยายต่อได้สูง
- เชื่อมต่อกับ Liveblocks หรือ Tiptap Cloud ได้
- ข้อเสีย (Cons)
- หากไม่ใช้งานตามแนวทางที่เหมาะสมที่สุด อาจเกิดปัญหาด้านประสิทธิภาพ
- การพัฒนาฟีเจอร์ขั้นสูงจำเป็นต้องเรียนรู้โครงสร้างภายในของ ProseMirror
- โดยพื้นฐานแล้วขาดความสามารถด้านการแก้ไขแบบ headless ฝั่งเซิร์ฟเวอร์
BlockNote
- BlockNote เป็นตัวแก้ไขแบบบล็อกที่ต่อยอดจาก Tiptap และ ProseMirror โดยมีฟีเจอร์สไตล์ Notion
- โครงสร้างส่วนใหญ่พัฒนาบน React ทำให้ใช้งาน UI component จากเฟรมเวิร์กอื่นได้ยาก
- มีฟีเจอร์ที่จำเป็นอย่าง Slash menu และ floating toolbar รวมมาให้แล้ว จึงนำไปใช้ได้สะดวก
- ข้อจำกัด
- แม้ BlockNote เองจะเป็นโอเพนซอร์ส แต่ฟีเจอร์บางอย่าง เช่น docx และ PDF exporter ต้องใช้การสมัครใช้งานแบบเสียเงิน
- การทำงานร่วมกันแบบเรียลไทม์
- รองรับฟีเจอร์การทำงานร่วมกันบนพื้นฐานของ Yjs และ Liveblocks
- มีแผนจะรองรับการเชื่อมต่อ Liveblocks อย่างเป็นทางการในเร็ว ๆ นี้
- ข้อดี
- สร้างบนพื้นฐาน Tiptap และ ProseMirror ที่ผ่านการพิสูจน์ความเสถียรแล้ว
- มีฟีเจอร์การทำงานร่วมกันแบบเรียลไทม์ด้วย Yjs และ Liveblocks
- มีทั้ง API และ UI component สำหรับการแก้ไขแบบบล็อกมาให้โดยค่าเริ่มต้น
- ข้อเสีย
- ออกแบบมาสำหรับ React เป็นหลัก
- ขนาด bundle ใหญ่กว่าตัวแก้ไขพื้นฐานทั่วไป
Lexical
- เป็นตัวแก้ไขที่ได้รับการสนับสนุนจาก Facebook (Meta) และกำลังได้รับความสนใจอย่างมาก
- จากการที่ Liveblocks พัฒนา extension อย่างคอมเมนต์ เมนชัน ประวัติเวอร์ชัน และการทำงานร่วมกันแบบเรียลไทม์มาเป็นเวลาหลายเดือน ทำให้รู้สึกว่ายังอยู่ในช่วงเริ่มต้น
- ปัจจุบันยังเป็นเวอร์ชันต่ำกว่า 1.0 และมีการอัปเดตอย่างรวดเร็วอย่างต่อเนื่อง
- ข้อจำกัด
- ไม่มีฟีเจอร์ “pure decorations” ทำให้การทำฟีเจอร์อย่างการแสดงเคอร์เซอร์ต้องวาง DOM element แยกทับบนตัวแก้ไข
- การรองรับการทำงานร่วมกันด้วย Yjs ขั้นพื้นฐานยังเปราะบางกับ edge case อยู่
- มีปัญหาเรื่องการ hardcode ชื่อ root node ทำให้ใช้งานหลายตัวแก้ไขพร้อมกันในเอกสารเดียวได้ยาก
- การทำงานร่วมกันแบบเรียลไทม์
- หากไม่ใช้แพ็กเกจของ Liveblocks การทำระบบ collaboration บน Lexical มีความยากสูง
- ในตัวอย่างอย่าง StickyNotes จะเลี่ยงปัญหาโดยใช้หลาย root node และแยกเอกสารกับการเชื่อมต่อ socket ของแต่ละตัวออกจากกัน
- ด้วยความเร็วในการพัฒนาที่สูง ปัญหาต่าง ๆ จึงกำลังถูกแก้ไขอย่างต่อเนื่อง
- Lexical extension
- Lexical จัดการข้อมูลผ่านโครงสร้างลำดับชั้นของ node
- สามารถสร้าง node ของตัวเองได้โดยสืบทอดจาก core node type ทั้ง 4 แบบ
- สามารถเร่งการพัฒนาได้ผ่าน LexicalComposer และแพ็กเกจ @lexical/react ที่ออกแบบมาสำหรับ React โดยเฉพาะ
- สามารถใช้แพ็กเกจ @lexical/headless เพื่อรัน Lexical บนแบ็กเอนด์โดยไม่ต้องมี DOM
- การเปลี่ยนแปลงฝั่งเซิร์ฟเวอร์
- สามารถแก้ไขเอกสาร Lexical บนเซิร์ฟเวอร์ได้ และ Liveblocks ก็มีไลบรารีที่ช่วยให้เรื่องนี้ง่ายขึ้น
- ข้อดี
- รองรับฟีเจอร์การทำงานร่วมกันแบบเรียลไทม์ด้วย Yjs
- ไม่ยึดติดกับเฟรมเวิร์ก และมีแพ็กเกจสำหรับ React โดยเฉพาะ
- รองรับ Liveblocks ที่ผสานกับคอมเมนต์ เมนชัน และประวัติเวอร์ชัน
- มีการพัฒนาที่คึกคักมากและคอมมูนิตี้ขนาดใหญ่ โดยได้รับการสนับสนุนจาก Meta
- ข้อเสีย
- ฟีเจอร์การทำงานร่วมกันแบบเรียลไทม์ด้วย Yjs อาจมีบั๊กเล็กน้อย หากไม่ได้จัดการ edge case ด้วยตัวเอง
- ขาดฟีเจอร์ pure decorations และต้องใช้วิธีอ้อมผ่าน DOM สำหรับฟีเจอร์ขั้นสูง
- ขนาดของ core package ใหญ่กว่าเมื่อเทียบกับ Tiptap และ Slate
Slate
- เฟรมเวิร์กเอดิเตอร์ที่ปรับแต่งได้ ซึ่งถูกใช้งานโดย Discord, Grafana, Sanity.io, Slite และอีกหลายแห่ง
- Liveblocks เลือกใช้ Slate เป็นค่าเริ่มต้นสำหรับ comment composer ของตัวเอง
- โครงสร้างข้อมูลเรียบง่าย ควบคุมได้ทั้งหมด และนำไปใช้งานได้ทั่วไปนอกเหนือจาก React
- การขยาย Slate
- สามารถขยาย Slate ได้ผ่านตัวอย่างและเอกสารหลากหลายรูปแบบ
- ecosystem ของปลั๊กอินยังมีจำกัด แต่การพัฒนาเองก็ไม่ได้ยากมาก
- มีโปรเจกต์ชื่อ Plate ที่เป็นรูปแบบต่อยอดที่ขยายความสามารถมากขึ้น
- ข้อจำกัด
- มีขนาด bundle หนักกว่า Tiptap เล็กน้อย
- ฟีเจอร์ที่มีมาให้ในตัวค่อนข้างน้อย ทำให้มีส่วนที่ต้องพัฒนาเอง
- การทำงานร่วมกันแบบเรียลไทม์
- สามารถทำระบบร่วมแก้ไขเอกสารแบบเรียลไทม์ของ Slate ได้ด้วย slate-yjs, @liveblocks/yjs เป็นต้น
- ข้อดี
- รองรับเอกสารประกอบได้ดีเยี่ยม
- รองรับฟีเจอร์การทำงานร่วมกันแบบเรียลไทม์ด้วย Yjs
- เป็นอิสระจากเฟรมเวิร์ก และมีแพ็กเกจเฉพาะสำหรับ React
- ขยายต่อได้สูง
- ข้อเสีย
- มีขนาด bundle ใหญ่กว่า Tiptap เล็กน้อย
- ฟีเจอร์ที่ให้มาโดยพื้นฐานยังไม่มาก
Quill
- เอดิเตอร์ที่เคยถูกใช้งานโดย Slack, LinkedIn, Figma, Zoom, Miro, Airtable และอีกหลายบริการ
- เคยมีช่วงที่การพัฒนาชะลอตัวไปพักหนึ่ง แต่กลับมาคึกคักอีกครั้งหลังออกเวอร์ชัน 2 ในเดือนเมษายน 2024 พร้อมการเขียนใหม่ด้วย TypeScript เป็นต้น
- ใช้โมเดลเอกสารเฉพาะของตัวเองชื่อ Parchment ซึ่งเป็นแนวคิดคล้ายกับ schema ของ ProseMirror
- ข้อจำกัด
- ไม่มีความสามารถด้าน pure decoration แบบ Lexical จึงต้องวาง DOM element ซ้อนทับแยกต่างหากหากต้องการฟีเจอร์อย่าง color highlight หรือ collaborative cursor
- ปลั๊กอินสำหรับ Quill 2 หลายตัวยังไม่ได้อัปเดต
- กิจกรรมของชุมชนอาจน้อยกว่าเอดิเตอร์ตัวอื่นเล็กน้อย
- การทำงานร่วมกันแบบเรียลไทม์
- สามารถทำงานร่วมกันแบบเรียลไทม์ได้โดยผสาน Yjs กับ y-quill
- ส่วน backend สามารถเลือกใช้ได้หลายแบบ เช่น Liveblocks
- ข้อดี
- รองรับเอกสารประกอบได้ดีเยี่ยม
- เป็นอิสระจากเฟรมเวิร์ก และมีแพ็กเกจเฉพาะสำหรับ React
- รองรับฟีเจอร์การทำงานร่วมกันแบบเรียลไทม์ด้วย Yjs
- ใช้ฟอร์แมต delta ที่เรียบง่าย
- ข้อเสีย
- ฟีเจอร์ที่มีมาให้ในตัวไม่มาก และปลั๊กอินจำนวนมากยังไม่อัปเดตให้เข้ากับ Quill 2
- ขาดความสามารถด้าน pure decoration
- การพัฒนาอาจไม่คึกคักมากนักและชุมชนมีขนาดเล็กกว่า
- มีขนาด bundle ใหญ่กว่า Tiptap หรือ Slate ประมาณสองเท่า
ProseMirror
- เฟรมเวิร์กหลักที่เป็นรากฐานให้เอดิเตอร์หลายตัว เช่น Tiptap, Remirror และ BlockNote
- มีโครงสร้างที่ชัดเจน เช่น schema, state, view, transform จึงช่วยให้การทำงานมีเสถียรภาพ
- หากต้องการสร้างเอดิเตอร์ขึ้นเองตั้งแต่ต้นโดยใช้แค่ core library โดยตรง ปริมาณโค้ดจะค่อนข้างมาก
- ข้อจำกัด
- มีการระบุไว้ในเอกสารชัดเจนว่า แม้จะสร้างเอดิเตอร์แบบง่ายก็ยังต้องใช้โค้ดค่อนข้างมาก
- แนะนำให้ใช้ wrapper ระดับสูงกว่าอย่าง Tiptap, Remirror หรือ BlockNote
- เส้นโค้งการเรียนรู้ค่อนข้างชัน แต่เอกสารและชุมชนจัดเตรียมไว้ดี
- ข้อดี
- มีชุมชนที่คึกคักและเอกสารประกอบที่ยอดเยี่ยม
- รองรับฟีเจอร์การทำงานร่วมกันแบบเรียลไทม์ด้วย Yjs
- ข้อเสีย
- ต้องใช้โค้ดจำนวนมากเพื่อทำตัวอย่างพื้นฐาน
- ฟีเจอร์ที่มีมาให้ในตัวค่อนข้างน้อย
- เส้นโค้งการเรียนรู้ค่อนข้างชัน
Plate
- โปรเจกต์บนฐาน Slate ที่ให้ปลั๊กอินแบบครบเครื่อง เช่น ฟีเจอร์ AI, mention, comment และอื่น ๆ
- มีความยืดหยุ่นเพราะเลือกใช้เฉพาะฟีเจอร์ที่ต้องการได้
- มีเทมเพลตแบบเสียเงินให้เลือก และออกแบบมาสำหรับ React โดยเฉพาะ
- ข้อจำกัด
- ปัจจุบันรองรับการทำงานร่วมกันอย่างเป็นทางการผ่าน Hocuspocus เท่านั้น และหากต้องการเชื่อมกับ Yjs backend อื่น ๆ (เช่น Liveblocks) ต้องพัฒนาเพิ่มเติมเอง
- เป็น React-only จึงอาจมีข้อจำกัดในการใช้ร่วมกับเฟรมเวิร์กอื่น
- ด้วยจำนวนฟีเจอร์ที่มาก ทำให้ขนาด bundle มีแนวโน้มใหญ่ขึ้น
- ข้อดี
- มีคลังปลั๊กอินหลากหลาย
- รองรับความสามารถในการแก้ไขฝั่งเซิร์ฟเวอร์
- มีเทมเพลตช่วยให้เริ่มต้นได้รวดเร็ว
- ข้อเสีย
- ออกแบบมาสำหรับ React เท่านั้น
- ฟีเจอร์ collaboration ใช้งานได้ผ่าน Hocuspocus เท่านั้น
- มีขนาด bundle ใหญ่กว่าเอดิเตอร์พื้นฐานทั่วไป
Remirror
- เอดิเตอร์ที่สร้างบน ProseMirror โดยมีแนวทางคล้าย Tiptap แต่เน้นความเป็นโซลูชันแบบ batteries included มากกว่า
- รองรับปลั๊กอินมากกว่า 30 ตัว, React hooks, ฟีเจอร์ internationalization (i18n), accessibility (a11y) เป็นต้น
- เป็นโอเพนซอร์สภายใต้ไลเซนส์ MIT และรองรับฟีเจอร์ collaboration ด้วย
- ข้อจำกัด
- ชุมชนมีขนาดเล็กกว่า Tiptap และการอัปเดตอาจช้ากว่า
- มีฟีเจอร์จำนวนมากที่เน้น React จึงอาจมีข้อจำกัดในสภาพแวดล้อมอื่น
- ขนาด bundle ค่อนข้างใหญ่
- การทำงานร่วมกันแบบเรียลไทม์
- Remirror รองรับการทำงานร่วมกันด้วย Yjs และ Liveblocks ผ่าน YjsExtension
- ข้อดี
- รองรับเอกสารประกอบได้ดีเยี่ยม
- มีคลังปลั๊กอินหลากหลาย
- รองรับฟีเจอร์ collaboration ด้วย Yjs และ Liveblocks
- ข้อเสีย
- ออกแบบมาสำหรับ React เท่านั้น
- ขนาด bundle ใหญ่กว่า
- ความถี่ในการอัปเดตต่ำกว่าและชุมชนมีขนาดเล็ก
Editor.js
- ริชเท็กซ์เอดิเตอร์ที่รองรับการแก้ไขแบบบล็อก มีปลั๊กอินหลากหลายและชุมชนขนาดใหญ่
- มีโครงสร้างข้อมูลที่ประกอบด้วย block, inline และ tune
- ไม่ผูกกับเฟรมเวิร์ก และมีฟีเจอร์อำนวยความสะดวกหลายอย่างในตัว เช่น tooltip
- ข้อจำกัด
- ไม่มีการรองรับการทำงานร่วมกันแบบเรียลไทม์อย่างเป็นทางการ แม้จะเคยมี PR ที่พยายามทำไว้บ้าง แต่สถานะการบำรุงรักษายังไม่ชัดเจน
- แม้ใช้แค่แพ็กเกจพื้นฐาน ขนาดก็ยังค่อนข้างใหญ่
- การทำงานร่วมกันแบบเรียลไทม์
- ยังไม่รองรับอย่างเป็นทางการ
- ข้อดี
- มีคลังปลั๊กอินขนาดใหญ่ที่มีฟีเจอร์หลากหลาย
- รองรับการเชื่อมต่อแบบชุมชนพัฒนาร่วมกับ CMS และ backend framework หลายตัว
- ข้อเสีย
- ขนาด bundle ใหญ่กว่า
- ไม่มีฟีเจอร์การทำงานร่วมกันแบบเรียลไทม์
CKEditor
- เอดิเตอร์ที่มีประวัติยาวนานกว่า 20 ปี โดยเวอร์ชันปัจจุบัน (5) มีสถาปัตยกรรมสมัยใหม่และฟีเจอร์ครบครัน
- รองรับเฟรมเวิร์กหลากหลาย เช่น Angular, React, Vue, Next
- เผยแพร่ภายใต้ไลเซนส์ GPL-2 ซึ่งในบางกรณีอาจบังคับให้ต้องเปิดซอร์ส และหากใช้เชิงพาณิชย์จำเป็นต้องซื้อไลเซนส์แยก
- ข้อจำกัด
- ปลั๊กอินจำนวนไม่น้อยเป็นแบบเสียเงิน และฟีเจอร์ collaboration ก็ใช้ได้เฉพาะผ่านบริการคลาวด์ของ CKEditor เท่านั้น
- ไลเซนส์ GPL-2 และระบบคิดค่าบริการตามจำนวนโหลดอาจเป็นอุปสรรคสำหรับผู้ใช้จำนวนมาก
- การทำงานร่วมกันแบบเรียลไทม์
- ไม่มีโซลูชัน collaboration อื่นนอกจากบริการคลาวด์แบบปิดของ CKEditor
- ข้อดี
- มีฟีเจอร์พื้นฐานครบครันมากโดยค่าเริ่มต้น
- ใช้งานร่วมกับเฟรมเวิร์กได้หลากหลาย
- ข้อเสีย
- ฟีเจอร์ collaboration ผูกติดกับบริการคลาวด์ของ CKEditor
- ไลเซนส์ GPL-2 อาจเป็นข้อจำกัดสำหรับผู้ใช้บางส่วน
- ฟีเจอร์บางอย่างคิดค่าบริการตามการใช้งาน
TinyMCE
- เช่นเดียวกับ CKEditor นี่คือเอดิเตอร์ที่มีประวัติยาวนานกว่า 20 ปี และใช้ไลเซนส์ GPL-2
- ใช้งานได้ในหลายสภาพแวดล้อม เช่น Angular, React, Vue
- มีบริการคลาวด์สำหรับ collaboration ที่คิดค่าบริการตามจำนวนโหลด
- ข้อจำกัด
- ฟีเจอร์สำคัญอย่าง Markdown, mention, comment, advanced typography เป็นต้น ถูกให้มาในรูปปลั๊กอินแบบเสียเงิน
- เอกสารเกี่ยวกับวิธีจัดการเอกสารฝั่งเซิร์ฟเวอร์ยังมีไม่มาก
- การทำงานร่วมกันแบบเรียลไทม์
- ยังไม่มีการเปิดเผยแนวทางอื่นนอกจากโซลูชัน collaboration แบบปิดของ TinyMCE
- ข้อดี
- มีฟีเจอร์พื้นฐานครบครันมากโดยค่าเริ่มต้น
- ใช้งานร่วมกับเฟรมเวิร์กได้หลากหลาย
- ข้อเสีย
- ฟีเจอร์ collaboration ผูกติดกับบริการ Tiny Cloud
- ไลเซนส์ GPL-2 อาจเป็นข้อจำกัดสำหรับผู้ใช้บางส่วน
- ฟีเจอร์บางอย่างคิดค่าบริการตามการใช้งาน
สรุปเปรียบเทียบเอดิเตอร์
-
ProseMirror
- Framework: Vanilla
- Collaboration: Yjs
- Comments: ไม่มีให้มาโดยตรง (มีตัวอย่าง)
- Mentions: ใช้ปลั๊กอิน Suggestion ได้
- Server-side editing: แก้ไขเอกสารบน Node.js ได้ด้วย prosemirror-state และ prosemirror-model
- License: MIT
- GitHub Stars: ⭐ 7.8k
-
Tiptap
- Framework: Vanilla, React, Vue, Svelte
- Collaboration: Liveblocks, Tiptap Cloud, Yjs
- Comments: ใช้งานได้ทันทีแบบไม่ต้องตั้งค่าผ่านการผสานรวมกับ Liveblocks และปรับแต่งได้
- Mentions: ใช้งานได้ทันทีแบบไม่ต้องตั้งค่าผ่านการผสานรวมกับ Liveblocks และปรับแต่งได้
- Server-side editing: ทำได้ผ่าน ProseMirror หรือแพ็กเกจ Node.js ProseMirror ของ Liveblocks
- License: MIT
- GitHub Stars: ⭐ 20k
-
Remirror
- Framework: React
- Collaboration: Yjs
- Comments: มี
- Mentions: มี
- Server-side editing: ทำได้ผ่าน ProseMirror หรือแพ็กเกจ Node.js ProseMirror ของ Liveblocks
- License: MIT
- GitHub Stars: ⭐ 2.8k
-
BlockNote
- Framework: React
- Collaboration: Yjs
- Comments: ใช้ได้ผ่าน Liveblocks หรือตัวอย่างแบบคัสตอม
- Mentions: มี
- Server-side editing: ทำได้ผ่าน ProseMirror หรือแพ็กเกจ Node.js ProseMirror ของ Liveblocks
- License: MPL 2
- GitHub Stars: ⭐ 7.1k
-
Lexical
- Framework: Vanilla, React, iOS, อื่น ๆ
- Collaboration: Liveblocks, Yjs
- Comments: ใช้งานได้ทันทีแบบไม่ต้องตั้งค่าผ่านการผสานรวมกับ Liveblocks และปรับแต่งได้
- Mentions: ใช้งานได้ทันทีแบบไม่ต้องตั้งค่าผ่านการผสานรวมกับ Liveblocks และปรับแต่งได้
- Server-side editing: ทำได้ผ่าน Lexical หรือแพ็กเกจ Node.js Lexical ของ Liveblocks
- License: MIT
- GitHub Stars: ⭐ 20k
-
Slate
- Framework: Vanilla, React
- Collaboration: Yjs
- Comments: ไม่มีให้มาโดยตรง (มีตัวอย่าง)
- Mentions: มีตัวอย่าง
- Server-side editing: ไม่มีให้มาโดยตรง
- License: MIT
- GitHub Stars: ⭐ 30k
-
Plate
- Framework: สำหรับ React เท่านั้น
- Collaboration: Hocuspocus (Yjs)
- Comments: มี
- Mentions: มี
- Server-side editing: มี
- License: MIT
- GitHub Stars: ⭐ 13k
-
Quill
- Framework: Vanilla
- Collaboration: Yjs
- Comments: ไม่มีให้มาโดยตรง (มีตัวอย่าง)
- Mentions: ใช้ไลบรารีจากบุคคลที่สามได้
- Server-side editing: ไม่มีให้มาโดยตรง
- License: BSD-3
- GitHub Stars: ⭐ 45k
-
Editor.js
- Framework: Vanilla
- Collaboration: ไม่รองรับ (มีตัวอย่างจากบุคคลที่สาม)
- Comments: ไม่มีให้มาโดยตรง (มีไลบรารีจากบุคคลที่สาม)
- Mentions: ไม่มีให้มาโดยตรง (มีตัวอย่าง)
- Server-side editing: ไม่มีให้มาโดยตรง
- License: Apache 2
- GitHub Stars: ⭐ 28k
-
CKEditor
- Framework: Vanilla, React, Vue, Angular
- Collaboration: ผสานรวมกับ CKEditor Cloud
- Comments: มี
- Mentions: มี
- Server-side editing: มี
- License: GPL-2+
- GitHub Stars: ⭐ 8.8k
-
TinyMCE
- Framework: Vanilla, React, Vue, Angular, อื่น ๆ
- Collaboration: ผสานรวมกับ Tiny Cloud
- Comments: ผสานรวมกับ Tiny Cloud
- Mentions: มี
- Server-side editing: ไม่มีให้มาโดยตรง
- License: GPL-2+
- GitHub Stars: ⭐ 15k
14 ความคิดเห็น
การนำ QuillJS มาใช้กับโปรเจกต์ SvelteKit ค่อนข้างไม่สะดวกพอสมควร ส่วน React ยังพอใช้งานง่ายกว่าหน่อยเพราะมีไลบรารีรองรับครับ
สำหรับการพัฒนา react custom component แล้ว
tiptapใช้งานสะดวกที่สุดครับช่วงหลังผมก็เพิ่งหาข้อมูลเหมือนกัน ขอบคุณที่สรุปไว้ดีมากครับ
สำหรับภาษาเกาหลี บางเอดิเตอร์จะมีบั๊กยิบย่อยเรื่องการพิมพ์บนมือถืออยู่ครับ
เวลาใส่
<동해물과>อาจถูกพิมพ์ออกมาเป็น<ㄷㅗㅇㅎㅐㅁㅜㄹㄱㅗㅏ>หรือเวลาใส่
<동해물과>อาจกลายเป็น<동동해해물물과과>(อ้างอิง: https://github.com/ckeditor/ckeditor5/issues/13693)
ผมไม่ได้ใช้ framework อย่าง react, vue และก็ไม่ค่อยอยากซื้อไลเซนส์เอดิเตอร์ด้วย เลยมีตัวเลือกค่อนข้างจำกัดมากครับ
ก็เลยลองดูอีก 4 ตัวด้านล่างนอกเหนือจากในบทความครับ
https://trix-editor.org/
เป็นเอดิเตอร์ที่ทำโดย 37signals ซึ่งมี DHH แห่ง Ruby on Rails เป็นผู้นำครับ สร้างด้วย JavaScript ล้วน (หมายถึงไม่ได้ใช้ React อะไรพวกนั้น) และก็ไม่ได้ปรับแต่งยากนักด้วยครับ (เช่น เวลาวางลิงก์ YouTube ก็แปลงเป็น YouTube embed อัตโนมัติ)
https://ui.toast.com/tui-editor
เป็นเครื่องมือที่ทำโดย nhncloud ครับ
https://naver.github.io/smarteditor2/demo/
นี่คือ Naver SmartEditor2 ครับ แม้จะดูคลาสสิก แต่สำหรับบริการที่เจาะผู้ใช้เกาหลี น่าจะเป็นความคุ้นเคยที่คนชอบกันครับ
https://summernote.org/
นี่คือ Summernote ที่นักพัฒนาชาวเกาหลีกำลังพัฒนาอยู่ และผมเลือกตัวนี้ครับ พอใส่ธีมแล้วก็ดูทันสมัยขึ้น อีกทั้งมีฟีเจอร์แบบที่คนเกาหลีมักต้องการติดมาให้เลยจึงใช้งานสะดวกครับ (รวมถึงการแปลงลิงก์ YouTube เป็น embed ข้างต้นด้วย) แต่ตอนจะตกแต่งด้วย tailwind prose มันมีสไตล์ typography ของตัวเองอยู่แล้ว เลยต้องมาปรับแก้กันพอสมควรครับ
มีจุดหนึ่งในเครื่องมือข้อ 2 ที่ผมอยากขอแก้ไขคือ
tui editorไม่ใช่โปรเจ็กต์ของ Toss แต่เป็นโปรเจ็กต์โอเพนซอร์สที่ NHN Cloud กำลังพัฒนาอยู่อ๋อ จริงด้วย ขอแก้ไขครับ (ไม่รู้ว่าแก้ไขตรงไหน.. )
แก้ไขเป็น nhncloud แล้ว
เดิมทีเว็บไซต์นี้ไม่มีระบบแก้ไข มีแต่ผู้ดูแลเท่านั้นที่แก้ไขได้
แม้จะไม่ได้อยู่ในนี้ แต่ผมก็หวังว่า WordPress Gutenberg จะออกมาเป็นไลบรารีอิสระ
https://github.com/Automattic/isolated-block-editor
มีระบุอยู่ก็จริง แต่เมื่อเทียบกับตัวที่แนะนำในเนื้อหาแล้ว กรณีการใช้งานยังน้อยกว่ามาก
โอ้! ที่แท้ Automattic เก็บมันไว้ภายใต้ชื่ออื่นนี่เอง ตอนที่บริษัทใช้ WordPress นี่เป็นฟีเจอร์ที่ผมชอบที่สุดครับ
ลิงก์เป็นบล็อกของ liveblocks.io แต่ URL พรีวิวดันแสดงเป็น
(github.com/US-Artificial-Intelligence)นะครับ?ตอนที่ผมโพสต์บทความ ผมใส่ที่อยู่ของบทความก่อนหน้าไว้ตามเดิม ทำให้เกิดปัญหาระหว่างแก้ไข ตอนนี้แก้ไขแล้ว
ผมเพิ่งลองนำ tiptap ไปใช้กับโปรเจ็กต์เป็นครั้งแรก แต่เมื่อเทียบกับเอดิเตอร์แบบดั้งเดิมตัวอื่น ๆ แล้ว ทั้งเอกสารประกอบ ฟีเจอร์ และการออกแบบการใช้งานล้วนทำได้ดี เลยใช้งานอย่างพอใจอยู่ครับ ความรู้สึกที่ดีคือสามารถหยิบมาใช้เฉพาะสิ่งที่จำเป็น แล้วทำ UI ให้ตรงกับที่ตัวเองต้องการได้พอดี แต่มีอยู่จุดหนึ่งที่ค่อนข้างหนักเหมือนกัน คือปริมาณงานในการทำให้มันออกมาตรงใจแบบนั้นไม่ธรรมดาเลย ฮือ...!
TinyMCE ดีครับ