ホスティングサービスをVercelに変更 (#32)

* vercel initial

* [ci skip] add gitignore

* fix config

* fix

* (add) prerendered routes を自動生成

* fix config

* fix path

* (fix) trailing slash
This commit is contained in:
かっこかり 2023-12-01 07:39:47 +09:00 committed by GitHub
parent b0ab53aefa
commit 1734b7bff6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 49 additions and 17 deletions

View File

@ -2,6 +2,7 @@
import type { LocaleObject } from '@nuxtjs/i18n/dist/runtime/composables'; import type { LocaleObject } from '@nuxtjs/i18n/dist/runtime/composables';
import NProgress from 'nprogress'; import NProgress from 'nprogress';
import type { Graph, Thing } from 'schema-dts'; import type { Graph, Thing } from 'schema-dts';
import { normalizeURL, withTrailingSlash } from 'ufo';
const nuxtApp = useNuxtApp(); 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 currentLocaleIso = computed(() => (locales.value as LocaleObject[]).find((e) => e?.code === locale.value)?.iso);
const head = useLocaleHead({ const head = useLocaleHead({
addSeoAttributes: true addSeoAttributes: true,
}); });
/** /**
@ -117,7 +118,7 @@ useHead((): Record<string, any> => ({
...(head.value.meta?.map((e) => ({ property: e.property, content: e.content, })) || []), ...(head.value.meta?.map((e) => ({ property: e.property, content: e.content, })) || []),
], ],
link: [ 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, ...cnHead,
], ],
script: [ script: [

View File

@ -1,11 +1,10 @@
// https://nuxt.com/docs/api/configuration/nuxt-config // https://nuxt.com/docs/api/configuration/nuxt-config
import yaml from '@rollup/plugin-yaml'; import yaml from '@rollup/plugin-yaml';
import svgLoader from 'vite-svg-loader'; 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 { genApiTranslationFiles } from './scripts/gen-api-translations';
import type { LocaleObject } from '@nuxtjs/i18n/dist/runtime/composables'; import type { LocaleObject } from '@nuxtjs/i18n/dist/runtime/composables';
import { genLocalesJson } from './scripts/gen-locales'; import { genLocalesJson } from './scripts/gen-locales';
import { getStaticEndpoints } from './scripts/get-static-endpoints';
import type { NuxtConfig } from 'nuxt/schema'; import type { NuxtConfig } from 'nuxt/schema';
// 公開時のドメイン(末尾スラッシュなし) // 公開時のドメイン(末尾スラッシュなし)
@ -31,8 +30,8 @@ export const locales = localesConst as unknown as LocaleObject[];
function getRouteRules(): NuxtConfig['routeRules'] { function getRouteRules(): NuxtConfig['routeRules'] {
// 言語ごとに割り当てる必要のないRouteRules // 言語ごとに割り当てる必要のないRouteRules
const staticRules: NuxtConfig['routeRules'] = { const staticRules: NuxtConfig['routeRules'] = {
'/**': { prerender: true },
'/ja/blog/**': { isr: true }, '/ja/blog/**': { isr: true },
'/ns/': { prerender: true },
}; };
// それぞれの言語について割り当てる必要のあるRouteRules // それぞれの言語について割り当てる必要のあるRouteRules
@ -40,6 +39,14 @@ function getRouteRules(): NuxtConfig['routeRules'] {
'/docs/**': { isr: true }, '/docs/**': { isr: true },
}; };
// 静的ページをすべて追加
getStaticEndpoints().forEach((route) => {
if (!route.includes('ns')) {
localeBasedRules[route] = { prerender: true };
staticRules[route] = { prerender: true };
}
});
// 言語ごとにすべて割り当てていく // 言語ごとにすべて割り当てていく
const _localeBasedRules: NuxtConfig['routeRules'] = {}; const _localeBasedRules: NuxtConfig['routeRules'] = {};
const localeCodes = locales.map((v) => v.code); const localeCodes = locales.map((v) => v.code);
@ -142,18 +149,7 @@ export default defineNuxtConfig({
], ],
}, },
nitro: { nitro: {
hooks: { preset: 'vercel',
'compiled': genSitemap,
},
/*prerender: {
concurrency: cpus().length * 8 ?? 12,
routes: [
"/404.html",
"/200.html"
],
// 【一時対応】とりあえずビルドできるようにする
failOnError: false,
},*/
plugins: [ plugins: [
'@/server/plugins/appendComment.ts', '@/server/plugins/appendComment.ts',
'@/server/plugins/i18nRedirector.ts', '@/server/plugins/i18nRedirector.ts',

View File

@ -21,6 +21,9 @@ export default async function genSitemap(nitro: Nitro) {
priority: .7, priority: .7,
} as SitemapItem; } as SitemapItem;
}); });
if (routes.length === 0) return;
const smStream = new SitemapStream({ hostname: domain }); const smStream = new SitemapStream({ hostname: domain });
Readable.from(routes).pipe(smStream); Readable.from(routes).pipe(smStream);

View File

@ -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();
}

3
vercel.json Normal file
View File

@ -0,0 +1,3 @@
{
"trailingSlash": true
}