Hero img
npm build前にスクリプトを起動する

npm build前に必要な処理をさせるプレビルド

nextjsでビルド前にスクリプトを実行させ静的ファイルが必要になりprebuildがあることを知った。


目次

  • npm run build
  • prebuild
  • いつ使うのか?
  • サイトマップの作成
  • build後の処理は?
  • まとめ

npm run build

next.jsでビルド前に静的ファイルが欲しかったのでどうすればいいのか?
を模索していましたがちゃんとビルド前に実行されるスクリプト記入方が用意されていました。

prebuild

npm run buildし、ビルドが実行される前に実行されるスクリプトを指定することができます。 package.jsonの中身に追加するだけのとても簡単な方法です。
npmがこんなことできるなんて全く知りませんでした。

  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "prebuild": "node createlocalfiles.js",//<--これ
  }

いつ使うのか?

私の場合毎回はサイトアクセス時forloop等で実行し、サーバー上にあるファイルを全て取得し、整列させ....という処理がありましたが、あまりにも無駄な処理だと感じたためビルド前に静的ファイル(json)ファイルを取得して、それを使えばいいんじゃない?と考えてビルド前にファイルを作成することにしました。

sitemap

nextjsのサイトマッププラグインが使いづらい、ってかエラーで作成できなかった。
一からサイトマップ作るコードを書くのはめんどくさいと思いましたが、案外簡単だったのでビルド前にサイトマップをpublicフォルダーに入れてしまう事にしました。

サイトマップの作成

実際に今このブログでも使いました。
ぶっちゃけほとんど参考にならないと思いますが一応載せておきます。

const fs = require('fs');
const matter = require('gray-matter')
const Writefile = async () => {
  const postf = fs.readdirSync("./blogposts").filter((postPath) => /\.md?$/.test(postPath));;
  fs.writeFile('postlist.txt', JSON.stringify(postf), function (err) {
    if (err) throw err;
    console.log('JSONファイルが作成されました!');
  });
  let xml = `<?xml version="1.0" encoding="UTF-8"?><urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:news="http://www.google.com/schemas/sitemap-news/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1" xmlns:video="http://www.google.com/schemas/sitemap-video/1.1"><url><loc>https://yumeno.me/</loc><changefreq>daily</changefreq><priority>0.7</priority></url>`;
  const posts = postf.map((slug) => {
    const content = fs.readFileSync("./blogposts/" + `${slug}`);
    const { data } = matter(content);

    let tmp =   slug.replace(/\.md?$/, '')
    xml +=`<url><loc>https://yumeno.me/${tmp}</loc><changefreq>daily</changefreq><priority>0.7</priority></url>`
      return {data};
  });

  xml +=`</urlset>`
  fs.writeFile('./public/sitemap-0.xml' ,xml , ((err)=>{
    if(err) throw err;
    console.log('created-sitemap');
  }))
  const allTags = posts.reduce((a, post) => {
    post.data.tag?.map((tag) => a.add(tag));
    return a;
  }, new Set([]));

  //sort tags
  const allTagssorted = [...allTags].sort((a, b) => a.localeCompare(b));
  allTagssorted.unshift('all');

  fs.writeFile('tags.txt', JSON.stringify(allTagssorted), function (err) {
    if (err) throw err;
    console.log('JSONファイルが作成されました!');
  });
}
Writefile();

とりあえずこの処理は何をしているのかを簡単にご紹介します。 postlist.txtファイルにサーバー上にあるmdファイル名を配列で書き込んでいます。
※一部抜粋

["aboutgatsby.md","aboutstripe.md","advance_array_curve.md",]

ついでに postf.mapでサイトマップのxmlにurlを追加していきます。

  const posts = postf.map((slug) => {
    const content = fs.readFileSync("./blogposts/" + `${slug}`);
    const { data } = matter(content);
    let tmp =   slug.replace(/\.md?$/, '')
    xml +=`<url><loc>https://yumeno.me/${tmp}</loc><changefreq>daily</changefreq><priority>0.7</priority></url>`
      return {data};
  });

その後ファイルのtagリストをアルファベット順に整列させてtag.txtファイルを作成しています。

  const allTags = posts.reduce((a, post) => {
    post.data.tag?.map((tag) => a.add(tag));
    return a;
  }, new Set([]));

  //sort tags
  const allTagssorted = [...allTags].sort((a, b) => a.localeCompare(b));
  allTagssorted.unshift('all');

  fs.writeFile('tags.txt', JSON.stringify(allTagssorted), function (err) {
    if (err) throw err;
    console.log('JSONファイルが作成されました!');
  });

build後の処理は?

nextjs-pm2でも書きましたがこんな感じで順番に実行させるという手段を取っています。

  "scripts": {
    "start": "npx next start -p 3000",
    "build": "npx next build & npm run build:clear ",
    "build:clear": "npm run build:7z ",
    "build:7z": "7z a hoge.tar ./.next/ ./public/ package.json ./prisma & npm run build:csp",
    "build:csp": "scp hoge.tar [email protected]:/home/usernames/next.tar"
  },

まとめ

ビルド前に静的ファイルが欲しい場合はprebuildを使えば実現できる。
ビルド後に何か欲しい場合は& npm hogeで実現することができる。

関連記事

コメント

コメントを書く

質問や、間違いがありましたら、お気軽にどうぞ

※お名前とコメントの内容を入力してください。
※全てこのブログ上に公表されます。
※許可なく管理者によって修正・削除する場合がございます。 詳しくはプライバシーポリシーを参照ください