From 329a176a5c736c898f2e54034decd420319b5374 Mon Sep 17 00:00:00 2001 From: Netfan Date: Wed, 9 Apr 2025 01:05:20 +0800 Subject: [PATCH] perf: optimize bootstrap modules to speed up first-screen loading (#5899) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 优化首屏加载速度 --- apps/web-antd/src/adapter/component/index.ts | 79 +++++++---- apps/web-antd/src/bootstrap.ts | 5 +- apps/web-antd/src/router/routes/core.ts | 6 +- apps/web-ele/src/adapter/component/index.ts | 132 +++++++++++++++--- apps/web-ele/src/bootstrap.ts | 5 +- apps/web-ele/src/router/routes/core.ts | 6 +- apps/web-naive/src/adapter/component/index.ts | 76 +++++++--- apps/web-naive/src/bootstrap.ts | 5 +- apps/web-naive/src/router/routes/core.ts | 6 +- packages/effects/common-ui/package.json | 8 ++ playground/src/adapter/component/index.ts | 79 +++++++---- playground/src/bootstrap.ts | 13 +- playground/src/router/routes/core.ts | 6 +- 13 files changed, 311 insertions(+), 115 deletions(-) diff --git a/apps/web-antd/src/adapter/component/index.ts b/apps/web-antd/src/adapter/component/index.ts index 7ae93072..5394c813 100644 --- a/apps/web-antd/src/adapter/component/index.ts +++ b/apps/web-antd/src/adapter/component/index.ts @@ -8,35 +8,64 @@ import type { Component } from 'vue'; import type { BaseFormComponentType } from '@vben/common-ui'; import type { Recordable } from '@vben/types'; -import { defineComponent, getCurrentInstance, h, ref } from 'vue'; +import { + defineAsyncComponent, + defineComponent, + getCurrentInstance, + h, + ref, +} from 'vue'; import { ApiComponent, globalShareState, IconPicker } from '@vben/common-ui'; import { $t } from '@vben/locales'; -import { - AutoComplete, - Button, - Checkbox, - CheckboxGroup, - DatePicker, - Divider, - Input, - InputNumber, - InputPassword, - Mentions, - notification, - Radio, - RadioGroup, - RangePicker, - Rate, - Select, - Space, - Switch, - Textarea, - TimePicker, - TreeSelect, - Upload, -} from 'ant-design-vue'; +import { notification } from 'ant-design-vue'; + +const AutoComplete = defineAsyncComponent( + () => import('ant-design-vue/es/auto-complete'), +); +const Button = defineAsyncComponent(() => import('ant-design-vue/es/button')); +const Checkbox = defineAsyncComponent( + () => import('ant-design-vue/es/checkbox'), +); +const CheckboxGroup = defineAsyncComponent(() => + import('ant-design-vue/es/checkbox').then((res) => res.CheckboxGroup), +); +const DatePicker = defineAsyncComponent( + () => import('ant-design-vue/es/date-picker'), +); +const Divider = defineAsyncComponent(() => import('ant-design-vue/es/divider')); +const Input = defineAsyncComponent(() => import('ant-design-vue/es/input')); +const InputNumber = defineAsyncComponent( + () => import('ant-design-vue/es/input-number'), +); +const InputPassword = defineAsyncComponent(() => + import('ant-design-vue/es/input').then((res) => res.InputPassword), +); +const Mentions = defineAsyncComponent( + () => import('ant-design-vue/es/mentions'), +); +const Radio = defineAsyncComponent(() => import('ant-design-vue/es/radio')); +const RadioGroup = defineAsyncComponent(() => + import('ant-design-vue/es/radio').then((res) => res.RadioGroup), +); +const RangePicker = defineAsyncComponent(() => + import('ant-design-vue/es/date-picker').then((res) => res.RangePicker), +); +const Rate = defineAsyncComponent(() => import('ant-design-vue/es/rate')); +const Select = defineAsyncComponent(() => import('ant-design-vue/es/select')); +const Space = defineAsyncComponent(() => import('ant-design-vue/es/space')); +const Switch = defineAsyncComponent(() => import('ant-design-vue/es/switch')); +const Textarea = defineAsyncComponent(() => + import('ant-design-vue/es/input').then((res) => res.Textarea), +); +const TimePicker = defineAsyncComponent( + () => import('ant-design-vue/es/time-picker'), +); +const TreeSelect = defineAsyncComponent( + () => import('ant-design-vue/es/tree-select'), +); +const Upload = defineAsyncComponent(() => import('ant-design-vue/es/upload')); const withDefaultPlaceholder = ( component: T, diff --git a/apps/web-antd/src/bootstrap.ts b/apps/web-antd/src/bootstrap.ts index fe7d9650..e4aaf405 100644 --- a/apps/web-antd/src/bootstrap.ts +++ b/apps/web-antd/src/bootstrap.ts @@ -1,8 +1,7 @@ import { createApp, watchEffect } from 'vue'; import { registerAccessDirective } from '@vben/access'; -import { initTippy, registerLoadingDirective } from '@vben/common-ui'; -import { MotionPlugin } from '@vben/plugins/motion'; +import { registerLoadingDirective } from '@vben/common-ui/es/loading'; import { preferences } from '@vben/preferences'; import { initStores } from '@vben/stores'; import '@vben/styles'; @@ -47,12 +46,14 @@ async function bootstrap(namespace: string) { registerAccessDirective(app); // 初始化 tippy + const { initTippy } = await import('@vben/common-ui/es/tippy'); initTippy(app); // 配置路由及路由守卫 app.use(router); // 配置Motion插件 + const { MotionPlugin } = await import('@vben/plugins/motion'); app.use(MotionPlugin); // 动态更新标题 diff --git a/apps/web-antd/src/router/routes/core.ts b/apps/web-antd/src/router/routes/core.ts index 7218da22..4a527a31 100644 --- a/apps/web-antd/src/router/routes/core.ts +++ b/apps/web-antd/src/router/routes/core.ts @@ -2,10 +2,10 @@ import type { RouteRecordRaw } from 'vue-router'; import { DEFAULT_HOME_PATH, LOGIN_PATH } from '@vben/constants'; -import { AuthPageLayout, BasicLayout } from '#/layouts'; import { $t } from '#/locales'; -import Login from '#/views/_core/authentication/login.vue'; +const BasicLayout = () => import('#/layouts/basic.vue'); +const AuthPageLayout = () => import('#/layouts/auth.vue'); /** 全局404页面 */ const fallbackNotFoundRoute: RouteRecordRaw = { component: () => import('#/views/_core/fallback/not-found.vue'), @@ -50,7 +50,7 @@ const coreRoutes: RouteRecordRaw[] = [ { name: 'Login', path: 'login', - component: Login, + component: () => import('#/views/_core/authentication/login.vue'), meta: { title: $t('page.auth.login'), }, diff --git a/apps/web-ele/src/adapter/component/index.ts b/apps/web-ele/src/adapter/component/index.ts index 5de17b75..cf7340a2 100644 --- a/apps/web-ele/src/adapter/component/index.ts +++ b/apps/web-ele/src/adapter/component/index.ts @@ -8,31 +8,121 @@ import type { Component } from 'vue'; import type { BaseFormComponentType } from '@vben/common-ui'; import type { Recordable } from '@vben/types'; -import { defineComponent, getCurrentInstance, h, ref } from 'vue'; +import { + defineAsyncComponent, + defineComponent, + getCurrentInstance, + h, + ref, +} from 'vue'; import { ApiComponent, globalShareState, IconPicker } from '@vben/common-ui'; import { $t } from '@vben/locales'; -import { - ElButton, - ElCheckbox, - ElCheckboxButton, - ElCheckboxGroup, - ElDatePicker, - ElDivider, - ElInput, - ElInputNumber, - ElNotification, - ElRadio, - ElRadioButton, - ElRadioGroup, - ElSelectV2, - ElSpace, - ElSwitch, - ElTimePicker, - ElTreeSelect, - ElUpload, -} from 'element-plus'; +import { ElNotification } from 'element-plus'; + +const ElButton = defineAsyncComponent(() => + Promise.all([ + import('element-plus/es/components/button/index'), + import('element-plus/es/components/button/style/css'), + ]).then(([res]) => res.ElButton), +); +const ElCheckbox = defineAsyncComponent(() => + Promise.all([ + import('element-plus/es/components/checkbox/index'), + import('element-plus/es/components/checkbox/style/css'), + ]).then(([res]) => res.ElCheckbox), +); +const ElCheckboxButton = defineAsyncComponent(() => + Promise.all([ + import('element-plus/es/components/checkbox/index'), + import('element-plus/es/components/checkbox-button/style/css'), + ]).then(([res]) => res.ElCheckboxButton), +); +const ElCheckboxGroup = defineAsyncComponent(() => + Promise.all([ + import('element-plus/es/components/checkbox/index'), + import('element-plus/es/components/checkbox-group/style/css'), + ]).then(([res]) => res.ElCheckboxGroup), +); +const ElDatePicker = defineAsyncComponent(() => + Promise.all([ + import('element-plus/es/components/date-picker/index'), + import('element-plus/es/components/date-picker/style/css'), + ]).then(([res]) => res.ElDatePicker), +); +const ElDivider = defineAsyncComponent(() => + Promise.all([ + import('element-plus/es/components/divider/index'), + import('element-plus/es/components/divider/style/css'), + ]).then(([res]) => res.ElDivider), +); +const ElInput = defineAsyncComponent(() => + Promise.all([ + import('element-plus/es/components/input/index'), + import('element-plus/es/components/input/style/css'), + ]).then(([res]) => res.ElInput), +); +const ElInputNumber = defineAsyncComponent(() => + Promise.all([ + import('element-plus/es/components/input-number/index'), + import('element-plus/es/components/input-number/style/css'), + ]).then(([res]) => res.ElInputNumber), +); +const ElRadio = defineAsyncComponent(() => + Promise.all([ + import('element-plus/es/components/radio/index'), + import('element-plus/es/components/radio/style/css'), + ]).then(([res]) => res.ElRadio), +); +const ElRadioButton = defineAsyncComponent(() => + Promise.all([ + import('element-plus/es/components/radio/index'), + import('element-plus/es/components/radio-button/style/css'), + ]).then(([res]) => res.ElRadioButton), +); +const ElRadioGroup = defineAsyncComponent(() => + Promise.all([ + import('element-plus/es/components/radio/index'), + import('element-plus/es/components/radio-group/style/css'), + ]).then(([res]) => res.ElRadioGroup), +); +const ElSelectV2 = defineAsyncComponent(() => + Promise.all([ + import('element-plus/es/components/select-v2/index'), + import('element-plus/es/components/select-v2/style/css'), + ]).then(([res]) => res.ElSelectV2), +); +const ElSpace = defineAsyncComponent(() => + Promise.all([ + import('element-plus/es/components/space/index'), + import('element-plus/es/components/space/style/css'), + ]).then(([res]) => res.ElSpace), +); +const ElSwitch = defineAsyncComponent(() => + Promise.all([ + import('element-plus/es/components/switch/index'), + import('element-plus/es/components/switch/style/css'), + ]).then(([res]) => res.ElSwitch), +); +const ElTimePicker = defineAsyncComponent(() => + Promise.all([ + import('element-plus/es/components/time-picker/index'), + import('element-plus/es/components/time-picker/style/css'), + ]).then(([res]) => res.ElTimePicker), +); +const ElTreeSelect = defineAsyncComponent(() => + Promise.all([ + import('element-plus/es/components/tree-select/index'), + import('element-plus/es/components/tree-select/style/css'), + ]).then(([res]) => res.ElTreeSelect), +); +const ElUpload = defineAsyncComponent(() => + Promise.all([ + import('element-plus/es/components/upload/index'), + import('element-plus/es/components/upload/style/css'), + ]).then(([res]) => res.ElUpload), +); const withDefaultPlaceholder = ( component: T, diff --git a/apps/web-ele/src/bootstrap.ts b/apps/web-ele/src/bootstrap.ts index 7e9e1cd4..be054f80 100644 --- a/apps/web-ele/src/bootstrap.ts +++ b/apps/web-ele/src/bootstrap.ts @@ -1,8 +1,7 @@ import { createApp, watchEffect } from 'vue'; import { registerAccessDirective } from '@vben/access'; -import { initTippy, registerLoadingDirective } from '@vben/common-ui'; -import { MotionPlugin } from '@vben/plugins/motion'; +import { registerLoadingDirective } from '@vben/common-ui'; import { preferences } from '@vben/preferences'; import { initStores } from '@vben/stores'; import '@vben/styles'; @@ -49,12 +48,14 @@ async function bootstrap(namespace: string) { registerAccessDirective(app); // 初始化 tippy + const { initTippy } = await import('@vben/common-ui/es/tippy'); initTippy(app); // 配置路由及路由守卫 app.use(router); // 配置Motion插件 + const { MotionPlugin } = await import('@vben/plugins/motion'); app.use(MotionPlugin); // 动态更新标题 diff --git a/apps/web-ele/src/router/routes/core.ts b/apps/web-ele/src/router/routes/core.ts index 7218da22..4a527a31 100644 --- a/apps/web-ele/src/router/routes/core.ts +++ b/apps/web-ele/src/router/routes/core.ts @@ -2,10 +2,10 @@ import type { RouteRecordRaw } from 'vue-router'; import { DEFAULT_HOME_PATH, LOGIN_PATH } from '@vben/constants'; -import { AuthPageLayout, BasicLayout } from '#/layouts'; import { $t } from '#/locales'; -import Login from '#/views/_core/authentication/login.vue'; +const BasicLayout = () => import('#/layouts/basic.vue'); +const AuthPageLayout = () => import('#/layouts/auth.vue'); /** 全局404页面 */ const fallbackNotFoundRoute: RouteRecordRaw = { component: () => import('#/views/_core/fallback/not-found.vue'), @@ -50,7 +50,7 @@ const coreRoutes: RouteRecordRaw[] = [ { name: 'Login', path: 'login', - component: Login, + component: () => import('#/views/_core/authentication/login.vue'), meta: { title: $t('page.auth.login'), }, diff --git a/apps/web-naive/src/adapter/component/index.ts b/apps/web-naive/src/adapter/component/index.ts index b7aa9d85..7da07897 100644 --- a/apps/web-naive/src/adapter/component/index.ts +++ b/apps/web-naive/src/adapter/component/index.ts @@ -8,32 +8,68 @@ import type { Component } from 'vue'; import type { BaseFormComponentType } from '@vben/common-ui'; import type { Recordable } from '@vben/types'; -import { defineComponent, getCurrentInstance, h, ref } from 'vue'; +import { + defineAsyncComponent, + defineComponent, + getCurrentInstance, + h, + ref, +} from 'vue'; import { ApiComponent, globalShareState, IconPicker } from '@vben/common-ui'; import { $t } from '@vben/locales'; -import { - NButton, - NCheckbox, - NCheckboxGroup, - NDatePicker, - NDivider, - NInput, - NInputNumber, - NRadio, - NRadioButton, - NRadioGroup, - NSelect, - NSpace, - NSwitch, - NTimePicker, - NTreeSelect, - NUpload, -} from 'naive-ui'; - import { message } from '#/adapter/naive'; +const NButton = defineAsyncComponent(() => + import('naive-ui/es/button').then((res) => res.NButton), +); +const NCheckbox = defineAsyncComponent(() => + import('naive-ui/es/checkbox').then((res) => res.NCheckbox), +); +const NCheckboxGroup = defineAsyncComponent(() => + import('naive-ui/es/checkbox').then((res) => res.NCheckboxGroup), +); +const NDatePicker = defineAsyncComponent(() => + import('naive-ui/es/date-picker').then((res) => res.NDatePicker), +); +const NDivider = defineAsyncComponent(() => + import('naive-ui/es/divider').then((res) => res.NDivider), +); +const NInput = defineAsyncComponent(() => + import('naive-ui/es/input').then((res) => res.NInput), +); +const NInputNumber = defineAsyncComponent(() => + import('naive-ui/es/input-number').then((res) => res.NInputNumber), +); +const NRadio = defineAsyncComponent(() => + import('naive-ui/es/radio').then((res) => res.NRadio), +); +const NRadioButton = defineAsyncComponent(() => + import('naive-ui/es/radio').then((res) => res.NRadioButton), +); +const NRadioGroup = defineAsyncComponent(() => + import('naive-ui/es/radio').then((res) => res.NRadioGroup), +); +const NSelect = defineAsyncComponent(() => + import('naive-ui/es/select').then((res) => res.NSelect), +); +const NSpace = defineAsyncComponent(() => + import('naive-ui/es/space').then((res) => res.NSpace), +); +const NSwitch = defineAsyncComponent(() => + import('naive-ui/es/switch').then((res) => res.NSwitch), +); +const NTimePicker = defineAsyncComponent(() => + import('naive-ui/es/time-picker').then((res) => res.NTimePicker), +); +const NTreeSelect = defineAsyncComponent(() => + import('naive-ui/es/tree-select').then((res) => res.NTreeSelect), +); +const NUpload = defineAsyncComponent(() => + import('naive-ui/es/upload').then((res) => res.NUpload), +); + const withDefaultPlaceholder = ( component: T, type: 'input' | 'select', diff --git a/apps/web-naive/src/bootstrap.ts b/apps/web-naive/src/bootstrap.ts index b8c21ad2..5fddd7d8 100644 --- a/apps/web-naive/src/bootstrap.ts +++ b/apps/web-naive/src/bootstrap.ts @@ -1,8 +1,7 @@ import { createApp, watchEffect } from 'vue'; import { registerAccessDirective } from '@vben/access'; -import { initTippy, registerLoadingDirective } from '@vben/common-ui'; -import { MotionPlugin } from '@vben/plugins/motion'; +import { registerLoadingDirective } from '@vben/common-ui'; import { preferences } from '@vben/preferences'; import { initStores } from '@vben/stores'; import '@vben/styles'; @@ -47,12 +46,14 @@ async function bootstrap(namespace: string) { registerAccessDirective(app); // 初始化 tippy + const { initTippy } = await import('@vben/common-ui/es/tippy'); initTippy(app); // 配置路由及路由守卫 app.use(router); // 配置Motion插件 + const { MotionPlugin } = await import('@vben/plugins/motion'); app.use(MotionPlugin); // 动态更新标题 diff --git a/apps/web-naive/src/router/routes/core.ts b/apps/web-naive/src/router/routes/core.ts index 7218da22..4a527a31 100644 --- a/apps/web-naive/src/router/routes/core.ts +++ b/apps/web-naive/src/router/routes/core.ts @@ -2,10 +2,10 @@ import type { RouteRecordRaw } from 'vue-router'; import { DEFAULT_HOME_PATH, LOGIN_PATH } from '@vben/constants'; -import { AuthPageLayout, BasicLayout } from '#/layouts'; import { $t } from '#/locales'; -import Login from '#/views/_core/authentication/login.vue'; +const BasicLayout = () => import('#/layouts/basic.vue'); +const AuthPageLayout = () => import('#/layouts/auth.vue'); /** 全局404页面 */ const fallbackNotFoundRoute: RouteRecordRaw = { component: () => import('#/views/_core/fallback/not-found.vue'), @@ -50,7 +50,7 @@ const coreRoutes: RouteRecordRaw[] = [ { name: 'Login', path: 'login', - component: Login, + component: () => import('#/views/_core/authentication/login.vue'), meta: { title: $t('page.auth.login'), }, diff --git a/packages/effects/common-ui/package.json b/packages/effects/common-ui/package.json index 5ae51a56..6730012f 100644 --- a/packages/effects/common-ui/package.json +++ b/packages/effects/common-ui/package.json @@ -17,6 +17,14 @@ ".": { "types": "./src/index.ts", "default": "./src/index.ts" + }, + "./es/tippy": { + "types": "./src/components/tippy/index.ts", + "default": "./src/components/tippy/index.ts" + }, + "./es/loading": { + "types": "./src/components/loading/index.ts", + "default": "./src/components/loading/index.ts" } }, "dependencies": { diff --git a/playground/src/adapter/component/index.ts b/playground/src/adapter/component/index.ts index 9b847dfc..88cfbf24 100644 --- a/playground/src/adapter/component/index.ts +++ b/playground/src/adapter/component/index.ts @@ -8,35 +8,64 @@ import type { Component } from 'vue'; import type { BaseFormComponentType } from '@vben/common-ui'; import type { Recordable } from '@vben/types'; -import { defineComponent, getCurrentInstance, h, ref } from 'vue'; +import { + defineAsyncComponent, + defineComponent, + getCurrentInstance, + h, + ref, +} from 'vue'; import { ApiComponent, globalShareState, IconPicker } from '@vben/common-ui'; import { $t } from '@vben/locales'; -import { - AutoComplete, - Button, - Checkbox, - CheckboxGroup, - DatePicker, - Divider, - Input, - InputNumber, - InputPassword, - Mentions, - notification, - Radio, - RadioGroup, - RangePicker, - Rate, - Select, - Space, - Switch, - Textarea, - TimePicker, - TreeSelect, - Upload, -} from 'ant-design-vue'; +import { notification } from 'ant-design-vue'; + +const AutoComplete = defineAsyncComponent( + () => import('ant-design-vue/es/auto-complete'), +); +const Button = defineAsyncComponent(() => import('ant-design-vue/es/button')); +const Checkbox = defineAsyncComponent( + () => import('ant-design-vue/es/checkbox'), +); +const CheckboxGroup = defineAsyncComponent(() => + import('ant-design-vue/es/checkbox').then((res) => res.CheckboxGroup), +); +const DatePicker = defineAsyncComponent( + () => import('ant-design-vue/es/date-picker'), +); +const Divider = defineAsyncComponent(() => import('ant-design-vue/es/divider')); +const Input = defineAsyncComponent(() => import('ant-design-vue/es/input')); +const InputNumber = defineAsyncComponent( + () => import('ant-design-vue/es/input-number'), +); +const InputPassword = defineAsyncComponent(() => + import('ant-design-vue/es/input').then((res) => res.InputPassword), +); +const Mentions = defineAsyncComponent( + () => import('ant-design-vue/es/mentions'), +); +const Radio = defineAsyncComponent(() => import('ant-design-vue/es/radio')); +const RadioGroup = defineAsyncComponent(() => + import('ant-design-vue/es/radio').then((res) => res.RadioGroup), +); +const RangePicker = defineAsyncComponent(() => + import('ant-design-vue/es/date-picker').then((res) => res.RangePicker), +); +const Rate = defineAsyncComponent(() => import('ant-design-vue/es/rate')); +const Select = defineAsyncComponent(() => import('ant-design-vue/es/select')); +const Space = defineAsyncComponent(() => import('ant-design-vue/es/space')); +const Switch = defineAsyncComponent(() => import('ant-design-vue/es/switch')); +const Textarea = defineAsyncComponent(() => + import('ant-design-vue/es/input').then((res) => res.Textarea), +); +const TimePicker = defineAsyncComponent( + () => import('ant-design-vue/es/time-picker'), +); +const TreeSelect = defineAsyncComponent( + () => import('ant-design-vue/es/tree-select'), +); +const Upload = defineAsyncComponent(() => import('ant-design-vue/es/upload')); const withDefaultPlaceholder = ( component: T, diff --git a/playground/src/bootstrap.ts b/playground/src/bootstrap.ts index cecb3cf6..6df3bd52 100644 --- a/playground/src/bootstrap.ts +++ b/playground/src/bootstrap.ts @@ -1,14 +1,12 @@ import { createApp, watchEffect } from 'vue'; import { registerAccessDirective } from '@vben/access'; -import { initTippy, registerLoadingDirective } from '@vben/common-ui'; -import { MotionPlugin } from '@vben/plugins/motion'; +import { registerLoadingDirective } from '@vben/common-ui'; import { preferences } from '@vben/preferences'; import { initStores } from '@vben/stores'; import '@vben/styles'; import '@vben/styles/antd'; -import { VueQueryPlugin } from '@tanstack/vue-query'; import { useTitle } from '@vueuse/core'; import { $t, setupI18n } from '#/locales'; @@ -21,13 +19,13 @@ async function bootstrap(namespace: string) { // 初始化组件适配器 await initComponentAdapter(); - // // 设置弹窗的默认配置 + // 设置弹窗的默认配置 // setDefaultModalProps({ // fullscreenButton: false, // }); - // // 设置抽屉的默认配置 + // 设置抽屉的默认配置 // setDefaultDrawerProps({ - // // zIndex: 1020, + // zIndex: 1020, // }); const app = createApp(App); @@ -48,15 +46,18 @@ async function bootstrap(namespace: string) { registerAccessDirective(app); // 初始化 tippy + const { initTippy } = await import('@vben/common-ui/es/tippy'); initTippy(app); // 配置路由及路由守卫 app.use(router); // 配置@tanstack/vue-query + const { VueQueryPlugin } = await import('@tanstack/vue-query'); app.use(VueQueryPlugin); // 配置Motion插件 + const { MotionPlugin } = await import('@vben/plugins/motion'); app.use(MotionPlugin); // 动态更新标题 diff --git a/playground/src/router/routes/core.ts b/playground/src/router/routes/core.ts index 7218da22..4a527a31 100644 --- a/playground/src/router/routes/core.ts +++ b/playground/src/router/routes/core.ts @@ -2,10 +2,10 @@ import type { RouteRecordRaw } from 'vue-router'; import { DEFAULT_HOME_PATH, LOGIN_PATH } from '@vben/constants'; -import { AuthPageLayout, BasicLayout } from '#/layouts'; import { $t } from '#/locales'; -import Login from '#/views/_core/authentication/login.vue'; +const BasicLayout = () => import('#/layouts/basic.vue'); +const AuthPageLayout = () => import('#/layouts/auth.vue'); /** 全局404页面 */ const fallbackNotFoundRoute: RouteRecordRaw = { component: () => import('#/views/_core/fallback/not-found.vue'), @@ -50,7 +50,7 @@ const coreRoutes: RouteRecordRaw[] = [ { name: 'Login', path: 'login', - component: Login, + component: () => import('#/views/_core/authentication/login.vue'), meta: { title: $t('page.auth.login'), },