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

Nuxtでビルド時にAPIを静的化して、完全にサーバーへのリクエストをなくすト

ビルド時にAPIを静的化するジェネレータを自作しましたので、ご紹介です。(コード有りです。)

最近はやりのヘッドレスCMSをやっていこうと思ったのですが、APIのリクエスト制限きびしいんですよね...。

現状だとNuxtは静的generateモードでも、ページ遷移時にリクエストが発生してしまうので、完全に静的化してしまう必要がありました。

以下のような流れになります。

  • Nuxtビルド時にJSONを生成
  • <link rel="prefetch"> にJSONを追加
  • ルート生成
  • コンポーネントからは /_nuxt/articles/xxx.json にリクエスト

<link rel="prefetch"> の指定で、生成したJSONは前もって準備するようにしています。)

ジェネレータの中身は以下。

modules/generator.js
import axios from 'axios'

module.exports = function generateModule(moduleOptions) {
  this.nuxt.hook('build:before', async ({ app }) => {

    // 全データを取得
    const { data } = await axios.get('/hogehoge')
    const posts = data

    // JSONを生成
    this.options.build.plugins.push({
      apply(compiler) {
        compiler.plugin('emit', (compilation, cb) => {
          posts.forEach(post => {
            compilation.assets[`articles/${post.slug}.json`] = {
              source: () => JSON.stringify(post),
              size: () => {}
            }
          })
          cb()
        })
      }
    })

    // link rel="prefetch"にJSONを追加
    const url = this.options.dev ? '' : 'https://xxx'
    this.options.head.link = [
      ...this.options.head.link,
      ...posts.map(post => ({
        rel: 'prefetch',
        href: `${url}/_nuxt/articles/${post.slug}.json`
      }))
    ]

    if (this.options.dev) return

    // ルート生成
    this.options.generate.routes = posts.map(post => `/${post.slug}`)
  })
}

こんな感じにモジュールを書いて、nuxt.config.js で設定します。

nuxt.config.js
module.exports = {
  // ジェネレータ内で開発orプロダクションの書き分けに使用しています
  dev: process.env.NODE_ENV !== 'production',

  // モジュールを指定
  modules: ['~/modules/generator'],

  ...
}

コンポーネントからは以下のようにデータを取得します。

pages/_id.vue
<script>
export default {
  async asyncData({ app, params }) {
    const url = process.env.NODE_ENV === 'development' ? '' : 'https://xxx'
    const { data } = await app.$axios.get(
      `${url}/_nuxt/articles/${params.id}.json`
    )
    return { article: data }
  }
}
</script>

これで表示・遷移時ともにサーバーへデータ取得のリクエストを送らずにすむようになりました😙

こちらの情報を参考にさせていただきました。
Firebase、Flamelink、Nuxt、Netlify、PWAを使ってJAMstackなブログを作る

soichiro_nitta
埼玉県在住、フリーランスのデザイナー兼デベロッパー。JavaScriptでのSPA開発、デザイン、2Dアニメーションが得意。
https://nitta.studio
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
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  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
ユーザーは見つかりませんでした