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 UploadUserFile,
type TableInstance, type TableInstance,
} from "element-plus"; } from "element-plus";
import ExcelJS from "exceljs";
import { reactive, ref, computed } from "vue"; import { reactive, ref, computed } from "vue";
import type { Column, Workbook } from "exceljs";
import type { IContentConfig, IObject, IOperateData } from "./types"; import type { IContentConfig, IObject, IOperateData } from "./types";
import type { IToolsButton } from "./types"; import type { IToolsButton } from "./types";
@@ -579,15 +579,20 @@ function handleCloseExportsModal() {
exportsFormRef.value?.clearValidate(); 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 const filename = exportsFormData.filename
? exportsFormData.filename ? exportsFormData.filename
: props.contentConfig.permPrefix || "export"; : props.contentConfig.permPrefix || "export";
const sheetname = exportsFormData.sheetname ? exportsFormData.sheetname : "sheet"; const sheetname = exportsFormData.sheetname ? exportsFormData.sheetname : "sheet";
const workbook = new ExcelJS.Workbook(); const workbook = await createWorkbook();
const worksheet = workbook.addWorksheet(sheetname); const worksheet = workbook.addWorksheet(sheetname);
const columns: Partial<ExcelJS.Column>[] = []; const columns: Partial<Column>[] = [];
cols.value.forEach((col) => { cols.value.forEach((col) => {
if (col.label && col.prop && exportsFormData.fields.includes(col.prop)) { if (col.label && col.prop && exportsFormData.fields.includes(col.prop)) {
columns.push({ header: col.label, key: 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; const importsAction = props.contentConfig.importsAction;
if (importsAction === undefined) { if (importsAction === undefined) {
ElMessage.error("未配置importsAction"); ElMessage.error("未配置importsAction");
@@ -706,7 +711,7 @@ function handleImports() {
// 获取选择的文件 // 获取选择的文件
const file = importFormData.files[0].raw as File; const file = importFormData.files[0].raw as File;
// 创建Workbook实例 // 创建Workbook实例
const workbook = new ExcelJS.Workbook(); const workbook = await createWorkbook();
// 使用FileReader对象来读取文件内容 // 使用FileReader对象来读取文件内容
const fileReader = new 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 "element-plus/theme-chalk/dark/css-vars.css";
import "vxe-table/lib/style.css";
import "@/styles/index.scss"; import "@/styles/index.scss";
import "uno.css"; import "uno.css";
import "animate.css"; import "animate.css";
@@ -24,11 +23,6 @@ import { setupI18n } from "@/lang";
// ===== 全局组件 ===== // ===== 全局组件 =====
import * as ElementPlusIcons from "@element-plus/icons-vue"; 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"; import { setupPermissionGuard } from "@/router/guards/permission";
@@ -47,16 +41,11 @@ setupStore(app);
// 2⃣ 全局组件Element Plus 图标) // 2⃣ 全局组件Element Plus 图标)
Object.entries(ElementPlusIcons).forEach(([name, comp]) => app.component(name, comp)); Object.entries(ElementPlusIcons).forEach(([name, comp]) => app.component(name, comp));
// 3第三方插件 // 3路由守卫
configureVxeTable();
app.use(VXETable);
app.use(InstallCodeMirror);
// 4⃣ 路由守卫
setupPermissionGuard(); setupPermissionGuard();
// 5️⃣ SSE 初始化 // 4️⃣ SSE 初始化
setupSse(); setupSse();
// 6️⃣ 挂载应用 // 5️⃣ 挂载应用
app.mount("#app"); app.mount("#app");

View File

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

View File

@@ -1,4 +1,4 @@
{ {
"extends": "./tsconfig.json", "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, defineConfig,
presetAttributify, presetAttributify,
presetIcons, presetIcons,
presetTypography,
presetUno, presetUno,
presetWebFonts,
transformerDirectives, transformerDirectives,
transformerVariantGroup, transformerVariantGroup,
} from "unocss"; } from "unocss";
@@ -71,12 +69,6 @@ export default defineConfig({
}), }),
}, },
}), }),
presetTypography(),
presetWebFonts({
fonts: {
// ...
},
}),
], ],
safelist: generateSafeList(), safelist: generateSafeList(),
transformers: [transformerDirectives(), transformerVariantGroup()], transformers: [transformerDirectives(), transformerVariantGroup()],

View File

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