From 1734b7bff632d6c8c9e3040d13b04a853ec7e8d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=8B=E3=81=A3=E3=81=93=E3=81=8B=E3=82=8A?= <67428053+kakkokari-gtyih@users.noreply.github.com> Date: Fri, 1 Dec 2023 07:39:47 +0900 Subject: [PATCH] =?UTF-8?q?=E3=83=9B=E3=82=B9=E3=83=86=E3=82=A3=E3=83=B3?= =?UTF-8?q?=E3=82=B0=E3=82=B5=E3=83=BC=E3=83=93=E3=82=B9=E3=82=92Vercel?= =?UTF-8?q?=E3=81=AB=E5=A4=89=E6=9B=B4=20(#32)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * vercel initial * [ci skip] add gitignore * fix config * fix * (add) prerendered routes を自動生成 * fix config * fix path * (fix) trailing slash --- app.vue | 5 +++-- nuxt.config.ts | 26 +++++++++++--------------- scripts/gen-sitemap.ts | 3 +++ scripts/get-static-endpoints.ts | 29 +++++++++++++++++++++++++++++ vercel.json | 3 +++ 5 files changed, 49 insertions(+), 17 deletions(-) create mode 100644 scripts/get-static-endpoints.ts create mode 100644 vercel.json diff --git a/app.vue b/app.vue index d79eb4fe..4577ba70 100644 --- a/app.vue +++ b/app.vue @@ -2,6 +2,7 @@ import type { LocaleObject } from '@nuxtjs/i18n/dist/runtime/composables'; import NProgress from 'nprogress'; import type { Graph, Thing } from 'schema-dts'; +import { normalizeURL, withTrailingSlash } from 'ufo'; const nuxtApp = useNuxtApp(); @@ -69,7 +70,7 @@ const getLdJson = (additionalGraphes: Thing[] = []): string => { const currentLocaleIso = computed(() => (locales.value as LocaleObject[]).find((e) => e?.code === locale.value)?.iso); const head = useLocaleHead({ - addSeoAttributes: true + addSeoAttributes: true, }); /** @@ -117,7 +118,7 @@ useHead((): Record => ({ ...(head.value.meta?.map((e) => ({ property: e.property, content: e.content, })) || []), ], link: [ - ...(head.value.link?.map((e) => ({ rel: e.rel, href: (e.href.endsWith('/') ? e.href : e.href + '/'), hreflang: e.hreflang, })) || []), + ...(head.value.link?.map((e) => ({ rel: e.rel, href: normalizeURL(withTrailingSlash(e.href)), hreflang: e.hreflang, })) || []), ...cnHead, ], script: [ diff --git a/nuxt.config.ts b/nuxt.config.ts index 8e3fb673..4e08f344 100644 --- a/nuxt.config.ts +++ b/nuxt.config.ts @@ -1,11 +1,10 @@ // https://nuxt.com/docs/api/configuration/nuxt-config import yaml from '@rollup/plugin-yaml'; import svgLoader from 'vite-svg-loader'; -import { cpus } from 'node:os'; -import genSitemap from './scripts/gen-sitemap'; import { genApiTranslationFiles } from './scripts/gen-api-translations'; import type { LocaleObject } from '@nuxtjs/i18n/dist/runtime/composables'; import { genLocalesJson } from './scripts/gen-locales'; +import { getStaticEndpoints } from './scripts/get-static-endpoints'; import type { NuxtConfig } from 'nuxt/schema'; // 公開時のドメイン(末尾スラッシュなし) @@ -31,8 +30,8 @@ export const locales = localesConst as unknown as LocaleObject[]; function getRouteRules(): NuxtConfig['routeRules'] { // 言語ごとに割り当てる必要のないRouteRules const staticRules: NuxtConfig['routeRules'] = { - '/**': { prerender: true }, '/ja/blog/**': { isr: true }, + '/ns/': { prerender: true }, }; // それぞれの言語について割り当てる必要のあるRouteRules @@ -40,6 +39,14 @@ function getRouteRules(): NuxtConfig['routeRules'] { '/docs/**': { isr: true }, }; + // 静的ページをすべて追加 + getStaticEndpoints().forEach((route) => { + if (!route.includes('ns')) { + localeBasedRules[route] = { prerender: true }; + staticRules[route] = { prerender: true }; + } + }); + // 言語ごとにすべて割り当てていく const _localeBasedRules: NuxtConfig['routeRules'] = {}; const localeCodes = locales.map((v) => v.code); @@ -142,18 +149,7 @@ export default defineNuxtConfig({ ], }, nitro: { - hooks: { - 'compiled': genSitemap, - }, - /*prerender: { - concurrency: cpus().length * 8 ?? 12, - routes: [ - "/404.html", - "/200.html" - ], - // 【一時対応】とりあえずビルドできるようにする - failOnError: false, - },*/ + preset: 'vercel', plugins: [ '@/server/plugins/appendComment.ts', '@/server/plugins/i18nRedirector.ts', diff --git a/scripts/gen-sitemap.ts b/scripts/gen-sitemap.ts index 702c6f67..8130bbe6 100644 --- a/scripts/gen-sitemap.ts +++ b/scripts/gen-sitemap.ts @@ -21,6 +21,9 @@ export default async function genSitemap(nitro: Nitro) { priority: .7, } as SitemapItem; }); + + if (routes.length === 0) return; + const smStream = new SitemapStream({ hostname: domain }); Readable.from(routes).pipe(smStream); diff --git a/scripts/get-static-endpoints.ts b/scripts/get-static-endpoints.ts new file mode 100644 index 00000000..943c282c --- /dev/null +++ b/scripts/get-static-endpoints.ts @@ -0,0 +1,29 @@ +import fs from 'fs'; +import { resolve, dirname } from 'path'; +import { fileURLToPath } from 'url'; + +export function getStaticEndpoints(): string[] { + const __dirname = dirname(fileURLToPath(import.meta.url)) + const dir = resolve(`${__dirname}/../pages`); + const files = getFiles(dir); + const filtered = files + .filter((file) => !file.includes('slug')) // exclude dynamic content + .map((file) => file.split('pages')[1]) + .map((file) => file.replaceAll('\\', '/')) + .map((file) => { + return (file.endsWith('index.vue') ? file.replace(/\/index.vue$/, '') : file.split('.vue')[0]) + '/'; + }); + return filtered; +} + +/** + * recursively get all files from /pages folder + */ +function getFiles(dir: string): string[] { + const dirents = fs.readdirSync(dir, { withFileTypes: true }); + const files = dirents.map((dirent) => { + const res = resolve(dir, dirent.name); + return dirent.isDirectory() ? getFiles(res) : res; + }) + return files.flat(); +} diff --git a/vercel.json b/vercel.json new file mode 100644 index 00000000..c83d9edb --- /dev/null +++ b/vercel.json @@ -0,0 +1,3 @@ +{ + "trailingSlash": true +} \ No newline at end of file