You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
vitepress/docs/ja/guide/data-loading.md

213 lines
7.6 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# ビルド時のデータの読み込み {#build-time-data-loading}
VitePress には **データローダー (data loaders)** という機能があり、任意のデータを読み込み、ページやコンポーネントからインポートすることができます。データの読み込みは **ビルド時のみ** 実行され、最終的な JavaScript バンドルには JSON としてシリアライズされたデータが含まれます。
データローダーはリモートデータの取得や、ローカルファイルに基づいたメタデータの生成に利用できます。たとえば、ローカルの API ページをすべて解析して API エントリのインデックスを自動生成するといったことが可能です。
## 基本的な使い方 {#basic-usage}
データローダーファイルは `.data.js` または `.data.ts` で終わる必要があります。ファイルは `load()` メソッドを持つオブジェクトをデフォルトエクスポートします。
```js [example.data.js]
export default {
load() {
return {
hello: 'world'
}
}
}
```
ローダーモジュールは Node.js 上でのみ評価されるため、Node API や npm 依存関係を自由に利用できます。
その後、このファイルから `.md` ページや `.vue` コンポーネントで `data` という名前のエクスポートを使ってデータをインポートできます。
```vue
<script setup>
import { data } from './example.data.js'
</script>
<pre>{{ data }}</pre>
```
出力:
```json
{
"hello": "world"
}
```
データローダー自体は `data` を直接エクスポートしていないことに気づくでしょう。これは VitePress が裏側で `load()` を呼び出し、その結果を暗黙的に `data` として公開しているためです。
ローダーが非同期でも動作します。
```js
export default {
async load() {
// リモートデータを取得
return (await fetch('...')).json()
}
}
```
## ローカルファイルからのデータ {#data-from-local-files}
ローカルファイルに基づいたデータを生成する必要がある場合は、データローダー内で `watch` オプションを使用し、ファイルの変更をホットリロードに反映させることが推奨されます。
`watch` では [glob パターン](https://github.com/mrmlnc/fast-glob#pattern-syntax) を利用して複数ファイルをマッチさせることができ、パターンはローダーファイルからの相対パスで指定できます。`load()` 関数にはマッチしたファイルの絶対パスが渡されます。
以下は CSV ファイルを読み込み [csv-parse](https://github.com/adaltas/node-csv/tree/master/packages/csv-parse/) を使って JSON に変換する例です。このコードはビルド時にのみ実行されるため、CSV パーサーがクライアントに送られることはありません。
```js
import fs from 'node:fs'
import { parse } from 'csv-parse/sync'
export default {
watch: ['./data/*.csv'],
load(watchedFiles) {
return watchedFiles.map((file) => {
return parse(fs.readFileSync(file, 'utf-8'), {
columns: true,
skip_empty_lines: true
})
})
}
}
```
## `createContentLoader`
コンテンツ中心のサイトを構築する場合、ブログ記事や API ページなどを一覧表示する「アーカイブ」や「インデックス」ページが必要になることがよくあります。これはデータローダー API を使って直接実装できますが、あまりにも一般的なケースなので VitePress では `createContentLoader` というヘルパーが用意されています。
```js [posts.data.js]
import { createContentLoader } from 'vitepress'
export default createContentLoader('posts/*.md', /* options */)
```
このヘルパーは [ソースディレクトリ](./routing#source-directory) からの相対 glob パターンを受け取り、`{ watch, load }` を返すデータローダーオブジェクトを生成します。これをデータローダーファイルのデフォルトエクスポートにできます。開発時のパフォーマンスを向上させるために、ファイルの更新時刻に基づくキャッシュも行われます。
このローダーは Markdown ファイルにのみ対応し、それ以外のファイルは無視されます。
読み込まれるデータは `ContentData[]` 型の配列です。
```ts
interface ContentData {
url: string // ページのマッピング URL例: /posts/hello.html
frontmatter: Record<string, any> // ページのフロントマター
src: string | undefined
html: string | undefined
excerpt: string | undefined
}
```
デフォルトでは `url``frontmatter` のみが提供されます。これは読み込まれたデータがクライアントバンドルに JSON としてインライン化されるため、サイズに注意する必要があるためです。
以下はデータを使って最小限のブログインデックスページを構築する例です。
```vue
<script setup>
import { data as posts } from './posts.data.js'
</script>
<template>
<h1>All Blog Posts</h1>
<ul>
<li v-for="post of posts">
<a :href="post.url">{{ post.frontmatter.title }}</a>
<span>by {{ post.frontmatter.author }}</span>
</li>
</ul>
</template>
```
### オプション {#options}
デフォルトデータが要件に合わない場合は、オプションで変換処理を追加できます。
```js [posts.data.js]
import { createContentLoader } from 'vitepress'
export default createContentLoader('posts/*.md', {
includeSrc: true, // 生の markdown ソースを含める?
render: true, // レンダリングされた HTML を含める?
excerpt: true, // 抜粋を含める?
transform(rawData) {
return rawData
.sort((a, b) => {
return +new Date(b.frontmatter.date) - +new Date(a.frontmatter.date)
})
.map((page) => {
page.src // 生の markdown ソース
page.html // レンダリングされた HTML
page.excerpt // 抜粋 HTML最初の `---` までの内容)
return {/* ... */}
})
}
})
```
[Vue.js ブログ](https://github.com/vuejs/blog/blob/main/.vitepress/theme/posts.data.ts) での使用例も参考になります。
`createContentLoader` API は [ビルドフック](../reference/site-config#build-hooks) 内でも利用可能です。
```js [.vitepress/config.js]
export default {
async buildEnd() {
const posts = await createContentLoader('posts/*.md').load()
// メタデータを基にファイルを生成(例: RSS フィード)
}
}
```
**型定義**
```ts
interface ContentOptions<T = ContentData[]> {
includeSrc?: boolean
render?: boolean
excerpt?:
| boolean
| ((file: { data: { [key: string]: any }; content: string; excerpt?: string }, options?: any) => void)
| string
transform?: (data: ContentData[]) => T | Promise<T>
}
```
## 型付きデータローダー {#typed-data-loaders}
TypeScript を使用する場合は、ローダーと `data` エクスポートを型付けできます。
```ts
import { defineLoader } from 'vitepress'
export interface Data {
// データ型
}
declare const data: Data
export { data }
export default defineLoader({
watch: ['...'],
async load(): Promise<Data> {
// ...
}
})
```
## 設定情報の取得 {#configuration}
ローダー内で設定情報を取得するには次のようにします。
```ts
import type { SiteConfig } from 'vitepress'
const config: SiteConfig = (globalThis as any).VITEPRESS_CONFIG
```