@nuxtjs/mdc

Nuxt MDC
MDCは通常のMarkdownを強化し、任意のVueコンポーネントと深く連携するドキュメント作成を可能にします。MDCはMarkDown Componentsの略です。
機能
- Markdown構文とHTMLタグまたはVueコンポーネントを組み合わせる
- 生成されたコンテンツ(例:各Markdown段落によって追加された<p>タグ)を削除する
- 名前付きスロットを使用してVueコンポーネントを使用する
- インラインコンポーネントをサポートする
- インラインHTMLタグに属性とクラスを追加する
MDC構文の詳細については、https://content.nuxtjs.org/guide/writing/mdcをご覧ください。
!注記 このパッケージは、Nuxtプロジェクト(標準設定)内または任意のVueプロジェクト内で使用できます。
詳細については、下記のVueプロジェクトでのレンダリングを参照してください。
インストール
npx nuxi@latest module add mdc
次に、@nuxtjs/mdc
をnuxt.config.ts
のmodulesセクションに追加します。
export default defineNuxtConfig({
modules: ['@nuxtjs/mdc']
})
これで完了です!NuxtプロジェクトでMarkdownファイルの記述とレンダリングを開始できます ✨
レンダリング
@nuxtjs/mdc
は、Markdownファイルをレンダリングするための3つのコンポーネントを提供します。
<MDC>
<MDC>
を使用すると、コンポーネント/ページ内でMarkdownコンテンツを直接解析してレンダリングできます。このコンポーネントは生のMarkdownを受け取り、parseMarkdown
関数を使用して解析し、<MDCRenderer>
を使用してレンダリングします。
<script setup lang="ts">
const md = `
::alert
Hello MDC
::
`
</script>
<template>
<MDC :value="md" tag="article" />
</template>
::alert
はcomponents/global/Alert.vue
コンポーネントを使用することに注意してください。
<MDCRenderer>
このコンポーネントは、parseMarkdown
関数の結果を受け取り、コンテンツをレンダリングします。たとえば、これはブラウザセクションのサンプルコードの拡張版で、MDCRenderer
を使用して解析されたMarkdownをレンダリングします。
<script setup lang="ts">
import { parseMarkdown } from '@nuxtjs/mdc/runtime'
const { data: ast } = await useAsyncData('markdown', () => parseMarkdown('::alert\nMissing markdown input\n::'))
</script>
<template>
<MDCRenderer :body="ast.body" :data="ast.data" />
</template>
<MDCSlot>
このコンポーネントは、Vueの<slot/>
コンポーネントの代替であり、特にMDC用に設計されています。このコンポーネントを使用すると、1つ以上のラッピング要素を削除しながら、コンポーネントの子をレンダリングできます。以下の例では、Alertコンポーネントはテキストとそのデフォルトスロット(子)を受け取ります。しかし、コンポーネントが通常の<slot/>
を使用してこのスロットをレンダリングする場合、テキストの周りに<p>
要素がレンダリングされます。
::alert
This is an Alert
::
<template>
<div class="alert">
<!-- Slot will render <p> tag around the text -->
<slot />
</div>
</template>
すべてのテキストを段落内にラップすることは、Markdownのデフォルトの動作です。MDCはMarkdownの動作を壊すためのものではなく、Markdownをより強力にすることを目的としています。この例や同様の状況では、<MDCSlot />
を使用して不要なラッパーを削除できます。
<template>
<div class="alert">
<!-- MDCSlot will only render the actual text without the wrapping <p> -->
<MDCSlot unwrap="p" />
</div>
</template>
散文コンポーネント
散文コンポーネントは、通常のHTMLタグの代わりにレンダリングされるコンポーネントのリストです。たとえば、<p>
タグをレンダリングする代わりに、@nuxtjs/mdc
は<ProseP>
コンポーネントをレンダリングします。これは、Markdownファイルに追加機能を追加する場合に役立ちます。たとえば、コードブロックに「コピー」ボタンを追加できます。
nuxt.config.ts
でprose
オプションをfalse
に設定して、散文コンポーネントを無効にすることができます。または、散文コンポーネントのマップを拡張して独自のコンポーネントを追加することもできます。
export default defineNuxtConfig({
modules: ['@nuxtjs/mdc'],
mdc: {
components: {
prose: false, // Disable predefined prose components
map: {
p: 'MyCustomPComponent'
}
}
}
})
利用可能な散文コンポーネントのリストを以下に示します。
タグ | コンポーネント | ソース | 説明 |
---|---|---|---|
p | <ProseP> | ProseP.vue | 段落 |
h1 | <ProseH1> | ProseH1.vue | 見出し1 |
h2 | <ProseH2> | ProseH2.vue | 見出し2 |
h3 | <ProseH3> | ProseH3.vue | 見出し3 |
h4 | <ProseH4> | ProseH4.vue | 見出し4 |
h5 | <ProseH5> | ProseH5.vue | 見出し5 |
h6 | <ProseH6> | ProseH6.vue | 見出し6 |
ul | <ProseUl> | ProseUl.vue | 箇条書きリスト |
ol | <ProseOl> | ProseOl.vue | 番号付きリスト |
li | <ProseLi> | ProseLi.vue | リスト項目 |
blockquote | <ProseBlockquote> | ProseBlockquote.vue | 引用ブロック |
hr | <ProseHr> | ProseHr.vue | 水平線 |
pre | <ProsePre> | ProsePre.vue | 整形済みテキスト |
code | <ProseCode> | ProseCode.vue | コードブロック |
table | <ProseTable> | ProseTable.vue | テーブル |
thead | <ProseThead> | ProseThead.vue | テーブルヘッダー |
tbody | <ProseTbody> | ProseTbody.vue | テーブルボディ |
tr | <ProseTr> | ProseTr.vue | テーブル行 |
th | <ProseTh> | ProseTh.vue | テーブルヘッダーセル |
td | <ProseTd> | ProseTd.vue | テーブルデータセル |
a | <ProseA> | ProseA.vue | アンカーリンク |
img | <ProseImg> | ProseImg.vue | 画像 |
em | <ProseEm> | ProseEm.vue | 強調 |
strong | <ProseStrong> | ProseStrong.vue | 強調(太字) |
Markdownの解析
Nuxt MDCは、MDCファイルを解析するための便利なヘルパーを提供します。@nuxtjs/mdc/runtime
からparseMarkdown
関数をインポートして、MDC構文で記述されたMarkdownファイルを解析するために使用できます。
Node.js
// server/api/parse-mdc.ts
import { parseMarkdown } from '@nuxtjs/mdc/runtime'
export default eventHandler(async () => {
const mdc = [
'# Hello MDC',
'',
'::alert',
'This is an Alert',
'::'
].join('\n')
const ast = await parseMarkdown(mdc)
return ast
})
ブラウザ
parseMarkdown
関数は汎用的なヘルパーであり、ブラウザ内(たとえば、Vueコンポーネント内)でも使用できます。
<script setup lang="ts">
import { parseMarkdown } from '@nuxtjs/mdc/runtime'
const { data: ast } = await useAsyncData('markdown', () => parseMarkdown('::alert\nMissing markdown input\n::'))
</script>
<template>
<MDCRenderer :body="ast.body" :data="ast.data" />
</template>
オプション
parseMarkdown
ヘルパーは、2番目の引数としてオプションを受け取り、パーサーの動作を制御します。(MDCParseOptions
インターフェース↗︎を確認してください)。
名前 | デフォルト | 説明 |
---|---|---|
remark.plugins | {} | パーサーのremarkプラグインを登録/設定します。 |
rehype.options | {} | remark-rehype オプションを設定します。 |
rehype.plugins | {} | パーサーのrehypeプラグインを登録/設定します。 |
highlight | false | コードブロックをハイライト表示するかどうかを制御します。カスタムハイライターを提供することもできます。 |
toc.depth | 2 | 目次を含める見出しの最大深度。 |
toc.searchDepth | 2 | 見出しを検索する入れ子になったタグの最大深度。 |
MDCParseOptions
タイプ↗︎を確認してください。
設定
nuxt.config.js
でmdc
プロパティを提供することで、モジュールを設定できます。デフォルトオプションを以下に示します。
import { defineNuxtConfig } from 'nuxt/config'
export default defineNuxtConfig({
modules: ['@nuxtjs/mdc'],
mdc: {
remarkPlugins: {
plugins: {
// Register/Configure remark plugin to extend the parser
}
},
rehypePlugins: {
options: {
// Configure rehype options to extend the parser
},
plugins: {
// Register/Configure rehype plugin to extend the parser
}
},
headings: {
anchorLinks: {
// Enable/Disable heading anchor links. { h1: true, h2: false }
}
},
highlight: false, // Control syntax highlighting
components: {
prose: false, // Add predefined map to render Prose Components instead of HTML tags, like p, ul, code
map: {
// This map will be used in `<MDCRenderer>` to control rendered components
}
}
}
})
ModuleOptions
タイプ↗︎を確認してください。
Vueプロジェクトでのレンダリング
いくつかのエクスポートされたパッケージユーティリティと組み合わせた<MDCRenderer>
コンポーネントは、通常の(非Nuxt)Vueプロジェクトでも使用できます。
標準的なVueプロジェクトに実装するには、以下の手順に従ってください。
パッケージのインストール
nuxt.config.ts
ファイルにNuxtモジュールを追加する手順を無視して、上記のインストール手順に従ってください。
Nuxtモジュールのインポートのスタブ作成
Nuxtを使用していないため、VueプロジェクトのVite設定ファイルでモジュールのインポートをいくつかスタブ化する必要があります。これは、モジュールがNuxt固有のインポートにアクセスしようとしたときにエラーを回避するために必要です。
Vueプロジェクトのルートディレクトリに、stub-mdc-imports.js
などの新しいファイルを作成し、次の内容を追加します。
// stub-mdc-imports.js
export default {}
次に、VueプロジェクトのVite設定ファイル(例:vite.config.ts
)を更新して、モジュールのインポートをスタブファイルにエイリアスします。
import { defineConfig } from 'vite'
import path from 'path'
export default defineConfig({
resolve: {
alias: {
'#mdc-imports': path.resolve(__dirname, './stub-mdc-imports.js'),
'#mdc-configs': path.resolve(__dirname, './stub-mdc-imports.js'),
}
}
})
使用方法
次に、Markdownコンテンツの解析と、Shikiを使用してコードブロックへの構文ハイライトの追加を処理するための新しいVueコンポーザブルを作成しましょう。
// composables/useMarkdownParser.ts
// Import package exports
import {
createMarkdownParser,
rehypeHighlight,
createShikiHighlighter,
} from '@nuxtjs/mdc/runtime'
// Import desired Shiki themes and languages
import MaterialThemePalenight from 'shiki/themes/material-theme-palenight.mjs'
import HtmlLang from 'shiki/langs/html.mjs'
import MdcLang from 'shiki/langs/mdc.mjs'
import TsLang from 'shiki/langs/typescript.mjs'
import VueLang from 'shiki/langs/vue.mjs'
import ScssLang from 'shiki/langs/scss.mjs'
import YamlLang from 'shiki/langs/yaml.mjs'
export default function useMarkdownParser() {
let parser: Awaited<ReturnType<typeof createMarkdownParser>>
const parse = async (markdown: string) => {
if (!parser) {
parser = await createMarkdownParser({
rehype: {
plugins: {
highlight: {
instance: rehypeHighlight,
options: {
// Pass in your desired theme(s)
theme: 'material-theme-palenight',
// Create the Shiki highlighter
highlighter: createShikiHighlighter({
bundledThemes: {
'material-theme-palenight': MaterialThemePalenight,
},
// Configure the bundled languages
bundledLangs: {
html: HtmlLang,
mdc: MdcLang,
vue: VueLang,
yml: YamlLang,
scss: ScssLang,
ts: TsLang,
typescript: TsLang,
},
}),
},
},
},
},
})
}
return parser(markdown)
}
return parse
}
作成したuseMarkdownParser
コンポーザブルとエクスポートされた型インターフェースをホストプロジェクトのVueコンポーネントにインポートし、それらを使用して生のMarkdownを処理し、<MDCRenderer>
コンポーネントを初期化します。
<script setup lang="ts">
import { onBeforeMount, ref, watch } from 'vue'
// Import package exports
import MDCRenderer from '@nuxtjs/mdc/runtime/components/MDCRenderer.vue'
import type { MDCParserResult } from '@nuxtjs/mdc'
import useMarkdownParser from './composables/useMarkdownParser';
const md = ref(`
# Just a Vue app
This is markdown content rendered via the \`<MDCRenderer>\` component, including MDC below.
::alert
Hello MDC
::
\`\`\`ts
const a = 1;
\`\`\`
`);
const ast = ref<MDCParserResult | null>(null)
const parse = useMarkdownParser()
onBeforeMount(async () => {
ast.value = await parse(md.value)
})
</script>
<template>
<Suspense>
<MDCRenderer v-if="ast?.body" :body="ast.body" :data="ast.data" />
</Suspense>
</template>
貢献
StackBlitzを使用して、このモジュールをオンラインで確認できます。
またはローカルで
- このリポジトリをクローンします。
pnpm install
を使用して依存関係をインストールします。pnpm dev
を使用して開発サーバーを起動します。
ライセンス
Copyright (c) NuxtLabs