chore: 🔨 修改配置文件和规则文件

This commit is contained in:
Bunny 2024-05-11 23:42:38 +08:00
parent 176ac5971f
commit 36240d1cba
29 changed files with 11079 additions and 16267 deletions

View File

@ -1,22 +0,0 @@
# eslint 忽略检查 (根据项目需要自行添加)
*.sh
node_modules
*.md
*.woff
*.ttf
.vscode
.idea
dist
html
/public
/docs
.husky
.local
/bin
.eslintrc.js
.prettierrc.js
.stylelintrc.js
lint-staged.config.js
/src/mock/*
src/utils/request.js
list

View File

@ -1,69 +0,0 @@
// @see: http://eslint.cn
module.exports = {
root: true,
env: {
browser: true,
node: true,
es6: true,
},
/* 指定如何解析语法 */
parser: 'vue-eslint-parser',
/* 优先级低于 parse 的语法解析配置 */
parserOptions: {
parser: '@typescript-eslint/parser',
ecmaVersion: 2020,
sourceType: 'module',
jsxPragma: 'React',
ecmaFeatures: {
jsx: true,
},
},
/* 继承某些已有的规则 */
extends: ['plugin:vue/vue3-recommended', 'plugin:@typescript-eslint/recommended', 'prettier', 'plugin:prettier/recommended'],
/*
* "off" 0 ==> 关闭规则
* "warn" 1 ==> 打开的规则作为警告不影响代码执行
* "error" 2 ==> 规则作为一个错误代码不能执行界面报错
*/
rules: {
// eslint (http://eslint.cn/docs/rules)
'no-var': 'error', // 要求使用 let 或 const 而不是 var
'no-multiple-empty-lines': ['error', { max: 1 }], // 不允许多个空行
'no-use-before-define': 'off', // 禁止在 函数/类/变量 定义之前使用它们
'prefer-const': 'off', // 此规则旨在标记使用 let 关键字声明但在初始分配后从未重新分配的变量,要求使用 const
'no-irregular-whitespace': 'off', // 禁止不规则的空白
// typeScript (https://typescript-eslint.io/rules)
'@typescript-eslint/no-unused-vars': 'error', // 禁止定义未使用的变量
'@typescript-eslint/prefer-ts-expect-error': 'error', // 禁止使用 @ts-ignore
'@typescript-eslint/no-inferrable-types': 'off', // 可以轻松推断的显式类型可能会增加不必要的冗长
'@typescript-eslint/no-namespace': 'off', // 禁止使用自定义 TypeScript 模块和命名空间。
'@typescript-eslint/no-explicit-any': 'off', // 禁止使用 any 类型
'@typescript-eslint/ban-types': 'off', // 禁止使用特定类型
'@typescript-eslint/explicit-function-return-type': 'off', // 不允许对初始化为数字、字符串或布尔值的变量或参数进行显式类型声明
'@typescript-eslint/no-var-requires': 'off', // 不允许在 import 语句中使用 require 语句
'@typescript-eslint/no-empty-function': 'off', // 禁止空函数
'@typescript-eslint/no-use-before-define': 'off', // 禁止在变量定义之前使用它们
'@typescript-eslint/ban-ts-comment': 'off', // 禁止 @ts-<directive> 使用注释或要求在指令后进行描述
'@typescript-eslint/no-non-null-assertion': 'off', // 不允许使用后缀运算符的非空断言(!)
'@typescript-eslint/explicit-module-boundary-types': 'off', // 要求导出函数和类的公共类方法的显式返回和参数类型
'@typescript-eslint/no-unused-vars': 'off',
// vue (https://eslint.vuejs.org/rules)
'vue/no-v-html': 'off', // 禁止使用 v-html
'vue/script-setup-uses-vars': 'error', // 防止<script setup>使用的变量<template>被标记为未使用此规则仅在启用该no-unused-vars规则时有效。
'vue/v-slot-style': 'error', // 强制执行 v-slot 指令样式
'vue/no-mutating-props': 'off', // 不允许组件 prop的改变
'vue/custom-event-name-casing': 'off', // 为自定义事件名称强制使用特定大小写
'vue/attributes-order': 'off', // vue api使用顺序强制执行属性顺序
'vue/one-component-per-file': 'off', // 强制每个组件都应该在自己的文件中
'vue/html-closing-bracket-newline': 'off', // 在标签的右括号之前要求或禁止换行
'vue/max-attributes-per-line': 'off', // 强制每行的最大属性数
'vue/multiline-html-element-content-newline': 'off', // 在多行元素的内容之前和之后需要换行符
'vue/singleline-html-element-content-newline': 'off', // 在单行元素的内容之前和之后需要换行符
'vue/attribute-hyphenation': 'off', // 对模板中的自定义组件强制执行属性命名样式
'vue/require-default-prop': 'off', // 此规则要求为每个 prop 为必填时,必须提供默认值
'vue/multi-word-component-names': 'off', // 要求组件名称始终为 “-” 链接的单词
},
};

5
.gitpod.yml Normal file
View File

@ -0,0 +1,5 @@
ports:
- port: 3344
onOpen: open-preview
tasks:
- init: pnpm install && pnpm serve

20
.lintstagedrc Normal file
View File

@ -0,0 +1,20 @@
{
"*.{js,jsx,ts,tsx}": [
"prettier --cache --ignore-unknown --write",
"eslint --cache --fix"
],
"{!(package)*.json,*.code-snippets,.!({browserslist,nvm})*rc}": [
"prettier --cache --write--parser json"
],
"package.json": ["prettier --cache --write"],
"*.vue": [
"prettier --write",
"eslint --cache --fix",
"stylelint --fix --allow-empty-input"
],
"*.{css,scss,html}": [
"prettier --cache --ignore-unknown --write",
"stylelint --fix --allow-empty-input"
],
"*.md": ["prettier --cache --ignore-unknown --write"]
}

11
.markdownlint.json Normal file
View File

@ -0,0 +1,11 @@
{
"default": true,
"MD003": false,
"MD033": false,
"MD013": false,
"MD001": false,
"MD025": false,
"MD024": false,
"MD007": { "indent": 4 },
"no-hard-tabs": false
}

View File

