dev #3

Merged
bunny merged 2 commits from dev into master 2024-05-29 17:35:48 +08:00
16 changed files with 568 additions and 461 deletions

18
.env
View File

@ -1,5 +1,17 @@
# 平台本地运行端口号
VITE_PORT = 8848
VITE_PORT=8202
# 预发布环境路由历史模式Hash模式传"hash"、HTML5模式传"h5"、Hash模式带base参数传"hash,base参数"、HTML5模式带base参数传"h5,base参数"
VITE_ROUTER_HISTORY="hash"
# 跨域代理地址
VITE_APP_URL="http://localhost:8801"
# 是否在打包时使用cdn替换本地库 替换 true 不替换 false
VITE_CDN=true
# 是否启用gzip压缩或brotli压缩分两种情况删除原始文件和不删除原始文件
# 压缩时不删除原始文件的配置gzip、brotli、both同时开启 gzip 与 brotli 压缩、none不开启压缩默认
# 压缩时删除原始文件的配置gzip-clear、brotli-clear、both-clear同时开启 gzip 与 brotli 压缩、none不开启压缩默认
VITE_COMPRESSION="none"
# 是否隐藏首页 隐藏 true 不隐藏 false 勿删除VITE_HIDE_HOME只需在.env文件配置
VITE_HIDE_HOME = false

View File

@ -1,8 +1,17 @@
# 平台本地运行端口号
VITE_PORT = 8848
VITE_PORT=8202
# 开发环境读取配置文件路径
VITE_PUBLIC_PATH = /
# 预发布环境路由历史模式Hash模式传"hash"、HTML5模式传"h5"、Hash模式带base参数传"hash,base参数"、HTML5模式带base参数传"h5,base参数"
VITE_ROUTER_HISTORY="hash"
# 跨域代理地址
VITE_APP_URL="http://localhost:8801"
# 是否在打包时使用cdn替换本地库 替换 true 不替换 false
VITE_CDN=true
# 是否启用gzip压缩或brotli压缩分两种情况删除原始文件和不删除原始文件
# 压缩时不删除原始文件的配置gzip、brotli、both同时开启 gzip 与 brotli 压缩、none不开启压缩默认
# 压缩时删除原始文件的配置gzip-clear、brotli-clear、both-clear同时开启 gzip 与 brotli 压缩、none不开启压缩默认
VITE_COMPRESSION="none"
# 开发环境路由历史模式Hash模式传"hash"、HTML5模式传"h5"、Hash模式带base参数传"hash,base参数"、HTML5模式带base参数传"h5,base参数"
VITE_ROUTER_HISTORY = "hash"

View File

@ -1,13 +1,17 @@
# 线上环境平台打包路径
VITE_PUBLIC_PATH = /
# 平台本地运行端口号
VITE_PORT=8202
# 线上环境路由历史模式Hash模式传"hash"、HTML5模式传"h5"、Hash模式带base参数传"hash,base参数"、HTML5模式带base参数传"h5,base参数"
VITE_ROUTER_HISTORY = "hash"
# 预发布环境路由历史模式Hash模式传"hash"、HTML5模式传"h5"、Hash模式带base参数传"hash,base参数"、HTML5模式带base参数传"h5,base参数"
VITE_ROUTER_HISTORY="hash"
# 跨域代理地址
VITE_APP_URL="http://localhost:8801"
# 是否在打包时使用cdn替换本地库 替换 true 不替换 false
VITE_CDN = false
VITE_CDN=true
# 是否启用gzip压缩或brotli压缩分两种情况删除原始文件和不删除原始文件
# 压缩时不删除原始文件的配置gzip、brotli、both同时开启 gzip 与 brotli 压缩、none不开启压缩默认
# 压缩时删除原始文件的配置gzip-clear、brotli-clear、both-clear同时开启 gzip 与 brotli 压缩、none不开启压缩默认
VITE_COMPRESSION = "none"
VITE_COMPRESSION="none"

View File

@ -1,16 +1,17 @@
# 预发布也需要生产环境的行为
# https://cn.vitejs.dev/guide/env-and-mode.html#modes
# NODE_ENV = development
VITE_PUBLIC_PATH = /
# 平台本地运行端口号
VITE_PORT=8202
# 预发布环境路由历史模式Hash模式传"hash"、HTML5模式传"h5"、Hash模式带base参数传"hash,base参数"、HTML5模式带base参数传"h5,base参数"
VITE_ROUTER_HISTORY = "hash"
VITE_ROUTER_HISTORY="hash"
# 跨域代理地址
VITE_APP_URL="http://localhost:8801"
# 是否在打包时使用cdn替换本地库 替换 true 不替换 false
VITE_CDN = true
VITE_CDN=true
# 是否启用gzip压缩或brotli压缩分两种情况删除原始文件和不删除原始文件
# 压缩时不删除原始文件的配置gzip、brotli、both同时开启 gzip 与 brotli 压缩、none不开启压缩默认
# 压缩时删除原始文件的配置gzip-clear、brotli-clear、both-clear同时开启 gzip 与 brotli 压缩、none不开启压缩默认
VITE_COMPRESSION = "none"
VITE_COMPRESSION="none"

1
.nvmrc Normal file
View File

@ -0,0 +1 @@
v20.13.1

52
build/buildEnv.ts Normal file
View File

