perf: 优化构建依赖加载

This commit is contained in:
Ray.Hao
2026-06-19 08:27:41 +08:00
parent 03a9c03401
commit 7ffcf8820e
6 changed files with 62 additions and 41 deletions

View File

@@ -333,8 +333,8 @@ import {
type UploadUserFile,
type TableInstance,
} from "element-plus";
import ExcelJS from "exceljs";
import { reactive, ref, computed } from "vue";
import type { Column, Workbook } from "exceljs";
import type { IContentConfig, IObject, IOperateData } from "./types";
import type { IToolsButton } from "./types";
@@ -579,15 +579,20 @@ function handleCloseExportsModal() {
exportsFormRef.value?.clearValidate();
});
}
async function createWorkbook(): Promise<Workbook> {
const ExcelJS = await import("exceljs");
return new ExcelJS.Workbook();
}
// 导出
function handleExports() {
async function handleExports() {
const filename = exportsFormData.filename
? exportsFormData.filename
: props.contentConfig.permPrefix || "export";
const sheetname = exportsFormData.sheetname ? exportsFormData.sheetname : "sheet";
const workbook = new ExcelJS.Workbook();
const workbook = await createWorkbook();
const worksheet = workbook.addWorksheet(sheetname);
const columns: Partial<ExcelJS.Column>[] = [];
const columns: Partial<Column>[] = [];
cols.value.forEach((col) => {
if (col.label && col.prop && exportsFormData.fields.includes(col.prop)) {
columns.push({ header: col.label, key: col.prop });
@@ -697,7 +702,7 @@ function handleImport() {
});
}
// 导入
function handleImports() {
async function handleImports() {
const importsAction = props.contentConfig.importsAction;
if (importsAction === undefined) {
ElMessage.error("未配置importsAction");
@@ -706,7 +711,7 @@ function handleImports() {
// 获取选择的文件
const file = importFormData.files[0].raw as File;
// 创建Workbook实例
const workbook = new ExcelJS.Workbook();
const workbook = await createWorkbook();
// 使用FileReader对象来读取文件内容
const fileReader = new FileReader();
// 二进制字符串的形式加载文件

View File

@@ -10,7 +10,6 @@ import App from "./App.vue";
// ===== 样式导入 =====
import "element-plus/theme-chalk/dark/css-vars.css";
import "vxe-table/lib/style.css";
import "@/styles/index.scss";
import "uno.css";
import "animate.css";
@@ -24,11 +23,6 @@ import { setupI18n } from "@/lang";
// ===== 全局组件 =====
import * as ElementPlusIcons from "@element-plus/icons-vue";
// ===== 第三方插件 =====
import VXETable from "vxe-table";
import { InstallCodeMirror } from "codemirror-editor-vue3";
import { configureVxeTable } from "@/plugins/vxe-table";
// ===== 路由守卫 =====
import { setupPermissionGuard } from "@/router/guards/permission";
@@ -47,16 +41,11 @@ setupStore(app);
// 2⃣ 全局组件Element Plus 图标)
Object.entries(ElementPlusIcons).forEach(([name, comp]) => app.component(name, comp));
// 3第三方插件
configureVxeTable();
app.use(VXETable);
app.use(InstallCodeMirror);
// 4⃣ 路由守卫
// 3路由守卫
setupPermissionGuard();
// 5️⃣ SSE 初始化
// 4️⃣ SSE 初始化
setupSse();
// 6️⃣ 挂载应用
// 5️⃣ 挂载应用
app.mount("#app");

View File

@@ -1,7 +1,7 @@
<template>
<div class="page-container">
<!-- 表格 -->
<vxe-grid ref="xGrid" v-bind="gridOptions" v-on="gridEvents">
<VxeGrid ref="xGrid" v-bind="gridOptions" v-on="gridEvents">
<!-- 搜索 -->
<!-- <template #form-roles="{ data }">
<el-select
@@ -23,12 +23,12 @@
</template> -->
<!-- 左侧按钮列表 -->
<template #toolbar-btns>
<vxe-button status="primary" icon="vxe-icon-add" @click="curd.onShowModal()">
<VxeButton status="primary" icon="vxe-icon-add" @click="curd.onShowModal()">
新增用户
</vxe-button>
<vxe-button status="danger" icon="vxe-icon-delete" @click="curd.onDelete()">
</VxeButton>
<VxeButton status="danger" icon="vxe-icon-delete" @click="curd.onDelete()">
批量删除
</vxe-button>
</VxeButton>
</template>
<!-- 展开行 -->
<template #column-expand="{ row }">
@@ -65,19 +65,44 @@
<el-button link type="primary" @click="curd.onShowModal(row)">修改</el-button>
<el-button link type="danger" @click="curd.onDelete(row)">删除</el-button>
</template>
</vxe-grid>
</VxeGrid>
<!-- 弹窗 -->
<vxe-modal ref="xModal" v-bind="modalOptions">
<VxeModal ref="xModal" v-bind="modalOptions">
<!-- 表单 -->
<vxe-form ref="xForm" v-bind="formOptions" />
</vxe-modal>
<VxeForm ref="xForm" v-bind="formOptions" />
</VxeModal>
</div>
</template>
<script setup lang="ts">
import "vxe-table/lib/style.css";
import { ref, reactive, onMounted } from "vue";
import type { VxeGridInstance, VxeGridProps, VxeGridListeners } from "vxe-table";
import { VXETable } from "vxe-table";
import {
VXETable,
VxeButton,
VxeButtonGroup,
VxeForm,
VxeGrid,
VxeInput,
VxeModal,
VxeSelect,
} from "vxe-table";
import { configureVxeTable } from "@/plugins/vxe-table";
defineOptions({
components: {
VxeButton,
VxeButtonGroup,
VxeForm,
VxeGrid,
VxeInput,
VxeModal,
VxeSelect,
},
});
configureVxeTable();
const options = [
{ label: "管理", value: "admin" },

View File

@@ -1,4 +1,4 @@
{
"extends": "./tsconfig.json",
"include": ["src/**/*", "mock/**/*", "vite.config.ts", "eslint.config.ts"]
"include": ["src/**/*", "mock/**/*", "vite.config.ts", "uno.config.ts", "eslint.config.ts"]
}

View File

@@ -3,9 +3,7 @@ import {
defineConfig,
presetAttributify,
presetIcons,
presetTypography,
presetUno,
presetWebFonts,
transformerDirectives,
transformerVariantGroup,
} from "unocss";
@@ -71,12 +69,6 @@ export default defineConfig({
}),
},
}),
presetTypography(),
presetWebFonts({
fonts: {
// ...
},
}),
],
safelist: generateSafeList(),
transformers: [transformerDirectives(), transformerVariantGroup()],

View File

@@ -1,6 +1,12 @@
import vue from "@vitejs/plugin-vue";
import type { PluginOption } from "vite";
import { type ConfigEnv, type UserConfig, loadEnv, defineConfig } from "vite";
import {
type ConfigEnv,
type PreRenderedAsset,
type UserConfig,
loadEnv,
defineConfig,
} from "vite";
import AutoImport from "unplugin-auto-import/vite";
import Components from "unplugin-vue-components/vite";
@@ -202,13 +208,17 @@ export default defineConfig(({ mode }: ConfigEnv): UserConfig => {
cssMinify: "lightningcss", // Vite 8 默认使用 Lightning CSS 压缩
// minify 默认使用 'oxc',压缩速度比 terser 快 30-90 倍
rolldownOptions: {
checks: {
invalidAnnotation: false,
pluginTimings: false,
},
output: {
// 用于从入口点创建的块的打包输出格式
entryFileNames: "js/[name].[hash].js",
// 用于命名代码拆分时创建的共享块的输出命名
chunkFileNames: "js/[name].[hash].js",
// 用于输出静态资源的命名
assetFileNames: (assetInfo: any) => {
assetFileNames: (assetInfo: PreRenderedAsset) => {
if (!assetInfo.name) {
return "assets/[name].[hash][extname]";
}