@ -1,10 +1 @@
list src/views/system/menu/README.md
/dist/*
/html/*
.local
/node_modules/**
**/*.svg
**/*.sh
/public/*

View File

@ -1,39 +1,10 @@
// @see: https://www.prettier.cn // @ts-check
module.exports = { /** @type {import("prettier").Config} */
// 超过最大值换行 export default {
printWidth: 130, printWidth: 200,
// 缩进字节数
tabWidth: 1,
// 使用制表符而不是空格缩进行
useTabs: true,
// 结尾不用分号(true有false没有)
semi: true,
// 使用单引号(true单引号false双引号)
singleQuote: true,
// 更改引用对象属性的时间 可选值"<as-needed|consistent|preserve>"
quoteProps: 'as-needed',
// 在对象,数组括号与文字之间加空格 "{ foo: bar }"
bracketSpacing: true, bracketSpacing: true,
// 多行时尽可能打印尾随逗号。(例如,单行数组永远不会出现逗号结尾。) 可选值"<none|es5|all>"默认none singleQuote: false,
trailingComma: 'all', arrowParens: "avoid",
// 在JSX中使用单引号而不是双引号 trailingComma: "none"
jsxSingleQuote: true,
// (x) => {} 箭头函数参数只有一个时是否要有小括号。avoid省略括号 ,always不省略括号
arrowParens: 'avoid',
// 如果文件顶部已经有一个 doclock这个选项将新建一行注释并打上@format标记。
insertPragma: false,
// 指定要使用的解析器,不需要写文件开头的 @prettier
requirePragma: false,
// 默认值。因为使用了一些折行敏感型的渲染器如GitHub comment而按照markdown文本样式进行折行
proseWrap: 'preserve',
// 在html中空格是否是敏感的 "css" - 遵守CSS显示属性的默认值 "strict" - 空格被认为是敏感的 "ignore" - 空格被认为是不敏感的
htmlWhitespaceSensitivity: 'css',
// 换行符使用 lf 结尾是 可选值"<auto|lf|crlf|cr>"
endOfLine: 'auto',
// 这两个选项可用于格式化以给定字符偏移量(分别包括和不包括)开始和结束的代码
rangeStart: 0,
rangeEnd: Infinity,
vueIndentScriptAndStyle: false, // Vue文件脚本和样式标签缩进
}; };

View File

@ -1,19 +1,4 @@
# .stylelintignore
# 旧的不需打包的样式库
*.min.css
# 其他类型文件
*.js
*.jpg
*.woff
# 测试和打包目录
/test/
/dist/* /dist/*
/public/* /public/*
public/* public/*
/node_modules/ src/style/reset.scss
.eslintrc.js
.prettierrc.js
.stylelintrc.js
lint-staged.config.js

View File

@ -1,62 +0,0 @@
// @see: https://stylelint.io
module.exports = {
root: true,
defaultSeverity: 'error',
plugins: ['stylelint-order', 'stylelint-scss'],
/* 继承某些已有的规则 */
extends: [
'stylelint-config-standard', // 配置stylelint拓展插件
'stylelint-config-html/html', // the shareable html config for Stylelint.
'stylelint-config-html/vue', // 配置 vue 中 template 样式格式化
'stylelint-config-recess-order', // 配置stylelint css属性书写顺序插件,
'stylelint-config-prettier', // 配置stylelint和prettier兼容
],
overrides: [
// 扫描 .vue/html 文件中的<style>标签内的样式
{
files: ['**/*.{vue,html}'],
customSyntax: 'postcss-html',
rules: {
// 禁止未知的伪类选择器
'selector-pseudo-class-no-unknown': [true, { ignorePseudoClasses: ['deep', 'global'] }],
// 禁止未知的伪元素选择器
'selector-pseudo-element-no-unknown': [true, { ignorePseudoElements: ['v-deep', 'v-global', 'v-slotted'] }],
},
},
{
files: ['*.less', '**/*.less', '*.scss', '**/*.scss'],
customSyntax: 'postcss-less',
rules: {
'less/color-no-invalid-hex': true,
'less/no-duplicate-variables': true,
},
},
],
/**
* null => 关闭该规则
*/
rules: {
'value-keyword-case': null, // 在 css 中使用 v-bind不报错
'no-descending-specificity': null, // 禁止在具有较高优先级的选择器后出现被其覆盖的较低优先级的选择器
'function-url-quotes': 'always', // 要求或禁止 URL 的引号 "always(必须加上引号)"|"never(没有引号)"
'string-quotes': 'double', // 指定字符串使用单引号或双引号
'unit-case': null, // 指定单位的大小写 "lower(全小写)"|"upper(全大写)"
'color-hex-case': 'lower', // 指定 16 进制颜色的大小写 "lower(全小写)"|"upper(全大写)"
'color-hex-length': 'long', // 指定 16 进制颜色的简写或扩写 "short(16进制简写)"|"long(16进制扩写)"
'rule-empty-line-before': 'never', // 要求或禁止在规则之前的空行 "always(规则之前必须始终有一个空行)"|"never(规则前绝不能有空行)"|"always-multi-line(多行规则之前必须始终有一个空行)"|"never-multi-line(多行规则之前绝不能有空行。)"
'font-family-no-missing-generic-family-keyword': null, // 禁止在字体族名称列表中缺少通用字体族关键字
'block-opening-brace-space-before': 'always', // 要求在块的开大括号之前必须有一个空格或不能有空白符 "always(大括号前必须始终有一个空格)"|"never(左大括号之前绝不能有空格)"|"always-single-line(在单行块中的左大括号之前必须始终有一个空格)"|"never-single-line(在单行块中的左大括号之前绝不能有空格)"|"always-multi-line(在多行块中,左大括号之前必须始终有一个空格)"|"never-multi-line(多行块中的左大括号之前绝不能有空格)"
'property-no-unknown': null, // 禁止未知的属性(true 为不允许)
'no-empty-source': null, // 禁止空源码
'declaration-block-trailing-semicolon': null, // 要求或不允许在声明块中使用尾随分号 string"always(必须始终有一个尾随分号)"|"never(不得有尾随分号)"
'selector-class-pattern': null, // 强制选择器类名的格式
'value-no-vendor-prefix': null, // 关闭 vendor-prefix(为了解决多行省略 -webkit-box)
'selector-pseudo-class-no-unknown': [
true,
{
ignorePseudoClasses: ['global', 'v-deep', 'deep'],
},
],
},
};

54
build/info.ts Normal file
View File

@ -0,0 +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";
dayjs.extend(duration);
const welcomeMessage = gradientString("cyan", "magenta").multiline(
`您好! 欢迎使用 bunny-template 模板项目
使Vite
访
http://localhost:6261/`
);
const boxenOptions: BoxenOptions = {
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)
);
}
});
}
}
};
}

47
build/plugins.ts Normal file
View File

