VuePressの外部から最新の記事を取得する

Category:
Tags:
Last Updated: 2021/12/13 12:40:54

Ninja PressではWeb Ninjaトップページ (opens new window)から最新記事を取得しているのだが、VuePressはデフォルトではRSSなど外部から記事を読み込むための機能を持っていないため、ビルドの際に最新記事を出力するファイルを生成している。

*こちらの作成にあたってはVuePressにRSSフィードを追加する (opens new window)という記事を大いに参考にさせていただいた。当サイトではトップページからそのまま記事リンクを作成するためにjson、およびjsonpもどきのjsファイルとして出力しているが、RSSを出力したい場合にはこちらを参考にすればよさそう。

# enchantApp.js とは

VuePressを構築すると、enchantApp.js というファイルが自動的に作られる。

マニュアル (opens new window)には簡単な説明のみでさらっと書いてあるが、ビルド時にページ情報の詳細が渡されてくるため、イレギュラーな処理をさっと行いたい場合はここに処理を記載するのがやりやすい。

# 修正内容

最終的に enchantApp.js の内容は下記のようになった。


const fs = require('fs')
const path = require('path')
const moment = require('moment');
const _ = require("lodash");

let _done =false;

export default ({
  Vue, // the version of Vue being used in the VuePress app
  options, // the options for the root Vue instance
  router, // the router instance for the app
  siteData // site metadata
}) => {
	// こうすれば `yarn dev` ではスキップされるらしい。
	// 参考)https://www.yo1000.com/vuepress-rss
	try {
		global;
	} catch(e) {
		return;
	}

	// 試してみたところ、一度のビルドでこの関数自体が何度も呼ばれるので、最初の1回目以外は無視する。
	if (_done) return;
	_done = true;
	
	let pages = siteData.pages.filter(post => {
		if (post.relativePath) {
			// articles 以下のみ
			if (post.relativePath.indexOf("articles/") !== 0) {
				return false;
			}

			// README.md は無視
			if (post.relativePath.substr(-9) === "README.md") {
				return false;
			}
		}

		return true;
	}).map(post => {
		// ここは各々のURLに修正する
		const url = "https://web-ninja21.com" + path.join("/press/" ,post.regularPath);

		return {
			title: post.title, 
			url, 
			category: post.frontmatter.category, 
			tags: post.frontmatter.tags, 
			date: moment(post.frontmatter.date).format("YYYY/MM/DD hh:mm"),

			// lastUpdatedはフォーマットが異なるため、momentで警告が出る。
			// ビルドに支障はないが、毎回エラーが出るのは鬱陶しいし、Ninja Pressでは不要なのでコメントアウト。
			// lastUpdated: moment(post.lastUpdated).format("YYYY/MM/DD hh:mm"),
		};
	});
	pages = _.orderBy(pages, ["date"], ["desc"]);

	// JSONファイル
	// なぜか __dirname 変数がきちんと参照できないので、`yarn build` を実行するパスからの相対パスを指定する。
	fs.writeFileSync(
		path.resolve('./src/.vuepress/dist/latest.json'),
		JSON.stringify(pages)
	);

	// JSONPもどき
	fs.writeFileSync(
		path.resolve('./src/.vuepress/dist/latest.js'),
		`window && window._ninjaPress && window._ninjaPress(${JSON.stringify(pages)})`
	);
	
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73

これでdist以下に latest.jsonlatest.js というファイルが作られる。

Category:
Tags:
Last Updated: 2021/12/13 12:40:54
Copyright © Web Ninja All Rights Reserved.