refactor: 〽️ 更新版本内容;简化项目内容
This commit is contained in:
parent
628fd47492
commit
65a956d4e9
35
.env
35
.env
|
@ -1,5 +1,34 @@
|
|||
# 平台本地运行端口号
|
||||
VITE_PORT = 8848
|
||||
VITE_PORT=8201
|
||||
|
||||
# 是否隐藏首页 隐藏 true 不隐藏 false (勿删除,VITE_HIDE_HOME只需在.env文件配置)
|
||||
VITE_HIDE_HOME = false
|
||||
# 预发布环境路由历史模式(Hash模式传"hash"、HTML5模式传"h5"、Hash模式带base参数传"hash,base参数"、HTML5模式带base参数传"h5,base参数")
|
||||
VITE_ROUTER_HISTORY="hash"
|
||||
|
||||
# 基础请求路径
|
||||
VITE_BASE_API=/api
|
||||
|
||||
# 跨域代理地址
|
||||
VITE_APP_URL=http://localhost:8801
|
||||
|
||||
# mock地址
|
||||
VITE_MOCK_BASE_API=/mock
|
||||
|
||||
# 网络请求延迟时间
|
||||
VITE_BASE_API_TIMEOUT=60000
|
||||
|
||||
# 失败重试次数
|
||||
VITE_BASE_API_RETRY=5
|
||||
|
||||
# 失败重试时间
|
||||
VITE_BASE_API_RETRY_DELAY=3000
|
||||
|
||||
# 是否在打包时使用cdn替换本地库 替换 true 不替换 false
|
||||
VITE_CDN=false
|
||||
|
||||
# 是否启用gzip压缩或brotli压缩(分两种情况,删除原始文件和不删除原始文件)
|
||||
# 压缩时不删除原始文件的配置:gzip、brotli、both(同时开启 gzip 与 brotli 压缩)、none(不开启压缩,默认)
|
||||
# 压缩时删除原始文件的配置:gzip-clear、brotli-clear、both-clear(同时开启 gzip 与 brotli 压缩)、none(不开启压缩,默认)
|
||||
VITE_COMPRESSION="none"
|
||||
|
||||
# 开发环境读取配置文件路径
|
||||
VITE_PUBLIC_PATH=/
|
||||
|
|
|
@ -1,8 +1,34 @@
|
|||
# 平台本地运行端口号
|
||||
VITE_PORT = 8848
|
||||
VITE_PORT=8201
|
||||
|
||||
# 预发布环境路由历史模式(Hash模式传"hash"、HTML5模式传"h5"、Hash模式带base参数传"hash,base参数"、HTML5模式带base参数传"h5,base参数")
|
||||
VITE_ROUTER_HISTORY="hash"
|
||||
|
||||
# 基础请求路径
|
||||
VITE_BASE_API=/api
|
||||
|
||||
# 跨域代理地址
|
||||
VITE_APP_URL=http://localhost:8801
|
||||
|
||||
# mock地址
|
||||
VITE_MOCK_BASE_API=/mock
|
||||
|
||||
# 网络请求延迟时间
|
||||
VITE_BASE_API_TIMEOUT=60000
|
||||
|
||||
# 失败重试次数
|
||||
VITE_BASE_API_RETRY=5
|
||||
|
||||
# 失败重试时间
|
||||
VITE_BASE_API_RETRY_DELAY=3000
|
||||
|
||||
# 是否在打包时使用cdn替换本地库 替换 true 不替换 false
|
||||
VITE_CDN=false
|
||||
|
||||
# 是否启用gzip压缩或brotli压缩(分两种情况,删除原始文件和不删除原始文件)
|
||||
# 压缩时不删除原始文件的配置:gzip、brotli、both(同时开启 gzip 与 brotli 压缩)、none(不开启压缩,默认)
|
||||
# 压缩时删除原始文件的配置:gzip-clear、brotli-clear、both-clear(同时开启 gzip 与 brotli 压缩)、none(不开启压缩,默认)
|
||||
VITE_COMPRESSION="none"
|
||||
|
||||
# 开发环境读取配置文件路径
|
||||
VITE_PUBLIC_PATH = /
|
||||
|
||||
# 开发环境路由历史模式(Hash模式传"hash"、HTML5模式传"h5"、Hash模式带base参数传"hash,base参数"、HTML5模式带base参数传"h5,base参数")
|
||||
VITE_ROUTER_HISTORY = "hash"
|
||||
VITE_PUBLIC_PATH=/
|
||||
|
|
|
@ -1,13 +1,34 @@
|
|||
# 线上环境平台打包路径
|
||||
VITE_PUBLIC_PATH = /
|
||||
# 平台本地运行端口号
|
||||
VITE_PORT=8201
|
||||
|
||||
# 线上环境路由历史模式(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_BASE_API=/api
|
||||
|
||||
# 跨域代理地址
|
||||
VITE_APP_URL=http://localhost:8801
|
||||
|
||||
# mock地址
|
||||
VITE_MOCK_BASE_API=/mock
|
||||
|
||||
# 网络请求延迟时间
|
||||
VITE_BASE_API_TIMEOUT=60000
|
||||
|
||||
# 失败重试次数
|
||||
VITE_BASE_API_RETRY=5
|
||||
|
||||
# 失败重试时间
|
||||
VITE_BASE_API_RETRY_DELAY=3000
|
||||
|
||||
# 是否在打包时使用cdn替换本地库 替换 true 不替换 false
|
||||
VITE_CDN = false
|
||||
VITE_CDN=false
|
||||
|
||||
# 是否启用gzip压缩或brotli压缩(分两种情况,删除原始文件和不删除原始文件)
|
||||
# 压缩时不删除原始文件的配置:gzip、brotli、both(同时开启 gzip 与 brotli 压缩)、none(不开启压缩,默认)
|
||||
# 压缩时删除原始文件的配置:gzip-clear、brotli-clear、both-clear(同时开启 gzip 与 brotli 压缩)、none(不开启压缩,默认)
|
||||
VITE_COMPRESSION = "none"
|
||||
VITE_COMPRESSION="none"
|
||||
|
||||
# 开发环境读取配置文件路径
|
||||
VITE_PUBLIC_PATH=/
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
#!/bin/sh
|
||||
. "$(dirname -- "$0")/_/husky.sh"
|
||||
|
||||
pnpm exec lint-staged
|
20
Dockerfile
20
Dockerfile
|
@ -1,20 +0,0 @@
|
|||
FROM node:20-alpine as build-stage
|
||||
|
||||
WORKDIR /app
|
||||
RUN corepack enable
|
||||
RUN corepack prepare pnpm@latest --activate
|
||||
|
||||
RUN npm config set registry https://registry.npmmirror.com
|
||||
|
||||
COPY .npmrc package.json pnpm-lock.yaml ./
|
||||
RUN pnpm install --frozen-lockfile
|
||||
|
||||
COPY . .
|
||||
RUN pnpm build
|
||||
|
||||
FROM nginx:stable-alpine as production-stage
|
||||
|
||||
COPY --from=build-stage /app/dist /usr/share/nginx/html
|
||||
EXPOSE 80
|
||||
|
||||
CMD ["nginx", "-g", "daemon off;"]
|
51
README.md
51
README.md
|
@ -1,51 +0,0 @@
|
|||
<h1>vue-pure-admin精简版(国际化版本)</h1>
|
||||
|
||||
[![license](https://img.shields.io/github/license/pure-admin/vue-pure-admin.svg)](LICENSE)
|
||||
|
||||
**中文** | [English](./README.en-US.md)
|
||||
|
||||
## 介绍
|
||||
|
||||
精简版是基于 [vue-pure-admin](https://github.com/pure-admin/vue-pure-admin) 提炼出的架子,包含主体功能,更适合实际项目开发,打包后的大小在全局引入 [element-plus](https://element-plus.org) 的情况下仍然低于 `2.3MB`,并且会永久同步完整版的代码。开启 `brotli` 压缩和 `cdn` 替换本地库模式后,打包大小低于 `350kb`
|
||||
|
||||
## 版本选择
|
||||
|
||||
当前是国际化版本,如果您需要非国际化版本 [请点击](https://github.com/pure-admin/pure-admin-thin)
|
||||
|
||||
## `js` 版本
|
||||
|
||||
[点我查看 js 版本](https://pure-admin.github.io/pure-admin-doc/pages/js/)
|
||||
|
||||
## `max` 版本
|
||||
|
||||
[点我查看 max 版本](https://github.com/pure-admin/vue-pure-admin-max)
|
||||
|
||||
## 配套视频
|
||||
|
||||
[点我查看 UI 设计](https://www.bilibili.com/video/BV17g411T7rq)
|
||||
[点我查看快速开发教程](https://www.bilibili.com/video/BV1kg411v7QT)
|
||||
|
||||
## 配套保姆级文档
|
||||
|
||||
[点我查看 vue-pure-admin 文档](https://pure-admin.github.io/pure-admin-doc)
|
||||
[点我查看 @pureadmin/utils 文档](https://pure-admin-utils.netlify.app)
|
||||
|
||||
## 优质服务、软件外包、赞助支持
|
||||
|
||||
[点我查看详情](https://pure-admin.github.io/pure-admin-doc/pages/service/)
|
||||
|
||||
## 预览
|
||||
|
||||
[查看预览](https://pure-admin-thin.netlify.app/#/login)
|
||||
|
||||
## 维护者
|
||||
|
||||
[xiaoxian521](https://github.com/xiaoxian521)
|
||||
|
||||
## ⚠️ 注意
|
||||
|
||||
精简版不接受任何 `issues` 和 `pr`,如果有问题请到完整版 [issues](https://github.com/pure-admin/vue-pure-admin/issues/new/choose) 去提,谢谢!
|
||||
|
||||
## 许可证
|
||||
|
||||
[MIT © 2020-present, pure-admin](./LICENSE)
|
|
@ -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.log,terser打包慢,但能去除 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;
|
||||
};
|
|
@ -0,0 +1,31 @@
|
|||
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",
|
||||
open: true,
|
||||
cors: true,
|
||||
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;
|
||||
};
|
|
@ -2,13 +2,13 @@ import dayjs from "dayjs";
|
|||
import { readdir, stat } from "node:fs";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { dirname, resolve } from "node:path";
|
||||
import { sum, formatBytes } from "@pureadmin/utils";
|
||||
import { formatBytes, sum } from "@pureadmin/utils";
|
||||
import {
|
||||
name,
|
||||
version,
|
||||
engines,
|
||||
dependencies,
|
||||
devDependencies
|
||||
devDependencies,
|
||||
engines,
|
||||
name,
|
||||
version
|
||||
} from "../package.json";
|
||||
|
||||
/** 启动`node`进程时所在工作目录的绝对路径 */
|
||||
|
@ -54,6 +54,7 @@ const wrapperEnv = (envConf: Recordable): ViteEnv => {
|
|||
VITE_PORT: 8848,
|
||||
VITE_PUBLIC_PATH: "",
|
||||
VITE_ROUTER_HISTORY: "",
|
||||
VITE_APP_URL: "",
|
||||
VITE_CDN: false,
|
||||
VITE_HIDE_HOME: "false",
|
||||
VITE_COMPRESSION: "none"
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/** @type {import("cz-git").UserConfig} */
|
||||
|
||||
export default {
|
||||
ignores: [commit => commit.includes("init")],
|
||||
ignores: [commit => commit === "init"],
|
||||
extends: ["@commitlint/config-conventional"],
|
||||
rules: {
|
||||
// @see: https://commitlint.js.org/#/reference-rules
|
||||
|
@ -17,11 +17,12 @@ export default {
|
|||
"always",
|
||||
[
|
||||
"init",
|
||||
"optimize",
|
||||
"feat",
|
||||
"page",
|
||||
"media",
|
||||
"completepage",
|
||||
"fix",
|
||||
"fixbug",
|
||||
"media",
|
||||
"docs",
|
||||
"style",
|
||||
"refactor",
|
||||
|
@ -34,7 +35,8 @@ export default {
|
|||
"wip",
|
||||
"workflow",
|
||||
"types",
|
||||
"release"
|
||||
"release",
|
||||
"optimize"
|
||||
]
|
||||
]
|
||||
},
|
||||
|
@ -54,8 +56,11 @@ export default {
|
|||
types: [
|
||||
{ value: "init", name: "初始化: ⏳ 初始化项目", emoji: "⏳" },
|
||||
{ value: "optimize", name: "优化代码: ♻️ 优化项目代码", emoji: "♻️" },
|
||||
{ value: "feat", name: "特性: 🚀 新增功能", emoji: "🚀" },
|
||||
{ value: "feat", name: "新增: 🚀 新增功能", emoji: "🚀" },
|
||||
{ value: "media", name: "媒体: 🎁 新增媒体资源", emoji: "🎁" },
|
||||
{ value: "page", name: "页面: 📄 新增页面", emoji: "📄" },
|
||||
{ value: "completepage", name: "完成页面: 🍻 完成页面", emoji: "🍻" },
|
||||
{ value: "fixbug", name: "bug: 🐛 修改bug", emoji: "🐛" },
|
||||
{ value: "fix", name: "修复: 🧩 修复缺陷", emoji: "🧩" },
|
||||
{ value: "docs", name: "文档: 📚 文档变更", emoji: "📚" },
|
||||
{
|
||||
|
@ -63,11 +68,10 @@ export default {
|
|||
name: "格式: 🎨 代码格式(不影响功能,例如空格、分号等格式修正)",
|
||||
emoji: "🎨"
|
||||
},
|
||||
{ value: "fixbug", name: "bug: 🐛 修改bug", emoji: "🐛" },
|
||||
{
|
||||
value: "refactor",
|
||||
name: "重构: ♻️ 代码重构(不包括 bug 修复、功能新增)",
|
||||
emoji: "♻️"
|
||||
name: "重构: 〽️ 代码重构(不包括 bug 修复、功能新增)",
|
||||
emoji: "〽️"
|
||||
},
|
||||
{ value: "perf", name: "性能: ⚡️ 性能优化", emoji: "⚡️" },
|
||||
{
|
||||
|
@ -76,17 +80,13 @@ export default {
|
|||
emoji: "✅"
|
||||
},
|
||||
{
|
||||
value: "build",
|
||||
value: "chore",
|
||||
name: "构建: 📦️ 构建流程、外部依赖变更(如升级 npm 包、修改 webpack 配置等)",
|
||||
emoji: "📦️"
|
||||
},
|
||||
{ value: "ci", name: "集成: 🎡 修改 CI 配置、脚本", emoji: "🎡" },
|
||||
{ value: "revert", name: "回退: ⏪️ 回滚 commit", emoji: "⏪️" },
|
||||
{
|
||||
value: "chore",
|
||||
name: "其他: 🔨 对构建过程或辅助工具和库的更改(不影响源文件、测试用例)",
|
||||
emoji: "🔨"
|
||||
}
|
||||
{ value: "build", name: "打包: 🔨 项目打包发布", emoji: "🔨" }
|
||||
],
|
||||
useEmoji: true,
|
||||
themeColorCode: "",
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
map $http_upgrade $connection_upgrade {
|
||||
default upgrade;
|
||||
'' close;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
|
@ -9,14 +14,25 @@ server {
|
|||
try_files $uri /index.html;
|
||||
}
|
||||
|
||||
# 后端跨域请求
|
||||
# 后端跨域请求
|
||||
location ~/api/ {
|
||||
proxy_pass http://192.168.3.98:1001;
|
||||
proxy_pass http://192.168.3.98:8200;
|
||||
}
|
||||
|
||||
# mock 跨域
|
||||
location ~/mock/ {
|
||||
proxy_pass http://192.168.3.98:1001;
|
||||
# 配置WebSocket
|
||||
location ~/ws/ {
|
||||
# WebSocket 代理配置
|
||||
proxy_pass http://192.168.3.98:8200; # WebSocket 服务器地址和端口
|
||||
proxy_http_version 1.1; # 使用 HTTP 1.1 版本
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection $connection_upgrade;
|
||||
proxy_read_timeout 600s; # 保持连接的超时时间,根据需要调整
|
||||
proxy_redirect off; # 关闭重定向
|
||||
}
|
||||
|
||||
# mock 跨域
|
||||
location ~/mock/ {
|
||||
proxy_pass http://192.168.3.98:8200;
|
||||
}
|
||||
|
||||
error_page 404 404.html;
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
export default {
|
||||
'*.{js,jsx,ts,tsx}': ['eslint --fix', 'prettier --write'],
|
||||
'{!(package)*.json,*.code-snippets,.!(browserslist)*rc}': ['prettier --write--parser json'],
|
||||
'package.json': ['prettier --write'],
|
||||
'*.vue': ['eslint --fix', 'prettier --write', 'stylelint --fix'],
|
||||
'*.{scss,less,styl,html}': ['stylelint --fix', 'prettier --write'],
|
||||
'*.md': ['prettier --write'],
|
||||
"*.{js,jsx,ts,tsx}": ["eslint --fix", "prettier --write"],
|
||||
"{!(package)*.json,*.code-snippets,.!(browserslist)*rc}": [
|
||||
"prettier --write--parser json"
|
||||
],
|
||||
"package.json": ["prettier --write"],
|
||||
"*.vue": ["eslint --fix", "prettier --write", "stylelint --fix"],
|
||||
"*.{scss,less,styl,html}": ["stylelint --fix", "prettier --write"],
|
||||
"*.md": ["prettier --write"]
|
||||
};
|
||||
|
|
|
@ -55,9 +55,10 @@ const permissionRouter = {
|
|||
]
|
||||
};
|
||||
|
||||
// 获取系统路由
|
||||
export default defineFakeRoute([
|
||||
{
|
||||
url: "/get-async-routes",
|
||||
url: "/mock/get-async-routes",
|
||||
method: "get",
|
||||
response: () => {
|
||||
return {
|
||||
|
|
|
@ -3,7 +3,7 @@ import { defineFakeRoute } from "vite-plugin-fake-server/client";
|
|||
|
||||
export default defineFakeRoute([
|
||||
{
|
||||
url: "/login",
|
||||
url: "/mock/login",
|
||||
method: "post",
|
||||
response: ({ body }) => {
|
||||
if (body.username === "admin") {
|
||||
|
|
|
@ -3,7 +3,7 @@ import { defineFakeRoute } from "vite-plugin-fake-server/client";
|
|||
// 模拟刷新token接口
|
||||
export default defineFakeRoute([
|
||||
{
|
||||
url: "/refresh-token",
|
||||
url: "/mock/refresh-token",
|
||||
method: "post",
|
||||
response: ({ body }) => {
|
||||
if (body.refreshToken) {
|
||||
|
|
183
package.json
183
package.json
|
@ -1,27 +1,8 @@
|
|||
{
|
||||
"name": "pure-admin-thin",
|
||||
"version": "5.8.0",
|
||||
"name": "bunny-admin-element",
|
||||
"version": "1.0.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "NODE_OPTIONS=--max-old-space-size=4096 vite",
|
||||
"serve": "pnpm dev",
|
||||
"build": "rimraf dist && NODE_OPTIONS=--max-old-space-size=8192 vite build",
|
||||
"build:staging": "rimraf dist && vite build --mode staging",
|
||||
"report": "rimraf dist && vite build",
|
||||
"preview": "vite preview",
|
||||
"preview:build": "pnpm build && vite preview",
|
||||
"typecheck": "tsc --noEmit && vue-tsc --noEmit --skipLibCheck",
|
||||
"svgo": "svgo -f . -r",
|
||||
"clean:cache": "rimraf .eslintcache && rimraf pnpm-lock.yaml && rimraf node_modules && pnpm store prune && pnpm install",
|
||||
"lint:eslint": "eslint --fix --ext .js,.ts,.vue ./src",
|
||||
"lint:prettier": "prettier --write --loglevel warn \"src/**/*.{js,ts,json,tsx,css,less,scss,vue,html,md}\"",
|
||||
"lint:stylelint": "stylelint --cache --fix \"**/*.{vue,less,postcss,css,scss}\" --cache --cache-location node_modules/.cache/stylelint/",
|
||||
"lint:lint-staged": "lint-staged",
|
||||
"prepare": "husky install",
|
||||
"release": "standard-version",
|
||||
"commit": "git status && git add -A && git-cz"
|
||||
},
|
||||
"keywords": [
|
||||
"bunny-admin-element",
|
||||
"bunny-cli",
|
||||
|
@ -45,115 +26,169 @@
|
|||
"author": {
|
||||
"name": "Bunny0212",
|
||||
"email": "1319900154@qq.com",
|
||||
"url": "https://github.com/BunnyMaster"
|
||||
"url": "https://github.com/xiaoxian521"
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "NODE_OPTIONS=--max-old-space-size=4096 vite",
|
||||
"serve": "pnpm vite",
|
||||
"start": "vite",
|
||||
"build": "rimraf dist && NODE_OPTIONS=--max-old-space-size=8192 vite build && generate-version-file",
|
||||
"build:staging": "rimraf dist && vite build --mode staging",
|
||||
"report": "rimraf dist && vite build",
|
||||
"preview": "vite preview",
|
||||
"preview:build": "pnpm build && vite preview",
|
||||
"typecheck": "tsc --noEmit && vue-tsc --noEmit --skipLibCheck",
|
||||
"svgo": "svgo -f . -r",
|
||||
"clean:cache": "rimraf .eslintcache && rimraf pnpm-lock.yaml && rimraf node_modules && pnpm store prune && pnpm install",
|
||||
"lint:eslint": "eslint --cache --max-warnings 0 \"{src,mock,build}/**/*.{vue,js,ts,tsx}\" --fix",
|
||||
"lint:prettier": "prettier --write \"src/**/*.{js,ts,json,tsx,css,scss,vue,html,md}\"",
|
||||
"lint:stylelint": "stylelint --cache --fix \"**/*.{html,vue,css,scss}\" --cache-location node_modules/.cache/stylelint/",
|
||||
"lint": "pnpm lint:eslint && pnpm lint:prettier && pnpm lint:stylelint",
|
||||
"prepare": "husky install",
|
||||
"preinstall": "npx only-allow pnpm",
|
||||
"commit": "git pull && git add -A && git-cz && git push"
|
||||
},
|
||||
"dependencies": {
|
||||
"@amap/amap-jsapi-loader": "^1.0.1",
|
||||
"@howdyjs/mouse-menu": "^2.1.3",
|
||||
"@infectoone/vue-ganttastic": "^2.3.2",
|
||||
"@logicflow/core": "^1.2.27",
|
||||
"@logicflow/extension": "^1.2.27",
|
||||
"@pureadmin/descriptions": "^1.2.1",
|
||||
"@pureadmin/table": "^3.2.0",
|
||||
"@pureadmin/utils": "^2.4.8",
|
||||
"@vueuse/core": "^10.11.1",
|
||||
"@vueuse/motion": "^2.2.3",
|
||||
"@pureadmin/table": "^3.1.2",
|
||||
"@pureadmin/utils": "^2.4.7",
|
||||
"@vue-flow/background": "^1.3.0",
|
||||
"@vue-flow/core": "^1.33.6",
|
||||
"@vueuse/core": "^10.9.0",
|
||||
"@vueuse/motion": "^2.1.0",
|
||||
"@wangeditor/editor": "^5.1.23",
|
||||
"@wangeditor/editor-for-vue": "^5.1.12",
|
||||
"@zxcvbn-ts/core": "^3.0.4",
|
||||
"animate.css": "^4.1.1",
|
||||
"axios": "^1.7.4",
|
||||
"dayjs": "^1.11.12",
|
||||
"axios": "^1.6.8",
|
||||
"china-area-data": "^5.0.1",
|
||||
"cropperjs": "^1.6.2",
|
||||
"dayjs": "^1.11.11",
|
||||
"echarts": "^5.5.0",
|
||||
"element-plus": "^2.8.0",
|
||||
"git-cz": "^4.9.0",
|
||||
"el-table-infinite-scroll": "^3.0.3",
|
||||
"element-plus": "2.7.1",
|
||||
"intro.js": "^7.2.0",
|
||||
"js-cookie": "^3.0.5",
|
||||
"jsbarcode": "^3.11.6",
|
||||
"localforage": "^1.10.0",
|
||||
"mint-filter": "^4.0.3",
|
||||
"mitt": "^3.0.1",
|
||||
"mqtt": "4.3.7",
|
||||
"nprogress": "^0.2.0",
|
||||
"path": "^0.12.7",
|
||||
"pinia": "^2.2.2",
|
||||
"pinyin-pro": "^3.24.2",
|
||||
"qs": "^6.13.0",
|
||||
"pinia": "^2.1.7",
|
||||
"pinia-plugin-persistedstate": "^3.2.1",
|
||||
"pinyin-pro": "^3.20.4",
|
||||
"plus-pro-components": "^0.1.1",
|
||||
"qrcode": "^1.5.3",
|
||||
"qs": "^6.12.1",
|
||||
"responsive-storage": "^2.2.0",
|
||||
"sortablejs": "^1.15.2",
|
||||
"vue": "^3.4.38",
|
||||
"vue-i18n": "^9.14.0",
|
||||
"vue-router": "^4.4.3",
|
||||
"vue-tippy": "^6.4.4",
|
||||
"vue-types": "^5.1.3"
|
||||
"swiper": "^11.1.1",
|
||||
"terser": "^5.31.0",
|
||||
"typeit": "^8.8.3",
|
||||
"v-contextmenu": "^3.2.0",
|
||||
"v3-infinite-loading": "^1.3.1",
|
||||
"version-rocket": "^1.7.1",
|
||||
"vite-plugin-vue-inspector": "^5.1.3",
|
||||
"vue": "^3.4.27",
|
||||
"vue-i18n": "^9.13.1",
|
||||
"vue-json-pretty": "^2.4.0",
|
||||
"vue-pdf-embed": "^2.0.3",
|
||||
"vue-router": "^4.3.2",
|
||||
"vue-tippy": "^6.4.1",
|
||||
"vue-types": "^5.1.2",
|
||||
"vue-virtual-scroller": "2.0.0-beta.8",
|
||||
"vue-waterfall-plugin-next": "^2.4.3",
|
||||
"vue3-danmaku": "^1.6.0",
|
||||
"vue3-puzzle-vcode": "^1.1.7",
|
||||
"vuedraggable": "^4.1.0",
|
||||
"vxe-table": "^4.6.9",
|
||||
"wavesurfer.js": "^7.7.13",
|
||||
"xgplayer": "^3.0.17",
|
||||
"xlsx": "^0.18.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@commitlint/cli": "^19.3.0",
|
||||
"@commitlint/config-conventional": "^19.2.2",
|
||||
"@commitlint/types": "^19.0.3",
|
||||
"commitizen": "^4.2.4",
|
||||
"commitlint": "^17.0.1",
|
||||
"@eslint/js": "^9.9.0",
|
||||
"@eslint/js": "^9.2.0",
|
||||
"@faker-js/faker": "^8.4.1",
|
||||
"@iconify-icons/ep": "^1.2.12",
|
||||
"@iconify-icons/ri": "^1.2.10",
|
||||
"@iconify/vue": "^4.1.2",
|
||||
"@intlify/unplugin-vue-i18n": "^4.0.0",
|
||||
"@pureadmin/theme": "^3.2.0",
|
||||
"@types/dagre": "^0.7.52",
|
||||
"@types/gradient-string": "^1.1.6",
|
||||
"@types/intro.js": "^5.1.5",
|
||||
"@types/js-cookie": "^3.0.6",
|
||||
"@types/node": "^20.16.1",
|
||||
"@types/node": "^20.12.11",
|
||||
"@types/nprogress": "^0.2.3",
|
||||
"@types/qrcode": "^1.5.5",
|
||||
"@types/qs": "^6.9.15",
|
||||
"@types/sortablejs": "^1.15.8",
|
||||
"@typescript-eslint/eslint-plugin": "^7.18.0",
|
||||
"@typescript-eslint/parser": "^7.18.0",
|
||||
"@vitejs/plugin-vue": "^5.1.2",
|
||||
"@vitejs/plugin-vue-jsx": "^4.0.1",
|
||||
"autoprefixer": "^10.4.20",
|
||||
"@typescript-eslint/eslint-plugin": "^7.8.0",
|
||||
"@typescript-eslint/parser": "^7.8.0",
|
||||
"@vitejs/plugin-vue": "^5.0.4",
|
||||
"@vitejs/plugin-vue-jsx": "^3.1.0",
|
||||
"autoprefixer": "^10.4.19",
|
||||
"boxen": "^7.1.1",
|
||||
"cssnano": "^7.0.5",
|
||||
"commitizen": "^4.2.4",
|
||||
"commitlint": "^17.0.1",
|
||||
"cssnano": "^7.0.1",
|
||||
"cz-git": "^1.3.2",
|
||||
"eslint": "^9.9.0",
|
||||
"dagre": "^0.8.5",
|
||||
"eslint": "^9.2.0",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"eslint-define-config": "^2.1.0",
|
||||
"eslint-plugin-prettier": "^5.2.1",
|
||||
"eslint-plugin-vue": "^9.27.0",
|
||||
"eslint-plugin-prettier": "^5.1.3",
|
||||
"eslint-plugin-vue": "^9.25.0",
|
||||
"gradient-string": "^2.0.2",
|
||||
"husky": "^9.1.5",
|
||||
"lint-staged": "^15.2.9",
|
||||
"postcss": "^8.4.41",
|
||||
"husky": "^8.0.1",
|
||||
"lint-staged": "^15.2.2",
|
||||
"postcss": "^8.4.38",
|
||||
"postcss-html": "^1.7.0",
|
||||
"postcss-import": "^16.1.0",
|
||||
"postcss-scss": "^4.0.9",
|
||||
"prettier": "^3.3.3",
|
||||
"rimraf": "^5.0.10",
|
||||
"prettier": "^3.2.5",
|
||||
"rimraf": "^5.0.5",
|
||||
"rollup-plugin-visualizer": "^5.12.0",
|
||||
"sass": "^1.77.8",
|
||||
"stylelint": "^16.8.2",
|
||||
"sass": "^1.77.0",
|
||||
"stylelint": "^16.5.0",
|
||||
"stylelint-config-recess-order": "^5.0.1",
|
||||
"stylelint-config-recommended-vue": "^1.5.0",
|
||||
"stylelint-config-standard-scss": "^13.1.0",
|
||||
"stylelint-prettier": "^5.0.2",
|
||||
"svgo": "^3.3.2",
|
||||
"tailwindcss": "^3.4.10",
|
||||
"typescript": "^5.5.4",
|
||||
"vite": "^5.4.1",
|
||||
"vite-plugin-cdn-import": "^1.0.1",
|
||||
"stylelint-prettier": "^5.0.0",
|
||||
"svgo": "^3.3.0",
|
||||
"tailwindcss": "^3.4.3",
|
||||
"typescript": "^5.4.5",
|
||||
"vite": "^5.2.11",
|
||||
"vite-plugin-cdn-import": "^0.3.5",
|
||||
"vite-plugin-compression": "^0.5.1",
|
||||
"vite-plugin-fake-server": "^2.1.1",
|
||||
"vite-plugin-remove-console": "^2.2.0",
|
||||
"vite-plugin-router-warn": "^1.0.0",
|
||||
"vite-plugin-vue-inspector": "^5.1.3",
|
||||
"vite-svg-loader": "^5.1.0",
|
||||
"vue-eslint-parser": "^9.4.3",
|
||||
"vue-eslint-parser": "^9.4.2",
|
||||
"vue-tsc": "^1.8.27"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0",
|
||||
"pnpm": ">=9"
|
||||
"pnpm": ">=8.6.10"
|
||||
},
|
||||
"pnpm": {
|
||||
"allowedDeprecatedVersions": {
|
||||
"are-we-there-yet": "*",
|
||||
"sourcemap-codec": "*",
|
||||
"domexception": "*",
|
||||
"w3c-hr-time": "*",
|
||||
"inflight": "*",
|
||||
"npmlog": "*",
|
||||
"rimraf": "*",
|
||||
"stable": "*",
|
||||
"gauge": "*",
|
||||
"abab": "*",
|
||||
"glob": "*"
|
||||
"abab": "*"
|
||||
},
|
||||
"peerDependencyRules": {
|
||||
"allowedVersions": {
|
||||
|
|
3646
pnpm-lock.yaml
3646
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,740 @@
|
|||
<!doctype html>
|
||||
<html lang="zh">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="btns">
|
||||
<div class="btn java">JAVA攻城狮</div>
|
||||
<div class="btn golang">Golang工程师!</div>
|
||||
<div class="btn js"><span>js攻城狮</span></div>
|
||||
<div class="btn nodd-ruby ruby">
|
||||
<div class="anim"></div>
|
||||
<span>Ruby攻城狮</span>
|
||||
</div>
|
||||
|
||||
<div class="btn vb">
|
||||
<span>VB攻城狮</span>
|
||||
<div class="dot"></div>
|
||||
</div>
|
||||
<div class="btn python python-1">python攻城狮</div>
|
||||
<div class="btn python python-2">python攻城狮</div>
|
||||
<div class="btn python python-3">python攻城狮</div>
|
||||
<div class="btn python python-4">python攻城狮</div>
|
||||
<div class="btn python python-5">python攻城狮</div>
|
||||
|
||||
<div class="btn php php-1">php攻城狮</div>
|
||||
<div class="btn php php-2">php攻城狮</div>
|
||||
<div class="btn php php-3">php攻城狮</div>
|
||||
<div class="btn php php-4">php攻城狮</div>
|
||||
<div class="btn php php-5">php攻城狮</div>
|
||||
|
||||
<div class="btn kotlin kotlin-3">kotlin攻城狮</div>
|
||||
<div class="btn kotlin kotlin-1">kotlin攻城狮</div>
|
||||
<div class="btn kotlin kotlin-4">kotlin攻城狮</div>
|
||||
<div class="btn kotlin kotlin-2">kotlin攻城狮</div>
|
||||
<div class="btn kotlin kotlin-5">kotlin攻城狮</div>
|
||||
<div class="btn c">C语言攻城狮</div>
|
||||
</div>
|
||||
</body>
|
||||
<style>
|
||||
.text-info {
|
||||
position: absolute;
|
||||
top: calc(50vh - 245px);
|
||||
text-align: center;
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
width: 100%;
|
||||
margin-left: -5px;
|
||||
}
|
||||
|
||||
.btn {
|
||||
vertical-align: top;
|
||||
margin: 15px;
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
width: 122px;
|
||||
height: 44px;
|
||||
line-height: 44px;
|
||||
border-radius: 4px;
|
||||
color: #fff;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.java {
|
||||
color: #eb9e05;
|
||||
height: 42px;
|
||||
line-height: 42px;
|
||||
width: 120px;
|
||||
border: 1px solid #eb9e05;
|
||||
opacity: 1;
|
||||
transition: all 0.6s;
|
||||
}
|
||||
|
||||
.java:hover {
|
||||
background: #eb9e05;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.java:active {
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.c {
|
||||
height: 44px;
|
||||
line-height: 44px;
|
||||
background: #55acee;
|
||||
transition: all 0.5s;
|
||||
box-shadow: 0px 5px 0px 0px #3486d5;
|
||||
}
|
||||
|
||||
.c:hover {
|
||||
background-color: #6fc6ff;
|
||||
}
|
||||
|
||||
.c:active {
|
||||
transform: translate(0px, 4px);
|
||||
box-shadow: 0px 1px 0px 0px #3486d5;
|
||||
}
|
||||
|
||||
@keyframes sheen {
|
||||
0% {
|
||||
transform: skewY(-45deg) translateX(0);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: skewY(-45deg) translateX(12.5em);
|
||||
}
|
||||
}
|
||||
|
||||
.golang {
|
||||
vertical-align: top;
|
||||
height: 42px;
|
||||
line-height: 42px;
|
||||
width: 120px;
|
||||
color: #2194e0;
|
||||
border: 1px solid #2194e0;
|
||||
transition: all 0.2s ease-in-out;
|
||||
position: relative;
|
||||
opacity: 1;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.golang:before {
|
||||
content: "";
|
||||
background-color: rgba(255, 255, 255, 0.5);
|
||||
height: 100%;
|
||||
width: 3em;
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: -4.5em;
|
||||
transform: skewX(-45deg) translateX(0);
|
||||
transition: none;
|
||||
}
|
||||
|
||||
.golang:hover {
|
||||
background-color: #2194e0;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.golang:hover:before {
|
||||
transform: skewX(-45deg) translateX(260px);
|
||||
transition: all 0.5s ease-in-out;
|
||||
}
|
||||
|
||||
.golang:active {
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.js {
|
||||
width: 160px;
|
||||
height: 42px;
|
||||
line-height: 42px;
|
||||
background: #0d6;
|
||||
width: 120px;
|
||||
border: 1px solid #0d6;
|
||||
overflow: hidden;
|
||||
transition: all 0.5s;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.js:hover,
|
||||
.js:active {
|
||||
text-decoration: none;
|
||||
color: #0c5;
|
||||
border-color: #0c5;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.js:active {
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.js span {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
padding-right: 0;
|
||||
transition: padding-right 0.5s;
|
||||
}
|
||||
|
||||
.js span:after {
|
||||
content: " ";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: -18px;
|
||||
opacity: 0;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
margin-top: -10px;
|
||||
background: rgba(0, 0, 0, 0);
|
||||
border: 2px solid #fff;
|
||||
border-top: none;
|
||||
border-right: none;
|
||||
transition:
|
||||
opacity 0.5s,
|
||||
top 0.5s,
|
||||
right 0.5s;
|
||||
transform: rotate(-140deg);
|
||||
}
|
||||
|
||||
.js:hover span,
|
||||
.js:active span {
|
||||
padding-right: 30px;
|
||||
}
|
||||
|
||||
.js:hover span:after,
|
||||
.js:active span:after {
|
||||
transition:
|
||||
opacity 0.5s,
|
||||
top 0.5s,
|
||||
right 0.5s;
|
||||
opacity: 1;
|
||||
border-color: #0c5;
|
||||
right: 0;
|
||||
top: calc(50% + 2.5px);
|
||||
transform: rotate(-140deg);
|
||||
}
|
||||
|
||||
.nodd-ruby {
|
||||
background: #c147e6;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
z-index: 0;
|
||||
cursor: pointer;
|
||||
opacity: 1;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
input[type="checkbox"].toggle {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
left: 0;
|
||||
top: 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
input[type="checkbox"].toggle:focus {
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
.anim {
|
||||
transform: translate(-50%, -50%);
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
.anim:before {
|
||||
position: relative;
|
||||
content: "";
|
||||
display: block;
|
||||
margin-top: 100%;
|
||||
}
|
||||
|
||||
.anim:after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.node .toggle:checked + .anim {
|
||||
animation: 0.75s anim-in;
|
||||
}
|
||||
|
||||
.node .toggle:checked + .anim:after {
|
||||
animation: anim-in-pseudo 0.75s;
|
||||
}
|
||||
|
||||
.node .toggle:not(:checked) + .anim {
|
||||
animation: anim-out 0.75s;
|
||||
}
|
||||
|
||||
.node .toggle:not(:checked) + .anim:after {
|
||||
animation: anim-out-pseudo 0.75s;
|
||||
}
|
||||
|
||||
.node {
|
||||
background: #ed3f14;
|
||||
}
|
||||
|
||||
.node:hover {
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.ruby:active {
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.ruby:hover > .anim {
|
||||
animation: anim-out 0.75s;
|
||||
}
|
||||
|
||||
.ruby:hover > .anim:after {
|
||||
animation: anim-out-pseudo 0.75s;
|
||||
}
|
||||
|
||||
@keyframes anim-in {
|
||||
0% {
|
||||
width: 0%;
|
||||
}
|
||||
|
||||
100% {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes anim-in-pseudo {
|
||||
0% {
|
||||
background: rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
100% {
|
||||
background: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes anim-out {
|
||||
0% {
|
||||
width: 0%;
|
||||
}
|
||||
|
||||
100% {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes anim-out-pseudo {
|
||||
0% {
|
||||
background: rgba(0, 0, 0, 0.35);
|
||||
}
|
||||
|
||||
100% {
|
||||
background: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
.python {
|
||||
transition: 0.5s;
|
||||
background-size: 200% auto;
|
||||
}
|
||||
|
||||
.python:hover {
|
||||
background-position: right center;
|
||||
}
|
||||
|
||||
.python-1 {
|
||||
background-image: linear-gradient(
|
||||
to right,
|
||||
#f6d365 0%,
|
||||
#fda085 51%,
|
||||
#f6d365 100%
|
||||
);
|
||||
}
|
||||
|
||||
.python-2 {
|
||||
background-image: linear-gradient(
|
||||
to right,
|
||||
#fbc2eb 0%,
|
||||
#a6c1ee 51%,
|
||||
#fbc2eb 100%
|
||||
);
|
||||
}
|
||||
|
||||
.python-3 {
|
||||
background-image: linear-gradient(
|
||||
to right,
|
||||
#84fab0 0%,
|
||||
#8fd3f4 51%,
|
||||
#84fab0 100%
|
||||
);
|
||||
}
|
||||
|
||||
.python-4 {
|
||||
background-image: linear-gradient(
|
||||
to right,
|
||||
#a1c4fd 0%,
|
||||
#c2e9fb 51%,
|
||||
#a1c4fd 100%
|
||||
);
|
||||
}
|
||||
|
||||
.python-5 {
|
||||
background-image: linear-gradient(
|
||||
to right,
|
||||
#ffecd2 0%,
|
||||
#fcb69f 51%,
|
||||
#ffecd2 100%
|
||||
);
|
||||
}
|
||||
|
||||
.php,
|
||||
.php::after {
|
||||
transition: all 0.5s;
|
||||
}
|
||||
|
||||
.php {
|
||||
border: 1px solid #c147e6;
|
||||
color: #c147e6;
|
||||
width: 120px;
|
||||
height: 42px;
|
||||
line-height: 42px;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.php:hover {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.php::before,
|
||||
.php::after {
|
||||
background: #c147e6;
|
||||
content: "";
|
||||
position: absolute;
|
||||
z-index: -2;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.php-1::after {
|
||||
height: 0;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.php-1:hover:after {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.php-2::after {
|
||||
height: 100%;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 0;
|
||||
}
|
||||
|
||||
.php-2:hover:after {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.php-3::after {
|
||||
height: 0;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
width: 0;
|
||||
}
|
||||
|
||||
.php-3:hover:after {
|
||||
height: 100%;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.php-4::before {
|
||||
height: 100%;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.php-4::after {
|
||||
background: #fff;
|
||||
height: 100%;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.php-4:hover:after {
|
||||
height: 0;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
width: 0;
|
||||
}
|
||||
|
||||
.php-5 {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.php-5::after {
|
||||
height: 100%;
|
||||
left: -35%;
|
||||
top: 0;
|
||||
transform: skew(50deg);
|
||||
transition-duration: 0.6s;
|
||||
transform-origin: top left;
|
||||
width: 0;
|
||||
}
|
||||
|
||||
.php-5:hover:after {
|
||||
height: 100%;
|
||||
width: 135%;
|
||||
}
|
||||
|
||||
.kotlin {
|
||||
background: none;
|
||||
border: 1px solid;
|
||||
width: 120px;
|
||||
height: 42px;
|
||||
line-height: 42px;
|
||||
letter-spacing: inherit;
|
||||
text-transform: inherit;
|
||||
transition: color 1s;
|
||||
}
|
||||
|
||||
.kotlin-1 {
|
||||
color: #9c89f7;
|
||||
}
|
||||
|
||||
.kotlin-1:hover {
|
||||
animation: halftone 1s forwards;
|
||||
background:
|
||||
radial-gradient(circle, #9c89f7 0.2em, transparent 0.25em) 0 0/1.25em
|
||||
1.25em,
|
||||
radial-gradient(circle, #9c89f7 0.2em, transparent 0.25em) 6.25em 6.25em/1.25em
|
||||
1.25em;
|
||||
color: #e4f789;
|
||||
}
|
||||
|
||||
@keyframes halftone {
|
||||
100% {
|
||||
background-size:
|
||||
2.375em 2.375em,
|
||||
0.1em 0.1em;
|
||||
}
|
||||
}
|
||||
|
||||
.kotlin-2 {
|
||||
color: #82f6d8;
|
||||
}
|
||||
|
||||
.kotlin-2:hover {
|
||||
animation: stripes-move 0.75s infinite linear;
|
||||
background: repeating-linear-gradient(
|
||||
45deg,
|
||||
#82f6d8 0,
|
||||
#82f6d8 0.25em,
|
||||
transparent 0.25em,
|
||||
transparent 0.5em
|
||||
);
|
||||
color: #f682a0;
|
||||
}
|
||||
|
||||
@keyframes stripes-move {
|
||||
100% {
|
||||
background-position: 5em 0px;
|
||||
}
|
||||
}
|
||||
|
||||
.kotlin-3 {
|
||||
color: #d3f169;
|
||||
}
|
||||
|
||||
.kotlin-3:hover {
|
||||
animation: sawtooth 0.35s infinite linear;
|
||||
background:
|
||||
linear-gradient(45deg, #d3f169 0.5em, transparent 0.5em) 0 0/1em 1em,
|
||||
linear-gradient(-45deg, #d3f169 0.5em, transparent 0.5em) 0 0/1em 1em;
|
||||
color: #8769f1;
|
||||
}
|
||||
|
||||
@keyframes sawtooth {
|
||||
100% {
|
||||
background-position: 1em 0;
|
||||
}
|
||||
}
|
||||
|
||||
.kotlin-4 {
|
||||
color: #eea163;
|
||||
}
|
||||
|
||||
.kotlin-4:hover {
|
||||
animation: zigzag 1s linear infinite;
|
||||
background:
|
||||
linear-gradient(
|
||||
135deg,
|
||||
rgba(238, 161, 99, 0.25) 0.25em,
|
||||
transparent 0.25em
|
||||
) -0.5em 0,
|
||||
linear-gradient(
|
||||
225deg,
|
||||
rgba(238, 161, 99, 0.25) 0.25em,
|
||||
transparent 0.25em
|
||||
) -0.5em 0,
|
||||
linear-gradient(
|
||||
315deg,
|
||||
rgba(238, 161, 99, 0.25) 0.25em,
|
||||
transparent 0.25em
|
||||
)
|
||||
0 0,
|
||||
linear-gradient(
|
||||
45deg,
|
||||
rgba(238, 161, 99, 0.25) 0.25em,
|
||||
transparent 0.25em
|
||||
)
|
||||
0 0;
|
||||
background-size: 0.75em 0.75em;
|
||||
color: #63b0ee;
|
||||
}
|
||||
|
||||
@keyframes zigzag {
|
||||
100% {
|
||||
background-position:
|
||||
1em 0,
|
||||
1em 0,
|
||||
-0.75em 0,
|
||||
-0.75em 0;
|
||||
}
|
||||
}
|
||||
|
||||
.kotlin-5 {
|
||||
color: #f9879b;
|
||||
}
|
||||
|
||||
.kotlin-5:hover {
|
||||
animation: pulse 1s ease-in infinite;
|
||||
background:
|
||||
radial-gradient(circle, rgba(249, 135, 155, 0.25) 43%, transparent 50%)
|
||||
0 0/1em 1em,
|
||||
radial-gradient(circle, rgba(249, 135, 155, 0.25) 43%, transparent 50%)
|
||||
0.5em 0.5em/2em 2em;
|
||||
color: #0bdcb7;
|
||||
}
|
||||
|
||||
@keyframes pulse {
|
||||
50% {
|
||||
background-position:
|
||||
0.66em 0.66em,
|
||||
-0.33em -0.33em;
|
||||
}
|
||||
|
||||
100% {
|
||||
background-size:
|
||||
2em 2em,
|
||||
1em 1em;
|
||||
background-position:
|
||||
-1.5em -1.5em,
|
||||
-1em -1em;
|
||||
}
|
||||
}
|
||||
|
||||
.vb:before,
|
||||
.vb:after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.vb {
|
||||
position: relative;
|
||||
width: 120px;
|
||||
color: #fa5555;
|
||||
height: 40px;
|
||||
line-height: 42px;
|
||||
border: 2px solid #fa5555;
|
||||
border-radius: 14px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.dot {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: 32px;
|
||||
height: 100%;
|
||||
border-radius: 50%;
|
||||
transition: all 300ms ease;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.dot:after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: -6px;
|
||||
height: 5px;
|
||||
width: 5px;
|
||||
background: #fa5555;
|
||||
border-radius: 50%;
|
||||
border: 4px solid #fa5555;
|
||||
box-shadow:
|
||||
0 0 0.7em #fff,
|
||||
0 0 2em #fa5555;
|
||||
}
|
||||
|
||||
.vb:hover .dot,
|
||||
.vb:focus .dot {
|
||||
animation: atom 2s infinite linear;
|
||||
display: block;
|
||||
}
|
||||
|
||||
/*calc(122px - 36px) 按钮宽度 - dot宽度 - 边框宽度*/
|
||||
@keyframes atom {
|
||||
0% {
|
||||
transform: translateX(0) rotate(0);
|
||||
}
|
||||
|
||||
30% {
|
||||
transform: translateX(calc(122px - 36px)) rotate(0);
|
||||
}
|
||||
|
||||
50% {
|
||||
transform: translateX(calc(122px - 36px)) rotate(180deg);
|
||||
}
|
||||
|
||||
80% {
|
||||
transform: translateX(0) rotate(180deg);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: translateX(0) rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
.btn-down {
|
||||
position: absolute;
|
||||
top: calc(50vh - 280px);
|
||||
text-align: center;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
left: calc(50vw - 87px);
|
||||
width: 122px;
|
||||
line-height: 44px;
|
||||
color: #fff;
|
||||
background: #2194e0;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.btn-down:active {
|
||||
opacity: 0.8;
|
||||
}
|
||||
</style>
|
||||
</html>
|
|
@ -1,4 +1,4 @@
|
|||
import { http } from "@/utils/http";
|
||||
import { http } from "@/utils/http/mockRequest";
|
||||
|
||||
type Result = {
|
||||
success: boolean;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { http } from "@/utils/http";
|
||||
import { http } from "@/utils/http/mockRequest";
|
||||
|
||||
export type UserResult = {
|
||||
success: boolean;
|
||||
|
|
|
@ -5,19 +5,26 @@ import Axios, {
|
|||
} from "axios";
|
||||
import type {
|
||||
PureHttpError,
|
||||
RequestMethods,
|
||||
PureHttpRequestConfig,
|
||||
PureHttpResponse,
|
||||
PureHttpRequestConfig
|
||||
RequestMethods
|
||||
} from "./types.d";
|
||||
import { stringify } from "qs";
|
||||
import NProgress from "../progress";
|
||||
import { getToken, formatToken } from "@/utils/auth";
|
||||
import { formatToken, getToken } from "@/utils/auth";
|
||||
import { useUserStoreHook } from "@/store/modules/user";
|
||||
|
||||
// 相关配置请参考:www.axios-js.com/zh-cn/docs/#axios-request-config-1
|
||||
const defaultConfig: AxiosRequestConfig = {
|
||||
// 请求超时时间
|
||||
timeout: 10000,
|
||||
// 默认请求地址
|
||||
baseURL: import.meta.env.VITE_BASE_API,
|
||||
// 设置超时时间
|
||||
timeout: import.meta.env.VITE_BASE_API_TIMEOUT,
|
||||
// @ts-expect-error
|
||||
retry: import.meta.env.VITE_BASE_API_RETRY, //设置全局重试请求次数(最多重试几次请求)
|
||||
retryDelay: import.meta.env.VITE_BASE_API_RETRY_DELAY, //设置全局请求间隔
|
||||
// 跨域允许携带凭证
|
||||
// withCredentials: true,
|
||||
headers: {
|
||||
Accept: "application/json, text/plain, */*",
|
||||
"Content-Type": "application/json",
|
||||
|
@ -30,23 +37,20 @@ const defaultConfig: AxiosRequestConfig = {
|
|||
};
|
||||
|
||||
class PureHttp {
|
||||
/** `token`过期后,暂存待执行的请求 */
|
||||
private static requests = [];
|
||||
/** 防止重复刷新`token` */
|
||||
private static isRefreshing = false;
|
||||
/** 初始化配置对象 */
|
||||
private static initConfig: PureHttpRequestConfig = {};
|
||||
/** 保存当前`Axios`实例对象 */
|
||||
private static axiosInstance: AxiosInstance = Axios.create(defaultConfig);
|
||||
|
||||
constructor() {
|
||||
this.httpInterceptorsRequest();
|
||||
this.httpInterceptorsResponse();
|
||||
}
|
||||
|
||||
/** `token`过期后,暂存待执行的请求 */
|
||||
private static requests = [];
|
||||
|
||||
/** 防止重复刷新`token` */
|
||||
private static isRefreshing = false;
|
||||
|
||||
/** 初始化配置对象 */
|
||||
private static initConfig: PureHttpRequestConfig = {};
|
||||
|
||||
/** 保存当前`Axios`实例对象 */
|
||||
private static axiosInstance: AxiosInstance = Axios.create(defaultConfig);
|
||||
|
||||
/** 重连原始请求 */
|
||||
private static retryOriginalRequest(config: PureHttpRequestConfig) {
|
||||
return new Promise(resolve => {
|
||||
|
@ -57,6 +61,51 @@ class PureHttp {
|
|||
});
|
||||
}
|
||||
|
||||
/** 通用请求工具函数 */
|
||||
public request<T>(
|
||||
method: RequestMethods,
|
||||
url: string,
|
||||
param?: AxiosRequestConfig,
|
||||
axiosConfig?: PureHttpRequestConfig
|
||||
): Promise<T> {
|
||||
const config = {
|
||||
method,
|
||||
url,
|
||||
...param,
|
||||
...axiosConfig
|
||||
} as PureHttpRequestConfig;
|
||||
|
||||
// 单独处理自定义请求/响应回调
|
||||
return new Promise((resolve, reject) => {
|
||||
PureHttp.axiosInstance
|
||||
.request(config)
|
||||
.then((response: undefined) => {
|
||||
resolve(response);
|
||||
})
|
||||
.catch(error => {
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/** 单独抽离的`post`工具函数 */
|
||||
public post<T, P>(
|
||||
url: string,
|
||||
params?: AxiosRequestConfig<P>,
|
||||
config?: PureHttpRequestConfig
|
||||
): Promise<T> {
|
||||
return this.request<T>("post", url, params, config);
|
||||
}
|
||||
|
||||
/** 单独抽离的`get`工具函数 */
|
||||
public get<T, P>(
|
||||
url: string,
|
||||
params?: AxiosRequestConfig<P>,
|
||||
config?: PureHttpRequestConfig
|
||||
): Promise<T> {
|
||||
return this.request<T>("get", url, params, config);
|
||||
}
|
||||
|
||||
/** 请求拦截 */
|
||||
private httpInterceptorsRequest(): void {
|
||||
PureHttp.axiosInstance.interceptors.request.use(
|
||||
|
@ -144,51 +193,6 @@ class PureHttp {
|
|||
}
|
||||
);
|
||||
}
|
||||
|
||||
/** 通用请求工具函数 */
|
||||
public request<T>(
|
||||
method: RequestMethods,
|
||||
url: string,
|
||||
param?: AxiosRequestConfig,
|
||||
axiosConfig?: PureHttpRequestConfig
|
||||
): Promise<T> {
|
||||
const config = {
|
||||
method,
|
||||
url,
|
||||
...param,
|
||||
...axiosConfig
|
||||
} as PureHttpRequestConfig;
|
||||
|
||||
// 单独处理自定义请求/响应回调
|
||||
return new Promise((resolve, reject) => {
|
||||
PureHttp.axiosInstance
|
||||
.request(config)
|
||||
.then((response: undefined) => {
|
||||
resolve(response);
|
||||
})
|
||||
.catch(error => {
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/** 单独抽离的`post`工具函数 */
|
||||
public post<T, P>(
|
||||
url: string,
|
||||
params?: AxiosRequestConfig<P>,
|
||||
config?: PureHttpRequestConfig
|
||||
): Promise<T> {
|
||||
return this.request<T>("post", url, params, config);
|
||||
}
|
||||
|
||||
/** 单独抽离的`get`工具函数 */
|
||||
public get<T, P>(
|
||||
url: string,
|
||||
params?: AxiosRequestConfig<P>,
|
||||
config?: PureHttpRequestConfig
|
||||
): Promise<T> {
|
||||
return this.request<T>("get", url, params, config);
|
||||
}
|
||||
}
|
||||
|
||||
export const http = new PureHttp();
|
||||
|
|
|
@ -0,0 +1,191 @@
|
|||
import Axios, {
|
||||
type AxiosInstance,
|
||||
type AxiosRequestConfig,
|
||||
type CustomParamsSerializer
|
||||
} from "axios";
|
||||
import type {
|
||||
PureHttpError,
|
||||
PureHttpRequestConfig,
|
||||
PureHttpResponse,
|
||||
RequestMethods
|
||||
} from "./types.d";
|
||||
import { stringify } from "qs";
|
||||
import NProgress from "../progress";
|
||||
import { formatToken, getToken } from "@/utils/auth";
|
||||
import { useUserStoreHook } from "@/store/modules/user";
|
||||
|
||||
// 相关配置请参考:www.axios-js.com/zh-cn/docs/#axios-request-config-1
|
||||
const defaultConfig: AxiosRequestConfig = {
|
||||
timeout: import.meta.env.VITE_BASE_API_TIMEOUT,
|
||||
baseURL: import.meta.env.VITE_MOCK_BASE_API || "/mock",
|
||||
headers: {
|
||||
Accept: "application/json, text/plain, */*",
|
||||
"Content-Type": "application/json",
|
||||
"X-Requested-With": "XMLHttpRequest"
|
||||
},
|
||||
// 数组格式参数序列化(https://github.com/axios/axios/issues/5142)
|
||||
paramsSerializer: {
|
||||
serialize: stringify as unknown as CustomParamsSerializer
|
||||
}
|
||||
};
|
||||
|
||||
class PureHttp {
|
||||
/** `token`过期后,暂存待执行的请求 */
|
||||
private static requests = [];
|
||||
/** 防止重复刷新`token` */
|
||||
private static isRefreshing = false;
|
||||
/** 初始化配置对象 */
|
||||
private static initConfig: PureHttpRequestConfig = {};
|
||||
/** 保存当前`Axios`实例对象 */
|
||||
private static axiosInstance: AxiosInstance = Axios.create(defaultConfig);
|
||||
|
||||
constructor() {
|
||||
this.httpInterceptorsRequest();
|
||||
this.httpInterceptorsResponse();
|
||||
}
|
||||
|
||||
/** 重连原始请求 */
|
||||
private static retryOriginalRequest(config: PureHttpRequestConfig) {
|
||||
return new Promise(resolve => {
|
||||
PureHttp.requests.push((token: string) => {
|
||||
config.headers["Authorization"] = formatToken(token);
|
||||
resolve(config);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/** 通用请求工具函数 */
|
||||
public request<T>(
|
||||
method: RequestMethods,
|
||||
url: string,
|
||||
param?: AxiosRequestConfig,
|
||||
axiosConfig?: PureHttpRequestConfig
|
||||
): Promise<T> {
|
||||
const config = {
|
||||
method,
|
||||
url,
|
||||
...param,
|
||||
...axiosConfig
|
||||
} as PureHttpRequestConfig;
|
||||
|
||||
// 单独处理自定义请求/响应回调
|
||||
return new Promise((resolve, reject) => {
|
||||
PureHttp.axiosInstance
|
||||
.request(config)
|
||||
.then((response: undefined) => {
|
||||
resolve(response);
|
||||
})
|
||||
.catch(error => {
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/** 单独抽离的`post`工具函数 */
|
||||
public post<T, P>(
|
||||
url: string,
|
||||
params?: AxiosRequestConfig<P>,
|
||||
config?: PureHttpRequestConfig
|
||||
): Promise<T> {
|
||||
return this.request<T>("post", url, params, config);
|
||||
}
|
||||
|
||||
/** 单独抽离的`get`工具函数 */
|
||||
public get<T, P>(
|
||||
url: string,
|
||||
params?: AxiosRequestConfig<P>,
|
||||
config?: PureHttpRequestConfig
|
||||
): Promise<T> {
|
||||
return this.request<T>("get", url, params, config);
|
||||
}
|
||||
|
||||
/** 请求拦截 */
|
||||
private httpInterceptorsRequest(): void {
|
||||
PureHttp.axiosInstance.interceptors.request.use(
|
||||
async (config: PureHttpRequestConfig): Promise<any> => {
|
||||
// 开启进度条动画
|
||||
NProgress.start();
|
||||
// 优先判断post/get等方法是否传入回调,否则执行初始化设置等回调
|
||||
if (typeof config.beforeRequestCallback === "function") {
|
||||
config.beforeRequestCallback(config);
|
||||
return config;
|
||||
}
|
||||
if (PureHttp.initConfig.beforeRequestCallback) {
|
||||
PureHttp.initConfig.beforeRequestCallback(config);
|
||||
return config;
|
||||
}
|
||||
/** 请求白名单,放置一些不需要`token`的接口(通过设置请求白名单,防止`token`过期后再请求造成的死循环问题) */
|
||||
const whiteList = ["/refresh-token", "/login"];
|
||||
return whiteList.some(url => config.url.endsWith(url))
|
||||
? config
|
||||
: new Promise(resolve => {
|
||||
const data = getToken();
|
||||
if (data) {
|
||||
const now = new Date().getTime();
|
||||
const expired = parseInt(data.expires) - now <= 0;
|
||||
if (expired) {
|
||||
if (!PureHttp.isRefreshing) {
|
||||
PureHttp.isRefreshing = true;
|
||||
// token过期刷新
|
||||
useUserStoreHook()
|
||||
.handRefreshToken({ refreshToken: data.refreshToken })
|
||||
.then(res => {
|
||||
const token = res.data.accessToken;
|
||||
config.headers["Authorization"] = formatToken(token);
|
||||
PureHttp.requests.forEach(cb => cb(token));
|
||||
PureHttp.requests = [];
|
||||
})
|
||||
.finally(() => {
|
||||
PureHttp.isRefreshing = false;
|
||||
});
|
||||
}
|
||||
resolve(PureHttp.retryOriginalRequest(config));
|
||||
} else {
|
||||
config.headers["Authorization"] = formatToken(
|
||||
data.accessToken
|
||||
);
|
||||
resolve(config);
|
||||
}
|
||||
} else {
|
||||
resolve(config);
|
||||
}
|
||||
});
|
||||
},
|
||||
error => {
|
||||
return Promise.reject(error);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/** 响应拦截 */
|
||||
private httpInterceptorsResponse(): void {
|
||||
const instance = PureHttp.axiosInstance;
|
||||
instance.interceptors.response.use(
|
||||
(response: PureHttpResponse) => {
|
||||
const $config = response.config;
|
||||
// 关闭进度条动画
|
||||
NProgress.done();
|
||||
// 优先判断post/get等方法是否传入回调,否则执行初始化设置等回调
|
||||
if (typeof $config.beforeResponseCallback === "function") {
|
||||
$config.beforeResponseCallback(response);
|
||||
return response.data;
|
||||
}
|
||||
if (PureHttp.initConfig.beforeResponseCallback) {
|
||||
PureHttp.initConfig.beforeResponseCallback(response);
|
||||
return response.data;
|
||||
}
|
||||
return response.data;
|
||||
},
|
||||
(error: PureHttpError) => {
|
||||
const $error = error;
|
||||
$error.isCancelRequest = Axios.isCancel($error);
|
||||
// 关闭进度条动画
|
||||
NProgress.done();
|
||||
// 所有的响应异常 区分来源为取消请求/非取消请求
|
||||
return Promise.reject($error);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export const http = new PureHttp();
|
|
@ -65,6 +65,7 @@ declare global {
|
|||
*/
|
||||
interface ViteEnv {
|
||||
VITE_PORT: number;
|
||||
VITE_APP_URL: string;
|
||||
VITE_PUBLIC_PATH: string;
|
||||
VITE_ROUTER_HISTORY: string;
|
||||
VITE_CDN: boolean;
|
||||
|
|
|
@ -1,13 +1,9 @@
|
|||
import { getPluginsList } from "./build/plugins";
|
||||
import { exclude, include } from "./build/optimize";
|
||||
import { type ConfigEnv, loadEnv, type UserConfigExport } from "vite";
|
||||
import {
|
||||
__APP_INFO__,
|
||||
alias,
|
||||
pathResolve,
|
||||
root,
|
||||
wrapperEnv
|
||||
} from "./build/utils";
|
||||
import { __APP_INFO__, alias, root, wrapperEnv } from "./build/utils";
|
||||
import { serverOptions } from "./build/server";
|
||||
import { buildEnvironment } from "./build/buildEnv";
|
||||
|
||||
export default ({ mode }: ConfigEnv): UserConfigExport => {
|
||||
const { VITE_CDN, VITE_PORT, VITE_COMPRESSION, VITE_PUBLIC_PATH } =
|
||||
|
@ -15,45 +11,19 @@ export default ({ mode }: ConfigEnv): UserConfigExport => {
|
|||
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, VITE_PORT),
|
||||
// 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__)
|
||||
|
|
Loading…
Reference in New Issue