Help us understand the problem. What is going on with this article?

Nuxtjsでgenerate時に、公開しているページのtitleとurlのリストを作成する

※力技での解決法です。絶対もっと良い方法があるはず。

発端としては、

フロントの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。

パーサー使えばもっと上品にできるかも。


非同期処理関連が結構躓いた。
当たり前だけど、同じサイトだろうが別ファイルの読み込みは時間かかるのね。

harmless_3d6
プログラマー(プログラマーではない)。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away