Slide 1

Slide 1 text

Webエディタ開発を 支える技術 Muddy Web #4 Speaker: Hirai Shuta 2023 / 01.19

Slide 2

Slide 2 text

平井 柊太(ひらい しゅうた) 2022年度 新卒入社 株式会社CAM Webフロントエンドエンジニア Twitter: did0es / GitHub: shuta13

Slide 3

Slide 3 text

はじめに

Slide 4

Slide 4 text

お話すること ● 何を解決するのか ● どのように解決するのか ● 振り返り ● 今後の展望 ● まとめ

Slide 5

Slide 5 text

エディタ →

Slide 6

Slide 6 text

エディタ →コンピュータ上で各種オブジェクトを編集する  ソフトウェア

Slide 7

Slide 7 text

Webエディタ →

Slide 8

Slide 8 text

Webエディタ →Webブラウザで使用するエディタ

Slide 9

Slide 9 text

VSCode エディタの例

Slide 10

Slide 10 text

VSCode Wordpress (Gutenberg) エディタの例

Slide 11

Slide 11 text

VSCode Wordpress (Gutenberg) Notion エディタの例

Slide 12

Slide 12 text

VSCode Wordpress (Gutenberg) Notion

Slide 13

Slide 13 text

VSCode Wordpress (Gutenberg) Notion テキストエディタ ブロックエディタ

Slide 14

Slide 14 text

これらのようなブロックエディタを実装するお話です。 Wordpress (Gutenberg) Notion

Slide 15

Slide 15 text

使用技術の紹介 Editor.js

Slide 16

Slide 16 text

Editor.jsとは ● 豊富なプラグイン ● 独自のプラグインも実装可能 ● (ある程度)クリーンデータ ● UIライブラリ非依存

Slide 17

Slide 17 text

Editor.jsとは ● 豊富なプラグイン ● 独自のプラグインも実装可能 ● (ある程度)クリーンデータ ● UIライブラリ非依存 機能性・拡張性の高いブロックエディタを UIライブラリ無しで実装できるライブラリ

Slide 18

Slide 18 text

Editor.jsとは ● 豊富なプラグイン ● 独自のプラグインも実装可能 ● (ある程度)クリーンデータ ● UIライブラリ非依存 機能性・拡張性の高いブロックエディタを UIライブラリ無しで実装できるライブラリ

Slide 19

Slide 19 text

Editor.jsプラグイン

Slide 20

Slide 20 text

Editor.jsプラグイン 赤枠内全て

Slide 21

Slide 21 text

Editor.jsプラグインの名称と機能 Block Tool Inline Tool Block Tune

Slide 22

Slide 22 text

Editor.jsプラグインの名称と機能 Block Tool →ブロック作成機能 Inline Tool →テキスト編集機能 Block Tune →ブロック編集機能

Slide 23

Slide 23 text

何を解決するのか

Slide 24

Slide 24 text

Editor.jsプラグイン実装

Slide 25

Slide 25 text

Editor.jsプラグイン実装 1.特定のメソッドを含む Classを作成

Slide 26

Slide 26 text

Editor.jsプラグイン実装 2.Editor.jsにClassを 渡す 1.特定のメソッドを含む Classを作成

Slide 27

Slide 27 text

Block ToolのメソッドとUI

Slide 28

Slide 28 text

Block ToolのメソッドとUI

Slide 29

Slide 29 text

Block ToolのメソッドとUI

Slide 30

Slide 30 text

プラグイン実装に潜む課題

Slide 31

Slide 31 text

DOMツリー → JSON(JSのObject) → プラグイン実装に潜む課題

Slide 32

Slide 32 text

DOMツリー →命令的なUIの記述 JSON(JSのObject) →宣言的なUIの記述 プラグイン実装に潜む課題

Slide 33

Slide 33 text

プラグイン実装に潜む課題 DOMツリー →命令的なUIの記述 JSON(JSのObject) →宣言的なUIの記述 UIを宣言的に書きたい

Slide 34

Slide 34 text

