diff --git a/next.config.js b/next.config.js index 17f9a5df..0d717fce 100644 --- a/next.config.js +++ b/next.config.js @@ -4,6 +4,10 @@ const STORE_ID = process.env.BLOB_READ_WRITE_TOKEN?.match( /^vercel_blob_rw_([a-z0-9]+)_[a-z0-9]+$/i, )?.[1].toLowerCase(); +const withBundleAnalyzer = require('@next/bundle-analyzer')({ + enabled: process.env.ANALYZE === 'true', +}) + const nextConfig = { images: { imageSizes: [200, 400, 1050], @@ -19,4 +23,4 @@ const nextConfig = { }, }; -module.exports = nextConfig; +module.exports = withBundleAnalyzer(nextConfig); diff --git a/package.json b/package.json index d27211a8..0a73754e 100644 --- a/package.json +++ b/package.json @@ -4,9 +4,11 @@ "dev": "next dev", "build": "next build", "start": "next start", - "lint": "next lint" + "lint": "next lint", + "analyze": "ANALYZE=true next build" }, "dependencies": { + "@next/bundle-analyzer": "^13.5.3", "@tailwindcss/forms": "^0.5.6", "@types/node": "^20.7.0", "@types/react": "18.2.22", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 89d6f4b1..af930c6a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,6 +1,7 @@ lockfileVersion: 5.4 specifiers: + '@next/bundle-analyzer': ^13.5.3 '@tailwindcss/forms': ^0.5.6 '@types/node': ^20.7.0 '@types/react': 18.2.22 @@ -30,6 +31,7 @@ specifiers: typescript: 5.2.2 dependencies: + '@next/bundle-analyzer': 13.5.3 '@tailwindcss/forms': 0.5.6_tailwindcss@3.3.3 '@types/node': 20.7.0 '@types/react': 18.2.22 @@ -262,6 +264,15 @@ packages: '@types/pg': 8.6.6 dev: false + /@next/bundle-analyzer/13.5.3: + resolution: {integrity: sha512-AUHl9hu/0SNo2TCu9awOGY5hJdQHTPThYbjKk3rmjL04GfYAotn5i5pFQGqe209mbCxtu+QnvMEHLXU4GdFi1Q==} + dependencies: + webpack-bundle-analyzer: 4.7.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + dev: false + /@next/env/13.5.3: resolution: {integrity: sha512-X4te86vsbjsB7iO4usY9jLPtZ827Mbx+WcwNBGUOIuswuTAKQtzsuoxc/6KLxCMvogKG795MhrR1LDhYgDvasg==} dev: false @@ -378,6 +389,10 @@ packages: resolution: {integrity: sha512-dhPeilub1NuIG0X5Kvhh9lH4iW3ZsHlnzwgwbOlgwQ2wG1IqFzsgHqmKPk3WzsdWAeaxKJxgM0+W433RmN45GA==} dev: false + /@polka/url/1.0.0-next.23: + resolution: {integrity: sha512-C16M+IYz0rgRhWZdCmK+h58JMv8vijAA61gmz2rspCSwKwzBebpdcsiUmwrtJRdphuY30i6BSLEOP8ppbNLyLg==} + dev: false + /@rushstack/eslint-patch/1.4.0: resolution: {integrity: sha512-cEjvTPU32OM9lUFegJagO0mRnIn+rbqrG89vV8/xLnLFX0DoR0r1oy5IlTga71Q7uT3Qus7qm7wgeiMT/+Irlg==} dev: false @@ -1044,6 +1059,11 @@ packages: engines: {node: '>= 6'} dev: false + /commander/7.2.0: + resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==} + engines: {node: '>= 10'} + dev: false + /concat-map/0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} dev: false @@ -1202,6 +1222,10 @@ packages: webidl-conversions: 7.0.0 dev: false + /duplexer/0.1.2: + resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==} + dev: false + /electron-to-chromium/1.4.525: resolution: {integrity: sha512-GIZ620hDK4YmIqAWkscG4W6RwY6gOx1y5J6f4JUQwctiJrqH2oxZYU4mXHi35oV32tr630UcepBzSBGJ/WYcZA==} dev: false @@ -1868,6 +1892,13 @@ packages: resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} dev: false + /gzip-size/6.0.0: + resolution: {integrity: sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==} + engines: {node: '>=10'} + dependencies: + duplexer: 0.1.2 + dev: false + /has-bigints/1.0.2: resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==} dev: false @@ -2361,6 +2392,10 @@ packages: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} dev: false + /lodash/4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + dev: false + /loose-envify/1.4.0: resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} hasBin: true @@ -2420,6 +2455,11 @@ packages: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} dev: false + /mrmime/1.0.1: + resolution: {integrity: sha512-hzzEagAgDyoU1Q6yg5uI+AorQgdvMCur3FcKf7NhMKWsaYg+RnbTyHRa/9IlLF9rf455MOCtcqqrQQ83pPP7Uw==} + engines: {node: '>=10'} + dev: false + /ms/2.1.2: resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} dev: false @@ -2624,6 +2664,11 @@ packages: wrappy: 1.0.2 dev: false + /opener/1.5.2: + resolution: {integrity: sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==} + hasBin: true + dev: false + /optionator/0.9.3: resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==} engines: {node: '>= 0.8.0'} @@ -3089,6 +3134,15 @@ packages: object-inspect: 1.12.3 dev: false + /sirv/1.0.19: + resolution: {integrity: sha512-JuLThK3TnZG1TAKDwNIqNq6QA2afLOCcm+iE8D1Kj3GA40pSPsxQjjJl0J8X3tsR7T+CP1GavpzLwYkgVLWrZQ==} + engines: {node: '>= 10'} + dependencies: + '@polka/url': 1.0.0-next.23 + mrmime: 1.0.1 + totalist: 1.1.0 + dev: false + /slash/3.0.0: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} engines: {node: '>=8'} @@ -3298,6 +3352,11 @@ packages: is-number: 7.0.0 dev: false + /totalist/1.1.0: + resolution: {integrity: sha512-gduQwd1rOdDMGxFG1gEvhV88Oirdo2p+KjoYFU7k2g+i7n6AFFbDQ5kMPUsW0pNbfQsB/cwXvT1i4Bue0s9g5g==} + engines: {node: '>=6'} + dev: false + /tough-cookie/4.1.3: resolution: {integrity: sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==} engines: {node: '>=6'} @@ -3490,6 +3549,25 @@ packages: engines: {node: '>=12'} dev: false + /webpack-bundle-analyzer/4.7.0: + resolution: {integrity: sha512-j9b8ynpJS4K+zfO5GGwsAcQX4ZHpWV+yRiHDiL+bE0XHJ8NiPYLTNVQdlFYWxtpg9lfAQNlwJg16J9AJtFSXRg==} + engines: {node: '>= 10.13.0'} + hasBin: true + dependencies: + acorn: 8.10.0 + acorn-walk: 8.2.0 + chalk: 4.1.2 + commander: 7.2.0 + gzip-size: 6.0.0 + lodash: 4.17.21 + opener: 1.5.2 + sirv: 1.0.19 + ws: 7.5.9 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + dev: false + /whatwg-encoding/2.0.0: resolution: {integrity: sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==} engines: {node: '>=12'} @@ -3570,6 +3648,19 @@ packages: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} dev: false + /ws/7.5.9: + resolution: {integrity: sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==} + engines: {node: '>=8.3.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ^5.0.2 + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + dev: false + /ws/8.14.2: resolution: {integrity: sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==} engines: {node: '>=10.0.0'} diff --git a/src/app/(static)/grid/page.tsx b/src/app/(static)/grid/page.tsx index 9d5b4c14..241cf5a6 100644 --- a/src/app/(static)/grid/page.tsx +++ b/src/app/(static)/grid/page.tsx @@ -10,12 +10,10 @@ import { generateOgImageMetaForPhotos, getPhotosLimitForQuery } from '@/photo'; import PhotoGrid from '@/photo/PhotoGrid'; import PhotosEmptyState from '@/photo/PhotosEmptyState'; import { MAX_PHOTOS_TO_SHOW_HOME } from '@/photo/image-response'; -import { IS_PRO_MODE } from '@/site/config'; import PhotoTag from '@/tag/PhotoTag'; import { Metadata } from 'next'; -// Limit edge runtime to Pro due to function size limit -export const runtime = IS_PRO_MODE ? 'edge' : 'nodejs'; +export const runtime = 'edge'; export async function generateMetadata(): Promise { const photos = await getPhotosCached({ limit: MAX_PHOTOS_TO_SHOW_HOME}); diff --git a/src/app/(static)/page.tsx b/src/app/(static)/page.tsx index 3c1462ef..2fcb8570 100644 --- a/src/app/(static)/page.tsx +++ b/src/app/(static)/page.tsx @@ -5,11 +5,9 @@ import SiteGrid from '@/components/SiteGrid'; import { generateOgImageMetaForPhotos, getPhotosLimitForQuery } from '@/photo'; import PhotoLarge from '@/photo/PhotoLarge'; import PhotosEmptyState from '@/photo/PhotosEmptyState'; -import { IS_PRO_MODE } from '@/site/config'; import { Metadata } from 'next'; -// Limit edge runtime to Pro due to function size limit -export const runtime = IS_PRO_MODE ? 'edge' : 'nodejs'; +export const runtime = 'edge'; export async function generateMetadata(): Promise { const photos = await getPhotosCached(); diff --git a/src/photo/index.ts b/src/photo/index.ts index b8cfdf56..94bfa5c1 100644 --- a/src/photo/index.ts +++ b/src/photo/index.ts @@ -11,7 +11,7 @@ import { formatFocalLength, } from '@/utility/exif'; import camelcaseKeys from 'camelcase-keys'; -import { Metadata } from 'next'; +import type { Metadata } from 'next'; export const GRID_THUMBNAILS_TO_SHOW_MAX = 12; diff --git a/src/utility/exif.ts b/src/utility/exif.ts index 1734e09d..9f05e46a 100644 --- a/src/utility/exif.ts +++ b/src/utility/exif.ts @@ -1,4 +1,4 @@ -import { ExifData } from 'ts-exif-parser'; +import type { ExifData } from 'ts-exif-parser'; const OFFSET_REGEX = /[+-]\d\d:\d\d/;