This commit is contained in:
Ironsp
2026-05-11 15:25:09 +08:00
parent a29a26e391
commit 31dc367e87
360 changed files with 29979 additions and 0 deletions

View File

@@ -0,0 +1,22 @@
import AutoImport from 'unplugin-auto-import/vite';
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers';
export default (path: any) => {
return AutoImport({
// 自动导入 Vue 相关函数
imports: ['vue', 'vue-router', '@vueuse/core', 'pinia'],
eslintrc: {
enabled: true,
filepath: './.eslintrc-auto-import.json',
globalsPropValue: true
},
resolvers: [
// 自动导入 Element Plus 相关函数ElMessage, ElMessageBox... (带样式)
ElementPlusResolver({
importStyle: false
})
],
vueTemplate: true, // 是否在 vue 模板中自动导入
dts: path.resolve(path.resolve(__dirname, '../../src'), 'types', 'auto-imports.d.ts')
});
};

View File

@@ -0,0 +1,19 @@
import Components from 'unplugin-vue-components/vite';
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers';
import IconsResolver from 'unplugin-icons/resolver';
export default (path: any) => {
return Components({
resolvers: [
// 自动导入 Element Plus 组件
ElementPlusResolver({
importStyle: false
}),
// 自动注册图标组件
IconsResolver({
enabledCollections: ['ep']
})
],
dts: path.resolve(path.resolve(__dirname, '../../src'), 'types', 'components.d.ts')
});
};

110
vite/plugins/compression.ts Normal file
View File

@@ -0,0 +1,110 @@
import { promises as fs } from 'fs';
import path from 'path';
import zlib from 'zlib';
import { promisify } from 'util';
import type { Plugin, ResolvedConfig } from 'vite';
const gzip = promisify(zlib.gzip);
const brotliCompress = promisify(zlib.brotliCompress);
const compressibleFileRE = /\.(js|mjs|json|css|html)$/i;
const defaultThreshold = 1025;
type CompressionKind = 'gzip' | 'brotli';
const compressionHandlers: Record<CompressionKind, { ext: string; compress: (content: Buffer) => Promise<Buffer> }> = {
gzip: {
ext: '.gz',
compress: (content) => gzip(content, { level: zlib.constants.Z_BEST_COMPRESSION })
},
brotli: {
ext: '.br',
compress: (content) =>
brotliCompress(content, {
params: {
[zlib.constants.BROTLI_PARAM_QUALITY]: zlib.constants.BROTLI_MAX_QUALITY,
[zlib.constants.BROTLI_PARAM_MODE]: zlib.constants.BROTLI_MODE_TEXT
}
})
}
};
async function collectFiles(rootDir: string): Promise<string[]> {
const entries = await fs.readdir(rootDir, { withFileTypes: true });
const files = await Promise.all(
entries.map(async (entry) => {
const fullPath = path.join(rootDir, entry.name);
if (entry.isDirectory()) {
return collectFiles(fullPath);
}
return compressibleFileRE.test(entry.name) ? [fullPath] : [];
})
);
return files.flat();
}
function createCompressionPlugin(kind: CompressionKind): Plugin {
const handler = compressionHandlers[kind];
let config: ResolvedConfig | undefined;
return {
name: `local:compression:${kind}`,
apply: 'build',
enforce: 'post',
configResolved(resolvedConfig) {
config = resolvedConfig;
},
async closeBundle() {
const outputDir = path.resolve(process.cwd(), config?.build.outDir ?? 'dist');
const files = await collectFiles(outputDir);
const compressedEntries: Array<{ file: string; originalKb: string; compressedKb: string }> = [];
await Promise.all(
files.map(async (filePath) => {
const stat = await fs.stat(filePath);
if (stat.size < defaultThreshold) {
return;
}
const content = await fs.readFile(filePath);
const compressed = await handler.compress(content);
const outputFile = `${filePath}${handler.ext}`;
await fs.writeFile(outputFile, compressed);
compressedEntries.push({
file: path.relative(outputDir, outputFile).replaceAll('\\', '/'),
originalKb: (stat.size / 1024).toFixed(2),
compressedKb: (compressed.byteLength / 1024).toFixed(2)
});
})
);
if (!compressedEntries.length) {
return;
}
compressedEntries.sort((a, b) => a.file.localeCompare(b.file));
config?.logger.info(`\n[compression:${kind}] generated ${compressedEntries.length} files`);
for (const entry of compressedEntries) {
config?.logger.info(`${path.basename(outputDir)}/${entry.file} ${entry.originalKb}kb -> ${entry.compressedKb}kb`);
}
config?.logger.info('');
}
};
}
export default (env: Record<string, string>) => {
const { VITE_BUILD_COMPRESS } = env;
const plugins: Plugin[] = [];
if (!VITE_BUILD_COMPRESS) {
return plugins;
}
const compressionList = VITE_BUILD_COMPRESS.split(',').map((item) => item.trim()) as CompressionKind[];
if (compressionList.includes('gzip')) {
plugins.push(createCompressionPlugin('gzip'));
}
if (compressionList.includes('brotli')) {
plugins.push(createCompressionPlugin('brotli'));
}
return plugins;
};

9
vite/plugins/icons.ts Normal file
View File

@@ -0,0 +1,9 @@
import Icons from 'unplugin-icons/vite';
export default () => {
return Icons({
// 自动安装图标库
autoInstall: true,
compiler: "vue3"
});
};

25
vite/plugins/index.ts Normal file
View File

@@ -0,0 +1,25 @@
import vue from '@vitejs/plugin-vue';
import vueDevTools from 'vite-plugin-vue-devtools';
import createUnoCss from './unocss';
import createAutoImport from './auto-import';
import createComponents from './components';
import createIcons from './icons';
import createSvgIconsPlugin from './svg-icon';
import createCompression from './compression';
import createSetupExtend from './setup-extend';
import path from 'path';
export default (viteEnv: any, isBuild = false): [] => {
const vitePlugins: any = [];
vitePlugins.push(vue());
vitePlugins.push(vueDevTools());
vitePlugins.push(createUnoCss());
vitePlugins.push(createAutoImport(path));
vitePlugins.push(createComponents(path));
vitePlugins.push(createCompression(viteEnv));
vitePlugins.push(createIcons());
vitePlugins.push(createSvgIconsPlugin(path));
vitePlugins.push(createSetupExtend());
return vitePlugins;
};

View File

@@ -0,0 +1,5 @@
import setupExtend from 'unplugin-vue-setup-extend-plus/vite';
export default () => {
return setupExtend({});
};

10
vite/plugins/svg-icon.ts Normal file
View File

@@ -0,0 +1,10 @@
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons-ng';
export default (path: any) => {
return createSvgIconsPlugin({
// 指定需要缓存的图标文件夹
iconDirs: [path.resolve(path.resolve(__dirname, '../../src'), 'assets/icons/svg')],
// 指定symbolId格式
symbolId: 'icon-[dir]-[name]'
});
};

7
vite/plugins/unocss.ts Normal file
View File

@@ -0,0 +1,7 @@
import UnoCss from 'unocss/vite';
export default () => {
return UnoCss({
hmrTopLevelAwait: false // unocss默认是true低版本浏览器是不支持的启动后会报错
});
};