You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel 9 + Vite 生产构建耗时过长问题求助

解决Laravel 9 + Vue 3 + Vuetify 3项目npm run build耗时过长问题

问题描述

我有一个基于Laravel 9、Vue 3和Vuetify 3的初期项目,npm run dev启动仅需几秒,但npm run build却耗时约30分钟。构建过程中会在单个步骤卡顿10-30秒,比如卡在transforming (856) node_modules/function-bind/implementation.js这一步。不想重新创建项目,希望将构建时间缩短至合理范围。

相关配置文件

vite.config.js

import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import vue from '@vitejs/plugin-vue';

export default defineConfig({
    plugins: [
        laravel({
            input: 'resources/js/app.js',
            refresh: true,
        }),
        vue({
            template: {
                transformAssetUrls: {
                    base: null,
                    includeAbsolute: false,
                },
            },
        }),
    ],
});

app.js

import './bootstrap';
import '../css/app.css';

// Default Scaffolding
import {createApp, h} from 'vue';
import {createInertiaApp} from '@inertiajs/inertia-vue3';
import {InertiaProgress} from '@inertiajs/progress';
import {resolvePageComponent} from 'laravel-vite-plugin/inertia-helpers';
import {ZiggyVue} from '../../vendor/tightenco/ziggy/dist/vue.m';

// Vuetify
import 'vuetify/styles'
import {createVuetify} from 'vuetify'
import * as components from 'vuetify/components'
import * as directives from 'vuetify/directives'
import {aliases, fa} from 'vuetify/iconsets/fa-svg'

// Font Awesome
import {library} from '@fortawesome/fontawesome-svg-core'
import {faEnvelope, faKey, faBars, faMoneyBillTrendUp} from '@fortawesome/free-solid-svg-icons'
import {FontAwesomeIcon} from '@fortawesome/vue-fontawesome'
import '@fortawesome/fontawesome-free/js/all'

library.add(faEnvelope, faKey, faBars, faMoneyBillTrendUp)

//Layouts
import AuthLayout from './Layouts/AuthLayout.vue'

const appName = window.document.getElementsByTagName('title')[0]?.innerText || 'Laravel';

////////////////////////////////////////////////////////////// DATEPICKER
import Datepicker from '@vuepic/vue-datepicker';
import '@vuepic/vue-datepicker/dist/main.css'
import colors from 'vuetify/lib/util/colors'

const vuetify = createVuetify({
    components,
    directives,
    theme: {
        themes: {
            light: {
                dark: false,
                colors: {
                    primary: '#43A047', // #E53935
                    danger: colors.red.base
                }
            },
        },
    },
    icons: {
        defaultSet: 'fa',
        aliases,
        sets: {
            fa,
        },
    },
})


import Vue3EasyDataTable from 'vue3-easy-data-table';
import 'vue3-easy-data-table/dist/style.css';
//
// const app = createApp(App);


createInertiaApp({
    title: (title) => `${title} - ${appName}`,
    // resolve: (name) => resolvePageComponent(`./Pages/${name}.vue`, import.meta.glob('./Pages/**/*.vue')),
    resolve: name => {
        const page = resolvePageComponent(`./Pages/${name}.vue`, import.meta.glob('./Pages/**/*.vue'))
        page.then((module) => {
            module.default.layout = module.default.layout || AuthLayout;
        });
        return page;
    },
    setup({el, app, props, plugin}) {
        return createApp({render: () => h(app, props)})
            .use(plugin)
            .use(vuetify)
            .use(ZiggyVue, Ziggy)
            .component('font-awesome-icon', FontAwesomeIcon)
            .component('Datepicker', Datepicker)
            .component('EasyDataTable', Vue3EasyDataTable)
            .mount(el);
    },
});

InertiaProgress.init({color: '#4B5563'});

优化方案

1. 按需引入Vuetify组件和指令

当前代码全量导入Vuetify所有组件和指令,会大幅增加打包体积与构建时间。改为仅导入项目实际使用的组件:

// 替换原Vuetify导入部分
import { createVuetify } from 'vuetify'
// 只导入用到的组件,示例:
import { VBtn, VCard, VTextField, VLayout } from 'vuetify/components'
// 只导入用到的指令,示例:
import { VTooltip } from 'vuetify/directives'
import 'vuetify/styles'

const vuetify = createVuetify({
    components: {
        VBtn,
        VCard,
        VTextField,
        VLayout
    },
    directives: {
        VTooltip
    },
    // 保留原有主题、图标配置
})

2. 清理Font Awesome冗余导入

同时导入@fortawesome/fontawesome-free/js/all和单个图标会导致重复加载,删除全量导入语句:

// 删除此行
// import '@fortawesome/fontawesome-free/js/all'

3. 启用Vite构建缓存

在vite.config.js中添加缓存配置,复用之前的构建结果:

export default defineConfig({
    plugins: [/* 原有插件 */],
    cacheDir: './node_modules/.vite',
    build: {
        cache: true,
        // 可选:尝试使用terser压缩(需先安装:npm i terser -D)
        minify: 'terser'
    }
})

4. 分析打包体积定位问题

使用rollup-plugin-visualizer分析打包后的依赖体积,找出大体积或冗余依赖:

# 安装分析插件
npm install rollup-plugin-visualizer -D

修改vite.config.js添加插件:

import { visualizer } from 'rollup-plugin-visualizer';

export default defineConfig({
    plugins: [
        laravel({/* 原有配置 */}),
        vue({/* 原有配置 */}),
        visualizer({ open: true }) // 构建后自动打开分析页面
    ],
})

运行npm run build后,会打开体积分析页面,针对性优化大体积依赖。

5. 优化Inertia页面解析逻辑

确保import.meta.glob仅匹配必要的页面文件,可添加eager: false明确延迟加载:

resolve: name => {
    const page = resolvePageComponent(
        `./Pages/${name}.vue`, 
        import.meta.glob('./Pages/**/*.vue', { eager: false })
    )
    page.then((module) => {
        module.default.layout = module.default.layout || AuthLayout;
    });
    return page;
},

内容的提问来源于stack exchange,提问作者Michael Erdmann

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 14:37:36