@ -0,0 +1,47 @@
import { resolve } from "path";
import type { PluginOption } from "vite";
import { createHtmlPlugin } from "vite-plugin-html";
import { createSvgIconsPlugin } from "vite-plugin-svg-icons";
import vue from "@vitejs/plugin-vue";
import vueJsx from "@vitejs/plugin-vue-jsx";
// 按需引入antdV
import Components from "unplugin-vue-components/vite";
import { AntDesignVueResolver } from "unplugin-vue-components/resolvers";
import unocss from "@unocss/vite";
import { viteBuildInfo } from "./info";
/**
* vite
* @param viteEnv
*/
export const createVitePlugins = (viteEnv: ViteEnv): (PluginOption | PluginOption[])[] => {
return [
vue(),
vueJsx(),
unocss(),
viteBuildInfo(),
// 标题设置
createHtmlPlugin({
inject: {
data: {
title: viteEnv.VITE_GLOB_APP_TITLE
}
}
}),
// * 使用 svg 图标
createSvgIconsPlugin({
// 指定需要缓存的图标文件夹
iconDirs: [resolve(process.cwd(), "src/assets/icons")],
// 指定symbolId格式
symbolId: "icon-[dir]-[name]"
}),
// UI组件库按需引入
Components({
resolvers: [
AntDesignVueResolver({
importStyle: false // 动态主题需配置
})
]
})
];
};

30
build/proxy.ts Normal file
View File

@ -0,0 +1,30 @@
import type { ProxyOptions } from "vite";
type ProxyItem = [string, string];
type ProxyList = ProxyItem[];
type ProxyTargetList = Record<string, ProxyOptions>;
/**
* .env.development
* @param list
*/
export function createProxy(list: ProxyList = []) {
const ret: ProxyTargetList = {};
for (const [prefix, target] of list) {
const httpsRE = /^https:\/\//;
const isHttps = httpsRE.test(target);
// https://github.com/http-party/node-http-proxy#options
ret[prefix] = {
target: target,
changeOrigin: true,
ws: true,
rewrite: path => path.replace(new RegExp(`^${prefix}`), ""),
// https is require secure=false
...(isHttps ? { secure: false } : {})
};
}
return ret;
}

102
build/utils.ts Normal file
View File

@ -0,0 +1,102 @@
import dayjs from "dayjs";
import { readdir, stat } from "node:fs";
import { fileURLToPath } from "node:url";
import { dirname, resolve } from "node:path";
import { formatBytes, type Recordable, sum } from "@pureadmin/utils";
import { dependencies, devDependencies, engines, name, version } from "../package.json";
/** 启动`node`进程时所在工作目录的绝对路径 */
const root: string = process.cwd();
/**
* @description
* @param dir `build`
* @param metaUrl `url``build``import.meta.url`
*/
const pathResolve = (dir = ".", metaUrl = import.meta.url) => {
// 当前文件目录的绝对路径
const currentFileDir = dirname(fileURLToPath(metaUrl));
// build 目录的绝对路径
const buildDir = resolve(currentFileDir, "build");
// 解析的绝对路径
const resolvedPath = resolve(currentFileDir, dir);
// 检查解析的绝对路径是否在 build 目录内
if (resolvedPath.startsWith(buildDir)) {
// 在 build 目录内,返回当前文件路径
return fileURLToPath(metaUrl);
}
// 不在 build 目录内,返回解析后的绝对路径
return resolvedPath;
};
/** 设置别名 */
const alias: Record<string, string> = {
"@": pathResolve("../src"),
"@build": pathResolve()
};
/** 平台的名称、版本、运行所需的`node`和`pnpm`版本、依赖、最后构建时间的类型提示 */
const __APP_INFO__ = {
pkg: { name, version, engines, dependencies, devDependencies },
lastBuildTime: dayjs(new Date()).format("YYYY-MM-DD HH:mm:ss")
};
/** 处理环境变量 */
const wrapperEnv = (envConf: Recordable): ViteEnv => {
// 默认值
const ret: ViteEnv = {
VITE_PORT: 6261,
VITE_PUBLIC_PATH: "",
VITE_ROUTER_HISTORY: "",
VITE_CDN: false,
VITE_HIDE_HOME: "false",
VITE_COMPRESSION: "none"
};
for (const envName of Object.keys(envConf)) {
let realName = envConf[envName].replace(/\\n/g, "\n");
realName = realName === "true" ? true : realName === "false" ? false : realName;
if (envName === "VITE_PORT") {
realName = Number(realName);
}
ret[envName] = realName;
if (typeof realName === "string") {
process.env[envName] = realName;
} else if (typeof realName === "object") {
process.env[envName] = JSON.stringify(realName);
}
}
return ret;
};
const fileListTotal: number[] = [];
/** 获取指定文件夹中所有文件的总大小 */
const getPackageSize = options => {
const { folder = "dist", callback, format = true } = options;
readdir(folder, (err, files: string[]) => {
if (err) throw err;
let count = 0;
const checkEnd = () => {
++count == files.length && callback(format ? formatBytes(sum(fileListTotal)) : sum(fileListTotal));
};
files.forEach((item: string) => {
stat(`${folder}/${item}`, async (err, stats) => {
if (err) throw err;
if (stats.isFile()) {
fileListTotal.push(stats.size);
checkEnd();
} else if (stats.isDirectory()) {
getPackageSize({
folder: `${folder}/${item}/`,
callback: checkEnd
});
}
});
});
files.length === 0 && callback(0);
});
};
export { root, pathResolve, alias, __APP_INFO__, wrapperEnv, getPackageSize };

View File

