Slide 1

Slide 1 text

MDXでブログを書こう 2022/3/12 全国学生エンジニア交流会「NSEEM」Author: tofu4956

Slide 2

Slide 2 text

誰? 名前: おとうふ(@tofu4956) 会津大学 B3 / 無職 場所: 宮城県仙台市->会津->? 所属: Zli / ASCs 最近取ったドメイン: admireve.ga やる: Typescript(React / Next.js) / Python (Keras / Pytorch) やりたい: Rust(Backend) / 絵

Slide 3

Slide 3 text

MDX? ● mdx-js/mdx

Slide 4

Slide 4 text

MDX? ● mdx-js/mdx ● MarkdownでJSXコンポーネントを使えるようにする黒魔術 ○ https://mdxjs.com/ ● JSXのimportもできるし変数も定義出来る ○ 外部でブロック要素の置き換えも可能 ● unifiedのプラグインも利用可 ○ 今回はあまり触れません ● Storybookでも使えますよ! ○ https://storybook.js.org/docs/react/api/mdx ● 最近(2月くらいに)2が出ました ○ なんかいろいろ早くなったり増えたりしたらしい

Slide 5

Slide 5 text

2で早くなった Quote: https://twitter.com/wooorm/status/1488549161297498113

Slide 6

Slide 6 text

具体例 Quote: https://mdxjs.com

Slide 7

Slide 7 text

つかいかた(普通) ● https://mdxjs.com/docs/getting-started/#quick-start ● やることが多い!(Quick Startって書いてるのに...) ○ jsx, bundler, フロントエンドシステム特有の設定など... ○ 特にReact以外の場合はjsxに対応させないといけない為、別途ローダーを設定しないと駄目 ● いいところ ○ そのまんま ● わるいところ ○ 後述の方法よりも(1つだけ除く)実装が難解 ○ これだけではblogは作りづらい ■ コンポーネントとしてロードするために前処理が必要

Slide 8

Slide 8 text

つかいかた(Next.js) ● https://github.com/vercel/next.js/tree/canary/packages/next-mdx ○ packageインストールしてnext.config.jsを書いて/pagesにmdxファイルおいておわり ○ MDXProviderもつかえます ● いいところ ○ わかりやすい ○ 設定が楽 ○ 上記の理由で(?)日本語記事多め ● わるいところ ○ mdxに一々ページ全体を書かないといけないので、blog等の複数のコンテンツには向かない(ス ニペットでどうにかなりそう?) ○ メタデータがexport constでしか書けない(そのままではfrontmatterが使えない) ■ https://mdxjs.com/guides/frontmatter/

Slide 9

Slide 9 text

もっとちゃんと使いたい! ● hashicorp/next-mdx-enhancedを使う(deprecated) ○ https://github.com/hashicorp/next-mdx-enhanced ● いいところ ○ デフォルトでfrontmatterが扱える ○ デフォルトの@next/mdxよりはマシな動きをする ● わるいところ ○ もう更新されてない;; ○ 重い(当社比)

Slide 10

Slide 10 text

もっとちゃんと使いたい!CMSも使いたい! ● MDX on demand ○ MDXをサーバーから読んでコンパイル ○ https://mdxjs.com/guides/mdx-on-demand/ ● いいところ ○ @mdx-js/mdxを直接使うので後述の方法よりも直接mdxを触れられる ○ 任意の場所からデータを取り込める ○ nextを使わない場合は現状この方法しかない(mdx-bundlerもあるがMDX 2非対応) ● わるいところ ○ 実運用上の実装が難解 ○ パフォーマンスの問題が発生する可能性がある

Slide 11

Slide 11 text

もっとちゃんと使いたい!CMSも使いたい! ● hashicorp/next-mdx-remoteを使う ○ https://github.com/hashicorp/next-mdx-remote ○ https://github.com/vercel/next.js/tree/canary/examples/with-mdx-remote ● いいところ ○ デフォルトでfrontmatterが扱える ○ 任意の場所からデータを取り込めるのでCMSも利用可 ● わるいところ ○ これを使うとmdx内部でimportが出来なくなる(外部からpropを渡さないと使えなくなる) ○ 上の問題もあってmdxの利用価値が半減する

