Help us understand the problem. What is going on with this article?

markdownを直接ReactElementに変換するコンパイラを書いた

More than 5 years have passed since last update.

mizchi/md2react

デモページはここ md2react playground

作った目的

巨大なmarkdownをリアルタイムプレビューする際、ただの文字列をinnerHTMLとかで更新したりしていると、更新の度にパース処理が走ってどんどん重くなってくる。

React には dangerouslySetInnerHTML というプロパティがあって、一応それっぽい感じで差分管理してくれるが、名前の通り色々怪しい挙動をする。

なのでmarkdownのASTから直接ReactElementを吐けるようにするとReactの差分計算で描画高速化されて良いのでは、というわけで作った。これはMarkdownPreview界にとって救いとなるであろう。

どこで使う目的かはお察しください

使い方

global.React = require('react');
var md2react = require('md2react');

var md = '# Hello md2react';
var html = React.renderToString(md2react(md));

/*
<div data-reactid=".14qrwokr3sw" data-react-checksum="20987480"><h1 data-reactid=".14qrwokr3sw.$_start_root_0_heading"><span data-reactid=".14qrwokr3sw.$_start_root_0_heading.0">Hello md2react</span></h1></div>'
//'<div data-reactid=".58nba97pxc" data-react-checksum="-55236619"><h1 data-reactid=".58nba97pxc.0"><span data-reactid=".58nba97pxc.0.0">Hello</span></h1></div>'
*/

たとえばReactで使う場合、

md2react = require 'md2react'
MarkdownPreview = React.createClass
  render: ->
    md = @props.body # ここにmd本文が入っているとする
    el = md2react(md, gfm:true, breaks: true)
    React.createElement 'div', className: 'markdown-content', [el]

概要

markedをforkしたmdastってプロジェクトがあって、これはmarkdownのASTを定義している。ソースマップ的なテキストレンジもとれる。パーサの第二引数はmdastにそのまま。

一応HTMLタグが出現した時はdangerouslySet~ にするしかなくてそうしているのだけど、渡す前にdompurifyでサニタイズ処理をいれている。

wooorm/mdast

なんかバグみつけて報告したら直してくれそうだった。よい。

Parse error in bullet with space before newline · Issue #15 · wooorm/mdast https://github.com/wooorm/mdast/issues/15

plaid
CXプラットフォーム「KARTE」の開発・運営、EC特化型メディア「Shopping Tribe」の企画・運営、CX特化型メディア「XD(クロスディー)」の企画・運営
https://plaid.co.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away