Editor.jsプラグイン実装の課題と問題 ● 書き方にばらつきがある ○ 宣言的な記述と命令的な記述が混在している ● 命令的な記述はコードの維持が難しい ○ 可読性が下がりがち ○ コードの実行順から UI の状態を推測しづらい ○ データ変更のタイミングが分かりづらい ● データの管理が難しい ○ エディタはデータの入出力が多い ○ HTMLのデータ属性にこのデータを詰め込みたくない(...ですよね?)

Slide 35

Slide 35 text

課題と問題に対する解決アプローチ ● 書き方にばらつきがある ○ 宣言的な記述と命令的な記述が混在している ● 命令的な記述はコードの維持が難しい ○ 可読性が下がりがち ○ コードの実行順から UI の状態を推測しづらい ○ データ変更のタイミングが分かりづらい ● データの管理が難しい ○ エディタはデータの入出力が多い ○ HTMLのデータ属性にこのデータを詰め込みたくない(...ですよね?)

Slide 36

Slide 36 text

課題と問題に対する解決アプローチ ● 書き方にばらつきがある ○ 宣言的な記述と命令的な記述が混在している ● 命令的な記述はコードの維持が難しい ○ 可読性が下がりがち ○ コードの実行順から UI の状態を推測しづらい ○ データ変更のタイミングが分かりづらい ● データの管理が難しい ○ エディタはデータの入出力が多い ○ HTMLのデータ属性にこのデータを詰め込みたくない(...ですよね?) 宣言的に書けるような 記法を提供する データ管理向けの 仕組みを提供する

Slide 37

Slide 37 text

どのように解決するのか

Slide 38

Slide 38 text

ゴール1. Editor.jsプラグインを宣言的に実装できる ゴール2. プラグインのデータ(状態)管理ができる ゴール3. 本来のインターフェースとかけ離れていない

Slide 39

Slide 39 text

Editor.jsとは ● 豊富なプラグイン ● 独自のプラグインも実装可能 ● (ある程度)クリーンデータ ● UIライブラリ非依存

Slide 40

Slide 40 text

Editor.jsとは ● 豊富なプラグイン ● 独自のプラグインも実装可能 ● (ある程度)クリーンデータ ● UIライブラリ非依存 これらの特性も活かすように実装する

Slide 41

Slide 41 text

理想(プラグイン実装時)

Slide 42

Slide 42 text

理想(プラグイン実装時)

Slide 43

Slide 43 text

理想(プラグイン実装時)

Slide 44

Slide 44 text

理想(プラグイン実装時)(+α)

Slide 45

Slide 45 text

理想(プラグイン使用時)

Slide 46

Slide 46 text

ゴール1. Editor.jsプラグインを宣言的に実装できる ゴール2. プラグインのデータ(状態)管理ができる ゴール3. 本来のインターフェースとかけ離れていない ✅

Slide 47

Slide 47 text

実装したもの =

Slide 48

Slide 48 text

実装したもの = Reactに依存しない、Reactっぽく書ける  Editor.jsプラグイン実装向けライブラリ

Slide 49

Slide 49 text

No content

Slide 50

Slide 50 text

Editor.jsとは ● 豊富なプラグイン ● 独自のプラグインも実装可能 ● (ある程度)クリーンデータ ● UIライブラリ非依存

Slide 51

Slide 51 text

Editor.jsとは ● 豊富なプラグイン ● 独自のプラグインも実装可能 ● (ある程度)クリーンデータ ● UIライブラリ非依存 特にこの特性を潰したくなかった

Slide 52

Slide 52 text

No content

Slide 53

Slide 53 text

手順 ● JSX Factoryの定義 ● 差分検出処理の導入 ● 状態管理を実現する

Slide 54

Slide 54 text

JSX Factoryとは JSXをJSに変換すると生成される 関数のこと。 @babel/preset-reactを用いて 変換すると右の画像のようになる。 React.createElementの部分が JSX Factoryに該当する。

Slide 55

Slide 55 text

