diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 80a4090ed6..a327d7ae5b 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -1112,6 +1112,12 @@ importers:
specifier: workspace:*
version: link:../../../packages/nuxt
+ test/fixtures/minimal-pages:
+ dependencies:
+ nuxt:
+ specifier: workspace:*
+ version: link:../../../packages/nuxt
+
test/fixtures/minimal-types:
dependencies:
nuxt:
diff --git a/test/bundle.test.ts b/test/bundle.test.ts
index fa71467805..a87a662094 100644
--- a/test/bundle.test.ts
+++ b/test/bundle.test.ts
@@ -7,11 +7,13 @@ import { join } from 'pathe'
describe.skipIf(process.env.SKIP_BUNDLE_SIZE === 'true' || process.env.ECOSYSTEM_CI)('minimal nuxt application', () => {
const rootDir = fileURLToPath(new URL('./fixtures/minimal', import.meta.url))
+ const pagesRootDir = fileURLToPath(new URL('./fixtures/minimal-pages', import.meta.url))
beforeAll(async () => {
await Promise.all([
exec('pnpm', ['nuxi', 'build', rootDir], { nodeOptions: { env: { EXTERNAL_VUE: 'false' } } }),
exec('pnpm', ['nuxi', 'build', rootDir], { nodeOptions: { env: { EXTERNAL_VUE: 'true' } } }),
+ exec('pnpm', ['nuxi', 'build', pagesRootDir]),
])
}, 120 * 1000)
@@ -33,6 +35,25 @@ describe.skipIf(process.env.SKIP_BUNDLE_SIZE === 'true' || process.env.ECOSYSTEM
`)
})
+ it('default client bundle size (pages)', async () => {
+ const clientStats = await analyzeSizes(['**/*.js'], join(pagesRootDir, '.output/public'))
+
+ expect.soft(roundToKilobytes(clientStats!.totalBytes)).toMatchInlineSnapshot(`"175k"`)
+
+ const files = clientStats!.files.map(f => f.replace(/\..*\.js/, '.js'))
+
+ expect([...files]).toMatchInlineSnapshot(`
+ [
+ "_nuxt/a.js",
+ "_nuxt/client-component.js",
+ "_nuxt/default.js",
+ "_nuxt/entry.js",
+ "_nuxt/index.js",
+ "_nuxt/server-component.js",
+ ]
+ `)
+ })
+
it('default server bundle size', async () => {
const serverDir = join(rootDir, '.output/server')
@@ -99,6 +120,47 @@ describe.skipIf(process.env.SKIP_BUNDLE_SIZE === 'true' || process.env.ECOSYSTEM
]
`)
})
+
+ it('default server bundle size (pages)', async () => {
+ const serverDir = join(pagesRootDir, '.output/server')
+
+ const serverStats = await analyzeSizes(['**/*.mjs', '!node_modules'], serverDir)
+ expect.soft(roundToKilobytes(serverStats.totalBytes)).toMatchInlineSnapshot(`"303k"`)
+
+ const modules = await analyzeSizes(['node_modules/**/*'], serverDir)
+ expect.soft(roundToKilobytes(modules.totalBytes)).toMatchInlineSnapshot(`"1396k"`)
+
+ const packages = modules.files
+ .filter(m => m.endsWith('package.json'))
+ .map(m => m.replace('/package.json', '').replace('node_modules/', ''))
+ .sort()
+ expect(packages).toMatchInlineSnapshot(`
+ [
+ "@babel/parser",
+ "@unhead/dom",
+ "@unhead/shared",
+ "@unhead/ssr",
+ "@vue/compiler-core",
+ "@vue/compiler-dom",
+ "@vue/compiler-ssr",
+ "@vue/reactivity",
+ "@vue/runtime-core",
+ "@vue/runtime-dom",
+ "@vue/server-renderer",
+ "@vue/shared",
+ "db0",
+ "devalue",
+ "entities",
+ "estree-walker",
+ "hookable",
+ "source-map-js",
+ "ufo",
+ "unhead",
+ "vue",
+ "vue-bundle-renderer",
+ ]
+ `)
+ })
})
async function analyzeSizes (pattern: string[], rootDir: string) {
diff --git a/test/fixtures/minimal-pages/app.vue b/test/fixtures/minimal-pages/app.vue
new file mode 100644
index 0000000000..8af1acfee3
--- /dev/null
+++ b/test/fixtures/minimal-pages/app.vue
@@ -0,0 +1,3 @@
+
+
+
diff --git a/test/fixtures/minimal-pages/error.vue b/test/fixtures/minimal-pages/error.vue
new file mode 100644
index 0000000000..17b1009956
--- /dev/null
+++ b/test/fixtures/minimal-pages/error.vue
@@ -0,0 +1,3 @@
+
+ Error page
+
diff --git a/test/fixtures/minimal-pages/layouts/default.vue b/test/fixtures/minimal-pages/layouts/default.vue
new file mode 100644
index 0000000000..ba4672f56d
--- /dev/null
+++ b/test/fixtures/minimal-pages/layouts/default.vue
@@ -0,0 +1,3 @@
+
+
+
diff --git a/test/fixtures/minimal-pages/middleware/test.global.ts b/test/fixtures/minimal-pages/middleware/test.global.ts
new file mode 100644
index 0000000000..3d59968d2c
--- /dev/null
+++ b/test/fixtures/minimal-pages/middleware/test.global.ts
@@ -0,0 +1 @@
+export default defineNuxtRouteMiddleware(() => {})
diff --git a/test/fixtures/minimal-pages/nuxt.config.ts b/test/fixtures/minimal-pages/nuxt.config.ts
new file mode 100644
index 0000000000..6b8487a425
--- /dev/null
+++ b/test/fixtures/minimal-pages/nuxt.config.ts
@@ -0,0 +1,27 @@
+import { readFileSync } from 'node:fs'
+import { fileURLToPath } from 'node:url'
+
+const nuxtEntry = fileURLToPath(new URL('../../../packages/nuxt/dist/index.mjs', import.meta.url))
+const isStubbed = readFileSync(nuxtEntry, 'utf-8').includes('const _module = await jiti')
+
+export default defineNuxtConfig({
+ $production: {
+ vite: {
+ $client: {
+ build: {
+ rollupOptions: {
+ output: {
+ chunkFileNames: '_nuxt/[name].js',
+ entryFileNames: '_nuxt/[name].js',
+ },
+ },
+ },
+ },
+ },
+ },
+ sourcemap: false,
+ compatibilityDate: '2024-06-28',
+ typescript: {
+ typeCheck: isStubbed ? false : 'build',
+ },
+})
diff --git a/test/fixtures/minimal-pages/package.json b/test/fixtures/minimal-pages/package.json
new file mode 100644
index 0000000000..ee88d9d738
--- /dev/null
+++ b/test/fixtures/minimal-pages/package.json
@@ -0,0 +1,13 @@
+{
+ "private": true,
+ "name": "fixture-minimal-pages",
+ "scripts": {
+ "build": "nuxi build"
+ },
+ "dependencies": {
+ "nuxt": "workspace:*"
+ },
+ "engines": {
+ "node": "^18.20.5 || ^20.9.0 || >=22.0.0"
+ }
+}
diff --git a/test/fixtures/minimal-pages/pages/a.client.vue b/test/fixtures/minimal-pages/pages/a.client.vue
new file mode 100644
index 0000000000..e2bcd0be73
--- /dev/null
+++ b/test/fixtures/minimal-pages/pages/a.client.vue
@@ -0,0 +1,3 @@
+
+ Client-only page
+
diff --git a/test/fixtures/minimal-pages/pages/b.server.vue b/test/fixtures/minimal-pages/pages/b.server.vue
new file mode 100644
index 0000000000..62aecd9915
--- /dev/null
+++ b/test/fixtures/minimal-pages/pages/b.server.vue
@@ -0,0 +1,3 @@
+
+ Server-only page
+
diff --git a/test/fixtures/minimal-pages/pages/index.vue b/test/fixtures/minimal-pages/pages/index.vue
new file mode 100644
index 0000000000..585f495151
--- /dev/null
+++ b/test/fixtures/minimal-pages/pages/index.vue
@@ -0,0 +1,3 @@
+
+ Hello World!
+
diff --git a/test/fixtures/minimal-pages/plugins/test.ts b/test/fixtures/minimal-pages/plugins/test.ts
new file mode 100644
index 0000000000..0b12056e3c
--- /dev/null
+++ b/test/fixtures/minimal-pages/plugins/test.ts
@@ -0,0 +1 @@
+export default defineNuxtPlugin(() => {})
diff --git a/test/fixtures/minimal-pages/tsconfig.json b/test/fixtures/minimal-pages/tsconfig.json
new file mode 100644
index 0000000000..4b34df1571
--- /dev/null
+++ b/test/fixtures/minimal-pages/tsconfig.json
@@ -0,0 +1,3 @@
+{
+ "extends": "./.nuxt/tsconfig.json"
+}