くらげになりたい。

くらげのようにふわふわ生きたい日曜プログラマなブログ。趣味の備忘録です。

Nuxtでgenerate後になにか処理をする(Generator hooks)

Nuxtでビルドするときに、ビルド時のコミットIDとかをファイルに書き出したいなと思ったときの備忘録。

hooksプロパティなんてのがあるらしい。
The hooks Property - NuxtJS

hooksプロパティ

Nuxtのモジュールとかで使うNuxtのイベントのhookがnuxt.configに用意されている。

ビルド完了時(build:done)にファイルを書き出す処理の例はこんな感じ。

import fs from 'fs'
import path from 'path'

export default {
  hooks: {
    build: {
      done(builder) {
        const extraFilePath = path.join(builder.nuxt.options.buildDir, 'extra-file')
        fs.writeFileSync(extraFilePath, 'Something extra')
      }
    }
  }
}

hookの種類

種類はこの5つ。build時やgenerate時以外にもrender時などいろいろ。

hookの一覧

一覧にするとこんな感じ。

Category Plugin Arguments When
Renderer render:before (renderer, options) Before setting up middleware and resources for the Renderer class, useful to overload some methods or options.
Renderer render:setupMiddleware (app) connect instance Before Nuxt adds its middleware stack. We can use it to register custom server side middleware.
Renderer render:errorMiddleware (app) connect instance Before adding Nuxt error middleware, useful to add your own middleware before using Nuxt's. See the Sentry module for more info.
Renderer render:resourcesLoaded (resources) Called after resources for renderer are loaded (client manifest, server bundle, etc).
Renderer render:done (renderer) SSR Middleware and all resources are ready (Renderer ready)
Renderer render:routeContext (context.nuxt) Every time a route is server-rendered and before render:route hook. Called before serializing Nuxt context into window.NUXT, useful to add some data that you can fetch on client-side.
Renderer render:route (url, result, context) Every time a route is server-rendered. Called before sending back the request to the browser.
Renderer render:routeDone (url, result, context) Every time a route is server-rendered. Called after the response has been sent to the browser.
ModulesContainer modules:before (moduleContainer, options) Called before creating ModuleContainer class, useful to overload methods and options.
ModulesContainer modules:done (moduleContainer) Called when all modules have been loaded.
Builder build:before (nuxt, buildOptions) Before Nuxt build started
Builder builder:prepared (nuxt, buildOptions) The build directories have been created
Builder builder:extendPlugins (plugins) Generating plugins
Builder build:templates ({ templatesFiles, templateVars, resolve }) Generating .nuxt template files
Builder build:extendRoutes (routes, resolve) Generating routes
Builder webpack:config (webpackConfigs) Before configuration of compilers
Builder build:compile ({ name, compiler }) Before webpack compile (compiler is a webpack Compiler instance), if universal mode, called twice with name 'client' and 'server'
Builder build:compiled ({ name, compiler, stats }) webpack build finished
Builder build:done (nuxt) Nuxt build finished
Generater generate:before (generator, generateOptions) Hook on before generation
Generater generate:distRemoved (generator) Hook on destination folder cleaned
Generater generate:distCopied (generator) Hook on copy static and built files
Generater generate:route ({ route, setPayload }) Hook before generating the page, useful for dynamic payload, see #7422, available for Nuxt 2.13+
Generater generate:page ({ route, path, html }) Hook to let user update the path & html after generation
Generater generate:routeCreated ({ route, path, errors }) Hook on saving generated page success
Generater generate:extendRoutes (routes) Hook to let user update the routes to generate
Generater generate:routeFailed ({ route, errors }) Hook on saving generated page failure
Generater generate:done (generator, errors) Hook on generation finished

generate完了時にファイルを書き出してみる

ビルド時にbuildInfo.jsonというファイルにコミットIDを書き出す例。
GitHub Actionsを使う想定で、コミットIDはprocess.env.GITHUB_SHAから取得。

import { NuxtConfig } from "@nuxt/types";
import fs from "fs";
import path from "path";

const config: NuxtConfig = {
  hooks: {
    generate: {
      done(generator) {
        const filePath = path.join(generator.distPath, "buildInfo.json");
        fs.writeFileSync(filePath, JSON.stringify({ sha: process.env.GITHUB_SHA }), {
          encoding: "utf-8"
        });
        console.info(`Generated ${filePath}`);
      }
    }
  }
}

ただ、generate時だけなので、開発中だとファイルがない。。
なので、開発時用の処理も追加しておくと便利かも。

import { NuxtConfig } from "@nuxt/types";
import fs from "fs";
import path from "path";

// 開発時用
if (process.env.NODE_ENV != "production") {
  const filePath = path.join("./app/static/", "buildInfo.json");
  fs.writeFileSync(filePath, JSON.stringify({ sha: "develop" }), {
    encoding: "utf-8"
  });
}

const config: NuxtConfig = {
// ...
}

以上!!

参考にしたサイト様