我正在使用 Laravel、Vue、Vite 和 Inertia。对于 UI,我使用 Vuetify,由于某种原因,当我加载页面时,我可以看到网络选项卡中有 500 多个请求,其中大多数正在加载一些我根本不需要的 Vuetify 组件。我怎样才能使它只加载应用程序中使用的组件?
这是我的 main.js 文件:
/* eslint-disable import/order */
import layoutsPlugin from '@/plugins/layouts'
import vuetify from '@/plugins/vuetify'
import VueToast from 'vue-toast-notification'
import 'vue-toast-notification/dist/theme-default.css'
import { createInertiaApp, Link } from '@inertiajs/vue3'
import { resolvePageComponent } from 'laravel-vite-plugin/inertia-helpers'
import { loadFonts } from '@/plugins/webfontloader'
import './../styles/@core/template/index.scss'
import '@styles/styles.scss'
import { createPinia } from 'pinia'
import { createApp } from 'vue'
import { ZiggyVue } from '../../vendor/tightenco/ziggy/dist/vue.m'
import 'sweetalert2/dist/sweetalert2.min.css'
loadFonts()
createInertiaApp({
title: title => `${title}`,
resolve: name => resolvePageComponent(`./pages/${name}.vue`, import.meta.glob('./pages/**/*.vue')),
setup({ el, App, props, plugin }) {
// eslint-disable-next-line vue/component-api-style
const vueApp = createApp({ render: () => h(App, props) })
vueApp.use(plugin)
.use(ZiggyVue, Ziggy)
.use(VueToast, {
position: 'top',
pauseOnHover: true,
}).provide('toast', vueApp.config.globalProperties.$toast)
.use(vuetify)
.use(createPinia())
.use(layoutsPlugin)
.use(Link)
.mount(el)
return vueApp
},
progress: {
color: '#4B5563',
},
})
还有 vite.config.js:
import { fileURLToPath } from 'url'
import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx'
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import DefineOptions from 'unplugin-vue-define-options/vite'
import { defineConfig } from 'vite'
import Pages from 'vite-plugin-pages'
import Layouts from 'vite-plugin-vue-layouts'
import vuetify from 'vite-plugin-vuetify'
import laravel from 'laravel-vite-plugin'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
laravel({
input: ['resources/js/main.js'],
refresh: true,
}),
vue({
template: {
transformAssetUrls: {
base: null,
includeAbsolute: false,
},
},
}),
vueJsx(),
// https://github.com/vuetifyjs/vuetify-loader/tree/next/packages/vite-plugin
vuetify({
styles: {
configFile: 'resources/styles/variables/_vuetify.scss',
},
}),
Pages({
dirs: ['./resources/js/pages'],
}),
Layouts({
layoutsDirs: './resources/js/layouts/',
}),
Components({
dirs: ['resources/js/@core/components', 'resources/js/views/demos'],
dts: true,
}),
AutoImport({
eslintrc: {
enabled: true,
filepath: './.eslintrc-auto-import.json',
},
imports: ['vue', 'vue-router', '@vueuse/core', '@vueuse/math', 'pinia'],
vueTemplate: true,
}),
DefineOptions(),
],
define: { 'process.env': {} },
resolve: {
alias: {
'@core-scss': fileURLToPath(new URL('./resources/styles/@core', import.meta.url)),
'@': fileURLToPath(new URL('./resources/js', import.meta.url)),
'@themeConfig': fileURLToPath(new URL('./themeConfig.js', import.meta.url)),
'@core': fileURLToPath(new URL('./resources/js/@core', import.meta.url)),
'@layouts': fileURLToPath(new URL('./resources/js/@layouts', import.meta.url)),
'@images': fileURLToPath(new URL('./resources/images/', import.meta.url)),
'@styles': fileURLToPath(new URL('./resources/styles/', import.meta.url)),
'@configured-variables': fileURLToPath(new URL('./resources/styles/variables/_template.scss', import.meta.url)),
'@axios': fileURLToPath(new URL('./resources/js/plugins/axios', import.meta.url)),
'@validators': fileURLToPath(new URL('./resources/js/@core/utils/validators', import.meta.url)),
'apexcharts': fileURLToPath(new URL('node_modules/apexcharts-clevision', import.meta.url)),
},
},
build: {
chunkSizeWarningLimit: 5000,
},
optimizeDeps: {
exclude: ['vuetify'],
entries: [
'./resources/js/**/*.vue',
],
},
})
资源/js/plugins/vuetify/index.js:
import { createVuetify } from 'vuetify'
import { VBtn } from 'vuetify/components'
import defaults from './defaults'
import { icons } from './icons'
import theme from './theme'
// Styles
// eslint-disable-next-line import/no-unresolved
import '@core-scss/template/libs/vuetify/index.scss'
import 'vuetify/styles'
export default createVuetify({
aliases: {
IconBtn: VBtn,
},
defaults,
icons,
theme,
})
defaults.js:
export default {
IconBtn: {
icon: true,
size: 'small',
color: 'default',
variant: 'text',
VIcon: {
size: 24,
},
},
VAlert: {
density: 'comfortable',
VBtn: {
color: undefined,
},
},
VAvatar: {
// ℹ️ Remove after next release
variant: 'flat',
},
VBadge: {
// set v-badge default color to primary
color: 'primary',
},
VBtn: {
// set v-btn default color to primary
color: 'primary',
},
VChip: {
elevation: 0,
},
VPagination: {
activeColor: 'primary',
density: 'comfortable',
size: '32',
},
VTabs: {
// set v-tabs default color to primary
color: 'primary',
VSlideGroup: {
showArrows: true,
},
},
VTooltip: {
// set v-tooltip default location to top
location: 'top',
},
VList: {
VListItem: {
activeColor: 'primary',
},
},
VCheckbox: {
// set v-checkbox default color to primary
color: 'primary',
density: 'comfortable',
hideDetails: 'auto',
},
VRadioGroup: {
color: 'primary',
hideDetails: 'auto',
},
VRadio: {
hideDetails: 'auto',
},
VSelect: {
variant: 'outlined',
color: 'primary',
hideDetails: 'auto',
},
VRangeSlider: {
// set v-range-slider default color to primary
color: 'primary',
density: 'comfortable',
thumbLabel: true,
hideDetails: 'auto',
},
VRating: {
// set v-rating default color to primary
density: 'compact',
activeColor: 'warning',
},
VProgressCircular: {
// set v-progress-circular default color to primary
color: 'primary',
},
VSlider: {
// set v-slider default color to primary
color: 'primary',
hideDetails: 'auto',
},
VTextField: {
variant: 'outlined',
color: 'primary',
hideDetails: 'auto',
},
VAutocomplete: {
variant: 'outlined',
density: 'comfortable',
color: 'primary',
hideDetails: 'auto',
},
VCombobox: {
variant: 'outlined',
color: 'primary',
hideDetails: 'auto',
},
VFileInput: {
variant: 'outlined',
color: 'primary',
hideDetails: 'auto',
},
VTextarea: {
variant: 'outlined',
density: 'comfortable',
color: 'primary',
hideDetails: 'auto',
},
VSwitch: {
// set v-switch default color to primary
color: 'primary',
hideDetails: 'auto',
},
}
最佳答案
在 resources/js/plugins/vuetify/index.js
中,通过 vuetify/components
导入 VBtn:
import { VBtn } from 'vuetify/components'
这会加载node_modules/vuetify/lib/components/index.mjs
,它会导出所有 Vuetify 组件。在为生产构建时,未使用的组件将通过摇树删除,但在运行开发服务器时不会。
当您直接从vuetify/components/VBtn
加载VBtn时,其他文件将不再加载:
import { VBtn } from 'vuetify/components/VBtn'
documentation 中也对此进行了描述:
Although treeshaking is automatically applied during production builds, it is advantageous to import components by specifying their full path in development mode. For instance, using
vuetify/components/VBtn
instead ofvuetify/components
ensures that the compiler loads fewer components, thus optimizing performance.
关于vue.js - Laravel 10/Vue 3/Vite 4/Vuetify 3 项目中不必要的组件加载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76765266/