@ -1,98 +1,63 @@
// @see: https://cz-git.qbenben.com/zh/guide // @see: https://cz-git.qbenben.com/zh/guide
/** @type {import('cz-git').UserConfig} */ /** @type {import('cz-git').UserConfig} */
module.exports= { export default {
ignores: [commit => commit === 'init'], ignores: [commit => commit.includes("init")],
extends: ['@commitlint/config-conventional'], extends: ["@commitlint/config-conventional"],
rules: { rules: {
// @see: https://commitlint.js.org/#/reference-rules // @see: https://commitlint.js.org/#/reference-rules
'body-leading-blank': [2, 'always'], "body-leading-blank": [2, "always"],
'footer-leading-blank': [1, 'always'], "footer-leading-blank": [1, "always"],
'header-max-length': [2, 'always', 108], "header-max-length": [2, "always", 108],
'subject-empty': [2, 'never'], "subject-empty": [2, "never"],
'type-empty': [2, 'never'], "type-empty": [2, "never"],
'subject-case': [0], "subject-case": [0],
'type-enum': [ "type-enum": [2, "always", ["feat", "fix", "media", "docs", "style", "refactor", "perf", "test", "build", "ci", "chore", "revert", "wip", "workflow", "types", "release"]]
2,
'always',
[
'init',
'feat',
'page',
'media',
'completepage',
'fix',
'fixbug',
'docs',
'style',
'refactor',
'perf',
'test',
'build',
'ci',
'chore',
'revert',
'wip',
'workflow',
'types',
'release',
'optimize',
],
],
}, },
prompt: { prompt: {
messages: { messages: {
type: '选择你要提交的类型 :', type: "选择你要提交的类型 :",
scope: '选择一个提交范围(可选):', scope: "选择一个提交范围(可选):",
customScope: '请输入自定义的提交范围 :', customScope: "请输入自定义的提交范围 :",
subject: '填写简短精炼的变更描述 :\n', subject: "填写简短精炼的变更描述 :\n",
body: '填写更加详细的变更描述(可选)。使用 "|" 换行 :\n', body: '填写更加详细的变更描述(可选)。使用 "|" 换行 :\n',
breaking: '列举非兼容性重大的变更(可选)。使用 "|" 换行 :\n', breaking: '列举非兼容性重大的变更(可选)。使用 "|" 换行 :\n',
footerPrefixsSelect: '选择关联issue前缀可选:', footerPrefixsSelect: "选择关联issue前缀可选:",
customFooterPrefixs: '输入自定义issue前缀 :', customFooterPrefixs: "输入自定义issue前缀 :",
footer: '列举关联issue (可选) 例如: #31, #I3244 :\n', footer: "列举关联issue (可选) 例如: #31, #I3244 :\n",
confirmCommit: '是否提交或修改commit ?', confirmCommit: "是否提交或修改commit ?"
}, },
types: [ types: [
{ value: 'init', name: '初始化: ⏳ 初始化项目', emoji: '⏳' }, { value: "feat", name: "特性: 🚀 新增功能", emoji: "🚀" },
{ value: 'optimize', name: '优化代码: ♻️ 优化项目代码', emoji: '♻️' }, { value: "media", name: "媒体: 🎁 新增媒体资源", emoji: "🎁" },
{ value: 'feat', name: '新增: 🚀 新增功能', emoji: '🚀' }, { value: "fix", name: "修复: 🧩 修复缺陷", emoji: "🧩" },
{ value: 'media', name: '媒体: 🎁 新增媒体资源', emoji: '🎁' }, { value: "docs", name: "文档: 📚 文档变更", emoji: "📚" },
{ value: 'page', name: '页面: 📄 新增页面', emoji: '📄' }, { value: "style", name: "格式: 🎨 代码格式(不影响功能,例如空格、分号等格式修正)", emoji: "🎨" },
{ value: 'completepage', name: '完成页面: 🍻 完成页面', emoji: '🍻' }, { value: "refactor", name: "重构: ♻️ 代码重构(不包括 bug 修复、功能新增)", emoji: "♻️" },
{ value: 'fixbug', name: 'bug: 🐛 修改bug', emoji: '🐛' }, { value: "perf", name: "性能: ⚡️ 性能优化", emoji: "⚡️" },
{ value: 'fix', name: '修复: 🧩 修复缺陷', emoji: '🧩' }, { value: "test", name: "测试: ✅ 添加疏漏测试或已有测试改动", emoji: "✅" },
{ value: 'docs', name: '文档: 📚 文档变更', emoji: '📚' }, { value: "build", name: "构建: 📦️ 构建流程、外部依赖变更(如升级 npm 包、修改 webpack 配置等)", emoji: "📦️" },
{ value: 'style', name: '格式: 🎨 代码格式(不影响功能,例如空格、分号等格式修正)', emoji: '🎨' }, { value: "ci", name: "集成: 🎡 修改 CI 配置、脚本", emoji: "🎡" },
{ value: 'refactor', name: '重构: 〽️ 代码重构(不包括 bug 修复、功能新增)', emoji: '〽️' }, { value: "revert", name: "回退: ⏪️ 回滚 commit", emoji: "⏪️" },
{ value: 'perf', name: '性能: ⚡️ 性能优化', emoji: '⚡️' }, { value: "chore", name: "其他: 🔨 对构建过程或辅助工具和库的更改(不影响源文件、测试用例)", emoji: "🔨" }
{ value: 'test', name: '测试: ✅ 添加疏漏测试或已有测试改动', emoji: '✅' },
{
value: 'chore',
name: '构建: 📦️ 构建流程、外部依赖变更(如升级 npm 包、修改 webpack 配置等)',
emoji: '📦️',
},
{ value: 'ci', name: '集成: 🎡 修改 CI 配置、脚本', emoji: '🎡' },
{ value: 'revert', name: '回退: ⏪️ 回滚 commit', emoji: '⏪️' },
{ value: 'build', name: '打包: 🔨 项目打包发布', emoji: '🔨' },
], ],
useEmoji: true, useEmoji: true,
themeColorCode: '', themeColorCode: "",
scopes: [], scopes: [],
allowCustomScopes: true, allowCustomScopes: true,
allowEmptyScopes: true, allowEmptyScopes: true,
customScopesAlign: 'bottom', customScopesAlign: "bottom",
customScopesAlias: 'custom', customScopesAlias: "custom",
emptyScopesAlias: 'empty', emptyScopesAlias: "empty",
upperCaseSubject: false, upperCaseSubject: false,
allowBreakingChanges: ['feat', 'fix'], allowBreakingChanges: ["feat", "fix"],
breaklineNumber: 100, breaklineNumber: 100,
breaklineChar: '|', breaklineChar: "|",
skipQuestions: [], skipQuestions: [],
issuePrefixs: [{ value: 'closed', name: 'closed: ISSUES has been processed' }], issuePrefixs: [{ value: "closed", name: "closed: ISSUES has been processed" }],
customIssuePrefixsAlign: 'top', customIssuePrefixsAlign: "top",
emptyIssuePrefixsAlias: 'skip', emptyIssuePrefixsAlias: "skip",
customIssuePrefixsAlias: 'custom', customIssuePrefixsAlias: "custom",
allowCustomIssuePrefixs: true, allowCustomIssuePrefixs: true,
allowEmptyIssuePrefixs: true, allowEmptyIssuePrefixs: true,
confirmColorize: true, confirmColorize: true,
@ -100,9 +65,9 @@ module.exports= {
maxSubjectLength: Infinity, maxSubjectLength: Infinity,
minSubjectLength: 0, minSubjectLength: 0,
scopeOverrides: undefined, scopeOverrides: undefined,
defaultBody: '', defaultBody: "",
defaultIssues: '', defaultIssues: "",
defaultScope: '', defaultScope: "",
defaultSubject: '', defaultSubject: ""
}, }
}; };

17
components.d.ts vendored Normal file
View File

@ -0,0 +1,17 @@
/* eslint-disable */
// @ts-nocheck
// Generated by unplugin-vue-components
// Read more: https://github.com/vuejs/core/pull/3399
export {};
/* prettier-ignore */
declare module 'vue' {
export interface GlobalComponents {
403: typeof import('./src/components/ErrorMessage/403.vue')['default']
404: typeof import('./src/components/ErrorMessage/404.vue')['default']
500: typeof import('./src/components/ErrorMessage/500.vue')['default']
Empty: typeof import('./src/components/Empty/index.vue')['default']
RouterLink: typeof import('vue-router')['RouterLink']
RouterView: typeof import('vue-router')['RouterView']
}
}

168
eslint.config.js Normal file
View File

@ -0,0 +1,168 @@
import js from "@eslint/js";
import pluginVue from "eslint-plugin-vue";
import * as parserVue from "vue-eslint-parser";
import configPrettier from "eslint-config-prettier";
import pluginPrettier from "eslint-plugin-prettier";
import { defineFlatConfig } from "eslint-define-config";
import * as parserTypeScript from "@typescript-eslint/parser";
import pluginTypeScript from "@typescript-eslint/eslint-plugin";
export default defineFlatConfig([
{
...js.configs.recommended,
ignores: ["**/.*", "dist/*", "*.d.ts", "public/*", "src/assets/**", "src/**/iconfont/**"],
languageOptions: {
globals: {
// index.d.ts
RefType: "readonly",
EmitType: "readonly",
TargetContext: "readonly",
ComponentRef: "readonly",
ElRef: "readonly",
ForDataType: "readonly",
AnyFunction: "readonly",
PropType: "readonly",
Writable: "readonly",
Nullable: "readonly",
NonNullable: "readonly",
Recordable: "readonly",
ReadonlyRecordable: "readonly",
Indexable: "readonly",
DeepPartial: "readonly",
Without: "readonly",
Exclusive: "readonly",
TimeoutHandle: "readonly",
IntervalHandle: "readonly",
Effect: "readonly",
ChangeEvent: "readonly",
WheelEvent: "readonly",
ImportMetaEnv: "readonly",
Fn: "readonly",
PromiseFn: "readonly",
ComponentElRef: "readonly",
parseInt: "readonly",
parseFloat: "readonly"
}
},
plugins: {
prettier: pluginPrettier
},
rules: {
...configPrettier.rules,
...pluginPrettier.configs.recommended.rules,
"no-debugger": "off",
"no-unused-vars": [
"error",
{
argsIgnorePattern: "^_",
varsIgnorePattern: "^_"
}
],
"prettier/prettier": [
"error",
{
endOfLine: "auto"
}
]
}
},
{
files: ["**/*.?([cm])ts", "**/*.?([cm])tsx"],
languageOptions: {
parser: parserTypeScript,
parserOptions: {
sourceType: "module"
}
},
plugins: {
"@typescript-eslint": pluginTypeScript
},
rules: {
...pluginTypeScript.configs.strict.rules,
"@typescript-eslint/ban-types": "off",
"@typescript-eslint/no-redeclare": "error",
"@typescript-eslint/ban-ts-comment": "off",
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/prefer-as-const": "warn",
"@typescript-eslint/no-empty-function": "off",
"@typescript-eslint/no-non-null-assertion": "off",
"@typescript-eslint/no-import-type-side-effects": "error",
"@typescript-eslint/explicit-module-boundary-types": "off",
"@typescript-eslint/consistent-type-imports": ["error", { disallowTypeAnnotations: false, fixStyle: "inline-type-imports" }],
"@typescript-eslint/prefer-literal-enum-member": ["error", { allowBitwiseExpressions: true }],
"@typescript-eslint/no-unused-vars": [
"error",
{
argsIgnorePattern: "^_",
varsIgnorePattern: "^_"
}
]
}
},
{
files: ["**/*.d.ts"],
rules: {
"eslint-comments/no-unlimited-disable": "off",
"import/no-duplicates": "off",
"unused-imports/no-unused-vars": "off"
}
},
{
files: ["**/*.?([cm])js"],
rules: {
"@typescript-eslint/no-require-imports": "off",
"@typescript-eslint/no-var-requires": "off"
}
},
{
files: ["**/*.vue"],
languageOptions: {
globals: {
$: "readonly",
$$: "readonly",
$computed: "readonly",
$customRef: "readonly",
$ref: "readonly",
$shallowRef: "readonly",
$toRef: "readonly"
},
parser: parserVue,
parserOptions: {
ecmaFeatures: {
jsx: true
},
extraFileExtensions: [".vue"],
parser: "@typescript-eslint/parser",
sourceType: "module"
}
},
plugins: {
vue: pluginVue
},
processor: pluginVue.processors[".vue"],
rules: {
...pluginVue.configs.base.rules,
...pluginVue.configs["vue3-essential"].rules,
...pluginVue.configs["vue3-recommended"].rules,
"no-undef": "off",
"no-unused-vars": "off",
"vue/no-v-html": "off",
"vue/require-default-prop": "off",
"vue/require-explicit-emits": "off",
"vue/multi-word-component-names": "off",
"vue/no-setup-props-reactivity-loss": "off",
"vue/html-self-closing": [
"error",
{
html: {
void: "always",
normal: "always",
component: "always"
},
svg: "always",
math: "always"
}
]
}
}
]);

View File

@ -1,8 +1,8 @@
module.exports = { export default {
'*.{js,jsx,ts,tsx}': ['eslint --fix --no-ignore', 'prettier --write'], "*.{js,jsx,ts,tsx}": ["eslint --fix", "prettier --write"],
'{!(package)*.json,*.code-snippets,.!(browserslist)*rc}': ['prettier --write--parser json'], "{!(package)*.json,*.code-snippets,.!(browserslist)*rc}": ["prettier --write--parser json"],
'package.json': ['prettier --write'], "package.json": ["prettier --write"],
'*.vue': ['eslint --fix --no-ignore', 'prettier --write'], "*.vue": ["eslint --fix", "prettier --write", "stylelint --fix"],
'*.{scss,less,styl,html}': ['prettier --write', 'eslint --fix --no-ignore'], // 'stylelint --fix', "*.{scss,less,styl,html}": ["stylelint --fix", "prettier --write"],
'*.md': ['prettier --write'], "*.md": ["prettier --write"]
}; };

15933
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -2,9 +2,32 @@
"name": "vite_ts_auto", "name": "vite_ts_auto",
"private": true, "private": true,
"version": "1.0.0", "version": "1.0.0",
"description": "Bunny-Vite模板", "type": "module",
"author": "Bunny-Admin <1319900154@qq.com>", "keywords": [
"bunny-admin",
"bunny-cli",
"ant-design",
"typescript",
"pinia",
"vue3",
"vite",
"esm"
],
"description": "Bunny-Admin后台管理系统",
"homepage": "https://gitee.com/BunnyBoss/bunny-admin",
"repository": {
"type": "git",
"url": "https://gitee.com/BunnyBoss/bunny-admin"
},
"bugs": {
"url": "https://gitee.com/BunnyBoss/bunny-admin/issues"
},
"license": "MIT", "license": "MIT",
"author": {
"name": "Bunny0212",
"email": "1319900154@qq.com",
"url": "https://gitee.com/BunnyBoss"
},
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",
"serve": "vite", "serve": "vite",
@ -21,20 +44,30 @@
"commit": "git pull && git add -A && git-cz && git push" "commit": "git pull && git add -A && git-cz && git push"
}, },
"dependencies": { "dependencies": {
"@pureadmin/utils": "^2.4.7",
"@unocss/preset-uno": "^0.60.0",
"@unocss/vite": "^0.60.0",
"@vitejs/plugin-vue-jsx": "^3.1.0",
"axios": "^1.6.7", "axios": "^1.6.7",
"boxen": "^7.1.1",
"compression-webpack-plugin": "^11.1.0", "compression-webpack-plugin": "^11.1.0",
"core-js": "^3.36.0", "core-js": "^3.36.0",
"crypto-js": "^4.2.0", "crypto-js": "^4.2.0",
"dayjs": "^1.11.10", "dayjs": "^1.11.10",
"dotenv": "^16.4.5", "dotenv": "^16.4.5",
"echarts": "^5.5.0", "echarts": "^5.5.0",
"eslint-define-config": "^2.1.0",
"gradient-string": "^2.0.2",
"loadsh": "^0.0.4", "loadsh": "^0.0.4",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"mitt": "^3.0.1", "mitt": "^3.0.1",
"moment": "^2.30.1", "moment": "^2.30.1",
"pinia": "^2.1.7", "pinia": "^2.1.7",
"stylelint-scss": "^6.3.0", "stylelint-scss": "^6.3.0",
"unplugin-vue-components": "^0.27.0",
"uuid": "^9.0.1", "uuid": "^9.0.1",
"vite-plugin-html": "^3.2.2",
"vite-plugin-svg-icons": "^2.0.1",
"vue": "^3.4.21", "vue": "^3.4.21",
"vue-cookies": "^1.8.3", "vue-cookies": "^1.8.3",
"vue-i18n": "^9.13.1", "vue-i18n": "^9.13.1",
@ -78,6 +111,25 @@
"gitHooks": { "gitHooks": {
"pre-commit": "lint-staged" "pre-commit": "lint-staged"
}, },
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0",
"yarn": ">=1.22.20"
},
"packageManager": "yarn@1.22.22",
"yarn": {
"allowedDeprecatedVersions": {
"sourcemap-codec": "*",
"domexception": "*",
"w3c-hr-time": "*",
"stable": "*",
"abab": "*"
},
"peerDependencyRules": {
"allowedVersions": {
"eslint": "9"
}
}
},
"config": { "config": {
"commitizen": { "commitizen": {
"path": "node_modules/cz-git" "path": "node_modules/cz-git"

12
postcss.config.js Normal file
View File

@ -0,0 +1,12 @@
// @ts-check
/** @type {import('postcss-load-config').Config} */
export default {
plugins: {
"postcss-import": {},
"tailwindcss/nesting": {},
tailwindcss: {},
autoprefixer: {},
...(process.env.NODE_ENV === "production" ? { cssnano: {} } : {})
}
};

84
src/utils/getEnv.ts Normal file
View File

@ -0,0 +1,84 @@
import dotenv from "dotenv";
import fs from "fs";
import path from "path";
export function isProdEnv(): boolean {
return import.meta.env.PROD;
}
export function isDevEnv(): boolean {
return import.meta.env.DEV;
}
export function isDevFn(mode: string): boolean {
return mode === "development";
}
export function isProdFn(mode: string): boolean {
return mode === "production";
}
/**
* Whether to generate package preview
*/
export function isReportMode(): boolean {
return process.env.VITE_REPORT === "true";
}
/**
* @description process.env
* @param envConf
* */
export function wrapperEnv(envConf: Recordable): ViteEnv {
const ret: any = {};
for (const envName of Object.keys(envConf)) {
let realName = envConf[envName].replace(/\\n/g, "\n");
realName = realName === "true" ? true : realName === "false" ? false : realName;
if (envName === "VITE_PORT") {
realName = Number(realName);
}
if (envName === "VITE_PROXY") {
try {
realName = JSON.parse(realName);
} catch (error) {}
}
ret[envName] = realName;
process.env[envName] = realName;
}
return ret;
}
/**
* Get the environment variables starting with the specified prefix
* @param match prefix
* @param confFiles ext
*/
export function getEnvConfig(match = "VITE_GLOB_", confFiles = [".env", ".env.production"]) {
let envConfig = {};
confFiles.forEach(item => {
try {
const env = dotenv.parse(fs.readFileSync(path.resolve(process.cwd(), item)));
envConfig = { ...envConfig, ...env };
} catch (error) {
console.error(`Error in parsing ${item}`, error);
}
});
Object.keys(envConfig).forEach(key => {
const reg = new RegExp(`^(${match})`);
if (!reg.test(key)) {
Reflect.deleteProperty(envConfig, key);
}
});
return envConfig;
}
/**
* Get user root directory
* @param dir file path
*/
export function getRootPath(...dir: string[]) {
return path.resolve(process.cwd(), ...dir);
}

68
stylelint.config.js Normal file
View File

@ -0,0 +1,68 @@
// @ts-check
/** @type {import("stylelint").Config} */
export default {
extends: ["stylelint-config-standard", "stylelint-config-html/vue", "stylelint-config-recess-order"],
plugins: ["stylelint-scss", "stylelint-order", "stylelint-prettier"],
overrides: [
{
files: ["**/*.(css|html|vue)"],
customSyntax: "postcss-html"
},
{
files: ["*.scss", "**/*.scss"],
customSyntax: "postcss-scss",
extends: ["stylelint-config-standard-scss", "stylelint-config-recommended-vue/scss"]
}
],
rules: {
"prettier/prettier": true,
"selector-class-pattern": null,
"no-descending-specificity": null,
"scss/dollar-variable-pattern": null,
"selector-pseudo-class-no-unknown": [
true,
{
ignorePseudoClasses: ["deep", "global"]
}
],
"selector-pseudo-element-no-unknown": [
true,
{
ignorePseudoElements: ["v-deep", "v-global", "v-slotted"]
}
],
"at-rule-no-unknown": [
true,
{
ignoreAtRules: ["tailwind", "apply", "variants", "responsive", "screen", "function", "if", "each", "include", "mixin", "use"]
}
],
"rule-empty-line-before": [
"always",
{
ignore: ["after-comment", "first-nested"]
}
],
"unit-no-unknown": [true, { ignoreUnits: ["rpx"] }],
"order/order": [
[
"dollar-variables",
"custom-properties",
"at-rules",
"declarations",
{
type: "at-rule",
name: "supports"
},
{
type: "at-rule",
name: "media"
},
"rules"
],
{ severity: "warning" }
]
},
ignoreFiles: ["**/*.js", "**/*.ts", "**/*.jsx", "**/*.tsx", "report.html"]
};

19
tailwind.config.ts Normal file
View File

@ -0,0 +1,19 @@
import type { Config } from "tailwindcss";
export default {
darkMode: "class",
corePlugins: {
preflight: false
},
content: ["./index.html", "./src/**/*.{vue,js,ts,jsx,tsx}"],
theme: {
extend: {
colors: {
bg_color: "var(--el-bg-color)",
primary: "var(--el-color-primary)",
text_color_primary: "var(--el-text-color-primary)",
text_color_regular: "var(--el-text-color-regular)"
}
}
}
} satisfies Config;

74
typings/global.d.ts vendored Normal file
View File

@ -0,0 +1,74 @@
/* Menu */
declare namespace Menu {
interface MenuOptions {
path: string;
name: string;
component?: string | (() => Promise<unknown>);
redirect?: string;
meta: MetaProps;
children?: MenuOptions[];
}
interface MetaProps {
icon: string;
title: string;
activeMenu?: string;
isLink?: string;
isHide: boolean;
isFull: boolean;
isAffix: boolean;
isKeepAlive: boolean;
}
}
/* table */
declare type Key = string | number;
declare type DefaultRecordType = any;
/* FileType */
declare namespace File {
type ImageMimeType = "image/apng" | "image/bmp" | "image/gif" | "image/jpeg" | "image/pjpeg" | "image/png" | "image/svg+xml" | "image/tiff" | "image/webp" | "image/x-icon";
type ExcelMimeType = "application/vnd.ms-excel" | "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
}
/* Vite */
declare type Recordable<T = any> = Record<string, T>;
declare interface ViteEnv {
VITE_USER_NODE_ENV: "development" | "production" | "test";
VITE_GLOB_APP_TITLE: string;
VITE_PORT: number;
VITE_OPEN: boolean;
VITE_REPORT: boolean;
VITE_BUILD_COMPRESS: "gzip" | "brotli" | "gzip,brotli" | "none";
VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE: boolean;
VITE_DROP_CONSOLE: boolean;
VITE_PWA: boolean;
VITE_PUBLIC_PATH: string;
VITE_API_URL: string;
VITE_PROXY: [string, string][];
}
interface ImportMetaEnv extends ViteEnv {
__: unknown;
}
/* __APP_INFO__ */
declare const __APP_INFO__: {
pkg: {
name: string;
version: string;
dependencies: Recordable<string>;
devDependencies: Recordable<string>;
};
lastBuildTime: string;
};
/* Generic Tools */
type ObjToKeyValUnion<T> = {
[K in keyof T]: { key: K; value: T[K] };
}[keyof T];
type ObjToKeyValArray<T> = {
[K in keyof T]: [K, T[K]];
}[keyof T];

3
typings/plugins.d.ts vendored Normal file
View File

@ -0,0 +1,3 @@
// declare module "nprogress";
// declare module "js-md5";
declare module "echarts-liquidfill";

8
typings/window.d.ts vendored Normal file
View File

@ -0,0 +1,8 @@
declare global {
interface Navigator {
msSaveOrOpenBlob: (blob: Blob, fileName: string) => void;
browserLanguage: string;
}
}
export {};

92
uno.config.ts Normal file
View File

@ -0,0 +1,92 @@
import presetUno from "@unocss/preset-uno";
import transformerDirectives from "@unocss/transformer-directives";
import { defineConfig } from "@unocss/vite";
export default defineConfig({
content: {
pipeline: {
exclude: ["node_modules", "dist", ".git", ".husky", ".vscode", "public", "build", "mock", "./stats.html"]
}
},
presets: [presetUno({ dark: "class" })],
transformers: [transformerDirectives()],
shortcuts: {
"wh-full": "w-full h-full",
"flex-center": "flex justify-center items-center",
"flex-col-center": "flex-center flex-col",
"flex-x-center": "flex justify-center",
"flex-y-center": "flex items-center",
"i-flex-center": "inline-flex justify-center items-center",
"i-flex-x-center": "inline-flex justify-center",
"i-flex-y-center": "inline-flex items-center",
"flex-col": "flex flex-col",
"flex-col-stretch": "flex-col items-stretch",
"i-flex-col": "inline-flex flex-col",
"i-flex-col-stretch": "i-flex-col items-stretch",
"flex-1-hidden": "flex-1 overflow-hidden",
"absolute-lt": "absolute left-0 top-0",
"absolute-lb": "absolute left-0 bottom-0",
"absolute-rt": "absolute right-0 top-0",
"absolute-rb": "absolute right-0 bottom-0",
"absolute-tl": "absolute-lt",
"absolute-tr": "absolute-rt",
"absolute-bl": "absolute-lb",
"absolute-br": "absolute-rb",
"absolute-center": "absolute-lt flex-center wh-full",
"fixed-lt": "fixed left-0 top-0",
"fixed-lb": "fixed left-0 bottom-0",
"fixed-rt": "fixed right-0 top-0",
"fixed-rb": "fixed right-0 bottom-0",
"fixed-tl": "fixed-lt",
"fixed-tr": "fixed-rt",
"fixed-bl": "fixed-lb",
"fixed-br": "fixed-rb",
"fixed-center": "fixed-lt flex-center wh-full",
"nowrap-hidden": "whitespace-nowrap overflow-hidden",
"ellipsis-text": "nowrap-hidden text-ellipsis",
"transition-base": "transition-all duration-300 ease-in-out"
},
theme: {
colors: {
primary: "var(--ant-primary-color)",
primary_hover: "var(--ant-primary-color-hover)",
primary_active: "var(--ant-primary-color-active)",
primary_disabled: "var(--ant-primary-color-disabled)",
primary_outline: "var(--ant-primary-color-outline)",
primary_deprecated_bg: "var(--ant-primary-color-deprecated-bg)",
primary_deprecated_border: "var(--ant-primary-color-deprecated-border)",
primary_1: "var(--ant-primary-1)",
primary_2: "var(--ant-primary-2)",
primary_3: "var(--ant-primary-3)",
primary_4: "var(--ant-primary-4)",
primary_5: "var(--ant-primary-5)",
primary_6: "var(--ant-primary-6)",
primary_7: "var(--ant-primary-7)",
primary_8: "var(--ant-primary-8)",
primary_9: "var(--ant-primary-9)",
primary_10: "var(--ant-primary-10)",
info: "var(--ant-info-color)",
info_deprecated_bg: "var(--ant-info-color-deprecated-bg)",
info_deprecated_border: "var(--ant-info-color-deprecated-border)",
success: "var(--ant-success-color)",
success_hover: "var(--ant-success-color-hover)",
success_active: "var(--ant-success-color-active)",
success_outline: "var(--ant-success-color-outline)",
success_deprecated_bg: "var(--ant-success-color-deprecated-bg)",
success_deprecated_border: "var(--ant-success-color-deprecated-border)",
warning: "var(--ant-warning-color)",
warning_hover: "var(--ant-warning-color-hover)",
warning_active: "var(--ant-warning-color-active)",
warning_outline: "var(--ant-warning-color-outline)",
warning_deprecated_bg: "var(--ant-warning-color-deprecated-bg)",
warning_deprecated_border: "var(--ant-warning-color-deprecated-bordr)",
error: "var(--ant-error-color)",
error_hover: "var(--ant-error-color-hover)",
error_active: "var(--ant-error-color-active)",
error_outline: "var(--ant-error-color-outline)",
error_deprecated_bg: "var(--ant-error-color-deprecated-bg)",
error_deprecated_border: "var(--ant-error-color-deprecated-border)",
dark: "#18181c"
}
}
});

View File

@ -1,51 +1,56 @@
import vue from '@vitejs/plugin-vue'; import { resolve } from "path";
import { resolve } from 'path'; import { type ConfigEnv, type UserConfig, defineConfig, loadEnv } from "vite";
import { UserConfig, defineConfig } from 'vite'; import { createVitePlugins } from "./build/plugins";
import { wrapperEnv } from "./src/utils/getEnv";
export default defineConfig( export default defineConfig(({ mode }: ConfigEnv): UserConfig => {
(): UserConfig => ({ const root = process.cwd();
const env = loadEnv(mode, root);
const viteEnv = wrapperEnv(env);
return {
resolve: { resolve: {
alias: { alias: {
'@': resolve(__dirname, './src'), "@": resolve(__dirname, "./src"),
'vue-i18n': 'vue-i18n/dist/vue-i18n.cjs.js', "vue-i18n": "vue-i18n/dist/vue-i18n.cjs.js"
}, }
}, },
server: { server: {
host: '0.0.0.0', host: "0.0.0.0",
port: 6261, port: 6261,
open: true, open: true,
cors: true, cors: true,
proxy: { proxy: {
'/api': { "/api": {
target: process.env.VUE_APP_URL, target: process.env.VUE_APP_URL,
changeOrigin: true, changeOrigin: true,
rewrite: (path: string) => path.replace(/^\/api/, '/api'), rewrite: (path: string) => path.replace(/^\/api/, "/api")
}, },
'/mock': { "/mock": {
target: process.env.VUE_APP_URL, target: process.env.VUE_APP_URL,
changeOrigin: true, changeOrigin: true,
rewrite: (path: string) => path.replace(/^\/mock/, ''), rewrite: (path: string) => path.replace(/^\/mock/, "")
}, }
}, }
}, },
plugins: [vue()], plugins: createVitePlugins(viteEnv),
esbuild: { esbuild: {
pure: ['console.log', 'debugger'], pure: ["console.log", "debugger"]
}, },
// 配置构建过程的选项,例如是否生成压缩文件和源映射 // 配置构建过程的选项,例如是否生成压缩文件和源映射
build: { build: {
// 构建输出的目录,默认值为"dist" // 构建输出的目录,默认值为"dist"
outDir: 'dist', outDir: "dist",
// 用于指定使用的代码压缩工具。在这里minify 被设置为 'terser',表示使用 Terser 进行代码压缩。默认值terser // 用于指定使用的代码压缩工具。在这里minify 被设置为 'terser',表示使用 Terser 进行代码压缩。默认值terser
// esbuild 打包更快,但是不能去除 console.logterser打包慢但能去除 console.log // esbuild 打包更快,但是不能去除 console.logterser打包慢但能去除 console.log
minify: 'terser', minify: "terser",
// 用于配置 Terser 的选项 // 用于配置 Terser 的选项
terserOptions: { terserOptions: {
// 用于配置压缩选项 // 用于配置压缩选项
compress: { compress: {
drop_console: true, // 是否删除代码中的 console 语句, 默认值false drop_console: true, // 是否删除代码中的 console 语句, 默认值false
drop_debugger: true, // 是否删除代码中的 debugger 语句, 默认值false drop_debugger: true // 是否删除代码中的 debugger 语句, 默认值false
}, }
}, },
// 禁用 gzip 压缩大小报告,可略微减少打包时间 // 禁用 gzip 压缩大小报告,可略微减少打包时间
reportCompressedSize: false, reportCompressedSize: false,
@ -54,7 +59,7 @@ export default defineConfig(
// 用于配置 CommonJS 模块的选项 // 用于配置 CommonJS 模块的选项
commonjsOptions: { commonjsOptions: {
// 用于指定是否忽略 CommonJS 模块中的 try-catch 语句。当设置为false时构建过程会保留 CommonJS 模块中的 try-catch 语句 // 用于指定是否忽略 CommonJS 模块中的 try-catch 语句。当设置为false时构建过程会保留 CommonJS 模块中的 try-catch 语句
ignoreTryCatch: false, ignoreTryCatch: false
}, },
// 规定触发警告的 chunk 大小, 当某个代码分块的大小超过该限制时Vite 会发出警告 // 规定触发警告的 chunk 大小, 当某个代码分块的大小超过该限制时Vite 会发出警告
chunkSizeWarningLimit: 2000, chunkSizeWarningLimit: 2000,
@ -63,11 +68,11 @@ export default defineConfig(
// 用于配置输出选项 // 用于配置输出选项
output: { output: {
// 静态资源分类和包装 // 静态资源分类和包装
chunkFileNames: 'assets/js/[name]-[hash].js', // 用于指定代码分块的输出文件名格式 chunkFileNames: "assets/js/[name]-[hash].js", // 用于指定代码分块的输出文件名格式
entryFileNames: 'assets/js/[name]-[hash].js', // 用于指定入口文件的输出文件名格式 entryFileNames: "assets/js/[name]-[hash].js", // 用于指定入口文件的输出文件名格式
assetFileNames: 'assets/[ext]/[name]-[hash].[ext]', // 用于指定静态资源的输出文件名格式 assetFileNames: "assets/[ext]/[name]-[hash].[ext]" // 用于指定静态资源的输出文件名格式
}, }
}, }
}, }
}), };
); });

10115
yarn.lock Normal file

File diff suppressed because it is too large Load Diff