Something went wrong. Try again.
[READ-ONLY] Mirror of https://github.com/danielroe/roe.dev. This is the code and content for my personal website, built in Nuxt. roe.dev
Something went wrong. Try again.
TypeScript
at feat/sentry
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470/** @vitest-environment node */
import { fileURLToPath } from 'node:url'import fsp from 'node:fs/promises'import { execSync } from 'node:child_process'
import { afterAll, beforeAll, describe, expect, it } from 'vitest'import { globby } from 'globby'import { join } from 'pathe'
describe('project sizes', () => { const rootDir = fileURLToPath(new URL('../..', import.meta.url)) const publicDir = join(rootDir, '.output/public') const serverDir = join(rootDir, '.output/server')
const stats = { client: { totalBytes: 0, files: [] as string[] }, server: { totalBytes: 0, files: [] as string[] }, }
beforeAll(async () => { execSync('pnpm nuxt build', { cwd: rootDir, env: { ...process.env, NODE_ENV: 'production', DISABLE_PRERENDER: 'true' }, }) }, 120 * 1000)
afterAll(async () => { await fsp.writeFile( join(rootDir, '.output/test-stats.json'), JSON.stringify(stats, null, 2), ) })
it('default client bundle size', async () => { stats.client = await analyzeSizes('**/*.js', publicDir) expect .soft(roundToKilobytes(stats.client.totalBytes)) .toMatchInlineSnapshot(`"397k"`) expect.soft(stats.client.files.map(f => f.replace(/\..*\.js/, '.js').replace(/_scripts\/.*\.js/, '_scripts/script.js')).sort()) .toMatchInlineSnapshot(` [ "_nuxt/CalSchedule.js", "_nuxt/ContentRendererMarkdown.js", "_nuxt/ProseA.js", "_nuxt/ProseBlockquote.js", "_nuxt/ProseCode.js", "_nuxt/ProseCode.js", "_nuxt/ProseCodeInline.js", "_nuxt/ProseEm.js", "_nuxt/ProseH1.js", "_nuxt/ProseH2.js", "_nuxt/ProseH3.js", "_nuxt/ProseH4.js", "_nuxt/ProseH5.js", "_nuxt/ProseH6.js", "_nuxt/ProseHr.js", "_nuxt/ProseImg.js", "_nuxt/ProseLi.js", "_nuxt/ProseOl.js", "_nuxt/ProseP.js", "_nuxt/ProsePre.js", "_nuxt/ProseScript.js", "_nuxt/ProseStrong.js", "_nuxt/ProseTable.js", "_nuxt/ProseTbody.js", "_nuxt/ProseTd.js", "_nuxt/ProseTh.js", "_nuxt/ProseThead.js", "_nuxt/ProseTr.js", "_nuxt/ProseUl.js", "_nuxt/SocialPost.js", "_nuxt/entry.js", "_nuxt/sentry.js", "_scripts/script.js", ] `) })
it('default server bundle size', async () => { stats.server = await analyzeSizes(['**/*.mjs', '!node_modules'], serverDir) expect .soft(roundToKilobytes(stats.server.totalBytes)) .toMatchInlineSnapshot(`"456k"`)
const modules = await analyzeSizes('node_modules/**/*', serverDir) expect .soft(roundToKilobytes(modules.totalBytes)) .toMatchInlineSnapshot(`"23172k"`)
const packages = modules.files .filter(m => m.endsWith('package.json')) .map(m => m.replace('/package.json', '').replace('node_modules/', '')) .sort() expect.soft(packages).toMatchInlineSnapshot(` [ "@atproto/api", "@atproto/common-web", "@atproto/lexicon", "@atproto/syntax", "@atproto/xrpc", "@babel/parser", "@opentelemetry/api", "@opentelemetry/api-logs", "@opentelemetry/context-async-hooks", "@opentelemetry/core", "@opentelemetry/core/node_modules/@opentelemetry/semantic-conventions", "@opentelemetry/instrumentation", "@opentelemetry/instrumentation-amqplib", "@opentelemetry/instrumentation-amqplib/node_modules/@opentelemetry/core", "@opentelemetry/instrumentation-amqplib/node_modules/@opentelemetry/core/node_modules/@opentelemetry/semantic-conventions", "@opentelemetry/instrumentation-amqplib/node_modules/@opentelemetry/instrumentation", "@opentelemetry/instrumentation-amqplib/node_modules/@opentelemetry/instrumentation/node_modules/@opentelemetry/api-logs", "@opentelemetry/instrumentation-amqplib/node_modules/@opentelemetry/semantic-conventions", "@opentelemetry/instrumentation-connect", "@opentelemetry/instrumentation-connect/node_modules/@opentelemetry/core", "@opentelemetry/instrumentation-connect/node_modules/@opentelemetry/core/node_modules/@opentelemetry/semantic-conventions", "@opentelemetry/instrumentation-connect/node_modules/@opentelemetry/instrumentation", "@opentelemetry/instrumentation-connect/node_modules/@opentelemetry/instrumentation/node_modules/@opentelemetry/api-logs", "@opentelemetry/instrumentation-connect/node_modules/@opentelemetry/semantic-conventions", "@opentelemetry/instrumentation-dataloader", "@opentelemetry/instrumentation-dataloader/node_modules/@opentelemetry/instrumentation", "@opentelemetry/instrumentation-dataloader/node_modules/@opentelemetry/instrumentation/node_modules/@opentelemetry/api-logs", "@opentelemetry/instrumentation-express", "@opentelemetry/instrumentation-express/node_modules/@opentelemetry/core", "@opentelemetry/instrumentation-express/node_modules/@opentelemetry/core/node_modules/@opentelemetry/semantic-conventions", "@opentelemetry/instrumentation-express/node_modules/@opentelemetry/instrumentation", "@opentelemetry/instrumentation-express/node_modules/@opentelemetry/instrumentation/node_modules/@opentelemetry/api-logs", "@opentelemetry/instrumentation-express/node_modules/@opentelemetry/semantic-conventions", "@opentelemetry/instrumentation-fastify", "@opentelemetry/instrumentation-fastify/node_modules/@opentelemetry/core", "@opentelemetry/instrumentation-fastify/node_modules/@opentelemetry/core/node_modules/@opentelemetry/semantic-conventions", "@opentelemetry/instrumentation-fastify/node_modules/@opentelemetry/instrumentation", "@opentelemetry/instrumentation-fastify/node_modules/@opentelemetry/instrumentation/node_modules/@opentelemetry/api-logs", "@opentelemetry/instrumentation-fastify/node_modules/@opentelemetry/semantic-conventions", "@opentelemetry/instrumentation-fs", "@opentelemetry/instrumentation-fs/node_modules/@opentelemetry/core", "@opentelemetry/instrumentation-fs/node_modules/@opentelemetry/core/node_modules/@opentelemetry/semantic-conventions", "@opentelemetry/instrumentation-fs/node_modules/@opentelemetry/instrumentation", "@opentelemetry/instrumentation-fs/node_modules/@opentelemetry/instrumentation/node_modules/@opentelemetry/api-logs", "@opentelemetry/instrumentation-generic-pool", "@opentelemetry/instrumentation-generic-pool/node_modules/@opentelemetry/instrumentation", "@opentelemetry/instrumentation-generic-pool/node_modules/@opentelemetry/instrumentation/node_modules/@opentelemetry/api-logs", "@opentelemetry/instrumentation-graphql", "@opentelemetry/instrumentation-graphql/node_modules/@opentelemetry/instrumentation", "@opentelemetry/instrumentation-graphql/node_modules/@opentelemetry/instrumentation/node_modules/@opentelemetry/api-logs", "@opentelemetry/instrumentation-hapi", "@opentelemetry/instrumentation-hapi/node_modules/@opentelemetry/core", "@opentelemetry/instrumentation-hapi/node_modules/@opentelemetry/core/node_modules/@opentelemetry/semantic-conventions", "@opentelemetry/instrumentation-hapi/node_modules/@opentelemetry/instrumentation", "@opentelemetry/instrumentation-hapi/node_modules/@opentelemetry/instrumentation/node_modules/@opentelemetry/api-logs", "@opentelemetry/instrumentation-hapi/node_modules/@opentelemetry/semantic-conventions", "@opentelemetry/instrumentation-http", "@opentelemetry/instrumentation-http/node_modules/@opentelemetry/core", "@opentelemetry/instrumentation-http/node_modules/@opentelemetry/core/node_modules/@opentelemetry/semantic-conventions", "@opentelemetry/instrumentation-http/node_modules/@opentelemetry/instrumentation", "@opentelemetry/instrumentation-http/node_modules/@opentelemetry/instrumentation/node_modules/@opentelemetry/api-logs", "@opentelemetry/instrumentation-http/node_modules/@opentelemetry/semantic-conventions", "@opentelemetry/instrumentation-ioredis", "@opentelemetry/instrumentation-ioredis/node_modules/@opentelemetry/instrumentation", "@opentelemetry/instrumentation-ioredis/node_modules/@opentelemetry/instrumentation/node_modules/@opentelemetry/api-logs", "@opentelemetry/instrumentation-ioredis/node_modules/@opentelemetry/semantic-conventions", "@opentelemetry/instrumentation-kafkajs", "@opentelemetry/instrumentation-kafkajs/node_modules/@opentelemetry/instrumentation", "@opentelemetry/instrumentation-kafkajs/node_modules/@opentelemetry/instrumentation/node_modules/@opentelemetry/api-logs", "@opentelemetry/instrumentation-kafkajs/node_modules/@opentelemetry/semantic-conventions", "@opentelemetry/instrumentation-knex", "@opentelemetry/instrumentation-knex/node_modules/@opentelemetry/instrumentation", "@opentelemetry/instrumentation-knex/node_modules/@opentelemetry/instrumentation/node_modules/@opentelemetry/api-logs", "@opentelemetry/instrumentation-knex/node_modules/@opentelemetry/semantic-conventions", "@opentelemetry/instrumentation-koa", "@opentelemetry/instrumentation-koa/node_modules/@opentelemetry/core", "@opentelemetry/instrumentation-koa/node_modules/@opentelemetry/core/node_modules/@opentelemetry/semantic-conventions", "@opentelemetry/instrumentation-koa/node_modules/@opentelemetry/instrumentation", "@opentelemetry/instrumentation-koa/node_modules/@opentelemetry/instrumentation/node_modules/@opentelemetry/api-logs", "@opentelemetry/instrumentation-koa/node_modules/@opentelemetry/semantic-conventions", "@opentelemetry/instrumentation-lru-memoizer", "@opentelemetry/instrumentation-lru-memoizer/node_modules/@opentelemetry/instrumentation", "@opentelemetry/instrumentation-lru-memoizer/node_modules/@opentelemetry/instrumentation/node_modules/@opentelemetry/api-logs", "@opentelemetry/instrumentation-mongodb", "@opentelemetry/instrumentation-mongodb/node_modules/@opentelemetry/instrumentation", "@opentelemetry/instrumentation-mongodb/node_modules/@opentelemetry/instrumentation/node_modules/@opentelemetry/api-logs", "@opentelemetry/instrumentation-mongodb/node_modules/@opentelemetry/semantic-conventions", "@opentelemetry/instrumentation-mongoose", "@opentelemetry/instrumentation-mongoose/node_modules/@opentelemetry/core", "@opentelemetry/instrumentation-mongoose/node_modules/@opentelemetry/core/node_modules/@opentelemetry/semantic-conventions", "@opentelemetry/instrumentation-mongoose/node_modules/@opentelemetry/instrumentation", "@opentelemetry/instrumentation-mongoose/node_modules/@opentelemetry/instrumentation/node_modules/@opentelemetry/api-logs", "@opentelemetry/instrumentation-mongoose/node_modules/@opentelemetry/semantic-conventions", "@opentelemetry/instrumentation-mysql", "@opentelemetry/instrumentation-mysql/node_modules/@opentelemetry/instrumentation", "@opentelemetry/instrumentation-mysql/node_modules/@opentelemetry/instrumentation/node_modules/@opentelemetry/api-logs", "@opentelemetry/instrumentation-mysql/node_modules/@opentelemetry/semantic-conventions", "@opentelemetry/instrumentation-mysql2", "@opentelemetry/instrumentation-mysql2/node_modules/@opentelemetry/instrumentation", "@opentelemetry/instrumentation-mysql2/node_modules/@opentelemetry/instrumentation/node_modules/@opentelemetry/api-logs", "@opentelemetry/instrumentation-mysql2/node_modules/@opentelemetry/semantic-conventions", "@opentelemetry/instrumentation-nestjs-core", "@opentelemetry/instrumentation-nestjs-core/node_modules/@opentelemetry/instrumentation", "@opentelemetry/instrumentation-nestjs-core/node_modules/@opentelemetry/instrumentation/node_modules/@opentelemetry/api-logs", "@opentelemetry/instrumentation-nestjs-core/node_modules/@opentelemetry/semantic-conventions", "@opentelemetry/instrumentation-pg", "@opentelemetry/instrumentation-pg/node_modules/@opentelemetry/instrumentation", "@opentelemetry/instrumentation-pg/node_modules/@opentelemetry/instrumentation/node_modules/@opentelemetry/api-logs", "@opentelemetry/instrumentation-pg/node_modules/@opentelemetry/semantic-conventions", "@opentelemetry/instrumentation-redis-4", "@opentelemetry/instrumentation-redis-4/node_modules/@opentelemetry/instrumentation", "@opentelemetry/instrumentation-redis-4/node_modules/@opentelemetry/instrumentation/node_modules/@opentelemetry/api-logs", "@opentelemetry/instrumentation-redis-4/node_modules/@opentelemetry/semantic-conventions", "@opentelemetry/instrumentation-tedious", "@opentelemetry/instrumentation-tedious/node_modules/@opentelemetry/instrumentation", "@opentelemetry/instrumentation-tedious/node_modules/@opentelemetry/instrumentation/node_modules/@opentelemetry/api-logs", "@opentelemetry/instrumentation-tedious/node_modules/@opentelemetry/semantic-conventions", "@opentelemetry/instrumentation-undici", "@opentelemetry/instrumentation-undici/node_modules/@opentelemetry/core", "@opentelemetry/instrumentation-undici/node_modules/@opentelemetry/core/node_modules/@opentelemetry/semantic-conventions", "@opentelemetry/instrumentation-undici/node_modules/@opentelemetry/instrumentation", "@opentelemetry/instrumentation-undici/node_modules/@opentelemetry/instrumentation/node_modules/@opentelemetry/api-logs", "@opentelemetry/instrumentation/node_modules/@opentelemetry/api-logs", "@opentelemetry/redis-common", "@opentelemetry/resources", "@opentelemetry/resources/node_modules/@opentelemetry/core", "@opentelemetry/resources/node_modules/@opentelemetry/core/node_modules/@opentelemetry/semantic-conventions", "@opentelemetry/resources/node_modules/@opentelemetry/semantic-conventions", "@opentelemetry/sdk-trace-base", "@opentelemetry/sdk-trace-base/node_modules/@opentelemetry/core", "@opentelemetry/sdk-trace-base/node_modules/@opentelemetry/core/node_modules/@opentelemetry/semantic-conventions", "@opentelemetry/sdk-trace-base/node_modules/@opentelemetry/semantic-conventions", "@opentelemetry/semantic-conventions", "@opentelemetry/sql-common", "@opentelemetry/sql-common/node_modules/@opentelemetry/core", "@opentelemetry/sql-common/node_modules/@opentelemetry/core/node_modules/@opentelemetry/semantic-conventions", "@prisma/instrumentation", "@prisma/instrumentation/node_modules/@opentelemetry/instrumentation", "@prisma/instrumentation/node_modules/@opentelemetry/instrumentation/node_modules/@opentelemetry/api-logs", "@sanity/client", "@sanity/eventsource", "@sentry/core", "@sentry/core/build/esm", "@sentry/node", "@sentry/node/build/esm", "@sentry/node/node_modules/@opentelemetry/core", "@sentry/node/node_modules/@opentelemetry/core/node_modules/@opentelemetry/semantic-conventions", "@sentry/node/node_modules/@opentelemetry/instrumentation", "@sentry/node/node_modules/@opentelemetry/instrumentation/node_modules/@opentelemetry/api-logs", "@sentry/node/node_modules/@opentelemetry/semantic-conventions", "@sentry/nuxt", "@sentry/nuxt/build/esm", "@sentry/opentelemetry", "@sentry/opentelemetry/build/esm", "@sentry/opentelemetry/node_modules/@opentelemetry/core", "@sentry/opentelemetry/node_modules/@opentelemetry/core/node_modules/@opentelemetry/semantic-conventions", "@sentry/opentelemetry/node_modules/@opentelemetry/instrumentation", "@sentry/opentelemetry/node_modules/@opentelemetry/instrumentation/node_modules/@opentelemetry/api-logs", "@sentry/opentelemetry/node_modules/@opentelemetry/semantic-conventions", "@shikijs/core", "@shikijs/engine-javascript", "@shikijs/engine-oniguruma", "@shikijs/transformers", "@shikijs/types", "@shikijs/vscode-textmate", "@sindresorhus/is", "@ungap/structured-clone", "@unhead/dom", "@unhead/shared", "@unhead/ssr", "@vue/compiler-core", "@vue/compiler-dom", "@vue/reactivity", "@vue/runtime-core", "@vue/runtime-dom", "@vue/shared", "acorn", "acorn-import-attributes", "await-lock", "bail", "ccount", "char-regex", "character-entities", "character-entities-html4", "character-entities-legacy", "character-reference-invalid", "cjs-module-lexer", "comma-separated-tokens", "core-util-is", "cssfilter", "debug", "decode-named-character-reference", "decompress-response", "detab", "devalue", "devlop", "emojilib", "emoticon", "entities", "entities/lib/esm", "escape-string-regexp", "estree-walker", "events-to-async", "events-to-async/module", "eventsource", "extend", "feed", "flat", "follow-redirects", "function-bind", "get-it", "github-slugger", "graphemer", "hasown", "hast-util-from-parse5", "hast-util-is-element", "hast-util-parse-selector", "hast-util-raw", "hast-util-to-html", "hast-util-to-parse5", "hast-util-to-string", "hast-util-whitespace", "hastscript", "hookable", "html-void-elements", "image-meta", "import-in-the-middle", "inherits", "is-absolute-url", "is-alphabetical", "is-alphanumerical", "is-core-module", "is-decimal", "is-hexadecimal", "is-plain-obj", "is-retry-allowed", "isarray", "iso-datestring-validator", "js-yaml", "longest-streak", "lru-cache", "lru-cache/dist/esm", "markdown-table", "mdast-util-find-and-replace", "mdast-util-from-markdown", "mdast-util-gfm", "mdast-util-gfm-autolink-literal", "mdast-util-gfm-footnote", "mdast-util-gfm-strikethrough", "mdast-util-gfm-table", "mdast-util-gfm-task-list-item", "mdast-util-phrasing", "mdast-util-to-hast", "mdast-util-to-markdown", "mdast-util-to-string", "micromark", "micromark-core-commonmark", "micromark-extension-gfm", "micromark-extension-gfm-autolink-literal", "micromark-extension-gfm-footnote", "micromark-extension-gfm-strikethrough", "micromark-extension-gfm-table", "micromark-extension-gfm-tagfilter", "micromark-extension-gfm-task-list-item", "micromark-factory-destination", "micromark-factory-label", "micromark-factory-space", "micromark-factory-title", "micromark-factory-whitespace", "micromark-util-character", "micromark-util-chunked", "micromark-util-classify-character", "micromark-util-combine-extensions", "micromark-util-decode-numeric-character-reference", "micromark-util-decode-string", "micromark-util-encode", "micromark-util-html-tag-name", "micromark-util-normalize-identifier", "micromark-util-resolve-all", "micromark-util-sanitize-uri", "micromark-util-subtokenize", "mimic-response", "module-details-from-path", "ms", "multiformats", "node-emoji", "oniguruma-to-es", "parse-entities", "parse5", "path-parse", "process-nextick-args", "progress-stream", "property-information", "readable-stream", "readable-stream/node_modules/safe-buffer", "rehype-external-links", "rehype-raw", "rehype-sort-attribute-values", "rehype-sort-attributes", "remark-emoji", "remark-gfm", "remark-mdc", "remark-parse", "remark-rehype", "require-in-the-middle", "resolve", "rxjs", "safe-buffer", "sax", "scule", "semver", "shiki", "shimmer", "skin-tone", "source-map-js", "space-separated-tokens", "speedometer", "string_decoder", "string_decoder/node_modules/safe-buffer", "stringify-entities", "supports-color", "through2", "tlds", "trim-lines", "trough", "ts-custom-error", "tunnel-agent", "tunnel-agent/node_modules/safe-buffer", "uint8arrays", "unhead", "unicode-emoji-modifier-base", "unified", "unist-util-is", "unist-util-position", "unist-util-stringify-position", "unist-util-visit", "unist-util-visit-parents", "util-deprecate", "vfile", "vfile-location", "vfile-message", "vue", "web-namespaces", "xml-js", "xss", "xtend", "zod", "zwitch", ] `) })})
async function analyzeSizes (pattern: string | string[], rootDir: string) { const files: string[] = await globby(pattern, { cwd: rootDir }) let totalBytes = 0 for (const file of files) { const path = join(rootDir, file) const isSymlink = ( await fsp.lstat(path).catch(() => null) )?.isSymbolicLink()
if (!isSymlink) { const bytes = Buffer.byteLength(await fsp.readFile(path)) totalBytes += bytes } } return { files, totalBytes }}
function roundToKilobytes (bytes: number) { return (bytes / 1024).toFixed(bytes > 100 * 1024 ? 0 : 1) + 'k'}