@ -0,0 +1,52 @@
import { pathResolve } from './utils';
import type { BuildOptions } from 'vite';
export const buildEnvironment = () => {
const environment: BuildOptions = {
target: 'es2015',
assetsInlineLimit: 20000,
// 构建输出的目录,默认值为"dist"
outDir: 'dist',
// 用于指定使用的代码压缩工具。在这里minify 被设置为 'terser',表示使用 Terser 进行代码压缩。默认值terser
// esbuild 打包更快,但是不能去除 console.logterser打包慢但能去除 console.log
minify: 'terser',
// 用于配置 Terser 的选项
terserOptions: {
// 用于配置压缩选项
compress: {
drop_console: true, // 是否删除代码中的 console 语句, 默认值false
drop_debugger: true, // 是否删除代码中的 debugger 语句, 默认值false
},
},
// 禁用 gzip 压缩大小报告,可略微减少打包时间
reportCompressedSize: false,
// 用于指定是否生成源映射文件。源映射文件可以帮助调试和定位源代码中的错误。当设置为false时构建过程不会生成源映射文件
sourcemap: false,
// 用于配置 CommonJS 模块的选项
commonjsOptions: {
// 用于指定是否忽略 CommonJS 模块中的 try-catch 语句。当设置为false时构建过程会保留 CommonJS 模块中的 try-catch 语句
ignoreTryCatch: false,
},
// 规定触发警告的 chunk 大小, 当某个代码分块的大小超过该限制时Vite 会发出警告
chunkSizeWarningLimit: 2000,
rollupOptions: {
input: {
index: pathResolve('../index.html', import.meta.url),
},
// 静态资源分类打包
output: {
chunkFileNames: 'static/js/[name]-[hash].js',
entryFileNames: 'static/js/[name]-[hash].js',
assetFileNames: 'static/[ext]/[name]-[hash].[ext]',
manualChunks: id => {
// 如果是包含在包中则打包成 vendor
if (id.includes('node_modules')) {
return 'vendor';
}
},
},
},
};
return environment;
};

View File

@ -1,4 +1,4 @@
import { Plugin as importToCDN } from "vite-plugin-cdn-import";
import { Plugin as importToCDN } from 'vite-plugin-cdn-import';
/**
* @description `cdn`使cdn模式 .env.production VITE_CDN true
@ -6,55 +6,56 @@ import { Plugin as importToCDN } from "vite-plugin-cdn-import";
* 使jscss文件cdn
*/
export const cdn = importToCDN({
//prodUrl解释 name: 对应下面modules的nameversion: 自动读取本地package.json中dependencies依赖中对应包的版本号path: 对应下面modules的path当然也可写完整路径会替换prodUrl
prodUrl: "https://cdn.bootcdn.net/ajax/libs/{name}/{version}/{path}",
modules: [
{
name: "vue",
var: "Vue",
path: "vue.global.prod.min.js"
},
{
name: "vue-router",
var: "VueRouter",
path: "vue-router.global.min.js"
},
{
name: "vue-i18n",
var: "VueI18n",
path: "vue-i18n.runtime.global.prod.min.js"
},
// 项目中没有直接安装vue-demi但是pinia用到了所以需要在引入pinia前引入vue-demihttps://github.com/vuejs/pinia/blob/v2/packages/pinia/package.json#L77
{
name: "vue-demi",
var: "VueDemi",
path: "index.iife.min.js"
},
{
name: "pinia",
var: "Pinia",
path: "pinia.iife.min.js"
},
{
name: "element-plus",
var: "ElementPlus",
path: "index.full.min.js",
css: "index.min.css"
},
{
name: "axios",
var: "axios",
path: "axios.min.js"
},
{
name: "dayjs",
var: "dayjs",
path: "dayjs.min.js"
},
{
name: "echarts",
var: "echarts",
path: "echarts.min.js"
}
]
//prodUrl解释 name: 对应下面modules的nameversion: 自动读取本地package.json中dependencies依赖中对应包的版本号path: 对应下面modules的path当然也可写完整路径会替换prodUrl
// prodUrl: 'https://cdn.bootcdn.net/ajax/libs/{name}/{version}/{path}',
prodUrl: 'https://unpkg.com/{name}@{version}/{path}',
modules: [
{
name: 'vue',
var: 'Vue',
path: 'dist/vue.global.js',
},
{
name: 'vue-router',
var: 'VueRouter',
path: 'dist/vue-router.global.js',
},
{
name: 'vue-i18n',
var: 'VueI18n',
path: 'dist/vue-i18n.global.js',
},
// 项目中没有直接安装vue-demi但是pinia用到了所以需要在引入pinia前引入vue-demihttps://github.com/vuejs/pinia/blob/v2/packages/pinia/package.json#L77
{
name: 'vue-demi',
var: 'VueDemi',
path: 'lib/index.iife.js',
},
{
name: 'pinia',
var: 'Pinia',
path: 'dist/pinia.iife.js',
},
{
name: 'element-plus',
var: 'ElementPlus',
path: 'dist/index.full.js',
css: 'dist/index.css',
},
{
name: 'axios',
var: 'axios',
path: 'dist/axios.min.js',
},
{
name: 'dayjs',
var: 'dayjs',
path: 'dayjs.min.js',
},
{
name: 'echarts',
var: 'echarts',
path: 'dist/echarts.js',
},
],
});

View File

