Vite build only transforming 53 modules instead of all Vue pages in Laravel Inertia.js SSR project

15 hours ago 2
ARTICLE AD BOX

Problem

I'm working on a Laravel 12 project with Inertia.js, Vue 3, TypeScript, and SSR. When I run npm run build:ssr, Vite only transforms 53 modules and produces a 36KB JavaScript file, even though I have 43 Vue component files in my resources/js/Pages directory.

The build completes without errors, but clearly isn't including all my Vue pages.

Expected Behavior

The build should:

Transform 300-500+ modules (including all Vue pages and dependencies)

Produce larger bundle files (500KB+)

Include all pages from resources/js/Pages/**/*.vue

Actual Behavior

Build output:

bash

vite v7.1.9 building for production... ✓ 53 modules transformed. public/build/manifest.json 0.31 kB │ gzip: 0.17 kB public/build/assets/app-BZmm_rKM.css 38.32 kB │ gzip: 8.38 kB public/build/assets/app-BZmm_rKM.js 36.08 kB │ gzip: 14.58 kB ✓ built in 587ms vite v7.1.9 building SSR bundle for production... ✓ 3 modules transformed. bootstrap/ssr/ssr-manifest.json 0.07 kB bootstrap/ssr/app2.js 0.13 kB ✓ built in 175ms

Only 2 asset files are generated (CSS and JS), with no code-split chunks for individual pages.

My Setup

Directory structure:

bash

resources/js/ ├── Pages/ # Capital P │ ├── Dashboard.vue │ ├── Welcome.vue │ ├── admin/ │ ├── auth/ │ ├── kitchen/ │ ├── pos/ │ └── settings/ ├── app.ts ├── ssr.ts └── components/

I have 43 .vue files total in the Pages directory (verified with find resources/js/Pages -name "*.vue" | wc -l).

vite.config.ts:

typescript

import { wayfinder } from '@laravel/vite-plugin-wayfinder'; import tailwindcss from '@tailwindcss/vite'; import vue from '@vitejs/plugin-vue'; import laravel from 'laravel-vite-plugin'; import { defineConfig } from 'vite'; export default defineConfig({ plugins: [ laravel({ input: ['resources/js/app.ts'], ssr: 'resources/js/ssr.ts', refresh: true, }), tailwindcss(), wayfinder({ formVariants: true, }), vue({ template: { transformAssetUrls: { base: null, includeAbsolute: false, }, }, }), ], });

resources/js/app.ts:

typescript

import '../css/app.css'; import { createInertiaApp } from '@inertiajs/vue3'; import { resolvePageComponent } from 'laravel-vite-plugin/inertia-helpers'; import { createPinia } from 'pinia'; import type { DefineComponent } from 'vue'; import { createApp, h } from 'vue'; const appName = import.meta.env.VITE_APP_NAME || 'Laravel'; createInertiaApp({ title: (title) => (title ? `${title} - ${appName}` : appName), resolve: (name) => resolvePageComponent( `./Pages/${name}.vue`, import.meta.glob<DefineComponent>('./Pages/**/*.vue'), ), setup({ el, App, props, plugin }) { createApp({ render: () => h(App, props) }) .use(plugin) .use(createPinia()) .mount(el); }, });

resources/js/ssr.ts:

typescript

import { createInertiaApp } from '@inertiajs/vue3'; import createServer from '@inertiajs/vue3/server'; import { resolvePageComponent } from 'laravel-vite-plugin/inertia-helpers'; import { createSSRApp, DefineComponent, h } from 'vue'; import { renderToString } from 'vue/server-renderer'; const appName = import.meta.env.VITE_APP_NAME || 'JollofMan'; createServer( (page) => createInertiaApp({ page, render: renderToString, title: (title) => (title ? `${title} - ${appName}` : appName), resolve: (name) => resolvePageComponent( `./Pages/${name}.vue`, import.meta.glob<DefineComponent>('./Pages/**/*.vue'), ), setup: ({ App, props, plugin }) => createSSRApp({ render: () => h(App, props) }).use(plugin), }), { cluster: true }, );

package.json (relevant dependencies):

json