独自のJSX Factoryを使う コンパイラの設定を変えると 独自(=React.createElement以外)の JSX Factoryを使える。 babelであればpragmaを typescriptであればjsxFactoryを それぞれ設定する。 ファイル内に/* @jsx */コメントを 書くことでも設定可能。

Slide 56

Slide 56 text

独自のJSX Factoryを使う

Slide 57

Slide 57 text

独自のJSX Factoryを使う /* @jsx myJsxFactory */

Slide 58

Slide 58 text

独自のJSX Factoryを使う /* @jsx myJsxFactory */

Slide 59

Slide 59 text

独自のJSX Factoryを使う /* @jsx myJsxFactory */ myJsxFactoryを実装すれば 任意の処理を適用しながらJSX要素を探索できる

Slide 60

Slide 60 text

(当資料における)差分検出処理とは 2つの木の前後を比較し差分を取る 処理のこと (木 = JSX要素ツリー) JSX FactoryではJSX要素ツリーを 差分を検出しやすい形に変換して返す。 (差分を検出しやすい形 = JSON) ※イメージ

Slide 61

Slide 61 text

差分検出処理を導入するにあたっての課題 当初はReactと同じ方法(react-reconciler) で差分を検出する予定だった。 ...が、react-reconcilerはreactに依存する。 react依存の部分を剥がし、差分検出処理のみ スタンドアロンで利用出来るように試みた。 ...が、コード量が膨大で誰も把握・メンテ できないことを懸念し、他の方法を模索した。

Slide 62

Slide 62 text

Preactで代用して解決 Preactの差分検出の仕組みを 移植(書き換え)することで解決した。 Preactの差分検出は1000行[※]程度の ミニマルなコードで記述されている。 (※ ライブラリ作成当初。参考) Reactよりもコードの全容が把握しやすく メンテできる。

Slide 63

Slide 63 text

とりあえずJSXで書けるようになった

Slide 64

Slide 64 text

状態管理 PreactのHooksを参考に実装。 useStateやuseReducerで状態を作成し 更新用関数を取得する。 useWatchやuseMountで副作用を管理する。

Slide 65

Slide 65 text

https://github.com/cam-inc/pde.js 完成したもの

Slide 66

Slide 66 text

No content

Slide 67

Slide 67 text

Playground CodeSandboxで色々試してみてください。

Slide 68

Slide 68 text

Docs https://cam-inc.github.io/pde.js

Slide 69

Slide 69 text

ライセンス ● pde.js: Apache-2.0 License ○ ライセンス ○ Editor.jsのサブセットとして、Editor.jsのライセンスに倣った ● Preact: MIT License ○ Preactをインストールしないので、自前で記載が必要。 ○ Preactのオリジナルのライセンス文と、そのリンクをコメントで挿入。 ○ sourcemapとして書き出して配信。

Slide 70

Slide 70 text

振り返り

Slide 71

Slide 71 text

まとめ・所感 ● Webエディタ開発で感じた課題を技術で解決した ○ 宣言的なUIの記述でEditor.jsプラグインを書けるようになった ○ ただ、未だ型やEditor.jsと接続する部分でバグが多い ● PreactやReactの差分検出処理に対する理解を深められた ○ JSX要素ツリーの比較 ○ Hooks ● 先人と技術へのリスペクトを忘れない ○ Editor.jsやPreactを作った先人に感謝

Slide 72

Slide 72 text

今後の展望

Slide 73

Slide 73 text

Coming Soon... Slate.js + Reactによる 更に質の高いブロックエディタ実装向けライブラリ(OSS)を開発中

Slide 74

Slide 74 text

おわりに

Slide 75

Slide 75 text

https://cam-inc.co.jp/p/techblog/710053497071993899 今回お話した内容はこちらからもご覧になれます

Slide 76

Slide 76 text

https://github.com/cam-inc/pde.js ご興味あればコントリビュートお待ちしております!

Slide 77

Slide 77 text

ご清聴ありがとうございました。

Slide 78

Slide 78 text

Webエディタ開発を 支える技術 Muddy Web #4 Speaker: Hirai Shuta 2023 / 01.19