@ -1,63 +1,57 @@
import type { Plugin } from "vite";
import { isArray } from "@pureadmin/utils";
import compressPlugin from "vite-plugin-compression";
import type { Plugin } from 'vite';
import { isArray } from '@pureadmin/utils';
import compressPlugin from 'vite-plugin-compression';
export const configCompressPlugin = (
compress: ViteCompression
): Plugin | Plugin[] => {
if (compress === "none") return null;
export const configCompressPlugin = (compress: ViteCompression): Plugin | Plugin[] => {
if (compress === 'none') return null;
const gz = {
// 生成的压缩包后缀
ext: ".gz",
// 体积大于threshold才会被压缩
threshold: 0,
// 默认压缩.js|mjs|json|css|html后缀文件设置成true压缩全部文件
filter: () => true,
// 压缩后是否删除原始文件
deleteOriginFile: false
};
const br = {
ext: ".br",
algorithm: "brotliCompress",
threshold: 0,
filter: () => true,
deleteOriginFile: false
};
const gz = {
// 生成的压缩包后缀
ext: '.gz',
// 体积大于threshold才会被压缩
threshold: 0,
// 默认压缩.js|mjs|json|css|html后缀文件设置成true压缩全部文件
filter: () => true,
// 压缩后是否删除原始文件
deleteOriginFile: false,
};
const br = {
ext: '.br',
algorithm: 'brotliCompress',
threshold: 0,
filter: () => true,
deleteOriginFile: false,
};
const codeList = [
{ k: "gzip", v: gz },
{ k: "brotli", v: br },
{ k: "both", v: [gz, br] }
];
const codeList = [
{ k: 'gzip', v: gz },
{ k: 'brotli', v: br },
{ k: 'both', v: [gz, br] },
];
const plugins: Plugin[] = [];
const plugins: Plugin[] = [];
codeList.forEach(item => {
if (compress.includes(item.k)) {
if (compress.includes("clear")) {
if (isArray(item.v)) {
item.v.forEach(vItem => {
plugins.push(
compressPlugin(Object.assign(vItem, { deleteOriginFile: true }))
);
});
} else {
plugins.push(
compressPlugin(Object.assign(item.v, { deleteOriginFile: true }))
);
}
} else {
if (isArray(item.v)) {
item.v.forEach(vItem => {
plugins.push(compressPlugin(vItem));
});
} else {
plugins.push(compressPlugin(item.v));
}
}
}
});
codeList.forEach(item => {
if (compress.includes(item.k)) {
if (compress.includes('clear')) {
if (isArray(item.v)) {
item.v.forEach(vItem => {
plugins.push(compressPlugin(Object.assign(vItem, { deleteOriginFile: true })));
});
} else {
plugins.push(compressPlugin(Object.assign(item.v, { deleteOriginFile: true })));
}
} else {
if (isArray(item.v)) {
item.v.forEach(vItem => {
plugins.push(compressPlugin(vItem));
});
} else {
plugins.push(compressPlugin(item.v));
}
}
}
});
return plugins;
return plugins;
};

View File

@ -1,51 +1,54 @@
import type { Plugin } from "vite";
import { getPackageSize } from "./utils";
import dayjs, { type Dayjs } from "dayjs";
import duration from "dayjs/plugin/duration";
import gradientString from "gradient-string";
import boxen, { type Options as BoxenOptions } from "boxen";
import type { Plugin } from 'vite';
import { getPackageSize } from './utils';
import dayjs, { type Dayjs } from 'dayjs';
import duration from 'dayjs/plugin/duration';
import gradientString from 'gradient-string';
import boxen, { type Options as BoxenOptions } from 'boxen';
dayjs.extend(duration);
const welcomeMessage = gradientString("cyan", "magenta").multiline(
`您好! 欢迎使用 bunny-admin 后台管理
访
http://localhost:8848/`
const welcomeMessage = gradientString('cyan', 'magenta').multiline(
`您好! 欢迎使用 bunny-admin 后台管理
访
http://localhost:8202/
访
http://localhost:8202/
`,
);
const boxenOptions: BoxenOptions = {
padding: 0.5,
borderColor: "cyan",
borderStyle: "round"
padding: 0.5,
borderColor: 'cyan',
borderStyle: 'round',
};
export function viteBuildInfo(): Plugin {
let config: { command: string };
let startTime: Dayjs;
let endTime: Dayjs;
let outDir: string;
return {
name: "vite:buildInfo",
configResolved(resolvedConfig) {
config = resolvedConfig;
outDir = resolvedConfig.build?.outDir ?? "dist";
},
buildStart() {
console.log(boxen(welcomeMessage, boxenOptions));
if (config.command === "build") {
startTime = dayjs(new Date());
}
},
closeBundle() {
if (config.command === "build") {
endTime = dayjs(new Date());
getPackageSize({
folder: outDir,
callback: (size: string) => {
console.log(boxen(gradientString("cyan", "magenta").multiline(`🎉 恭喜打包完成(总用时${dayjs.duration(endTime.diff(startTime)).format("mm分ss秒")},打包后的大小为${size}`), boxenOptions));
}
});
}
}
};
let config: { command: string };
let startTime: Dayjs;
let endTime: Dayjs;
let outDir: string;
return {
name: 'vite:buildInfo',
configResolved(resolvedConfig) {
config = resolvedConfig;
outDir = resolvedConfig.build?.outDir ?? 'dist';
},
buildStart() {
console.log(boxen(welcomeMessage, boxenOptions));
if (config.command === 'build') {
startTime = dayjs(new Date());
}
},
closeBundle() {
if (config.command === 'build') {
endTime = dayjs(new Date());
getPackageSize({
folder: outDir,
callback: (size: string) => {
console.log(boxen(gradientString('cyan', 'magenta').multiline(`🎉 恭喜打包完成(总用时${dayjs.duration(endTime.diff(startTime)).format('mm分ss秒')},打包后的大小为${size}`), boxenOptions));
},
});
}
},
};
}

29
build/server.ts Normal file
View File

@ -0,0 +1,29 @@
import { loadEnv, type ServerOptions } from 'vite';
import { root, wrapperEnv } from './utils';
export const serverOptions = (mode: string) => {
const { VITE_PORT, VITE_APP_URL } = wrapperEnv(loadEnv(mode, root));
const options: ServerOptions = {
port: VITE_PORT, // ? 端口号
host: '0.0.0.0',
proxy: {
'/api': {
target: VITE_APP_URL,
changeOrigin: true,
rewrite: (path: string) => path.replace(/^\/api/, '/api'),
},
'/mock': {
target: VITE_APP_URL,
changeOrigin: true,
rewrite: (path: string) => path.replace(/^\/mock/, '/mock'),
},
},
// 预热文件以提前转换和缓存结果,降低启动期间的初始页面加载时长并防止转换瀑布
warmup: {
clientFiles: ['./index.html', './src/{views,components}/*'],
},
};
return options;
};

View File

@ -34,7 +34,6 @@ const alias: Record<string, string> = {
'@': pathResolve('../src'),
'@build': pathResolve(),
};
/** 平台的名称、版本、运行所需的`node`和`pnpm`版本、依赖、最后构建时间的类型提示 */
const __APP_INFO__ = {
pkg: { name, version, engines, dependencies, devDependencies },
@ -43,14 +42,12 @@ const __APP_INFO__ = {
/** 处理环境变量 */
const wrapperEnv = (envConf: Recordable): ViteEnv => {
// 默认值
// TODO 默认值
const ret: ViteEnv = {
VITE_PORT: 8848,
VITE_PUBLIC_PATH: '',
VITE_ROUTER_HISTORY: '',
VITE_CDN: false,
VITE_HIDE_HOME: 'false',
VITE_COMPRESSION: 'none',
VITE_APP_URL: '',
VITE_COMPRESSION: 'gzip',
VITE_CDN: true,
};
for (const envName of Object.keys(envConf)) {
@ -67,6 +64,7 @@ const wrapperEnv = (envConf: Recordable): ViteEnv => {
process.env[envName] = JSON.stringify(realName);
}
}
return ret;
};

View File

@ -90,6 +90,7 @@
"responsive-storage": "^2.2.0",
"sortablejs": "^1.15.2",
"swiper": "^11.1.1",
"terser": "^5.31.0",
"typeit": "^8.8.3",
"v-contextmenu": "^3.2.0",
"v3-infinite-loading": "^1.3.1",

View File

@ -131,6 +131,9 @@ importers:
swiper:
specifier: ^11.1.1
version: 11.1.3
terser:
specifier: ^5.31.0
version: 5.31.0
typeit:
specifier: ^8.8.3
version: 8.8.3
@ -257,10 +260,10 @@ importers:
version: 7.10.0(eslint@9.3.0)(typescript@5.4.5)
'@vitejs/plugin-vue':
specifier: ^5.0.4
version: 5.0.4(vite@5.2.11(@types/node@20.12.12)(sass@1.77.2))(vue@3.4.27(typescript@5.4.5))
version: 5.0.4(vite@5.2.11(@types/node@20.12.12)(sass@1.77.2)(terser@5.31.0))(vue@3.4.27(typescript@5.4.5))
'@vitejs/plugin-vue-jsx':
specifier: ^3.1.0
version: 3.1.0(vite@5.2.11(@types/node@20.12.12)(sass@1.77.2))(vue@3.4.27(typescript@5.4.5))
version: 3.1.0(vite@5.2.11(@types/node@20.12.12)(sass@1.77.2)(terser@5.31.0))(vue@3.4.27(typescript@5.4.5))
autoprefixer:
specifier: ^10.4.19
version: 10.4.19(postcss@8.4.38)
@ -356,13 +359,13 @@ importers:
version: 5.4.5
vite:
specifier: ^5.2.11
version: 5.2.11(@types/node@20.12.12)(sass@1.77.2)
version: 5.2.11(@types/node@20.12.12)(sass@1.77.2)(terser@5.31.0)
vite-plugin-cdn-import:
specifier: ^0.3.5
version: 0.3.5(rollup@4.18.0)
vite-plugin-compression:
specifier: ^0.5.1
version: 0.5.1(vite@5.2.11(@types/node@20.12.12)(sass@1.77.2))
version: 0.5.1(vite@5.2.11(@types/node@20.12.12)(sass@1.77.2)(terser@5.31.0))
vite-plugin-fake-server:
specifier: ^2.1.1
version: 2.1.1
@ -1250,6 +1253,9 @@ packages:
resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==}
engines: {node: '>=6.0.0'}
'@jridgewell/source-map@0.3.6':
resolution: {integrity: sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==}
'@jridgewell/sourcemap-codec@1.4.15':
resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==}
@ -2289,6 +2295,9 @@ packages:
resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==}
engines: {node: '>=18'}
commander@2.20.3:
resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==}
commander@4.1.1:
resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==}
engines: {node: '>= 6'}
@ -5395,6 +5404,11 @@ packages:
resolution: {integrity: sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==}
engines: {node: '>=8'}
terser@5.31.0:
resolution: {integrity: sha512-Q1JFAoUKE5IMfI4Z/lkE/E6+SwgzO+x4tq4v1AyBLRj8VSYvRO6A/rQrPg1yud4g0En9EKI1TvFRF2tQFcoUkg==}
engines: {node: '>=10'}
hasBin: true
test-exclude@6.0.0:
resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==}
engines: {node: '>=8'}
@ -6376,7 +6390,7 @@ snapshots:
lodash.merge: 4.6.2
lodash.uniq: 4.5.0
resolve-from: 5.0.0
ts-node: 10.9.2(@types/node@20.5.1)(typescript@5.4.5)
ts-node: 10.9.2(@types/node@20.12.12)(typescript@5.4.5)
typescript: 5.4.5
transitivePeerDependencies:
- '@swc/core'
@ -6954,6 +6968,11 @@ snapshots:
'@jridgewell/set-array@1.2.1': {}
'@jridgewell/source-map@0.3.6':
dependencies:
'@jridgewell/gen-mapping': 0.3.5
'@jridgewell/trace-mapping': 0.3.25
'@jridgewell/sourcemap-codec@1.4.15': {}
'@jridgewell/trace-mapping@0.3.25':
@ -7394,19 +7413,19 @@ snapshots:
'@uppy/utils': 4.1.3
nanoid: 3.3.7
'@vitejs/plugin-vue-jsx@3.1.0(vite@5.2.11(@types/node@20.12.12)(sass@1.77.2))(vue@3.4.27(typescript@5.4.5))':
'@vitejs/plugin-vue-jsx@3.1.0(vite@5.2.11(@types/node@20.12.12)(sass@1.77.2)(terser@5.31.0))(vue@3.4.27(typescript@5.4.5))':
dependencies:
'@babel/core': 7.24.6
'@babel/plugin-transform-typescript': 7.24.6(@babel/core@7.24.6)
'@vue/babel-plugin-jsx': 1.2.2(@babel/core@7.24.6)
vite: 5.2.11(@types/node@20.12.12)(sass@1.77.2)
vite: 5.2.11(@types/node@20.12.12)(sass@1.77.2)(terser@5.31.0)
vue: 3.4.27(typescript@5.4.5)
transitivePeerDependencies:
- supports-color
'@vitejs/plugin-vue@5.0.4(vite@5.2.11(@types/node@20.12.12)(sass@1.77.2))(vue@3.4.27(typescript@5.4.5))':
'@vitejs/plugin-vue@5.0.4(vite@5.2.11(@types/node@20.12.12)(sass@1.77.2)(terser@5.31.0))(vue@3.4.27(typescript@5.4.5))':
dependencies:
vite: 5.2.11(@types/node@20.12.12)(sass@1.77.2)
vite: 5.2.11(@types/node@20.12.12)(sass@1.77.2)(terser@5.31.0)
vue: 3.4.27(typescript@5.4.5)
'@volar/language-core@1.11.1':
@ -8180,6 +8199,8 @@ snapshots:
commander@12.1.0: {}
commander@2.20.3: {}
commander@4.1.1: {}
commander@7.2.0: {}
@ -8281,7 +8302,7 @@ snapshots:
dependencies:
'@types/node': 20.5.1
cosmiconfig: 8.3.6(typescript@5.4.5)
ts-node: 10.9.2(@types/node@20.5.1)(typescript@5.4.5)
ts-node: 10.9.2(@types/node@20.12.12)(typescript@5.4.5)
typescript: 5.4.5
cosmiconfig-typescript-loader@5.0.0(@types/node@20.12.12)(cosmiconfig@9.0.0(typescript@5.4.5))(typescript@5.4.5):
@ -9699,7 +9720,7 @@ snapshots:
slash: 3.0.0
strip-json-comments: 3.1.1
optionalDependencies:
ts-node: 10.9.2(@types/node@20.5.1)(typescript@5.4.5)
ts-node: 10.9.2(@types/node@20.12.12)(typescript@5.4.5)
transitivePeerDependencies:
- bufferutil
- canvas
@ -10786,7 +10807,7 @@ snapshots:
yaml: 2.4.2
optionalDependencies:
postcss: 8.4.38
ts-node: 10.9.2(@types/node@20.5.1)(typescript@5.4.5)
ts-node: 10.9.2(@types/node@20.12.12)(typescript@5.4.5)
postcss-media-query-parser@0.2.3: {}
@ -11721,6 +11742,13 @@ snapshots:
ansi-escapes: 4.3.2
supports-hyperlinks: 2.3.0
terser@5.31.0:
dependencies:
'@jridgewell/source-map': 0.3.6
acorn: 8.11.3
commander: 2.20.3
source-map-support: 0.5.21
test-exclude@6.0.0:
dependencies:
'@istanbuljs/schema': 0.1.3
@ -11796,14 +11824,14 @@ snapshots:
ts-interface-checker@0.1.13: {}
ts-node@10.9.2(@types/node@20.5.1)(typescript@5.4.5):
ts-node@10.9.2(@types/node@20.12.12)(typescript@5.4.5):
dependencies:
'@cspotcode/source-map-support': 0.8.1
'@tsconfig/node10': 1.0.11
'@tsconfig/node12': 1.0.11
'@tsconfig/node14': 1.0.3
'@tsconfig/node16': 1.0.4
'@types/node': 20.5.1
'@types/node': 20.12.12
acorn: 8.11.3
acorn-walk: 8.3.2
arg: 4.1.3
@ -11964,12 +11992,12 @@ snapshots:
transitivePeerDependencies:
- rollup
vite-plugin-compression@0.5.1(vite@5.2.11(@types/node@20.12.12)(sass@1.77.2)):
vite-plugin-compression@0.5.1(vite@5.2.11(@types/node@20.12.12)(sass@1.77.2)(terser@5.31.0)):
dependencies:
chalk: 4.1.2
debug: 4.3.4
fs-extra: 10.1.0
vite: 5.2.11(@types/node@20.12.12)(sass@1.77.2)
vite: 5.2.11(@types/node@20.12.12)(sass@1.77.2)(terser@5.31.0)
transitivePeerDependencies:
- supports-color
@ -11990,7 +12018,7 @@ snapshots:
svgo: 3.3.2
vue: 3.4.27(typescript@5.4.5)
vite@5.2.11(@types/node@20.12.12)(sass@1.77.2):
vite@5.2.11(@types/node@20.12.12)(sass@1.77.2)(terser@5.31.0):
dependencies:
esbuild: 0.20.2
postcss: 8.4.38
@ -11999,6 +12027,7 @@ snapshots:
'@types/node': 20.12.12
fsevents: 2.3.3
sass: 1.77.2
terser: 5.31.0
vue-demi@0.14.7(vue@3.4.27(typescript@5.4.5)):
dependencies:

