본문 바로가기
C.W.K.
Stream
Lesson 01 of 04 · published

코어를 손수 짜지 마

~11 min · cm6-thin, contenteditable, borrow, uxp-thin

Level 0식은 초고
0 XP0/33 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete
"에디터가 어려운 이유의 절반은 텍스트 원시 레이어에 있어. 그러니까 짓지 말고 빌려."

공짜처럼 보이는데 아닌 레이어

브라우저가 contenteditable 을 건네줄 땐 선물처럼 보여. <div> 에 속성 하나 붙이면 텍스트가 편집되니까. 그게 함정이야. 제대로 된 동작이 필요해지는 순간, 그러니까 커서가 예상한 자리에 앉아야 하고, 스타일 먹은 span 을 가로질러 선택이 돼야 하고, undo/redo 가 편집을 통째로 묶어줘야 하고, 붙여넣기가 쓰레기 HTML 을 안 흘려야 하고, 무엇보다 IME 조합이 안 깨져야 하는 순간, 네가 바닥 없는 구덩이를 떠안았다는 걸 깨닫게 돼. 브라우저마다 조금씩 다르게 굴고, 하나같이 네 편이 아니야.

이게 텍스트 원시 레이어고, 에디터를 어렵게 만드는 절반이 여기에 있어. 화려한 작업이 아니라 몇 달치 엣지 케이스 더미지. Rekindle 은 그 몇 달을 안 써. CodeMirror 6 위에 서고 raw contenteditable 은 절대 직접 안 짜.

상품화된 어려운 부분을 빌려

커서 계산, 선택 모델, 히스토리, IME 라이프사이클까지 편집 코어 전체를, 빌려 오면 몇 줄이면 끝나. 직접 하면 1년 갈아 넣을 게 import 한 줄이 되는 거야.

import { EditorView, basicSetup } from "codemirror";
import { markdown } from "@codemirror/lang-markdown";

new EditorView({
  doc: "# Hello\n\nStart writing...",
  extensions: [basicSetup, markdown()],
  parent: document.querySelector("#editor")!,
});

커서와 선택, undo, IME 가 전부 해결된 채로, 정확하게, 플랫폼 가리지 않고 딸려 와. 네가 할 일은 그걸 다시 만드는 게 아니야. 누가 이미 방탄으로 다져놓은 코어 위에 가치를 얹는 거지. Live Preview, voice underline, CMD+K 같은 것들 말이야.

Cinder 가 따르는 바로 그 규칙

이건 Rekindle 만의 별난 규칙이 아니라 가족 전체의 법이야. Cinder 판은 UXP 는 얇게야. 플러그인 안에 미니 Photoshop 을 다시 짓지 말고 Photoshop 이 손 역할을 하게 두라는 거지. Loomis 판은 결정론적 기하부터, ML 은 landmark fitting 에만이고. 형제들 전부가 이미 상품이 된 어려운 부분을 콕 집어 이름 붙이고 다시 짓기를 거부해. Rekindle 한테 그 부분은 텍스트 편집이고, 답은 CodeMirror 6 에 이미 나와 있어.

Code

편집 코어 전체를, 몇 줄로 빌려·typescript
import { EditorView, basicSetup } from "codemirror";
import { markdown } from "@codemirror/lang-markdown";

// 커서, 선택, undo/redo, IME 조합에 크로스플랫폼까지
// 전부 여기 딸려 와. 짓는 게 아니라 빌리는 거야.
const view = new EditorView({
  doc: "# Hello\n\nStart writing...",
  extensions: [basicSetup, markdown()],
  parent: document.querySelector("#editor")!,
});

// 네 일은 이 줄 위에서 시작해. 이미 방탄인 코어 위에
// Live Preview, voice underline, CMD+K 를 얹는 것.

External links

Exercise

평범한 HTML 파일을 하나 열어서 contenteditable div 를 넣고 '간단한' 기능 하나를 만들어봐. Ctrl+Z 를 눌렀을 때 마지막 단어가 한 글자씩이 아니라 통째로 되돌아가게 하는 거야. 라이브러리에 손 뻗기까지 몇 분이나 버티는지 재봐. 거기서 부딪힌 벽이 바로 CodeMirror 6 이 이미 넘어준 벽이야.
Hint
금방 부딪힐 거야. contenteditable 의 브라우저 기본 undo 는 입력 이벤트 단위라서 원하는 대로 묶을 수가 없거든. 편집을 의미 있는 undo 단위로 묶는 것 자체가 하나의 서브시스템이고, CM6 이 그냥 얹어주는 여러 손 중에 하나야.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.