Slide 12

Slide 12 text

参考: 自分のブログ Umamusume Project: © Cygames, Inc. All Rights Reserved.

Slide 13

Slide 13 text

参考: 自分のブログ ● 中身 ● https://github.com/tofu4956/vercel_pagedata ○ blog-starter-typescriptを流用/改造 ○ hashicorp/next-mdx-remoteを利用 ● https://korejyanaide.cyou/

Slide 14

Slide 14 text

ところで何をしているのか ● Playgroundがあるので見てみると... ○ https://mdxjs.com/playground/

Slide 15

Slide 15 text

これが

Slide 16

Slide 16 text

これになる

Slide 17

Slide 17 text

Slide 18

Slide 18 text

解説します

Slide 19

Slide 19 text

なんだこれ ● やり方は端的にはこう 1. unifiedでvfileで入力された.mdx(.md)をmdast(Markdown AST)に変換 2. その過程でhast(Hypertext AST)に変換してASTにする 3. Hastをsyntax-tree/hast-util-to-estreeでesast(ECMAScript AST)にする 4. 生成されたesastをJavascriptとしてestree-utilでSerialize ○ https://github.com/mdx-js/mdx/blob/main/packages/mdx/lib/core.js

Slide 20

Slide 20 text

rehype-reactとreact-markdownとの違い ● https://github.com/rehypejs/rehype-react ○ https://github.com/remarkjs/remark-react(deprecated) ● https://github.com/remarkjs/react-markdown ● rehype-reactはhastの要素を置き換える ○ importとかconstとか書いても動かない(そのまま出力される) ○ 外部から任意の要素を書き換え可能なのはほぼ同じ ● react-markdownはそもそもremarkのラッパー ○ 仕組み上rehype-reactを通して、結果をReactの要素扱いにすれば同じになる ○ https://github.com/remarkjs/react-markdown#architecture ● MDXは要素そのものをJSXにする ○ その気になればJSXなので何でもできる ○ 2ならjs表現も使えるので小回りが利くのもメリット

Slide 21

Slide 21 text

まとめ ● MDXを使えばブログの幅が広がる ● ブログだけじゃなく色々なところでも使えます ● markdownに慣れた方、こちらもどうですか?

Slide 22

Slide 22 text

参考 ● Markdown for the component era | MDX ○ https://mdxjs.com/ ● mdx-jsの実装を解読するまでの話 ○ https://himenon.github.io/docs/javascript/decipher-mdx-js ● Next.js + MDXでブログを作った ○ https://titanicrising.jp/blog/nextjs-mdx ● Load mdx content from anywhere through getStaticProps in next.js ○ https://github.com/hashicorp/next-mdx-remote

Slide 23

Slide 23 text

(おまけ)外部向けにremark/MDXを使う場合 ● readme.mdにも書いてあるようにそのまま使うのは割と危険 ○ https://github.com/remarkjs/remark#security ○ XSS対策が行われてないので普通に攻撃されます ● 不特定多数が利用するアプリケーションの場合は絶対にrehype-sanitizeを使う ○ 一応rehype-stringfyも使えるけどsyntax-tree/hast-util-santizeがないので両方使ったほうが 良い ○ allowDangerousHtml: trueとかは言語道断(自分用ならok) ● 正直現時点ではMDXを使うのは外部向けではあまりお勧めしないかも... ○ そもそもMDXを入力させて表示するだけでも結構壁が多い ■ セキュリティ面(一番大きい)、技術面、速度面etc… ○ mdの独自表現が欲しいなら自分でremarkプラグインを作るか、rehype-reactを使うとよさ げ? ■ rehype-reactのvue版を探したんですけど全部deprecatedでした。ごめんなさい! ○ 個人用としてmdの代わりとしてなら全然あり

Slide 24

Slide 24 text

ありがとうございました!