※力技での解決法です。絶対もっと良い方法があるはず。
発端としては、
フロントのNuxt側でデータを受け取るだけでなく、
外部に渡せる形で書き出せないか?
と思ったこと。
ググったけど、あまり情報が見当たらず、
「そもそもこの発想自体がズレてるのでは?」と思えてきたが、
とりあえず作ってみた。
内容としてはシンプルに、
nuxt generate
で生成された
distの中のhtmlファイル群をスクレイピングすること。
まずはささっとモジュール作成。
generate-pages-info.js
const {resolve} = require('path')
const {readFileSync, writeFileSync} = require('fs')
const requireContext = require('require-context');
module.exports = async function () {
const {rootDir, generate: {dir: generateDir}} = this.options
const fileName = 'pages.json'
this.nuxt.hook('generate:done', async () => {
const dir_path = resolve(rootDir, generateDir);
const html_files = {};
const page_paths = requireContext(dir_path, true, /\.html$/).keys();
for (const page_path of page_paths) {
const name = page_path
.split("./")
.pop()
.split(".")
.shift();
html_files[name] = await getPageInfo(dir_path, page_path);
}
const pages_json = JSON.stringify(html_files);
const generate_file_path = resolve(rootDir, generateDir, fileName);
writeFileSync(generate_file_path, pages_json);
})
}
async function getPageInfo(dir_path, page_path) {
const file_path = resolve(dir_path, page_path);
const content = await readFileSync(file_path, "utf-8");
const page_title = content.match(/<title>(.*?)<\/title>/)[1];
const page_metas = await pageMetas(content);
return {
"title": page_title,
"metas": page_metas,
"url": page_path
}
}
async function pageMetas(content) {
const regex_text = /<meta[^<>]*?name=\"(.*?)\"[^<>]*?content=\"(.*?)\"/;
const metas = content.match(new RegExp(regex_text, 'g'));
let result = [];
for (const meta of metas) {
const match = meta.match(new RegExp(regex_text));
result.push({
"name": match[1],
"content": match[2]
})
}
return result;
}
nuxt.config.jsにモジュール登録。
nuxt.config.js
modules: [
'~modules/generate-pages-info.js'
]
あとはnuxt generate
して、
公開フォルダ(デフォルトではdist)にpages.jsonが出来ていればOK。
パーサー使えばもっと上品にできるかも。
非同期処理関連が結構躓いた。
当たり前だけど、同じサイトだろうが別ファイルの読み込みは時間かかるのね。