View File

@ -1,52 +1,51 @@
import axios from "axios";
import type { App } from "vue";
import axios from 'axios';
import type { App } from 'vue';
let config: object = {};
const { VITE_PUBLIC_PATH } = import.meta.env;
const setConfig = (cfg?: unknown) => {
config = Object.assign(config, cfg);
config = Object.assign(config, cfg);
};
const getConfig = (key?: string): PlatformConfigs => {
if (typeof key === "string") {
const arr = key.split(".");
if (arr && arr.length) {
let data = config;
arr.forEach(v => {
if (data && typeof data[v] !== "undefined") {
data = data[v];
} else {
data = null;
}
});
return data;
}
}
return config;
if (typeof key === 'string') {
const arr = key.split('.');
if (arr && arr.length) {
let data = config;
arr.forEach(v => {
if (data && typeof data[v] !== 'undefined') {
data = data[v];
} else {
data = null;
}
});
return data;
}
}
return config;
};
/** 获取项目动态全局配置 */
export const getPlatformConfig = async (app: App): Promise<undefined> => {
app.config.globalProperties.$config = getConfig();
return axios({
method: "get",
url: `${VITE_PUBLIC_PATH}platform-config.json`
})
.then(({ data: config }) => {
let $config = app.config.globalProperties.$config;
// 自动注入系统配置
if (app && $config && typeof config === "object") {
$config = Object.assign($config, config);
app.config.globalProperties.$config = $config;
// 设置全局配置
setConfig($config);
}
return $config;
})
.catch(() => {
throw "请在public文件夹下添加platform-config.json配置文件";
});
app.config.globalProperties.$config = getConfig();
return axios({
method: 'get',
url: `platform-config.json`,
})
.then(({ data: config }) => {
let $config = app.config.globalProperties.$config;
// 自动注入系统配置
if (app && $config && typeof config === 'object') {
$config = Object.assign($config, config);
app.config.globalProperties.$config = $config;
// 设置全局配置
setConfig($config);
}
return $config;
})
.catch(() => {
throw '请在public文件夹下添加platform-config.json配置文件';
});
};
/** 本地响应式存储的命名空间 */

