-
Notifications
You must be signed in to change notification settings - Fork 3
๐ฅ ๋์ํธ์ง ๋งํฌ๋ค์ด ์๋ํฐ ๊ตฌํ๊ธฐ
- ๋งํฌ๋ค์ด์ ์ง์ํ๋ ์๋ํฐ
๋งํฌ๋ค์ด์ ๊ฐ๊ฒฐํ๊ณ ํจ์จ์ ์ผ๋ก ๊ธ์ ๊ตฌ์กฐ๋ฅผ ํํํ ์ ์๊ธฐ ๋๋ฌธ์, ์ต๊ทผ ๋ง์ ์๋ํฐ์์ ์ง์ํ๊ณ ์๊ณ ์ ํธ๋๊ฐ ๋์ต๋๋ค. ๋ฐ๋ผ์ ์๋ํฐ ์๊ตฌ์ฌํญ์ ์ถ๊ฐ๋์์ต๋๋ค.
- ํ์ ์ด ๊ฐ๋ฅํ ์๋ํฐ
ํ๋ํ๋ก์ฐ ์๋น์ค ๋ชฉํ์ โ๋์ ํธ์งโ์ด ํฌํจ๋์ด์์ต๋๋ค. ์ด๋ ํ์
ํ๊ฒฝ์ ๊ณ ๋ คํ๋ ๊ฒ์ผ๋ก Notion
๊ณผ ๊ฐ์ ์ค์๊ฐ ๋์ํธ์ง ๊ธฐ๋ฅ์ ๋ชฉํ๋ก ๊ตฌํ์ ์์ํ๊ฒ ๋์์ต๋๋ค.
๋งํฌ๋ค์ด ์๋ํฐ๋ฅผ ๊ตฌํํ๊ธฐ ์ํด Milkdown
๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํฉ๋๋ค.
Milkdown
์ ํ
์คํธ ํธ์ง ์์ง์ธ ProseMirror
์คํ ์์์ ๊ตฌํ๋์์ผ๋ฉฐ, ํ๋ฌ๊ทธ์ธ ํํ๋ก ๊ธฐ๋ฅ์ ์ ๊ณตํ์ฌ ํ์ฅ์ฑ๊ณผ ์ปค์คํฐ๋ง์ด์ง์ด ๋งค์ฐ ๋ฐ์ด๋ฉ๋๋ค. ๋ํ, headless ์ปดํฌ๋ํธ๋ก ์ค๊ณ๋์ด ์์ด ์คํ์ผ์ ์์ ๋กญ๊ฒ ์ปค์คํฐ๋ง์ด์งํ ์ ์์ต๋๋ค. Milkdown
์ Y.js
์์ ๊ฒฐํฉ์ฑ์ด ๋ฐ์ด๋ ์ค์๊ฐ ํ์
๊ธฐ๋ฅ ๊ตฌํ์ ์ ํฉํ๋ฉฐ, Vue
์ React
์์ ํตํฉ๋ ์ง์ํฉ๋๋ค.
๋ค๋ฅธ ์ด๋ค ์ฅ์ ๋ณด๋ค, Yjs
์ ๊ฒฐํฉ์ด ๋ฐ์ด๋๋ค๋ ์ ์ด ๊ฐ์ฅ ์ปธ์ต๋๋ค. ๋์ ํธ์ง ๊ธฐ๋ฅ์ ์ง์ํ๊ธฐ ์ํด์ ์ด๋ฏธ Yjs
๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์ค๊ณ๊ฐ ์ด๋ฃจ์ด์ง๊ณ ์์๊ธฐ ๋๋ฌธ์
๋๋ค.
Milkdown
์ BlockProvider
์ ์ฌ์ฉํ์ฌ, ๋ฌธ๋จ ์์ ๋๋๊ทธ ๊ฐ๋ฅํ Block View๋ฅผ ํ์ํฉ๋๋ค. ์ด UI๋ฅผ ์กฐ์ํ๋ฉด ์๋ํฐ์ ์ปจํ
์คํธ์๋ ๋ณ๊ฒฝ ์ฌํญ์ด ๋ฐ์๋๋ ๋ฐฉ์์ผ๋ก ๊ตฌํ๋ฉ๋๋ค.
Block View๋, ํ๋ฌ๊ทธ์ธ์ด ์๋ํฐ ๋ทฐ์ ์ํธ ์์ฉํ๊ฑฐ๋ DOM์์ ๋ฌด์ธ๊ฐ๋ฅผ ์ค์ ํด์ผ ํ๋ ๊ฒฝ์ฐ ์ฌ์ฉ๋ฉ๋๋ค. ์ด ํจ์๋ ํ๋ฌ๊ทธ์ธ์ ์ํ๊ฐ ์๋ํฐ ๋ทฐ์ ์ฐ๊ฒฐ๋ ๋ ํธ์ถ๋ฉ๋๋ค.
Yjs
๋ฅผ ํตํ ํ์
๊ธฐ๋ฅ์ ๊ตฌํํ๊ธฐ ์ํด์ collab
ํ๋ฌ๊ทธ์ธ์ ์ฌ์ฉํฉ๋๋ค. ์ ์ฒด์ ์ธ ํ๋ฆ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
-
Y.Doc
์ธ์คํด์ค๋ฅผ ์์ฑํ์ฌ ๋ฌธ์ ์ํ๋ฅผ ๊ด๋ฆฌํฉ๋๋ค. -
y-websocket
์ ์ฌ์ฉํ์ฌ ์น์์ผ ์ฐ๊ฒฐ์ ๊ตฌ์ฑํ๊ณ , ์ค์๊ฐ ํ์ ์ ์ํ ๋ฐ์ดํฐ ๋๊ธฐํ๋ฅผ ํ์ฑํํฉ๋๋ค. -
Milkdown
์ ํ์ ์๋น์ค(CollabService
)๋ฅผ ์ด๊ธฐํํ๊ณ ,Y.doc
์ธ์คํด์ค์ ์๋ํฐ ์ปจํ ์คํธ๋ฅผ ๋ฐ์ธ๋ฉํฉ๋๋ค. - ์ด๊ธฐ ๋๊ธฐํ ๊ณผ์ ์ด ์๋ฃ๋๋ฉด ๋ฐ์ํ๋
synced
์ด๋ฒคํธ๊ฐ ๊ฐ์ง๋๋ฉด, ๊ธฐ๋ณธ ํ ํ๋ฆฟ์ ๋ฌธ์์ ์ ์ฉํฉ๋๋ค. - ์ปดํฌ๋ํธ๊ฐ ์ธ๋ง์ดํธ๋ ๋ WebSocket ์ฐ๊ฒฐ์ ํด์ ํ๊ณ , ๊ด๋ จ ๋ฆฌ์์ค๋ฅผ ์ ๋ฆฌํ์ฌ ๋ฉ๋ชจ๋ฆฌ ๋์๋ฅผ ๋ฐฉ์งํฉ๋๋ค.
์๋ฒ์์๋ ์น์์ผ ์ฐ๊ฒฐ ์ ๊ณต์ ๋๊ณ ์๋ Y.doc
๋ฐ์ดํฐ๋ฅผ ๋ด๋ถ์์ ์ ๊ณต๋๋ ๋ฉ์๋์ธ Y.encodeStateAsUpdate
๋ฅผ ํตํด์ ๋ฐ์ด๋๋ฆฌ ๋ฐ์ดํฐ๋ก ๋ณํํ์ฌ ๊ฐ์ ธ์ฌ ์ ์์ต๋๋ค. ์ด๋ ๊ฒ ๊ฐ์ ธ์จ ๋ฐ์ดํฐ๋ฅผ ๋ฌธ์์ด๋ก ๋ณํํ์ฌ DB์ ์ ์ฅํ๋ ๊ฒ๋ ๊ฐ๋ฅํฉ๋๋ค. ๋ง์ฝ, ์ด๋ฏธ ์ ์ฅ๋์ด์๋ ๋ฐ์ด๋๋ฆฌ ๋ฐ์ดํฐ๋ฅผ Y.doc
๋ฐ์ดํฐ์ ์ ์ฉํ๊ณ ์ถ์ ๋๋, Y.applyUpdate
๋ฅผ ์ฌ์ฉํ๋ฉด ๋ชจ๋ ๊ณต์ ๋๊ณ ์๋ ๋ฐ์ดํฐ์ ์
๋ฐ์ดํธ๋ฅผ ์ ์ฉ์ํฌ ์ ์์ต๋๋ค.
- react warns: "flushSync was called from inside a lifecycle method. React cannot flush when React is already rendering. Consider moving this call to a scheduler task or micro task."
-
flushSync()
๊ฐ ๋ ๋๋ง ์ค์ ํธ์ถ๋์๊ธฐ ๋๋ฌธ์ ๋ฐ์ํฉ๋๋ค.ย ์ฆ๊ฐ์ ์ผ๋ก ๋ ๋๋ง์ ๊ฐ์ ํ๋flushSync
๋ฅผ ๋ ๋๋ง์ด ์งํ ์ค์ผ ๋ ํธ์ถํ๋ฉด React์ ๋ด๋ถ ์ฒ๋ฆฌ ํ๋ฆ์ ๋ฐฉํดํ ์ ์์ด ๊ฒฝ๊ณ ๊ฐ ๋ฐ์ํฉ๋๋ค. - ํ์ธ ๊ฒฐ๊ณผ, ์๋ํฐ์ ํ์
ํ๋ฌ๊ทธ์ธ์ ๊ฒฐํฉํ๋ ๋ก์ง์์ ์ฌ์ฉํ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ
flushSync
๋ฅผ ์ฌ์ฉํ๊ณ ์์์ต๋๋ค. ์ด ๊ธฐ๋ฅ์ดuseEffect
์์์, ์ฆ ๋ผ์ดํ์ฌ์ดํด ๋ฉ์๋ ๋ด์์ ์ฌ์ฉ๋๊ณ ์๊ธฐ ๋๋ฌธ์ ๋ฌธ์ ๊ฐ ๋์๋ ๊ฒ์ ๋๋ค.
- ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ค๋ฉดย
flushSync()
ย ํธ์ถ์ย setTimeout๊ณผ ๊ฐ์ ๋ฐฉ๋ฒ์ผ๋ก ๋งคํฌ๋ก ํ์คํฌ๋ก ์ทจ๊ธ๋๊ฒ ํ์ฌ ํด๊ฒฐํ ์ ์์ต๋๋ค. ์๋ฌ ๋ฌธ๊ตฌ์์๋ ์ค์ผ์ฅด๋ฌ ํ์คํฌ ํน์ ๋ง์ดํฌ๋ก ํ์คํฌ๋ก ์ด๋ํ ๊ฒ์ ๊ถ์ฅํ๊ณ ์์ง๋ง, ๋ง์ดํฌ๋ก ํ์คํฌ๋ก ์ฎ๊ธฐ๊ฒ ๋ ์ ๋ ๋๋ง ์ฌ์ดํด ๋ํ ๋ง์ดํฌ๋ก ํ์คํฌ์ด๊ธฐ ๋๋ฌธ์ ๋๊ฐ์ ์๋ฌ๋ฅผ ๋ค์ ๋ง์ฃผํ ์ ์์ต๋๋ค. ๋งคํฌ๋ก ํ์คํฌ๋ก ์ด๋์ํค๋ฉด React๊ฐ ๋ ๋๋ง ์ฌ์ดํด์ ์๋ฃํ ํ์ ์ฒ๋ฆฌํ ๊ฒ์ ํ์คํ ํ ์ ์์ต๋๋ค.
useEffect(() => {
setTimeout(() => {
flushSync(() => {
// ๋๊ธฐ์ ์ผ๋ก ์ฒ๋ฆฌํ ์ฝ๋
});
}, 0);
}, []);
- ์ถ๊ฐ ๊ธฐ๋ฅ ๋์ : Notion๊ณผ ๊ฐ์ด ํดํ์ด๋ ์ฌ๋์๋ฅผ ํตํด ์์์ ์ถ๊ฐ/๋ณ๊ฒฝํ ์ ์๋ ๊ธฐ๋ฅ ๋์ ์ด ํ์ํฉ๋๋ค.
-
ํต์ผ๋ UI: ์ฌ์ฉ์ค์ธ
shadcn
๊ฐ UI๋ก ์ฌ์ฉ๋ ์ ์๋๋ก ๊ฒฐํฉ ๊ณผ์ ์ด ์ถ๊ฐ์ ์ผ๋ก ํ์ํฉ๋๋ค. - ๋์ํธ์ง ํ ์คํธ: ๋ค์ํ ๋์ ํธ์ง ์ํฉ์์ ๋ฐ์ํ ์ ์๋ ๋ฌธ์ ์ ์ ํ ์คํธ๋ฅผ ํตํด ํ์ธ์ด ํ์ํฉ๋๋ค.
[Collaborative Editing | Milkdown](https://milkdown.dev/docs/guide/collaborative-editing)
[Total Studio โ Serverless CRDT-Based Markdown Editor | Computer Science Blog @ HdM Stuttgart](https://blog.mi.hdm-stuttgart.de/index.php/2024/08/31/total-studio-serverless-crdt-based-markdown-editor/)
[Using Milkdown Kit | Milkdown](https://milkdown.dev/docs/guide/using-milkdown-kit)
- ๐ ํ ๋ ธ์
- ๐ค ๊ทธ๋ผ์ด๋ ๋ฃฐ
- ๐ค๏ธ ๋ฐ์ผ๋ฆฌ ์คํฌ๋ผ
- ๐ ํ์๋ก
- โ๏ธ ๊ทธ๋ฃน ํ๊ณ
- โ๏ธ Git & Github ์ปจ๋ฒค์
- ๐ฏ ์๋น์ค ๊ฐ์
- ๐ฅ๏ธ ์์ด์ดํ๋ ์
- โ๏ธ ์ธํ๋ผ ์ํคํ ์ณ
- ๐๏ธ ํ๋ก๋ํธ ๋ฐฑ๋ก๊ทธ
- ๐จ Canvas ๋ผ์ด๋ธ๋ฌ๋ฆฌ, ๋น๊ต์ ๊ณ ๋ฏผ
- ๐ซ CSS, JS ์์ด๋ SVG ๋ชจํ์ ๊ตฌํํ ์ ์๋ค๋
- ๐ฅ CRDT๋ฅผ ํ๋ก์ ํธ์ ์ ์ฉํ๊ธฐ - Yjs ๋ฐ์ดํฐํ์ ์ ์
- ๐ณ CI-CD-๊ฐ์ -๊ฒฝํ-๋ฐ-Dockerโcompose-ํ์ฉ
- ๐ฌ FPS ํ ์คํธ๋ก ์ฑ๋ฅ ์ต์ ํ ๊ณ ๋ฏผ ํด๊ฒฐํ๊ธฐ
- ๐ฉโ๐ Konva.js๋ก ์คํ์ด์ค ์ค ๊ธฐ๋ฅ ๊ตฌํํ๊ธฐ
- ๐ค Palette๋ฉ๋ด ์ก๊ฐํ ๊ตฌํ์ฒด์ ๋ํ ๊ฐ๋จํ ๊ณ ๋ฏผ
- ๐งโ๐ป React์์ Y.js๋ฅผ ์ฌ์ฉํ๊ธฐ
- ๐ค React์์ Dialog๋ฅผ ๋งค๋๋ฝ๊ฒ ๊ด๋ฆฌํ๊ธฐ
- ๐ WebRTC, WebSocket, SocketIO ๊ธฐ์ ์ ์ ์ ๊ทผ๊ฑฐ์ ์ด์
- ๐ฅ ๋์ํธ์ง ๋งํฌ๋ค์ด ์๋ํฐ ๊ตฌํ๊ธฐ
- ๐ฑ ๋ชจ๋ฐ์ผ ํ๊ฒฝ์ ์ํ ๋ ธ๋.๊ฐ์ ์กฐ์ ๊ธฐ๋ฅ์ ์ง์ํด๋ณด์
- ๐งฑ ๋ชนํ๋ก๊ทธ๋๋ฐ์ผ๋ก ์ค๊ณํ ๊ธฐ๋ณธ ์ปดํฌ๋ํธ
- ๐จ ๋ฐฑ์๋ MySQL์์ MongoDB๋ก ๊ฐ์ ํ ๊ทผ๊ฑฐ ๋ฐ Redis๋ก ์บ์ฑ์ ํ์ง ์๋ ์ด์
- ๐ช ์ฐ์ฌ๊ณก์ ์ฌํ์ํ Gooey ์ธํฐ๋์
- โจ ์ธํฐ๋์ ๊ตฌํ๊ธฐ: ํ๋, ๊ทธ๋ฆฌ๊ณ ์ด๋