{ "$schema": "https://www.schemastore.org/package.json", "private": true, "type": "module", "scripts": { "build": "vite build", "build:ssr": "vite build && vite build --ssr", "dev": "vite", "format": "prettier --write resources/", "format:check": "prettier --check resources/", "lint": "eslint . --fix" }, "devDependencies": { "@eslint/js": "^9.19.0", "@laravel/echo-vue": "^2.2.6", "@laravel/vite-plugin-wayfinder": "^0.1.3", "@tailwindcss/vite": "^4.1.11", "@types/node": "^22.13.5", "@vitejs/plugin-vue": "^6.0.0", "@vue/eslint-config-typescript": "^14.3.0", "concurrently": "^9.0.1", "eslint": "^9.17.0", "eslint-config-prettier": "^10.0.1", "eslint-plugin-vue": "^9.32.0", "laravel-echo": "^2.2.6", "prettier": "^3.4.2", "prettier-plugin-organize-imports": "^4.1.0", "prettier-plugin-tailwindcss": "^0.6.11", "pusher-js": "^8.4.0", "typescript": "^5.2.2", "typescript-eslint": "^8.23.0", "vite": "^7.0.4", "vue-tsc": "^2.2.4" }, "dependencies": { "@headlessui/vue": "^1.7.23", "@heroicons/vue": "^2.2.0", "@inertiajs/vue3": "^2.1.0", "@types/lodash": "^4.17.21", "@vee-validate/zod": "^4.15.1", "@vueuse/core": "^12.8.2", "chart.js": "^4.5.1", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "date-fns": "^4.1.0", "embla-carousel-vue": "^8.6.0", "escpos": "^3.0.0-alpha.6", "escpos-network": "^3.0.0-alpha.5", "escpos-serialport": "^3.0.0-alpha.4", "escpos-usb": "^3.0.0-alpha.4", "laravel-vite-plugin": "^2.0.0", "lucide-vue-next": "^0.468.0", "pinia": "^3.0.4", "radix-vue": "^1.9.17", "reka-ui": "^2.4.1", "tailwind-merge": "^3.4.0", "tailwindcss": "^4.1.1", "tailwindcss-animate": "^1.0.7", "tw-animate-css": "^1.2.5", "uninstall": "^0.0.0", "vee-validate": "^4.15.1", "vue": "^3.5.13", "vue-chartjs": "^5.3.3", "vue-sonner": "^2.0.9", "vue-toastification": "^2.0.0-rc.5", "zod": "^4.1.13" }, "optionalDependencies": { "@rollup/rollup-linux-x64-gnu": "4.9.5", "@rollup/rollup-win32-x64-msvc": "4.9.5", "@tailwindcss/oxide-linux-x64-gnu": "^4.0.1", "@tailwindcss/oxide-win32-x64-msvc": "^4.0.1", "lightningcss-linux-x64-gnu": "^1.29.1", "lightningcss-win32-x64-msvc": "^1.29.1" } }

What I've Tried

Added { eager: true } to import.meta.glob() - This caused TypeScript errors: error TS2345: Argument of type 'Record<string, DefineComponent>' is not assignable to parameter of type 'Record<string, Promise<DefineComponent> | (() => Promise<DefineComponent>)>'.

Verified file paths - The glob pattern ./Pages/**/*.vue is correct and matches my directory structure

Cleared caches:

bash

rm -rf node_modules/.vite rm -rf public/build rm -rf bootstrap/ssr

Checked TypeScript errors - Running npx tsc --noEmit shows many component import errors but no errors in the Pages directory itself

Tried different glob patterns - No change in behavior

Checked Vite dev mode - npm run dev works fine and pages load correctly in development

Questions

Why is Vite only transforming 53 modules when I have 43+ Vue files?

Why aren't individual page components being included in the build?

Is there an issue with how import.meta.glob() works with resolvePageComponent?

Should the build create separate chunk files for each page, or bundle everything into one file?

Environment

OS: Linux (shared hosting)

Node: v20.19.6

npm: 10.9.2

Laravel: 12.x

Vite: 7.1.9

Vue: 3.5.x

Inertia.js: 2.x with SSR enabled

Any help would be greatly appreciated!

Read Entire Article