372
types/global.d.ts vendored
View File

@ -1,203 +1,201 @@
import type { ECharts } from "echarts";
import type { TableColumns } from "@pureadmin/table";
import type { ECharts } from 'echarts';
import type { TableColumns } from '@pureadmin/table';
/**
* `.vue` `.ts` `.tsx` 使
*/
declare global {
/**
* `node``pnpm`
*/
const __APP_INFO__: {
pkg: {
name: string;
version: string;
engines: {
node: string;
pnpm: string;
};
dependencies: Recordable<string>;
devDependencies: Recordable<string>;
};
lastBuildTime: string;
};
/**
* `node``pnpm`
*/
const __APP_INFO__: {
pkg: {
name: string;
version: string;
engines: {
node: string;
pnpm: string;
};
dependencies: Recordable<string>;
devDependencies: Recordable<string>;
};
lastBuildTime: string;
};
/**
* Window
*/
interface Window {
// Global vue app instance
__APP__: App<Element>;
webkitCancelAnimationFrame: (handle: number) => void;
mozCancelAnimationFrame: (handle: number) => void;
oCancelAnimationFrame: (handle: number) => void;
msCancelAnimationFrame: (handle: number) => void;
webkitRequestAnimationFrame: (callback: FrameRequestCallback) => number;
mozRequestAnimationFrame: (callback: FrameRequestCallback) => number;
oRequestAnimationFrame: (callback: FrameRequestCallback) => number;
msRequestAnimationFrame: (callback: FrameRequestCallback) => number;
}
/**
* Window
*/
interface Window {
// Global vue app instance
__APP__: App<Element>;
webkitCancelAnimationFrame: (handle: number) => void;
mozCancelAnimationFrame: (handle: number) => void;
oCancelAnimationFrame: (handle: number) => void;
msCancelAnimationFrame: (handle: number) => void;
webkitRequestAnimationFrame: (callback: FrameRequestCallback) => number;
mozRequestAnimationFrame: (callback: FrameRequestCallback) => number;
oRequestAnimationFrame: (callback: FrameRequestCallback) => number;
msRequestAnimationFrame: (callback: FrameRequestCallback) => number;
}
/**
* Document
*/
interface Document {
webkitFullscreenElement?: Element;
mozFullScreenElement?: Element;
msFullscreenElement?: Element;
}
/**
* Document
*/
interface Document {
webkitFullscreenElement?: Element;
mozFullScreenElement?: Element;
msFullscreenElement?: Element;
}
/**
*
*/
type ViteCompression = "none" | "gzip" | "brotli" | "both" | "gzip-clear" | "brotli-clear" | "both-clear";
/**
*
*/
type ViteCompression = 'none' | 'gzip' | 'brotli' | 'both' | 'gzip-clear' | 'brotli-clear' | 'both-clear';
/**
*
* @see {@link https://pure-admin.github.io/pure-admin-doc/pages/config/#%E5%85%B7%E4%BD%93%E9%85%8D%E7%BD%AE}
*/
interface ViteEnv {
VITE_PORT: number;
VITE_PUBLIC_PATH: string;
VITE_ROUTER_HISTORY: string;
VITE_CDN: boolean;
VITE_HIDE_HOME: string;
VITE_COMPRESSION: ViteCompression;
}
/**
* TODO
* @see {@link https://pure-admin.github.io/pure-admin-doc/pages/config/#%E5%85%B7%E4%BD%93%E9%85%8D%E7%BD%AE}
*/
interface ViteEnv {
VITE_PORT: number; // 启动端口号
VITE_APP_URL: string; // 跨域代理地址
VITE_COMPRESSION: ViteCompression;
VITE_CDN: boolean; // 是否启用CDN
}
/**
* `@pureadmin/table` `TableColumns` 便
*/
interface TableColumnList extends Array<TableColumns> {}
/**
* `@pureadmin/table` `TableColumns` 便
*/
interface TableColumnList extends Array<TableColumns> {}
/**
* `public/platform-config.json`
* @see {@link https://pure-admin.github.io/pure-admin-doc/pages/config/#platform-config-json}
*/
interface PlatformConfigs {
Version?: string;
Title?: string;
Copyright?: string;
FixedHeader?: boolean;
HiddenSideBar?: boolean;
MultiTagsCache?: boolean;
MaxTagsLevel?: number;
KeepAlive?: boolean;
Locale?: string;
Layout?: string;
Theme?: string;
DarkMode?: boolean;
OverallStyle?: string;
Grey?: boolean;
Weak?: boolean;
HideTabs?: boolean;
HideFooter?: boolean;
Stretch?: boolean | number;
SidebarStatus?: boolean;
EpThemeColor?: string;
ShowLogo?: boolean;
ShowModel?: string;
MenuArrowIconNoTransition?: boolean;
CachingAsyncRoutes?: boolean;
TooltipEffect?: Effect;
ResponsiveStorageNameSpace?: string;
MenuSearchHistory?: number;
MapConfigure?: {
amapKey?: string;
options: {
resizeEnable?: boolean;
center?: number[];
zoom?: number;
};
};
}
/**
* `public/platform-config.json`
* @see {@link https://pure-admin.github.io/pure-admin-doc/pages/config/#platform-config-json}
*/
interface PlatformConfigs {
Version?: string;
Title?: string;
Copyright?: string;
FixedHeader?: boolean;
HiddenSideBar?: boolean;
MultiTagsCache?: boolean;
MaxTagsLevel?: number;
KeepAlive?: boolean;
Locale?: string;
Layout?: string;
Theme?: string;
DarkMode?: boolean;
OverallStyle?: string;
Grey?: boolean;
Weak?: boolean;
HideTabs?: boolean;
HideFooter?: boolean;
Stretch?: boolean | number;
SidebarStatus?: boolean;
EpThemeColor?: string;
ShowLogo?: boolean;
ShowModel?: string;
MenuArrowIconNoTransition?: boolean;
CachingAsyncRoutes?: boolean;
TooltipEffect?: Effect;
ResponsiveStorageNameSpace?: string;
MenuSearchHistory?: number;
MapConfigure?: {
amapKey?: string;
options: {
resizeEnable?: boolean;
center?: number[];
zoom?: number;
};
};
}
/**
* `PlatformConfigs`
* @see {@link https://pure-admin.github.io/pure-admin-doc/pages/config/#platform-config-json}
*/
interface StorageConfigs {
version?: string;
title?: string;
fixedHeader?: boolean;
hiddenSideBar?: boolean;
multiTagsCache?: boolean;
keepAlive?: boolean;
locale?: string;
layout?: string;
theme?: string;
darkMode?: boolean;
grey?: boolean;
weak?: boolean;
hideTabs?: boolean;
hideFooter?: boolean;
sidebarStatus?: boolean;
epThemeColor?: string;
themeColor?: string;
overallStyle?: string;
showLogo?: boolean;
showModel?: string;
menuSearchHistory?: number;
mapConfigure?: {
amapKey?: string;
options: {
resizeEnable?: boolean;
center?: number[];
zoom?: number;
};
};
username?: string;
}
/**
* `PlatformConfigs`
* @see {@link https://pure-admin.github.io/pure-admin-doc/pages/config/#platform-config-json}
*/
interface StorageConfigs {
version?: string;
title?: string;
fixedHeader?: boolean;
hiddenSideBar?: boolean;
multiTagsCache?: boolean;
keepAlive?: boolean;
locale?: string;
layout?: string;
theme?: string;
darkMode?: boolean;
grey?: boolean;
weak?: boolean;
hideTabs?: boolean;
hideFooter?: boolean;
sidebarStatus?: boolean;
epThemeColor?: string;
themeColor?: string;
overallStyle?: string;
showLogo?: boolean;
showModel?: string;
menuSearchHistory?: number;
mapConfigure?: {
amapKey?: string;
options: {
resizeEnable?: boolean;
center?: number[];
zoom?: number;
};
};
username?: string;
}
/**
* `responsive-storage` `storage`
*/
interface ResponsiveStorage {
locale: {
locale?: string;
};
layout: {
layout?: string;
theme?: string;
darkMode?: boolean;
sidebarStatus?: boolean;
epThemeColor?: string;
themeColor?: string;
overallStyle?: string;
};
configure: {
grey?: boolean;
weak?: boolean;
hideTabs?: boolean;
hideFooter?: boolean;
showLogo?: boolean;
showModel?: string;
multiTagsCache?: boolean;
stretch?: boolean | number;
};
tags?: Array<any>;
}
/**
* `responsive-storage` `storage`
*/
interface ResponsiveStorage {
locale: {
locale?: string;
};
layout: {
layout?: string;
theme?: string;
darkMode?: boolean;
sidebarStatus?: boolean;
epThemeColor?: string;
themeColor?: string;
overallStyle?: string;
};
configure: {
grey?: boolean;
weak?: boolean;
hideTabs?: boolean;
hideFooter?: boolean;
showLogo?: boolean;
showModel?: string;
multiTagsCache?: boolean;
stretch?: boolean | number;
};
tags?: Array<any>;
}
/**
* 访
*/
interface GlobalPropertiesApi {
$echarts: ECharts;
$storage: ResponsiveStorage;
$config: PlatformConfigs;
}
/**
* 访
*/
interface GlobalPropertiesApi {
$echarts: ECharts;
$storage: ResponsiveStorage;
$config: PlatformConfigs;
}
/**
* `Element`
*/
interface Element {
// v-ripple 作用于 src/directives/ripple/index.ts 文件
_ripple?: {
enabled?: boolean;
centered?: boolean;
class?: string;
circle?: boolean;
touched?: boolean;
};
}
/**
* `Element`
*/
interface Element {
// v-ripple 作用于 src/directives/ripple/index.ts 文件
_ripple?: {
enabled?: boolean;
centered?: boolean;
class?: string;
circle?: boolean;
touched?: boolean;
};
}
}

