$30 off During Our Annual Pro Sale. View Details »

Building markdown editor using Rust’s parser

Building markdown editor using Rust’s parser

HiroyukiYagihashi

November 27, 2021
Tweet

More Decks by HiroyukiYagihashi

Other Decks in Technology

Transcript

  1. Building markdown editor
    using Rust’s parser
    @yagipy
    JS Conf JP 2021

    View Slide

  2. 自己紹介
    @yagipy(Hiroyuki Yagihashi)
    - 所属: からくり株式会社/エンジニア
    - TypeScript/Next.jsでフロントエンドや、 Go/Node.jsで
    APIサーバー、AWSでインフラ構築、Figmaでデザイン作成、
    Java/KotlinでAndroid等
    - エンジニア募集中です
    - Twitter: @yagipy_
    - GitHub: @yagipy
    - Blog: https://blog.yagipy.me

    View Slide

  3. 本セッションのゴール
    - wasmのユースケースの一部を理解できるようになる
    - Rustのコードからwasm pkgを生成できるようになる
    - wasm pkgをReactで使用できるようになる
    - マークダウンエディタが構築できるようになる

    View Slide

  4. 本セッションで話すこと
    - 作ったもの
    - アーキテクチャ
    - アーキテクチャのモチベーション
    - フロントエンド複雑化の流れ
    - 問題点
    - 解決策
    - 実装の紹介
    - Rustのライブラリをwasm pkg化する
    - wasm pkgをdependenciesに追加する
    - wasm pkgをロードするReact Hookを定義する
    - 定義したReact Hookを呼び出す
    - まとめ

    View Slide

  5. 作ったもの

    View Slide

  6. https://editor.yagipy.me
    - 3種類のプレビュー形式に対応
    - デフォルト
    - マインドマップ
    - スライド
    - 3種類のレイアウトに対応
    - 2カラム(textarea,preview)
    - textareaのみ
    - Previewのみ
    - 本セッションでは、デフォルト/スライドで使用しているRustコード(マー
    クダウンパーサー)をReactで使用するまでのアーキテクチャを紹介します

    View Slide

  7. アーキテクチャ

    View Slide

  8. RustコードがReactアプリで使用できるまで
    Reactアプリ
    wasm pkg
    Rustコード
    wasm-pack import
    マークダウンパー
    サー
    tsの型定義
    Jsのラッパー
    wasm

    View Slide

  9. アーキテクチャのモチベーション

    View Slide

  10. 前提: フロントエンド大規模化の流れ
    - ロジックがフロントエンドに寄ってきている
    - 主なメリット: 無駄な通信の削減、サーバーリソースの削減
    - よりユーザーの近くで計算した方が良い
    - エッジコンピューティングやフォグコンピューティングの流れ
    - サーバーに戻そう、という動きもあるにはあるが ...(React Server Components等)

    View Slide

  11. 問題点
    - サーバーに書いていた処理をフロントエンド用に書き直す必要がある
    - 今までサーバーサイドはデータストアの役割に加えて、共通ロジックの置き場所として働い
    ていたがそうではなくなってきている

    View Slide

  12. 解決策
    - 色々ある
    - blitz, Kotlin Multiplatform, wasm, etc..
    - 様々な言語の資産を活用したい場合はwasmが選択肢に入る
    - 今回は、実験としてRustのコードをwasmにしてWeb上で使用するという実
    装を行った

    View Slide

  13. 実装の紹介

    View Slide

  14. 1. Rustのコードをwasm pkg化する
    2. wasm pkgをdependenciesに追加する
    3. wasm pkgをロードするReact Hookを定義する
    4. 定義したReact Hookを呼び出す
    RustコードをReactアプリで使用するまでの手順

    View Slide

  15. Rustのコードをwasm pkg化する
    - wasm-packを使用
    - wasm_bindgen + package.json等を出力(npm publishする場合にスムーズに対応でき
    る)
    - wasm_bindgen: #[wasm_bindgen]アトリビュートを付けた関数の wasmとJavaScript
    のラッパーとTypeScriptの型定義を生成する
    - https://developer.mozilla.org/ja/docs/WebAssembly/Rust_to_wasm#buildi
    ng_the_package
    use pulldown_cmark::{html, Options, Parser};
    use wasm_bindgen::prelude::*;
    #[wasm_bindgen]
    pub fn pulldown_cmark(source_text: &str) -> String {
    // ~~~ 省略 ~~~
    html_output
    }

    View Slide

  16. wasm pkgをdependenciesに追加する
    - package.jsonのdependenciesに追加
    - 直接/pkgのパスを指定する形でも可能
    {
    "dependencies": {
    "markdown-parser": "file:./markdown-parser/pkg"
    }
    }

    View Slide

  17. wasm pkgをロードするReact Hookを定義する
    - wasmを含んだJavaScriptは動的に読み込む必要があるので、その読み込み
    を待ってrerenderする
    import { pulldown_cmark } from 'markdown-parser'
    export interface IPullDownCmark {
    pulldown_cmark: typeof pulldown_cmark
    }
    export const usePullDownCmark = () => {
    const [state, setState] = useState(null)
    useEffect(() => {
    (async () => {
    const wasmContainer = await import('markdown-parser')
    setState(wasmContainer)
    })()
    }, [])
    return state
    }

    View Slide

  18. 定義したReact Hookを呼び出す
    - 作成したHookを呼ぶ
    - wasm_bindgenした関数が呼べる
    interface IProps {
    text: string
    }
    export const DefaultPreview = ({ text }: IProps): ReactElement => {
    const instance = usePullDownCmark()
    return (
    dangerouslySetInnerHTML={{
    __html: instance?.pulldown_cmark(text) ?? '',
    }}
    />
    )
    }

    View Slide

  19. まとめ

    View Slide

  20. まとめ
    - wasm-packを使用することで、簡単にRustで書いたコードをWeb上で使用
    できた
    - その他のwasmがサポートされている言語のコードも、wasmを介することで
    Web上で使用できるようになるため、既存の言語資産をWeb上で使用できる

    View Slide

  21. Thank you for listening!

    View Slide