View File

@ -1,52 +1,28 @@
import { getPluginsList } from './build/plugins';
import { include, exclude } from './build/optimize';
import { type UserConfigExport, type ConfigEnv, loadEnv } from 'vite';
import { root, alias, wrapperEnv, pathResolve, __APP_INFO__ } from './build/utils';
import { exclude, include } from './build/optimize';
import { type ConfigEnv, loadEnv, type UserConfigExport } from 'vite';
import { __APP_INFO__, alias, root, wrapperEnv } from './build/utils';
import { buildEnvironment } from './build/buildEnv';
import { serverOptions } from './build/server'; // Vite中文文档https://cn.vitejs.dev/guide/build#browser-compatibility
// Vite中文文档https://cn.vitejs.dev/guide/build#browser-compatibility
export default ({ mode }: ConfigEnv): UserConfigExport => {
const { VITE_CDN, VITE_PORT, VITE_COMPRESSION, VITE_PUBLIC_PATH } = wrapperEnv(loadEnv(mode, root));
const { VITE_CDN, VITE_COMPRESSION } = wrapperEnv(loadEnv(mode, root));
return {
base: VITE_PUBLIC_PATH,
root,
resolve: {
alias,
},
resolve: { alias },
// 服务端渲染
server: {
// 端口号
port: VITE_PORT,
host: '0.0.0.0',
// 本地跨域代理 https://cn.vitejs.dev/config/server-options.html#server-proxy
proxy: {},
// 预热文件以提前转换和缓存结果,降低启动期间的初始页面加载时长并防止转换瀑布
warmup: {
clientFiles: ['./index.html', './src/{views,components}/*'],
},
},
server: serverOptions(mode),
// 插件相关
plugins: getPluginsList(VITE_CDN, VITE_COMPRESSION),
// https://cn.vitejs.dev/config/dep-optimization-options.html#dep-optimization-options
optimizeDeps: {
include,
exclude,
},
build: {
// https://cn.vitejs.dev/guide/build.html#browser-compatibility
target: 'es2015',
sourcemap: false,
// 消除打包大小超过500kb警告
chunkSizeWarningLimit: 4000,
rollupOptions: {
input: {
index: pathResolve('./index.html', import.meta.url),
},
// 静态资源分类打包
output: {
chunkFileNames: 'static/js/[name]-[hash].js',
entryFileNames: 'static/js/[name]-[hash].js',
assetFileNames: 'static/[ext]/[name]-[hash].[ext]',
},
},
optimizeDeps: { include, exclude },
esbuild: {
pure: ['console.log', 'debugger'],
jsxFactory: 'h',
jsxFragment: 'Fragment',
jsxInject: "import { h } from 'vue';",
},
build: buildEnvironment(),
define: {
__INTLIFY_PROD_DEVTOOLS__: false,
__APP_INFO__: JSON.stringify(__APP_INFO__),