style: 添加大屏插件和格式化代码
This commit is contained in:
parent
d5acd952d6
commit
2458802210
3
.env
3
.env
|
@ -13,6 +13,9 @@ VITE_APP_URL=http://localhost:8801
|
||||||
# 如果端口被占用会直接退出,而不是尝试下一个端口
|
# 如果端口被占用会直接退出,而不是尝试下一个端口
|
||||||
VITE_STRICT_PORT=false
|
VITE_STRICT_PORT=false
|
||||||
|
|
||||||
|
# 是否启用屏幕转vw适配
|
||||||
|
VITE_POST_CSS_PX_TO_VIEWPORT8_PLUGIN=false
|
||||||
|
|
||||||
# 是否在打包时使用cdn替换本地库 替换 true 不替换 false
|
# 是否在打包时使用cdn替换本地库 替换 true 不替换 false
|
||||||
VITE_CDN=false
|
VITE_CDN=false
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,9 @@ VITE_APP_URL=http://localhost:8801
|
||||||
# 如果端口被占用会直接退出,而不是尝试下一个端口
|
# 如果端口被占用会直接退出,而不是尝试下一个端口
|
||||||
VITE_STRICT_PORT=false
|
VITE_STRICT_PORT=false
|
||||||
|
|
||||||
|
# 是否启用屏幕转vw适配
|
||||||
|
VITE_POST_CSS_PX_TO_VIEWPORT8_PLUGIN=false
|
||||||
|
|
||||||
# 是否在打包时使用cdn替换本地库 替换 true 不替换 false
|
# 是否在打包时使用cdn替换本地库 替换 true 不替换 false
|
||||||
VITE_CDN=false
|
VITE_CDN=false
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,9 @@ VITE_APP_URL=http://localhost:8000
|
||||||
# 如果端口被占用会直接退出,而不是尝试下一个端口
|
# 如果端口被占用会直接退出,而不是尝试下一个端口
|
||||||
VITE_STRICT_PORT=false
|
VITE_STRICT_PORT=false
|
||||||
|
|
||||||
|
# 是否启用屏幕转vw适配
|
||||||
|
VITE_POST_CSS_PX_TO_VIEWPORT8_PLUGIN=false
|
||||||
|
|
||||||
# 是否在打包时使用cdn替换本地库 替换 true 不替换 false
|
# 是否在打包时使用cdn替换本地库 替换 true 不替换 false
|
||||||
VITE_CDN=false
|
VITE_CDN=false
|
||||||
|
|
||||||
|
|
|
@ -1,46 +1,46 @@
|
||||||
module.exports = {
|
export default {
|
||||||
// (x)=>{},单个参数箭头函数是否显示小括号。(always:始终显示;avoid:省略括号。默认:always)
|
// (x)=>{},单个参数箭头函数是否显示小括号。(always:始终显示;avoid:省略括号。默认:always)
|
||||||
arrowParens: "always",
|
arrowParens: "always",
|
||||||
// 开始标签的右尖括号是否跟随在最后一行属性末尾,默认false
|
// 开始标签的右尖括号是否跟随在最后一行属性末尾,默认false
|
||||||
bracketSameLine: false,
|
bracketSameLine: false,
|
||||||
// 对象字面量的括号之间打印空格 (true - Example: { foo: bar } ; false - Example: {foo:bar})
|
// 对象字面量的括号之间打印空格 (true - Example: { foo: bar } ; false - Example: {foo:bar})
|
||||||
bracketSpacing: true,
|
bracketSpacing: true,
|
||||||
// 是否格式化一些文件中被嵌入的代码片段的风格(auto|off;默认auto)
|
// 是否格式化一些文件中被嵌入的代码片段的风格(auto|off;默认auto)
|
||||||
embeddedLanguageFormatting: "auto",
|
embeddedLanguageFormatting: "auto",
|
||||||
// 指定 HTML 文件的空格敏感度 (css|strict|ignore;默认css)
|
// 指定 HTML 文件的空格敏感度 (css|strict|ignore;默认css)
|
||||||
htmlWhitespaceSensitivity: "ignore",
|
htmlWhitespaceSensitivity: "ignore",
|
||||||
// 当文件已经被 Prettier 格式化之后,是否会在文件顶部插入一个特殊的 @format 标记,默认false
|
// 当文件已经被 Prettier 格式化之后,是否会在文件顶部插入一个特殊的 @format 标记,默认false
|
||||||
insertPragma: false,
|
insertPragma: false,
|
||||||
// 在 JSX 中使用单引号替代双引号,默认false
|
// 在 JSX 中使用单引号替代双引号,默认false
|
||||||
jsxSingleQuote: false,
|
jsxSingleQuote: false,
|
||||||
// 每行最多字符数量,超出换行(默认100)
|
// 每行最多字符数量,超出换行(默认100)
|
||||||
printWidth: 100,
|
printWidth: 100,
|
||||||
// 超出打印宽度 (always | never | preserve )
|
// 超出打印宽度 (always | never | preserve )
|
||||||
proseWrap: "preserve",
|
proseWrap: "preserve",
|
||||||
// 对象属性是否使用引号(as-needed | consistent | preserve;默认as-needed:对象的属性需要加引号才添加;)
|
// 对象属性是否使用引号(as-needed | consistent | preserve;默认as-needed:对象的属性需要加引号才添加;)
|
||||||
quoteProps: "as-needed",
|
quoteProps: "as-needed",
|
||||||
// 是否只格式化在文件顶部包含特定注释(@prettier| @format)的文件,默认false
|
// 是否只格式化在文件顶部包含特定注释(@prettier| @format)的文件,默认false
|
||||||
requirePragma: false,
|
requirePragma: false,
|
||||||
// 结尾添加分号
|
// 结尾添加分号
|
||||||
semi: true,
|
semi: true,
|
||||||
// 使用单引号 (true:单引号;false:双引号)
|
// 使用单引号 (true:单引号;false:双引号)
|
||||||
singleQuote: false,
|
singleQuote: true,
|
||||||
// 缩进空格数,默认2个空格
|
// 缩进空格数,默认2个空格
|
||||||
tabWidth: 2,
|
tabWidth: 2,
|
||||||
// 元素末尾是否加逗号,默认es5: ES5中的 objects, arrays 等会添加逗号,TypeScript 中的 type 后不加逗号
|
// 元素末尾是否加逗号,默认es5: ES5中的 objects, arrays 等会添加逗号,TypeScript 中的 type 后不加逗号
|
||||||
trailingComma: "es5",
|
trailingComma: "es5",
|
||||||
// 指定缩进方式,空格或tab,默认false,即使用空格
|
// 指定缩进方式,空格或tab,默认false,即使用空格
|
||||||
useTabs: false,
|
useTabs: false,
|
||||||
// vue 文件中是否缩进 <style> 和 <script> 标签,默认 false
|
// vue 文件中是否缩进 <style> 和 <script> 标签,默认 false
|
||||||
vueIndentScriptAndStyle: false,
|
vueIndentScriptAndStyle: false,
|
||||||
|
|
||||||
endOfLine: "auto",
|
endOfLine: "auto",
|
||||||
overrides: [
|
overrides: [
|
||||||
{
|
{
|
||||||
files: "*.html",
|
files: "*.html",
|
||||||
options: {
|
options: {
|
||||||
parser: "html",
|
parser: "html",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,51 +1,52 @@
|
||||||
import type { BuildOptions } from 'vite';
|
import type { BuildOptions } from 'vite';
|
||||||
|
|
||||||
import { pathResolve } from './utils';
|
import { pathResolve } from './utils';
|
||||||
|
|
||||||
export const buildEnv = (): BuildOptions => {
|
export const buildEnv = (): BuildOptions => {
|
||||||
return {
|
return {
|
||||||
target: 'es2015',
|
target: 'es2015',
|
||||||
assetsInlineLimit: 20000,
|
assetsInlineLimit: 20000,
|
||||||
// 构建输出的目录,默认值为"dist"
|
// 构建输出的目录,默认值为"dist"
|
||||||
outDir: 'docker/dist',
|
outDir: 'docker/dist',
|
||||||
// 用于指定使用的代码压缩工具。在这里,minify 被设置为 'terser',表示使用 Terser 进行代码压缩。默认值terser
|
// 用于指定使用的代码压缩工具。在这里,minify 被设置为 'terser',表示使用 Terser 进行代码压缩。默认值terser
|
||||||
// esbuild 打包更快,但是不能去除 console.log,terser打包慢,但能去除 console.log
|
// esbuild 打包更快,但是不能去除 console.log,terser打包慢,但能去除 console.log
|
||||||
minify: 'terser', // "esbuild"
|
minify: 'terser', // "esbuild"
|
||||||
// 用于配置 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,
|
||||||
// 用于指定是否生成源映射文件。源映射文件可以帮助调试和定位源代码中的错误。当设置为false时,构建过程不会生成源映射文件
|
// 用于指定是否生成源映射文件。源映射文件可以帮助调试和定位源代码中的错误。当设置为false时,构建过程不会生成源映射文件
|
||||||
sourcemap: false,
|
sourcemap: false,
|
||||||
// 用于配置 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,
|
||||||
rollupOptions: {
|
rollupOptions: {
|
||||||
external: ['md-editor-v3', 'echarts'],
|
external: ['md-editor-v3', 'echarts'],
|
||||||
input: {
|
input: {
|
||||||
index: pathResolve('../index.html', import.meta.url),
|
index: pathResolve('../index.html', import.meta.url),
|
||||||
},
|
},
|
||||||
// 静态资源分类打包
|
// 静态资源分类打包
|
||||||
output: {
|
output: {
|
||||||
chunkFileNames: 'static/js/[name]-[hash].js',
|
chunkFileNames: 'static/js/[name]-[hash].js',
|
||||||
entryFileNames: 'static/js/[name]-[hash].js',
|
entryFileNames: 'static/js/[name]-[hash].js',
|
||||||
assetFileNames: 'static/[ext]/[name]-[hash].[ext]',
|
assetFileNames: 'static/[ext]/[name]-[hash].[ext]',
|
||||||
manualChunks: id => {
|
manualChunks: (id) => {
|
||||||
// 如果是包含在包中则打包成 vendor
|
// 如果是包含在包中则打包成 vendor
|
||||||
if (id.includes('node_modules')) {
|
if (id.includes('node_modules')) {
|
||||||
return `vendor`;
|
return `vendor`;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
109
build/cdn.ts
109
build/cdn.ts
|
@ -1,4 +1,5 @@
|
||||||
import { Plugin as importToCDN } from 'vite-plugin-cdn-import';
|
import { Plugin as importToCDN } from 'vite-plugin-cdn-import';
|
||||||
|
|
||||||
import { wrapperEnv } from './utils';
|
import { wrapperEnv } from './utils';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -7,61 +8,61 @@ import { wrapperEnv } from './utils';
|
||||||
* 注意:上面提到的仅限外网使用也不是完全肯定的,如果你们公司内网部署的有相关js、css文件,也可以将下面配置对应改一下,整一套内网版cdn
|
* 注意:上面提到的仅限外网使用也不是完全肯定的,如果你们公司内网部署的有相关js、css文件,也可以将下面配置对应改一下,整一套内网版cdn
|
||||||
*/
|
*/
|
||||||
export const cdn = importToCDN({
|
export const cdn = importToCDN({
|
||||||
//(prodUrl解释: name: 对应下面modules的name,version: 自动读取本地package.json中dependencies依赖中对应包的版本号,path: 对应下面modules的path,当然也可写完整路径,会替换prodUrl)
|
//(prodUrl解释: name: 对应下面modules的name,version: 自动读取本地package.json中dependencies依赖中对应包的版本号,path: 对应下面modules的path,当然也可写完整路径,会替换prodUrl)
|
||||||
// prodUrl: 'https://cdn.bootcdn.net/ajax/libs/{name}/{version}/{path}',
|
// prodUrl: 'https://cdn.bootcdn.net/ajax/libs/{name}/{version}/{path}',
|
||||||
prodUrl: 'https://unpkg.com/{name}@{version}/{path}',
|
prodUrl: 'https://unpkg.com/{name}@{version}/{path}',
|
||||||
modules: [
|
modules: [
|
||||||
{
|
{
|
||||||
name: 'vue',
|
name: 'vue',
|
||||||
var: 'Vue',
|
var: 'Vue',
|
||||||
path: 'dist/vue.global.prod.js',
|
path: 'dist/vue.global.prod.js',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'vue-router',
|
name: 'vue-router',
|
||||||
var: 'VueRouter',
|
var: 'VueRouter',
|
||||||
path: 'dist/vue-router.global.js',
|
path: 'dist/vue-router.global.js',
|
||||||
},
|
},
|
||||||
// {
|
// {
|
||||||
// name: 'vue-i18n',
|
// name: 'vue-i18n',
|
||||||
// var: 'VueI18n',
|
// var: 'VueI18n',
|
||||||
// path: 'dist/vue-i18n.global.prod.js',
|
// path: 'dist/vue-i18n.global.prod.js',
|
||||||
// },
|
// },
|
||||||
// {
|
// {
|
||||||
// name: 'vue-demi',
|
// name: 'vue-demi',
|
||||||
// var: 'VueDemi',
|
// var: 'VueDemi',
|
||||||
// path: 'lib/index.iife.js',
|
// path: 'lib/index.iife.js',
|
||||||
// },
|
// },
|
||||||
{
|
{
|
||||||
name: 'pinia',
|
name: 'pinia',
|
||||||
var: 'Pinia',
|
var: 'Pinia',
|
||||||
path: 'dist/pinia.iife.js',
|
path: 'dist/pinia.iife.js',
|
||||||
},
|
},
|
||||||
// {
|
// {
|
||||||
// name: 'element-plus',
|
// name: 'element-plus',
|
||||||
// var: 'ElementPlus',
|
// var: 'ElementPlus',
|
||||||
// path: 'dist/index.full.js',
|
// path: 'dist/index.full.js',
|
||||||
// css: 'dist/index.css',
|
// css: 'dist/index.css',
|
||||||
// },
|
// },
|
||||||
{
|
{
|
||||||
name: 'axios',
|
name: 'axios',
|
||||||
var: 'axios',
|
var: 'axios',
|
||||||
path: 'dist/axios.min.js',
|
path: 'dist/axios.min.js',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'dayjs',
|
name: 'dayjs',
|
||||||
var: 'dayjs',
|
var: 'dayjs',
|
||||||
path: 'dayjs.min.js',
|
path: 'dayjs.min.js',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'echarts',
|
name: 'echarts',
|
||||||
var: 'echarts',
|
var: 'echarts',
|
||||||
path: 'dist/echarts.min.js',
|
path: 'dist/echarts.min.js',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
/* 是否使用CDN加速 */
|
/* 是否使用CDN加速 */
|
||||||
export const useCDN = mode => {
|
export const useCDN = (mode) => {
|
||||||
const env = wrapperEnv(mode, 'VITE');
|
const env = wrapperEnv(mode, 'VITE');
|
||||||
return env.VITE_CDN ? cdn : null;
|
return env.VITE_CDN ? cdn : null;
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
import postCssPxToViewport8plugin from 'postcss-px-to-viewport-8-plugin';
|
||||||
|
import type { CSSOptions, Plugin } from 'vite';
|
||||||
|
|
||||||
|
import { wrapperEnv } from './utils';
|
||||||
|
|
||||||
|
export const css = (mode): CSSOptions => {
|
||||||
|
const plugins: Plugin[] = [usePostCssPxToViewport8plugin(mode)];
|
||||||
|
|
||||||
|
return {
|
||||||
|
postcss: {
|
||||||
|
plugins: plugins.filter(Boolean),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 是否启用px转换vw插件 */
|
||||||
|
const usePostCssPxToViewport8plugin = (mode): Plugin => {
|
||||||
|
const { VITE_POST_CSS_PX_TO_VIEWPORT8_PLUGIN } = wrapperEnv(mode, 'VITE');
|
||||||
|
|
||||||
|
return VITE_POST_CSS_PX_TO_VIEWPORT8_PLUGIN
|
||||||
|
? postCssPxToViewport8plugin({
|
||||||
|
unitToConvert: 'px',
|
||||||
|
viewportWidth: 1920, // 设计稿的宽度
|
||||||
|
unitPrecision: 5, // 单位转换后保留的精度
|
||||||
|
propList: ['*'], // 能转化为vw的属性列表
|
||||||
|
viewportUnit: 'vw', // 希望使用的视口单位
|
||||||
|
fontViewportUnit: 'vw', // 字体使用的视口单位
|
||||||
|
selectorBlackList: [], // 需要忽略的CSS选择器,不会转为视口单位,使用原有的px等单位。
|
||||||
|
minPixelValue: 1, // 设置最小的转换数值,如果为1的话,只有大于1的值会被转换
|
||||||
|
mediaQuery: true, // 媒体查询里的单位是否需要转换单位
|
||||||
|
replace: true, // 是否直接更换属性值,而不添加备用属性
|
||||||
|
exclude: [/node_modules/], // 忽略某些文件夹下的文件或特定文件,例如 'node_modules' 下的文件
|
||||||
|
include: [], // 如果设置了include,那将只有匹配到的文件才会被转换
|
||||||
|
landscape: false, // 是否添加根据 landscapeWidth 生成的媒体查询条件 @media (orientation: landscape)
|
||||||
|
landscapeUnit: 'vw', // 横屏时使用的单位
|
||||||
|
landscapeWidth: 1024, // 横屏时使用的视口宽度
|
||||||
|
})
|
||||||
|
: null;
|
||||||
|
};
|
|
@ -1,13 +1,14 @@
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
|
|
||||||
import { dependencies, devDependencies, engines, name, version } from '../package.json';
|
import { dependencies, devDependencies, engines, name, version } from '../package.json';
|
||||||
|
|
||||||
const __APP_INFO__ = {
|
const __APP_INFO__ = {
|
||||||
pkg: { name, version, engines, dependencies, devDependencies },
|
pkg: { name, version, engines, dependencies, devDependencies },
|
||||||
lastBuildTime: dayjs(new Date()).format('YYYY-MM-DD HH:mm:ss'),
|
lastBuildTime: dayjs(new Date()).format('YYYY-MM-DD HH:mm:ss'),
|
||||||
};
|
};
|
||||||
|
|
||||||
export const define = () => {
|
export const define = () => {
|
||||||
return {
|
return {
|
||||||
__APP_INFO__: JSON.stringify(__APP_INFO__),
|
__APP_INFO__: JSON.stringify(__APP_INFO__),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,50 +1,56 @@
|
||||||
import { wrapperEnv } from './utils';
|
|
||||||
import dayjs, { type Dayjs } from 'dayjs';
|
|
||||||
import gradientString from 'gradient-string';
|
|
||||||
import duration from 'dayjs/plugin/duration';
|
|
||||||
import boxen, { type Options as BoxenOptions } from 'boxen';
|
import boxen, { type Options as BoxenOptions } from 'boxen';
|
||||||
|
import dayjs, { type Dayjs } from 'dayjs';
|
||||||
|
import duration from 'dayjs/plugin/duration';
|
||||||
|
import gradientString from 'gradient-string';
|
||||||
|
|
||||||
|
import { wrapperEnv } from './utils';
|
||||||
|
|
||||||
dayjs.extend(duration);
|
dayjs.extend(duration);
|
||||||
|
|
||||||
const boxenOptions: BoxenOptions = {
|
const boxenOptions: BoxenOptions = {
|
||||||
padding: 0.94,
|
padding: 0.94,
|
||||||
borderColor: 'cyan',
|
borderColor: 'cyan',
|
||||||
borderStyle: 'round',
|
borderStyle: 'round',
|
||||||
textAlignment: 'left',
|
textAlignment: 'left',
|
||||||
};
|
};
|
||||||
|
|
||||||
/* 输出日志信息 */
|
/* 输出日志信息 */
|
||||||
const printLogMessage = (VITE_PORT: number) => {
|
const printLogMessage = (VITE_PORT: number) => {
|
||||||
return gradientString('cyan', 'magenta').multiline(
|
return gradientString('cyan', 'magenta').multiline(
|
||||||
`保存成功!服务器重新启动
|
`保存成功!服务器重新启动...
|
||||||
项目访问地址如下:
|
项目访问地址如下:
|
||||||
http://localhost:${VITE_PORT}`,
|
http://localhost:${VITE_PORT}`
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const viteConsoleLog = mode => {
|
export const viteConsoleLog = (mode) => {
|
||||||
const { VITE_PORT } = wrapperEnv(mode);
|
const { VITE_PORT } = wrapperEnv(mode);
|
||||||
|
|
||||||
let config: { command: string };
|
let config: { command: string };
|
||||||
let startTime: Dayjs;
|
let startTime: Dayjs;
|
||||||
let endTime: Dayjs;
|
let endTime: Dayjs;
|
||||||
return {
|
return {
|
||||||
name: 'vite:buildInfo',
|
name: 'vite:buildInfo',
|
||||||
configResolved(resolvedConfig) {
|
configResolved(resolvedConfig) {
|
||||||
config = resolvedConfig;
|
config = resolvedConfig;
|
||||||
},
|
},
|
||||||
buildStart() {
|
buildStart() {
|
||||||
console.log(boxen(printLogMessage(VITE_PORT), boxenOptions));
|
console.log(boxen(printLogMessage(VITE_PORT), boxenOptions));
|
||||||
if (config.command === 'build') {
|
if (config.command === 'build') {
|
||||||
startTime = dayjs(new Date());
|
startTime = dayjs(new Date());
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
closeBundle() {
|
closeBundle() {
|
||||||
if (config.command === 'build') {
|
if (config.command === 'build') {
|
||||||
endTime = dayjs(new Date());
|
endTime = dayjs(new Date());
|
||||||
const format = dayjs.duration(endTime.diff(startTime)).format('mm分ss秒');
|
const format = dayjs.duration(endTime.diff(startTime)).format('mm分ss秒');
|
||||||
console.log(boxen(gradientString('cyan', 'magenta').multiline(`🎉 恭喜打包完成(总用时${format})`), boxenOptions));
|
console.log(
|
||||||
}
|
boxen(
|
||||||
},
|
gradientString('cyan', 'magenta').multiline(`🎉 恭喜打包完成(总用时${format})`),
|
||||||
};
|
boxenOptions
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,44 +1,44 @@
|
||||||
|
import UnoCssIcons from '@unocss/preset-icons';
|
||||||
import vue from '@vitejs/plugin-vue';
|
import vue from '@vitejs/plugin-vue';
|
||||||
import type { PluginOption } from 'vite';
|
|
||||||
import vueJsx from '@vitejs/plugin-vue-jsx';
|
import vueJsx from '@vitejs/plugin-vue-jsx';
|
||||||
import Inspector from 'vite-plugin-vue-inspector';
|
import { presetIcons, presetUno } from 'unocss';
|
||||||
import { compressPack, report } from './utils';
|
import UnoCSS from 'unocss/vite';
|
||||||
|
import type { PluginOption } from 'vite';
|
||||||
import removeConsole from 'vite-plugin-remove-console';
|
import removeConsole from 'vite-plugin-remove-console';
|
||||||
|
import Inspector from 'vite-plugin-vue-inspector';
|
||||||
|
|
||||||
import { useCDN } from './cdn';
|
import { useCDN } from './cdn';
|
||||||
import { viteConsoleLog } from './info';
|
import { viteConsoleLog } from './info';
|
||||||
import UnoCSS from 'unocss/vite';
|
import { compressPack, report } from './utils';
|
||||||
import { presetIcons, presetUno } from 'unocss';
|
|
||||||
import UnoCssIcons from '@unocss/preset-icons';
|
|
||||||
|
|
||||||
export const plugins = (mode): PluginOption[] => {
|
export const plugins = (mode): PluginOption[] => {
|
||||||
return [
|
return [
|
||||||
vue(),
|
vue(),
|
||||||
vueJsx(),
|
vueJsx(),
|
||||||
Inspector(),
|
Inspector(),
|
||||||
report(),
|
report(),
|
||||||
removeConsole(),
|
removeConsole(),
|
||||||
useCDN(mode),
|
useCDN(mode),
|
||||||
viteConsoleLog(mode),
|
viteConsoleLog(mode),
|
||||||
UnoCSS({
|
UnoCSS({
|
||||||
hmrTopLevelAwait: false,
|
hmrTopLevelAwait: false,
|
||||||
|
inspector: true, // 控制台是否打印 UnoCSS inspector
|
||||||
presets: [
|
presets: [
|
||||||
presetIcons({
|
presetIcons({
|
||||||
extraProperties: {
|
extraProperties: {
|
||||||
display: 'inline-block',
|
display: 'inline-block',
|
||||||
'vertical-align': 'middle',
|
'vertical-align': 'middle',
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
UnoCssIcons({
|
UnoCssIcons({
|
||||||
// 其他选项
|
prefix: 'i-',
|
||||||
prefix: 'i-',
|
extraProperties: {
|
||||||
extraProperties: {
|
display: 'inline-block',
|
||||||
display: 'inline-block',
|
},
|
||||||
},
|
}),
|
||||||
}),
|
presetUno(),
|
||||||
presetUno(),
|
],
|
||||||
],
|
}),
|
||||||
}),
|
compressPack(mode),
|
||||||
compressPack(mode),
|
];
|
||||||
];
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import { pathResolve } from './utils';
|
import { pathResolve } from './utils';
|
||||||
|
|
||||||
export const resolve = () => {
|
export const resolve = () => {
|
||||||
return {
|
return {
|
||||||
alias: {
|
alias: {
|
||||||
'@': pathResolve('../src'),
|
'@': pathResolve('../src'),
|
||||||
'@build': pathResolve(),
|
'@build': pathResolve(),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,33 +1,34 @@
|
||||||
import type { ServerOptions } from 'vite';
|
import type { ServerOptions } from 'vite';
|
||||||
|
|
||||||
import { wrapperEnv } from './utils';
|
import { wrapperEnv } from './utils';
|
||||||
|
|
||||||
/* 开发服务配置 */
|
/* 开发服务配置 */
|
||||||
export const server = mode => {
|
export const server = (mode) => {
|
||||||
const { VITE_PORT, VITE_APP_URL, VITE_STRICT_PORT } = wrapperEnv(mode);
|
const { VITE_PORT, VITE_APP_URL, VITE_STRICT_PORT } = wrapperEnv(mode);
|
||||||
|
|
||||||
const options: ServerOptions = {
|
const options: ServerOptions = {
|
||||||
strictPort: VITE_STRICT_PORT,
|
strictPort: VITE_STRICT_PORT,
|
||||||
port: VITE_PORT,
|
port: VITE_PORT,
|
||||||
host: '0.0.0.0',
|
host: '0.0.0.0',
|
||||||
open: true,
|
open: true,
|
||||||
cors: true,
|
cors: true,
|
||||||
proxy: {
|
proxy: {
|
||||||
'/api': {
|
'/api': {
|
||||||
target: VITE_APP_URL,
|
target: VITE_APP_URL,
|
||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
rewrite: (path: string) => path.replace(/^\/admin/, '/api'),
|
rewrite: (path: string) => path.replace(/^\/admin/, '/api'),
|
||||||
},
|
},
|
||||||
'/mock': {
|
'/mock': {
|
||||||
target: VITE_APP_URL,
|
target: VITE_APP_URL,
|
||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
rewrite: (path: string) => path.replace(/^\/mock/, '/mock'),
|
rewrite: (path: string) => path.replace(/^\/mock/, '/mock'),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
// 预热文件以提前转换和缓存结果,降低启动期间的初始页面加载时长并防止转换瀑布
|
// 预热文件以提前转换和缓存结果,降低启动期间的初始页面加载时长并防止转换瀑布
|
||||||
warmup: {
|
warmup: {
|
||||||
clientFiles: ['./index.html', './src/{views,components}/*'],
|
clientFiles: ['./index.html', './src/{views,components}/*'],
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
return options;
|
return options;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
import { dirname, resolve } from 'node:path';
|
import { dirname, resolve } from 'node:path';
|
||||||
import { fileURLToPath } from 'node:url';
|
import { fileURLToPath } from 'node:url';
|
||||||
import { loadEnv } from 'vite';
|
|
||||||
import { visualizer } from 'rollup-plugin-visualizer';
|
import { visualizer } from 'rollup-plugin-visualizer';
|
||||||
|
import { loadEnv } from 'vite';
|
||||||
import viteCompression from 'vite-plugin-compression';
|
import viteCompression from 'vite-plugin-compression';
|
||||||
|
|
||||||
export const root: string = process.cwd();
|
export const root: string = process.cwd();
|
||||||
|
@ -12,19 +13,19 @@ export const root: string = process.cwd();
|
||||||
* @param metaUrl 模块的完整`url`,如果在`build`目录外调用必传`import.meta.url`
|
* @param metaUrl 模块的完整`url`,如果在`build`目录外调用必传`import.meta.url`
|
||||||
*/
|
*/
|
||||||
export const pathResolve = (dir = '.', metaUrl = import.meta.url) => {
|
export const pathResolve = (dir = '.', metaUrl = import.meta.url) => {
|
||||||
// 当前文件目录的绝对路径
|
// 当前文件目录的绝对路径
|
||||||
const currentFileDir = dirname(fileURLToPath(metaUrl));
|
const currentFileDir = dirname(fileURLToPath(metaUrl));
|
||||||
// build 目录的绝对路径
|
// build 目录的绝对路径
|
||||||
const buildDir = resolve(currentFileDir, 'build');
|
const buildDir = resolve(currentFileDir, 'build');
|
||||||
// 解析的绝对路径
|
// 解析的绝对路径
|
||||||
const resolvedPath = resolve(currentFileDir, dir);
|
const resolvedPath = resolve(currentFileDir, dir);
|
||||||
// 检查解析的绝对路径是否在 build 目录内
|
// 检查解析的绝对路径是否在 build 目录内
|
||||||
if (resolvedPath.startsWith(buildDir)) {
|
if (resolvedPath.startsWith(buildDir)) {
|
||||||
// 在 build 目录内,返回当前文件路径
|
// 在 build 目录内,返回当前文件路径
|
||||||
return fileURLToPath(metaUrl);
|
return fileURLToPath(metaUrl);
|
||||||
}
|
}
|
||||||
// 不在 build 目录内,返回解析后的绝对路径
|
// 不在 build 目录内,返回解析后的绝对路径
|
||||||
return resolvedPath;
|
return resolvedPath;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -33,32 +34,34 @@ export const pathResolve = (dir = '.', metaUrl = import.meta.url) => {
|
||||||
* @param prefix 需要过滤的前缀
|
* @param prefix 需要过滤的前缀
|
||||||
* @link 参考:https://cn.vite.dev/config/#using-environment-variables-in-config
|
* @link 参考:https://cn.vite.dev/config/#using-environment-variables-in-config
|
||||||
*/
|
*/
|
||||||
export const wrapperEnv = (mode, prefix = ''): ViteEnv => {
|
export const wrapperEnv = (mode, prefix: string = ''): ViteEnv => {
|
||||||
const env = loadEnv(mode, root, prefix);
|
const env = loadEnv(mode, root, prefix);
|
||||||
|
|
||||||
// 将变量转换指定类型
|
// 将变量转换指定类型
|
||||||
for (const envName of Object.keys(env)) {
|
for (const envName of Object.keys(env)) {
|
||||||
let realName = env[envName].replace(/\\n/g, '\n');
|
let realName = env[envName].replace(/\\n/g, '\n');
|
||||||
realName = realName === 'true' ? true : realName === 'false' ? false : realName;
|
realName = realName === 'true' ? true : realName === 'false' ? false : realName;
|
||||||
|
|
||||||
if (envName === 'VITE_PORT') {
|
if (envName === 'VITE_PORT') {
|
||||||
realName = Number(realName);
|
realName = Number(realName);
|
||||||
}
|
}
|
||||||
env[envName] = realName;
|
env[envName] = realName;
|
||||||
process.env[envName] = realName;
|
process.env[envName] = realName;
|
||||||
}
|
}
|
||||||
return env;
|
return env;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* 打包分析 */
|
/* 打包分析 */
|
||||||
export const report = () => {
|
export const report = () => {
|
||||||
const lifecycle = process.env.npm_lifecycle_event;
|
const lifecycle = process.env.npm_lifecycle_event;
|
||||||
return lifecycle === 'report' ? visualizer({ open: true, brotliSize: true, filename: 'report.html' }) : (null as any);
|
return lifecycle === 'report'
|
||||||
|
? visualizer({ open: true, brotliSize: true, filename: 'report.html' })
|
||||||
|
: (null as any);
|
||||||
};
|
};
|
||||||
|
|
||||||
/* 启用gzip压缩 */
|
/* 启用gzip压缩 */
|
||||||
export const compressPack = mode => {
|
export const compressPack = (mode) => {
|
||||||
const { VITE_COMPRESSION } = wrapperEnv(mode);
|
const { VITE_COMPRESSION } = wrapperEnv(mode);
|
||||||
|
|
||||||
return VITE_COMPRESSION == 'gzip' ? viteCompression({ threshold: 1024000 }) : null;
|
return VITE_COMPRESSION == 'gzip' ? viteCompression({ threshold: 1024000 }) : null;
|
||||||
};
|
};
|
||||||
|
|
339
eslint.config.js
339
eslint.config.js
|
@ -1,174 +1,177 @@
|
||||||
import js from '@eslint/js';
|
import js from '@eslint/js';
|
||||||
|
import pluginTypeScript from '@typescript-eslint/eslint-plugin';
|
||||||
|
import * as parserTypeScript from '@typescript-eslint/parser';
|
||||||
|
import configPrettier from 'eslint-config-prettier';
|
||||||
|
import { defineFlatConfig } from 'eslint-define-config';
|
||||||
|
import pluginPrettier from 'eslint-plugin-prettier';
|
||||||
|
import eslintPluginSimpleImportSort from 'eslint-plugin-simple-import-sort';
|
||||||
import pluginVue from 'eslint-plugin-vue';
|
import pluginVue from 'eslint-plugin-vue';
|
||||||
import * as parserVue from 'vue-eslint-parser';
|
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([
|
export default defineFlatConfig([
|
||||||
{
|
{
|
||||||
...js.configs.recommended,
|
...js.configs.recommended,
|
||||||
ignores: ['**/.*', 'dist/*', '*.d.ts', 'public/*', 'src/assets/**', 'src/**/iconfont/**'],
|
ignores: ['**/.*', 'dist/*', '*.d.ts', 'public/*', 'src/assets/**', 'src/**/iconfont/**'],
|
||||||
languageOptions: {
|
languageOptions: {
|
||||||
globals: {
|
globals: {
|
||||||
// index.d.ts
|
// index.d.ts
|
||||||
RefType: 'readonly',
|
RefType: 'readonly',
|
||||||
EmitType: 'readonly',
|
EmitType: 'readonly',
|
||||||
TargetContext: 'readonly',
|
TargetContext: 'readonly',
|
||||||
ComponentRef: 'readonly',
|
ComponentRef: 'readonly',
|
||||||
ElRef: 'readonly',
|
ElRef: 'readonly',
|
||||||
ForDataType: 'readonly',
|
ForDataType: 'readonly',
|
||||||
AnyFunction: 'readonly',
|
AnyFunction: 'readonly',
|
||||||
PropType: 'readonly',
|
PropType: 'readonly',
|
||||||
Writable: 'readonly',
|
Writable: 'readonly',
|
||||||
Nullable: 'readonly',
|
Nullable: 'readonly',
|
||||||
NonNullable: 'readonly',
|
NonNullable: 'readonly',
|
||||||
Recordable: 'readonly',
|
Recordable: 'readonly',
|
||||||
ReadonlyRecordable: 'readonly',
|
ReadonlyRecordable: 'readonly',
|
||||||
Indexable: 'readonly',
|
Indexable: 'readonly',
|
||||||
DeepPartial: 'readonly',
|
DeepPartial: 'readonly',
|
||||||
Without: 'readonly',
|
Without: 'readonly',
|
||||||
Exclusive: 'readonly',
|
Exclusive: 'readonly',
|
||||||
TimeoutHandle: 'readonly',
|
TimeoutHandle: 'readonly',
|
||||||
IntervalHandle: 'readonly',
|
IntervalHandle: 'readonly',
|
||||||
Effect: 'readonly',
|
Effect: 'readonly',
|
||||||
ChangeEvent: 'readonly',
|
ChangeEvent: 'readonly',
|
||||||
WheelEvent: 'readonly',
|
WheelEvent: 'readonly',
|
||||||
ImportMetaEnv: 'readonly',
|
ImportMetaEnv: 'readonly',
|
||||||
Fn: 'readonly',
|
Fn: 'readonly',
|
||||||
PromiseFn: 'readonly',
|
PromiseFn: 'readonly',
|
||||||
ComponentElRef: 'readonly',
|
ComponentElRef: 'readonly',
|
||||||
parseInt: 'readonly',
|
parseInt: 'readonly',
|
||||||
parseFloat: 'readonly',
|
parseFloat: 'readonly',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
plugins: {
|
plugins: {
|
||||||
prettier: pluginPrettier,
|
prettier: pluginPrettier,
|
||||||
},
|
'simple-import-sort': eslintPluginSimpleImportSort,
|
||||||
rules: {
|
},
|
||||||
...configPrettier.rules,
|
rules: {
|
||||||
...pluginPrettier.configs.recommended.rules,
|
...configPrettier.rules,
|
||||||
'no-debugger': 'off',
|
...pluginPrettier.configs.recommended.rules,
|
||||||
'no-unused-vars': [
|
'simple-import-sort/imports': 'error',
|
||||||
'error',
|
'no-debugger': 'off',
|
||||||
{
|
'no-unused-vars': [
|
||||||
argsIgnorePattern: '^_',
|
'error',
|
||||||
varsIgnorePattern: '^_',
|
{
|
||||||
},
|
argsIgnorePattern: '^_',
|
||||||
],
|
varsIgnorePattern: '^_',
|
||||||
'prettier/prettier': [
|
},
|
||||||
'error',
|
],
|
||||||
{
|
'prettier/prettier': [
|
||||||
endOfLine: 'auto',
|
'error',
|
||||||
},
|
{
|
||||||
],
|
endOfLine: 'auto',
|
||||||
},
|
},
|
||||||
},
|
],
|
||||||
{
|
},
|
||||||
files: ['**/*.?([cm])ts', '**/*.?([cm])tsx'],
|
},
|
||||||
languageOptions: {
|
{
|
||||||
parser: parserTypeScript,
|
files: ['**/*.?([cm])ts', '**/*.?([cm])tsx'],
|
||||||
parserOptions: {
|
languageOptions: {
|
||||||
sourceType: 'module',
|
parser: parserTypeScript,
|
||||||
},
|
parserOptions: {
|
||||||
},
|
sourceType: 'module',
|
||||||
plugins: {
|
},
|
||||||
'@typescript-eslint': pluginTypeScript,
|
},
|
||||||
},
|
plugins: {
|
||||||
rules: {
|
'@typescript-eslint': pluginTypeScript,
|
||||||
...pluginTypeScript.configs.strict.rules,
|
},
|
||||||
'@typescript-eslint/ban-types': 'off',
|
rules: {
|
||||||
'@typescript-eslint/no-redeclare': 'error',
|
...pluginTypeScript.configs.strict.rules,
|
||||||
'@typescript-eslint/ban-ts-comment': 'off',
|
'@typescript-eslint/ban-types': 'off',
|
||||||
'@typescript-eslint/no-explicit-any': 'off',
|
'@typescript-eslint/no-redeclare': 'error',
|
||||||
'@typescript-eslint/prefer-as-const': 'warn',
|
'@typescript-eslint/ban-ts-comment': 'off',
|
||||||
'@typescript-eslint/no-empty-function': 'off',
|
'@typescript-eslint/no-explicit-any': 'off',
|
||||||
'@typescript-eslint/no-non-null-assertion': 'off',
|
'@typescript-eslint/prefer-as-const': 'warn',
|
||||||
'@typescript-eslint/no-import-type-side-effects': 'error',
|
'@typescript-eslint/no-empty-function': 'off',
|
||||||
'@typescript-eslint/prefer-literal-enum-member': 'off',
|
'@typescript-eslint/no-non-null-assertion': 'off',
|
||||||
'@typescript-eslint/explicit-module-boundary-types': 'off',
|
'@typescript-eslint/no-import-type-side-effects': 'error',
|
||||||
'@typescript-eslint/consistent-type-imports': [
|
'@typescript-eslint/prefer-literal-enum-member': 'off',
|
||||||
'error',
|
'@typescript-eslint/explicit-module-boundary-types': 'off',
|
||||||
{
|
'@typescript-eslint/consistent-type-imports': [
|
||||||
disallowTypeAnnotations: false,
|
'error',
|
||||||
fixStyle: 'inline-type-imports',
|
{
|
||||||
},
|
disallowTypeAnnotations: false,
|
||||||
],
|
fixStyle: 'inline-type-imports',
|
||||||
'@typescript-eslint/no-unused-vars': [
|
},
|
||||||
'error',
|
],
|
||||||
{
|
'@typescript-eslint/no-unused-vars': [
|
||||||
argsIgnorePattern: '^_',
|
'error',
|
||||||
varsIgnorePattern: '^_',
|
{
|
||||||
},
|
argsIgnorePattern: '^_',
|
||||||
],
|
varsIgnorePattern: '^_',
|
||||||
},
|
},
|
||||||
},
|
],
|
||||||
{
|
},
|
||||||
files: ['**/*.d.ts'],
|
},
|
||||||
rules: {
|
{
|
||||||
'eslint-comments/no-unlimited-disable': 'off',
|
files: ['**/*.d.ts'],
|
||||||
'import/no-duplicates': 'off',
|
rules: {
|
||||||
'unused-imports/no-unused-vars': 'off',
|
'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',
|
files: ['**/*.?([cm])js'],
|
||||||
'@typescript-eslint/no-var-requires': 'off',
|
rules: {
|
||||||
},
|
'@typescript-eslint/no-require-imports': 'off',
|
||||||
},
|
'@typescript-eslint/no-var-requires': 'off',
|
||||||
{
|
},
|
||||||
files: ['**/*.vue'],
|
},
|
||||||
languageOptions: {
|
{
|
||||||
globals: {
|
files: ['**/*.vue'],
|
||||||
$: 'readonly',
|
languageOptions: {
|
||||||
$$: 'readonly',
|
globals: {
|
||||||
$computed: 'readonly',
|
$: 'readonly',
|
||||||
$customRef: 'readonly',
|
$$: 'readonly',
|
||||||
$ref: 'readonly',
|
$computed: 'readonly',
|
||||||
$shallowRef: 'readonly',
|
$customRef: 'readonly',
|
||||||
$toRef: 'readonly',
|
$ref: 'readonly',
|
||||||
},
|
$shallowRef: 'readonly',
|
||||||
parser: parserVue,
|
$toRef: 'readonly',
|
||||||
parserOptions: {
|
},
|
||||||
ecmaFeatures: {
|
parser: parserVue,
|
||||||
jsx: true,
|
parserOptions: {
|
||||||
},
|
ecmaFeatures: {
|
||||||
extraFileExtensions: ['.vue'],
|
jsx: true,
|
||||||
parser: '@typescript-eslint/parser',
|
},
|
||||||
sourceType: 'module',
|
extraFileExtensions: ['.vue'],
|
||||||
},
|
parser: '@typescript-eslint/parser',
|
||||||
},
|
sourceType: 'module',
|
||||||
plugins: {
|
},
|
||||||
vue: pluginVue,
|
},
|
||||||
},
|
plugins: {
|
||||||
processor: pluginVue.processors['.vue'],
|
vue: pluginVue,
|
||||||
rules: {
|
},
|
||||||
...pluginVue.configs.base.rules,
|
processor: pluginVue.processors['.vue'],
|
||||||
...pluginVue.configs['vue3-essential'].rules,
|
rules: {
|
||||||
...pluginVue.configs['vue3-recommended'].rules,
|
...pluginVue.configs.base.rules,
|
||||||
'no-undef': 'off',
|
...pluginVue.configs['vue3-essential'].rules,
|
||||||
'no-unused-vars': 'off',
|
...pluginVue.configs['vue3-recommended'].rules,
|
||||||
'vue/no-v-html': 'off',
|
'no-undef': 'off',
|
||||||
'vue/require-default-prop': 'off',
|
'no-unused-vars': 'off',
|
||||||
'vue/require-explicit-emits': 'off',
|
'vue/no-v-html': 'off',
|
||||||
'vue/multi-word-component-names': 'off',
|
'vue/require-default-prop': 'off',
|
||||||
'vue/no-setup-props-reactivity-loss': 'off',
|
'vue/require-explicit-emits': 'off',
|
||||||
'vue/html-self-closing': [
|
'vue/multi-word-component-names': 'off',
|
||||||
'error',
|
'vue/no-setup-props-reactivity-loss': 'off',
|
||||||
{
|
'vue/html-self-closing': [
|
||||||
html: {
|
'error',
|
||||||
void: 'always',
|
{
|
||||||
normal: 'always',
|
html: {
|
||||||
component: 'always',
|
void: 'always',
|
||||||
},
|
normal: 'always',
|
||||||
svg: 'always',
|
component: 'always',
|
||||||
math: 'always',
|
},
|
||||||
},
|
svg: 'always',
|
||||||
],
|
math: 'always',
|
||||||
},
|
},
|
||||||
},
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
]);
|
]);
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
"lint": "pnpm lint:eslint && pnpm lint:prettier && pnpm lint:stylelint"
|
"lint": "pnpm lint:eslint && pnpm lint:prettier && pnpm lint:stylelint"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@eslint/js": "^9.21.0",
|
||||||
"@typescript-eslint/eslint-plugin": "^8.24.1",
|
"@typescript-eslint/eslint-plugin": "^8.24.1",
|
||||||
"@typescript-eslint/parser": "^8.24.1",
|
"@typescript-eslint/parser": "^8.24.1",
|
||||||
"@unocss/preset-icons": "^66.0.0",
|
"@unocss/preset-icons": "^66.0.0",
|
||||||
|
@ -33,6 +34,7 @@
|
||||||
"nprogress": "^0.2.0",
|
"nprogress": "^0.2.0",
|
||||||
"pinia": "^2.3.1",
|
"pinia": "^2.3.1",
|
||||||
"pinia-plugin-persistedstate": "^3.2.3",
|
"pinia-plugin-persistedstate": "^3.2.3",
|
||||||
|
"postcss-px-to-viewport-8-plugin": "^1.2.5",
|
||||||
"prettier": "^3.3.3",
|
"prettier": "^3.3.3",
|
||||||
"rimraf": "^5.0.10",
|
"rimraf": "^5.0.10",
|
||||||
"rollup-plugin-visualizer": "^5.14.0",
|
"rollup-plugin-visualizer": "^5.14.0",
|
||||||
|
@ -48,6 +50,7 @@
|
||||||
"vite-plugin-remove-console": "^2.2.0",
|
"vite-plugin-remove-console": "^2.2.0",
|
||||||
"vite-plugin-vue-inspector": "^5.3.1",
|
"vite-plugin-vue-inspector": "^5.3.1",
|
||||||
"vue": "^3.5.13",
|
"vue": "^3.5.13",
|
||||||
|
"vue-eslint-parser": "^9.4.3",
|
||||||
"vue-router": "^4.4.3",
|
"vue-router": "^4.4.3",
|
||||||
"vue-types": "^6.0.0"
|
"vue-types": "^6.0.0"
|
||||||
},
|
},
|
||||||
|
@ -55,6 +58,7 @@
|
||||||
"@iconify/json": "^2.2.310",
|
"@iconify/json": "^2.2.310",
|
||||||
"@vitejs/plugin-vue": "^5.2.1",
|
"@vitejs/plugin-vue": "^5.2.1",
|
||||||
"@vue/tsconfig": "^0.7.0",
|
"@vue/tsconfig": "^0.7.0",
|
||||||
|
"eslint-plugin-simple-import-sort": "^12.1.1",
|
||||||
"typescript": "~5.7.2",
|
"typescript": "~5.7.2",
|
||||||
"vite": "^6.1.0",
|
"vite": "^6.1.0",
|
||||||
"vite-plugin-compression": "^0.5.1",
|
"vite-plugin-compression": "^0.5.1",
|
||||||
|
|
121
pnpm-lock.yaml
121
pnpm-lock.yaml
|
@ -8,6 +8,9 @@ importers:
|
||||||
|
|
||||||
.:
|
.:
|
||||||
dependencies:
|
dependencies:
|
||||||
|
'@eslint/js':
|
||||||
|
specifier: ^9.21.0
|
||||||
|
version: 9.21.0
|
||||||
'@typescript-eslint/eslint-plugin':
|
'@typescript-eslint/eslint-plugin':
|
||||||
specifier: ^8.24.1
|
specifier: ^8.24.1
|
||||||
version: 8.24.1(@typescript-eslint/parser@8.24.1(eslint@9.21.0(jiti@2.4.2))(typescript@5.7.3))(eslint@9.21.0(jiti@2.4.2))(typescript@5.7.3)
|
version: 8.24.1(@typescript-eslint/parser@8.24.1(eslint@9.21.0(jiti@2.4.2))(typescript@5.7.3))(eslint@9.21.0(jiti@2.4.2))(typescript@5.7.3)
|
||||||
|
@ -43,16 +46,16 @@ importers:
|
||||||
version: 9.21.0(jiti@2.4.2)
|
version: 9.21.0(jiti@2.4.2)
|
||||||
eslint-config-prettier:
|
eslint-config-prettier:
|
||||||
specifier: ^9.1.0
|
specifier: ^9.1.0
|
||||||
version: 9.1.0(eslint@9.21.0)
|
version: 9.1.0(eslint@9.21.0(jiti@2.4.2))
|
||||||
eslint-define-config:
|
eslint-define-config:
|
||||||
specifier: ^2.1.0
|
specifier: ^2.1.0
|
||||||
version: 2.1.0
|
version: 2.1.0
|
||||||
eslint-plugin-prettier:
|
eslint-plugin-prettier:
|
||||||
specifier: ^5.2.1
|
specifier: ^5.2.1
|
||||||
version: 5.2.3(eslint-config-prettier@9.1.0(eslint@9.21.0))(eslint@9.21.0)(prettier@3.5.2)
|
version: 5.2.3(eslint-config-prettier@9.1.0(eslint@9.21.0(jiti@2.4.2)))(eslint@9.21.0(jiti@2.4.2))(prettier@3.5.2)
|
||||||
eslint-plugin-vue:
|
eslint-plugin-vue:
|
||||||
specifier: ^9.27.0
|
specifier: ^9.27.0
|
||||||
version: 9.32.0(eslint@9.21.0)
|
version: 9.32.0(eslint@9.21.0(jiti@2.4.2))
|
||||||
gradient-string:
|
gradient-string:
|
||||||
specifier: ^3.0.0
|
specifier: ^3.0.0
|
||||||
version: 3.0.0
|
version: 3.0.0
|
||||||
|
@ -71,6 +74,9 @@ importers:
|
||||||
pinia-plugin-persistedstate:
|
pinia-plugin-persistedstate:
|
||||||
specifier: ^3.2.3
|
specifier: ^3.2.3
|
||||||
version: 3.2.3(pinia@2.3.1(typescript@5.7.3)(vue@3.5.13(typescript@5.7.3)))
|
version: 3.2.3(pinia@2.3.1(typescript@5.7.3)(vue@3.5.13(typescript@5.7.3)))
|
||||||
|
postcss-px-to-viewport-8-plugin:
|
||||||
|
specifier: ^1.2.5
|
||||||
|
version: 1.2.5
|
||||||
prettier:
|
prettier:
|
||||||
specifier: ^3.3.3
|
specifier: ^3.3.3
|
||||||
version: 3.5.2
|
version: 3.5.2
|
||||||
|
@ -116,6 +122,9 @@ importers:
|
||||||
vue:
|
vue:
|
||||||
specifier: ^3.5.13
|
specifier: ^3.5.13
|
||||||
version: 3.5.13(typescript@5.7.3)
|
version: 3.5.13(typescript@5.7.3)
|
||||||
|
vue-eslint-parser:
|
||||||
|
specifier: ^9.4.3
|
||||||
|
version: 9.4.3(eslint@9.21.0(jiti@2.4.2))
|
||||||
vue-router:
|
vue-router:
|
||||||
specifier: ^4.4.3
|
specifier: ^4.4.3
|
||||||
version: 4.5.0(vue@3.5.13(typescript@5.7.3))
|
version: 4.5.0(vue@3.5.13(typescript@5.7.3))
|
||||||
|
@ -128,10 +137,13 @@ importers:
|
||||||
version: 2.2.310
|
version: 2.2.310
|
||||||
'@vitejs/plugin-vue':
|
'@vitejs/plugin-vue':
|
||||||
specifier: ^5.2.1
|
specifier: ^5.2.1
|
||||||
version: 5.2.1(vite@6.1.1(sass@1.85.0))(vue@3.5.13(typescript@5.7.3))
|
version: 5.2.1(vite@6.1.1(jiti@2.4.2)(sass@1.85.0)(terser@5.39.0))(vue@3.5.13(typescript@5.7.3))
|
||||||
'@vue/tsconfig':
|
'@vue/tsconfig':
|
||||||
specifier: ^0.7.0
|
specifier: ^0.7.0
|
||||||
version: 0.7.0(typescript@5.7.3)(vue@3.5.13(typescript@5.7.3))
|
version: 0.7.0(typescript@5.7.3)(vue@3.5.13(typescript@5.7.3))
|
||||||
|
eslint-plugin-simple-import-sort:
|
||||||
|
specifier: ^12.1.1
|
||||||
|
version: 12.1.1(eslint@9.21.0(jiti@2.4.2))
|
||||||
typescript:
|
typescript:
|
||||||
specifier: ~5.7.2
|
specifier: ~5.7.2
|
||||||
version: 5.7.3
|
version: 5.7.3
|
||||||
|
@ -1374,6 +1386,11 @@ packages:
|
||||||
eslint-config-prettier:
|
eslint-config-prettier:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
eslint-plugin-simple-import-sort@12.1.1:
|
||||||
|
resolution: {integrity: sha512-6nuzu4xwQtE3332Uz0to+TxDQYRLTKRESSc2hefVT48Zc8JthmN23Gx9lnYhu0FtkRSL1oxny3kJ2aveVhmOVA==}
|
||||||
|
peerDependencies:
|
||||||
|
eslint: '>=5.0.0'
|
||||||
|
|
||||||
eslint-plugin-vue@9.32.0:
|
eslint-plugin-vue@9.32.0:
|
||||||
resolution: {integrity: sha512-b/Y05HYmnB/32wqVcjxjHZzNpwxj1onBOvqW89W+V+XNG1dRuaFbNd3vT9CLbr2LXjEoq+3vn8DanWf7XU22Ug==}
|
resolution: {integrity: sha512-b/Y05HYmnB/32wqVcjxjHZzNpwxj1onBOvqW89W+V+XNG1dRuaFbNd3vT9CLbr2LXjEoq+3vn8DanWf7XU22Ug==}
|
||||||
engines: {node: ^14.17.0 || >=16.0.0}
|
engines: {node: ^14.17.0 || >=16.0.0}
|
||||||
|
@ -1890,6 +1907,10 @@ packages:
|
||||||
nth-check@2.1.1:
|
nth-check@2.1.1:
|
||||||
resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==}
|
resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==}
|
||||||
|
|
||||||
|
object-assign@4.1.1:
|
||||||
|
resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
|
||||||
|
engines: {node: '>=0.10.0'}
|
||||||
|
|
||||||
ofetch@1.4.1:
|
ofetch@1.4.1:
|
||||||
resolution: {integrity: sha512-QZj2DfGplQAr2oj9KzceK9Hwz6Whxazmn85yYeVuS3u9XTMOGMRx0kO95MQ+vLsj/S/NwBDMMLU5hpxvI6Tklw==}
|
resolution: {integrity: sha512-QZj2DfGplQAr2oj9KzceK9Hwz6Whxazmn85yYeVuS3u9XTMOGMRx0kO95MQ+vLsj/S/NwBDMMLU5hpxvI6Tklw==}
|
||||||
|
|
||||||
|
@ -1986,6 +2007,9 @@ packages:
|
||||||
postcss-media-query-parser@0.2.3:
|
postcss-media-query-parser@0.2.3:
|
||||||
resolution: {integrity: sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig==}
|
resolution: {integrity: sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig==}
|
||||||
|
|
||||||
|
postcss-px-to-viewport-8-plugin@1.2.5:
|
||||||
|
resolution: {integrity: sha512-+yc69+q/euV7iKh5fGXY6C/lpepmVx2DGFHeYj5BpzIFyBBpdACDjZyrZ8AV0kCg+J0bplBv4ZA1QTzgaK0rGg==}
|
||||||
|
|
||||||
postcss-resolve-nested-selector@0.1.6:
|
postcss-resolve-nested-selector@0.1.6:
|
||||||
resolution: {integrity: sha512-0sglIs9Wmkzbr8lQwEyIzlDOOC9bGmfVKcJTaxv3vMmd3uo4o4DerC3En0bnmgceeql9BfC8hRkp7cg0fjdVqw==}
|
resolution: {integrity: sha512-0sglIs9Wmkzbr8lQwEyIzlDOOC9bGmfVKcJTaxv3vMmd3uo4o4DerC3En0bnmgceeql9BfC8hRkp7cg0fjdVqw==}
|
||||||
|
|
||||||
|
@ -2849,11 +2873,6 @@ snapshots:
|
||||||
eslint: 9.21.0(jiti@2.4.2)
|
eslint: 9.21.0(jiti@2.4.2)
|
||||||
eslint-visitor-keys: 3.4.3
|
eslint-visitor-keys: 3.4.3
|
||||||
|
|
||||||
'@eslint-community/eslint-utils@4.4.1(eslint@9.21.0)':
|
|
||||||
dependencies:
|
|
||||||
eslint: 9.21.0
|
|
||||||
eslint-visitor-keys: 3.4.3
|
|
||||||
|
|
||||||
'@eslint-community/regexpp@4.12.1': {}
|
'@eslint-community/regexpp@4.12.1': {}
|
||||||
|
|
||||||
'@eslint/config-array@0.19.2':
|
'@eslint/config-array@0.19.2':
|
||||||
|
@ -3342,9 +3361,9 @@ snapshots:
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
'@vitejs/plugin-vue@5.2.1(vite@6.1.1(sass@1.85.0))(vue@3.5.13(typescript@5.7.3))':
|
'@vitejs/plugin-vue@5.2.1(vite@6.1.1(jiti@2.4.2)(sass@1.85.0)(terser@5.39.0))(vue@3.5.13(typescript@5.7.3))':
|
||||||
dependencies:
|
dependencies:
|
||||||
vite: 6.1.1(sass@1.85.0)
|
vite: 6.1.1(jiti@2.4.2)(sass@1.85.0)(terser@5.39.0)
|
||||||
vue: 3.5.13(typescript@5.7.3)
|
vue: 3.5.13(typescript@5.7.3)
|
||||||
|
|
||||||
'@volar/language-core@2.4.11':
|
'@volar/language-core@2.4.11':
|
||||||
|
@ -3797,31 +3816,35 @@ snapshots:
|
||||||
|
|
||||||
escape-string-regexp@4.0.0: {}
|
escape-string-regexp@4.0.0: {}
|
||||||
|
|
||||||
eslint-config-prettier@9.1.0(eslint@9.21.0):
|
eslint-config-prettier@9.1.0(eslint@9.21.0(jiti@2.4.2)):
|
||||||
dependencies:
|
dependencies:
|
||||||
eslint: 9.21.0
|
eslint: 9.21.0(jiti@2.4.2)
|
||||||
|
|
||||||
eslint-define-config@2.1.0: {}
|
eslint-define-config@2.1.0: {}
|
||||||
|
|
||||||
eslint-plugin-prettier@5.2.3(eslint-config-prettier@9.1.0(eslint@9.21.0))(eslint@9.21.0)(prettier@3.5.2):
|
eslint-plugin-prettier@5.2.3(eslint-config-prettier@9.1.0(eslint@9.21.0(jiti@2.4.2)))(eslint@9.21.0(jiti@2.4.2))(prettier@3.5.2):
|
||||||
dependencies:
|
dependencies:
|
||||||
eslint: 9.21.0
|
eslint: 9.21.0(jiti@2.4.2)
|
||||||
prettier: 3.5.2
|
prettier: 3.5.2
|
||||||
prettier-linter-helpers: 1.0.0
|
prettier-linter-helpers: 1.0.0
|
||||||
synckit: 0.9.2
|
synckit: 0.9.2
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
eslint-config-prettier: 9.1.0(eslint@9.21.0)
|
eslint-config-prettier: 9.1.0(eslint@9.21.0(jiti@2.4.2))
|
||||||
|
|
||||||
eslint-plugin-vue@9.32.0(eslint@9.21.0):
|
eslint-plugin-simple-import-sort@12.1.1(eslint@9.21.0(jiti@2.4.2)):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@eslint-community/eslint-utils': 4.4.1(eslint@9.21.0)
|
eslint: 9.21.0(jiti@2.4.2)
|
||||||
eslint: 9.21.0
|
|
||||||
|
eslint-plugin-vue@9.32.0(eslint@9.21.0(jiti@2.4.2)):
|
||||||
|
dependencies:
|
||||||
|
'@eslint-community/eslint-utils': 4.4.1(eslint@9.21.0(jiti@2.4.2))
|
||||||
|
eslint: 9.21.0(jiti@2.4.2)
|
||||||
globals: 13.24.0
|
globals: 13.24.0
|
||||||
natural-compare: 1.4.0
|
natural-compare: 1.4.0
|
||||||
nth-check: 2.1.1
|
nth-check: 2.1.1
|
||||||
postcss-selector-parser: 6.1.2
|
postcss-selector-parser: 6.1.2
|
||||||
semver: 7.7.1
|
semver: 7.7.1
|
||||||
vue-eslint-parser: 9.4.3(eslint@9.21.0)
|
vue-eslint-parser: 9.4.3(eslint@9.21.0(jiti@2.4.2))
|
||||||
xml-name-validator: 4.0.0
|
xml-name-validator: 4.0.0
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
@ -3840,45 +3863,6 @@ snapshots:
|
||||||
|
|
||||||
eslint-visitor-keys@4.2.0: {}
|
eslint-visitor-keys@4.2.0: {}
|
||||||
|
|
||||||
eslint@9.21.0:
|
|
||||||
dependencies:
|
|
||||||
'@eslint-community/eslint-utils': 4.4.1(eslint@9.21.0)
|
|
||||||
'@eslint-community/regexpp': 4.12.1
|
|
||||||
'@eslint/config-array': 0.19.2
|
|
||||||
'@eslint/core': 0.12.0
|
|
||||||
'@eslint/eslintrc': 3.3.0
|
|
||||||
'@eslint/js': 9.21.0
|
|
||||||
'@eslint/plugin-kit': 0.2.7
|
|
||||||
'@humanfs/node': 0.16.6
|
|
||||||
'@humanwhocodes/module-importer': 1.0.1
|
|
||||||
'@humanwhocodes/retry': 0.4.2
|
|
||||||
'@types/estree': 1.0.6
|
|
||||||
'@types/json-schema': 7.0.15
|
|
||||||
ajv: 6.12.6
|
|
||||||
chalk: 4.1.2
|
|
||||||
cross-spawn: 7.0.6
|
|
||||||
debug: 4.4.0
|
|
||||||
escape-string-regexp: 4.0.0
|
|
||||||
eslint-scope: 8.2.0
|
|
||||||
eslint-visitor-keys: 4.2.0
|
|
||||||
espree: 10.3.0
|
|
||||||
esquery: 1.6.0
|
|
||||||
esutils: 2.0.3
|
|
||||||
fast-deep-equal: 3.1.3
|
|
||||||
file-entry-cache: 8.0.0
|
|
||||||
find-up: 5.0.0
|
|
||||||
glob-parent: 6.0.2
|
|
||||||
ignore: 5.3.2
|
|
||||||
imurmurhash: 0.1.4
|
|
||||||
is-glob: 4.0.3
|
|
||||||
json-stable-stringify-without-jsonify: 1.0.1
|
|
||||||
lodash.merge: 4.6.2
|
|
||||||
minimatch: 3.1.2
|
|
||||||
natural-compare: 1.4.0
|
|
||||||
optionator: 0.9.4
|
|
||||||
transitivePeerDependencies:
|
|
||||||
- supports-color
|
|
||||||
|
|
||||||
eslint@9.21.0(jiti@2.4.2):
|
eslint@9.21.0(jiti@2.4.2):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@eslint-community/eslint-utils': 4.4.1(eslint@9.21.0(jiti@2.4.2))
|
'@eslint-community/eslint-utils': 4.4.1(eslint@9.21.0(jiti@2.4.2))
|
||||||
|
@ -4347,6 +4331,8 @@ snapshots:
|
||||||
dependencies:
|
dependencies:
|
||||||
boolbase: 1.0.0
|
boolbase: 1.0.0
|
||||||
|
|
||||||
|
object-assign@4.1.1: {}
|
||||||
|
|
||||||
ofetch@1.4.1:
|
ofetch@1.4.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
destr: 2.0.3
|
destr: 2.0.3
|
||||||
|
@ -4445,6 +4431,10 @@ snapshots:
|
||||||
|
|
||||||
postcss-media-query-parser@0.2.3: {}
|
postcss-media-query-parser@0.2.3: {}
|
||||||
|
|
||||||
|
postcss-px-to-viewport-8-plugin@1.2.5:
|
||||||
|
dependencies:
|
||||||
|
object-assign: 4.1.1
|
||||||
|
|
||||||
postcss-resolve-nested-selector@0.1.6: {}
|
postcss-resolve-nested-selector@0.1.6: {}
|
||||||
|
|
||||||
postcss-safe-parser@6.0.0(postcss@8.5.3):
|
postcss-safe-parser@6.0.0(postcss@8.5.3):
|
||||||
|
@ -4924,25 +4914,16 @@ snapshots:
|
||||||
sass: 1.85.0
|
sass: 1.85.0
|
||||||
terser: 5.39.0
|
terser: 5.39.0
|
||||||
|
|
||||||
vite@6.1.1(sass@1.85.0):
|
|
||||||
dependencies:
|
|
||||||
esbuild: 0.24.2
|
|
||||||
postcss: 8.5.3
|
|
||||||
rollup: 4.34.8
|
|
||||||
optionalDependencies:
|
|
||||||
fsevents: 2.3.3
|
|
||||||
sass: 1.85.0
|
|
||||||
|
|
||||||
vscode-uri@3.1.0: {}
|
vscode-uri@3.1.0: {}
|
||||||
|
|
||||||
vue-demi@0.14.10(vue@3.5.13(typescript@5.7.3)):
|
vue-demi@0.14.10(vue@3.5.13(typescript@5.7.3)):
|
||||||
dependencies:
|
dependencies:
|
||||||
vue: 3.5.13(typescript@5.7.3)
|
vue: 3.5.13(typescript@5.7.3)
|
||||||
|
|
||||||
vue-eslint-parser@9.4.3(eslint@9.21.0):
|
vue-eslint-parser@9.4.3(eslint@9.21.0(jiti@2.4.2)):
|
||||||
dependencies:
|
dependencies:
|
||||||
debug: 4.4.0
|
debug: 4.4.0
|
||||||
eslint: 9.21.0
|
eslint: 9.21.0(jiti@2.4.2)
|
||||||
eslint-scope: 7.2.2
|
eslint-scope: 7.2.2
|
||||||
eslint-visitor-keys: 3.4.3
|
eslint-visitor-keys: 3.4.3
|
||||||
espree: 9.6.1
|
espree: 9.6.1
|
||||||
|
|
14
src/App.vue
14
src/App.vue
|
@ -1,22 +1,22 @@
|
||||||
<script lang="ts" setup></script>
|
<script lang="ts" setup></script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<router-view />
|
<router-view />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.logo {
|
.logo {
|
||||||
height: 6em;
|
height: 6em;
|
||||||
padding: 1.5em;
|
padding: 1.5em;
|
||||||
will-change: filter;
|
will-change: filter;
|
||||||
transition: filter 300ms;
|
transition: filter 300ms;
|
||||||
}
|
}
|
||||||
|
|
||||||
.logo:hover {
|
.logo:hover {
|
||||||
filter: drop-shadow(0 0 2em #646cffaa);
|
filter: drop-shadow(0 0 2em #646cffaa);
|
||||||
}
|
}
|
||||||
|
|
||||||
.logo.vue:hover {
|
.logo.vue:hover {
|
||||||
filter: drop-shadow(0 0 2em #42b883aa);
|
filter: drop-shadow(0 0 2em #42b883aa);
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
<script setup lang="ts">
|
<script lang="ts" setup>
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue';
|
||||||
|
|
||||||
defineProps<{ msg: string }>()
|
defineProps<{ msg: string }>();
|
||||||
|
|
||||||
const count = ref(0)
|
const count = ref(0);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
@ -13,23 +13,22 @@ const count = ref(0)
|
||||||
<button type="button" @click="count++">count is {{ count }}</button>
|
<button type="button" @click="count++">count is {{ count }}</button>
|
||||||
<p>
|
<p>
|
||||||
Edit
|
Edit
|
||||||
<code>components/HelloWorld.vue</code> to test HMR
|
<code>components/HelloWorld.vue</code>
|
||||||
|
to test HMR
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Check out
|
Check out
|
||||||
<a href="https://vuejs.org/guide/quick-start.html#local" target="_blank"
|
<a href="https://vuejs.org/guide/quick-start.html#local" target="_blank">create-vue</a>
|
||||||
>create-vue</a
|
, the official Vue + Vite starter
|
||||||
>, the official Vue + Vite starter
|
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
Learn more about IDE Support for Vue in the
|
Learn more about IDE Support for Vue in the
|
||||||
<a
|
<a href="https://vuejs.org/guide/scaling-up/tooling.html#ide-support" target="_blank">
|
||||||
href="https://vuejs.org/guide/scaling-up/tooling.html#ide-support"
|
Vue Docs Scaling up Guide
|
||||||
target="_blank"
|
</a>
|
||||||
>Vue Docs Scaling up Guide</a
|
.
|
||||||
>.
|
|
||||||
</p>
|
</p>
|
||||||
<p class="read-the-docs">Click on the Vite and Vue logos to learn more</p>
|
<p class="read-the-docs">Click on the Vite and Vue logos to learn more</p>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -2,5 +2,5 @@ import type { App } from 'vue';
|
||||||
|
|
||||||
// 全局注册 directive
|
// 全局注册 directive
|
||||||
export function setupDirective(app: App<Element>) {
|
export function setupDirective(app: App<Element>) {
|
||||||
// 使 v-hasPerm 在所有组件中都可用
|
// 使 v-hasPerm 在所有组件中都可用
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,26 +1,27 @@
|
||||||
<script lang="ts" setup></script>
|
<script lang="ts" setup></script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="w-full flex items-center justify-center flex-wrap gap-x-4 text-4xl p-2 mt-4">
|
<div class="w-full flex items-center justify-center flex-wrap gap-x-4 text-4xl p-2 mt-4">
|
||||||
<div class="w-full flex items-center justify-center mb-4">
|
<div class="w-full flex items-center justify-center mb-4">
|
||||||
<button>清除默认样式的按钮</button>
|
<button>清除默认样式的按钮</button>
|
||||||
</div>
|
<div class="w-[100px] h-[100px] bg-green" />
|
||||||
<div class="i-ph-anchor-simple-thin" />
|
</div>
|
||||||
<!-- 来自 Phosphor 图标的基本锚点图标 -->
|
<div class="i-ph-anchor-simple-thin" />
|
||||||
<div class="i-ph-anchor-simple-thin" />
|
<!-- 来自 Phosphor 图标的基本锚点图标 -->
|
||||||
<!-- 来自 Material Design Icons 的一个橙色闹钟 -->
|
<div class="i-ph-anchor-simple-thin" />
|
||||||
<div class="i-mdi-alarm text-orange-400" />
|
<!-- 来自 Material Design Icons 的一个橙色闹钟 -->
|
||||||
<!-- 一个大尺寸的 Vue 标志 -->
|
<div class="i-mdi-alarm text-orange-400" />
|
||||||
<div class="i-logos-vue text-3xl" />
|
<!-- 一个大尺寸的 Vue 标志 -->
|
||||||
<!-- 太阳在亮模式,月亮在暗模式,来自 Carbon -->
|
<div class="i-logos-vue text-3xl" />
|
||||||
<button class="i-carbon-sun dark:i-carbon-moon" />
|
<!-- 太阳在亮模式,月亮在暗模式,来自 Carbon -->
|
||||||
<!-- Twemoji 笑脸,悬停时变成流泪表情 -->
|
<button class="i-carbon-sun dark:i-carbon-moon" />
|
||||||
<div class="i-twemoji-grinning-face-with-smiling-eyes hover:i-twemoji-face-with-tears-of-joy" />
|
<!-- Twemoji 笑脸,悬停时变成流泪表情 -->
|
||||||
<div class="i-vscode-icons:file-type-light-pnpm" />
|
<div class="i-twemoji-grinning-face-with-smiling-eyes hover:i-twemoji-face-with-tears-of-joy" />
|
||||||
<div class="i-vscode-icons:file-type-light-pnpm?mask text-red-300" />
|
<div class="i-vscode-icons:file-type-light-pnpm" />
|
||||||
<span class="i-ic:baseline-16mp" />
|
<div class="i-vscode-icons:file-type-light-pnpm?mask text-red-300" />
|
||||||
<span class="i-vscode-icons:file-type-java" />
|
<span class="i-ic:baseline-16mp" />
|
||||||
</div>
|
<span class="i-vscode-icons:file-type-java" />
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped></style>
|
<style scoped></style>
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
import { createApp } from 'vue';
|
|
||||||
import 'animate.css';
|
import 'animate.css';
|
||||||
import App from './App.vue';
|
|
||||||
import plugins from '@/plugins';
|
|
||||||
import '@unocss/reset/tailwind-compat.css';
|
import '@unocss/reset/tailwind-compat.css';
|
||||||
import 'uno.css';
|
import 'uno.css';
|
||||||
import 'virtual:unocss-devtools';
|
import 'virtual:unocss-devtools';
|
||||||
|
|
||||||
|
import { createApp } from 'vue';
|
||||||
|
|
||||||
|
import plugins from '@/plugins';
|
||||||
|
|
||||||
|
import App from './App.vue';
|
||||||
|
|
||||||
createApp(App).use(plugins).mount('#app');
|
createApp(App).use(plugins).mount('#app');
|
||||||
|
|
|
@ -1,15 +1,16 @@
|
||||||
import type { App } from 'vue';
|
import type { App } from 'vue';
|
||||||
|
|
||||||
import { setupDirective } from '@/directive';
|
import { setupDirective } from '@/directive';
|
||||||
import { setUpRouter } from '@/router';
|
import { setUpRouter } from '@/router';
|
||||||
import { setupStore } from '@/store';
|
import { setupStore } from '@/store';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
install(app: App<Element>) {
|
install(app: App<Element>) {
|
||||||
// 设置路由
|
// 设置路由
|
||||||
setUpRouter(app);
|
setUpRouter(app);
|
||||||
// 设置状态管理
|
// 设置状态管理
|
||||||
setupStore(app);
|
setupStore(app);
|
||||||
// 设置指令
|
// 设置指令
|
||||||
setupDirective(app);
|
setupDirective(app);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -5,57 +5,57 @@ export const Layout = () => import('@/layout/index.vue');
|
||||||
|
|
||||||
// 静态路由
|
// 静态路由
|
||||||
const routes: RouteRecordRaw[] = [
|
const routes: RouteRecordRaw[] = [
|
||||||
{
|
{
|
||||||
path: '/redirect',
|
path: '/redirect',
|
||||||
component: Layout,
|
component: Layout,
|
||||||
meta: { hidden: true },
|
meta: { hidden: true },
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: '/redirect/:path(.*)',
|
path: '/redirect/:path(.*)',
|
||||||
component: () => import('@/views/redirect/index.vue'),
|
component: () => import('@/views/redirect/index.vue'),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/',
|
path: '/',
|
||||||
name: '/',
|
name: '/',
|
||||||
component: Layout,
|
component: Layout,
|
||||||
// redirect: '/dashboard',
|
// redirect: '/dashboard',
|
||||||
children: [
|
children: [
|
||||||
// {
|
// {
|
||||||
// path: 'dashboard',
|
// path: 'dashboard',
|
||||||
// component: () => import('@/views/index.vue'),
|
// component: () => import('@/views/index.vue'),
|
||||||
// // 用于 keep-alive 功能,需要与 SFC 中自动推导或显式声明的组件名称一致
|
// // 用于 keep-alive 功能,需要与 SFC 中自动推导或显式声明的组件名称一致
|
||||||
// // 参考文档: https://cn.vuejs.org/guide/built-ins/keep-alive.html#include-exclude
|
// // 参考文档: https://cn.vuejs.org/guide/built-ins/keep-alive.html#include-exclude
|
||||||
// name: 'Dashboard',
|
// name: 'Dashboard',
|
||||||
// meta: {
|
// meta: {
|
||||||
// title: 'dashboard',
|
// title: 'dashboard',
|
||||||
// icon: 'homepage',
|
// icon: 'homepage',
|
||||||
// affix: true,
|
// affix: true,
|
||||||
// keepAlive: true,
|
// keepAlive: true,
|
||||||
// },
|
// },
|
||||||
// },
|
// },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/404',
|
path: '/404',
|
||||||
component: () => import('@/views/error-page/404.vue'),
|
component: () => import('@/views/error-page/404.vue'),
|
||||||
meta: { hidden: true },
|
meta: { hidden: true },
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
const router = createRouter({
|
const router = createRouter({
|
||||||
history: createWebHashHistory(),
|
history: createWebHashHistory(),
|
||||||
routes,
|
routes,
|
||||||
scrollBehavior: () => ({ x: 0, y: 0 }),
|
scrollBehavior: () => ({ x: 0, y: 0 }),
|
||||||
});
|
});
|
||||||
|
|
||||||
/** 全局注册 router */
|
/** 全局注册 router */
|
||||||
export const setUpRouter = (app: App<Element>) => {
|
export const setUpRouter = (app: App<Element>) => {
|
||||||
app.use(router);
|
app.use(router);
|
||||||
};
|
};
|
||||||
|
|
||||||
/** 重置路由 */
|
/** 重置路由 */
|
||||||
export const resetRouter = () => {
|
export const resetRouter = () => {
|
||||||
router.replace({ path: '/' }).then();
|
router.replace({ path: '/' }).then();
|
||||||
};
|
};
|
||||||
export default router;
|
export default router;
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import type { App } from 'vue';
|
|
||||||
import { createPinia } from 'pinia';
|
import { createPinia } from 'pinia';
|
||||||
|
import type { App } from 'vue';
|
||||||
|
|
||||||
const store = createPinia();
|
const store = createPinia();
|
||||||
|
|
||||||
// 全局注册 store
|
// 全局注册 store
|
||||||
export function setupStore(app: App<Element>) {
|
export function setupStore(app: App<Element>) {
|
||||||
app.use(store);
|
app.use(store);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
declare global {
|
declare global {
|
||||||
/* 环境便配置 */
|
/* 环境便配置 */
|
||||||
declare interface ViteEnv {
|
declare interface ViteEnv {
|
||||||
VITE_APP_TITLE: string;
|
VITE_APP_TITLE: string;
|
||||||
VITE_PORT: number;
|
VITE_PORT: number;
|
||||||
VITE_PUBLIC_PATH: string;
|
VITE_PUBLIC_PATH: string;
|
||||||
VITE_APP_URL: string;
|
VITE_APP_URL: string;
|
||||||
VITE_STRICT_PORT: boolean;
|
VITE_STRICT_PORT: boolean;
|
||||||
VITE_CDN: boolean;
|
VITE_POST_CSS_PX_TO_VIEWPORT8_PLUGIN: boolean;
|
||||||
VITE_COMPRESSION: string;
|
VITE_CDN: boolean;
|
||||||
}
|
VITE_COMPRESSION: string;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,18 +1,19 @@
|
||||||
import NProgress from 'nprogress';
|
|
||||||
import 'nprogress/nprogress.css';
|
import 'nprogress/nprogress.css';
|
||||||
|
|
||||||
|
import NProgress from 'nprogress';
|
||||||
|
|
||||||
// 进度条
|
// 进度条
|
||||||
NProgress.configure({
|
NProgress.configure({
|
||||||
// 动画方式
|
// 动画方式
|
||||||
easing: 'ease',
|
easing: 'ease',
|
||||||
// 递增进度条的速度
|
// 递增进度条的速度
|
||||||
speed: 500,
|
speed: 500,
|
||||||
// 是否显示加载ico
|
// 是否显示加载ico
|
||||||
showSpinner: false,
|
showSpinner: false,
|
||||||
// 自动递增间隔
|
// 自动递增间隔
|
||||||
trickleSpeed: 200,
|
trickleSpeed: 200,
|
||||||
// 初始化时的最小百分比
|
// 初始化时的最小百分比
|
||||||
minimum: 0.3,
|
minimum: 0.3,
|
||||||
});
|
});
|
||||||
|
|
||||||
export default NProgress;
|
export default NProgress;
|
||||||
|
|
|
@ -1,70 +1,71 @@
|
||||||
import axios, { type AxiosResponse, type InternalAxiosRequestConfig } from 'axios';
|
import axios, { type AxiosResponse, type InternalAxiosRequestConfig } from 'axios';
|
||||||
import { useUserStoreHook } from '@/store/modules/user';
|
|
||||||
import { ResultEnum } from '@/enums/ResultEnum';
|
|
||||||
import { TOKEN_KEY } from '@/enums/CacheEnum';
|
|
||||||
import qs from 'qs';
|
import qs from 'qs';
|
||||||
|
|
||||||
|
import { TOKEN_KEY } from '@/enums/CacheEnum';
|
||||||
|
import { ResultEnum } from '@/enums/ResultEnum';
|
||||||
|
import { useUserStoreHook } from '@/store/modules/user';
|
||||||
|
|
||||||
// 创建 axios 实例
|
// 创建 axios 实例
|
||||||
const service = axios.create({
|
const service = axios.create({
|
||||||
baseURL: import.meta.env.VITE_APP_BASE_API,
|
baseURL: import.meta.env.VITE_APP_BASE_API,
|
||||||
timeout: 50000,
|
timeout: 50000,
|
||||||
headers: { 'Content-Type': 'application/json;charset=utf-8' },
|
headers: { 'Content-Type': 'application/json;charset=utf-8' },
|
||||||
paramsSerializer: params => {
|
paramsSerializer: (params) => {
|
||||||
return qs.stringify(params);
|
return qs.stringify(params);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
// 请求拦截器
|
// 请求拦截器
|
||||||
service.interceptors.request.use(
|
service.interceptors.request.use(
|
||||||
(config: InternalAxiosRequestConfig) => {
|
(config: InternalAxiosRequestConfig) => {
|
||||||
const accessToken = localStorage.getItem(TOKEN_KEY);
|
const accessToken = localStorage.getItem(TOKEN_KEY);
|
||||||
if (accessToken) {
|
if (accessToken) {
|
||||||
config.headers.Authorization = accessToken;
|
config.headers.Authorization = accessToken;
|
||||||
}
|
}
|
||||||
return config;
|
return config;
|
||||||
},
|
},
|
||||||
(error: any) => {
|
(error: any) => {
|
||||||
return Promise.reject(error);
|
return Promise.reject(error);
|
||||||
},
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
// 响应拦截器
|
// 响应拦截器
|
||||||
service.interceptors.response.use(
|
service.interceptors.response.use(
|
||||||
(response: AxiosResponse) => {
|
(response: AxiosResponse) => {
|
||||||
// 检查配置的响应类型是否为二进制类型('blob' 或 'arraybuffer'), 如果是,直接返回响应对象
|
// 检查配置的响应类型是否为二进制类型('blob' 或 'arraybuffer'), 如果是,直接返回响应对象
|
||||||
if (response.config.responseType === 'blob' || response.config.responseType === 'arraybuffer') {
|
if (response.config.responseType === 'blob' || response.config.responseType === 'arraybuffer') {
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { code, data, msg } = response.data;
|
const { code, data, msg } = response.data;
|
||||||
if (code === ResultEnum.SUCCESS) {
|
if (code === ResultEnum.SUCCESS) {
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
ElMessage.error(msg || '系统出错');
|
ElMessage.error(msg || '系统出错');
|
||||||
return Promise.reject(new Error(msg || 'Error'));
|
return Promise.reject(new Error(msg || 'Error'));
|
||||||
},
|
},
|
||||||
(error: any) => {
|
(error: any) => {
|
||||||
// 异常处理
|
// 异常处理
|
||||||
if (error.response.data) {
|
if (error.response.data) {
|
||||||
const { code, msg } = error.response.data;
|
const { code, msg } = error.response.data;
|
||||||
if (code === ResultEnum.TOKEN_INVALID) {
|
if (code === ResultEnum.TOKEN_INVALID) {
|
||||||
ElNotification({
|
ElNotification({
|
||||||
title: '提示',
|
title: '提示',
|
||||||
message: '您的会话已过期,请重新登录',
|
message: '您的会话已过期,请重新登录',
|
||||||
type: 'info',
|
type: 'info',
|
||||||
});
|
});
|
||||||
useUserStoreHook()
|
useUserStoreHook()
|
||||||
.resetToken()
|
.resetToken()
|
||||||
.then(() => {
|
.then(() => {
|
||||||
location.reload();
|
location.reload();
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
ElMessage.error(msg || '系统出错');
|
ElMessage.error(msg || '系统出错');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Promise.reject(error.message);
|
return Promise.reject(error.message);
|
||||||
},
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
// 导出 axios 实例
|
// 导出 axios 实例
|
||||||
|
|
|
@ -5,228 +5,233 @@ const router = useRouter();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="page-container">
|
<div class="page-container">
|
||||||
<div class="pic-404">
|
<div class="pic-404">
|
||||||
<img alt="404" class="pic-404__parent" src="@/assets/images/404.png" />
|
<img alt="404" class="pic-404__parent" src="@/assets/images/404.png" />
|
||||||
<img alt="404" class="pic-404__child left" src="@/assets/images/404_cloud.png" />
|
<img alt="404" class="pic-404__child left" src="@/assets/images/404_cloud.png" />
|
||||||
<img alt="404" class="pic-404__child mid" src="@/assets/images/404_cloud.png" />
|
<img alt="404" class="pic-404__child mid" src="@/assets/images/404_cloud.png" />
|
||||||
<img alt="404" class="pic-404__child right" src="@/assets/images/404_cloud.png" />
|
<img alt="404" class="pic-404__child right" src="@/assets/images/404_cloud.png" />
|
||||||
</div>
|
</div>
|
||||||
<div class="bullshit">
|
<div class="bullshit">
|
||||||
<div class="bullshit__oops">OOPS!</div>
|
<div class="bullshit__oops">OOPS!</div>
|
||||||
<div class="bullshit__info">
|
<div class="bullshit__info">
|
||||||
All rights reserved
|
All rights reserved
|
||||||
<a href="https://wallstreetcn.com" style="color: #20a0ff" target="_blank">wallstreetcn</a>
|
<a href="https://wallstreetcn.com" style="color: #20a0ff" target="_blank">wallstreetcn</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="bullshit__headline">The webmaster said that you can not enter this page...</div>
|
<div class="bullshit__headline">The webmaster said that you can not enter this page...</div>
|
||||||
<div class="bullshit__info">Please check that the URL you entered is correct, or click the button below to return to the homepage.</div>
|
<div class="bullshit__info">
|
||||||
<a class="bullshit__return-home" href="/" @click.prevent="router.replace('/')"> Back to home </a>
|
Please check that the URL you entered is correct, or click the button below to return to the
|
||||||
</div>
|
homepage.
|
||||||
</div>
|
</div>
|
||||||
|
<a class="bullshit__return-home" href="/" @click.prevent="router.replace('/')">
|
||||||
|
Back to home
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.page-container {
|
.page-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
padding: 100px;
|
padding: 100px;
|
||||||
|
|
||||||
.pic-404 {
|
.pic-404 {
|
||||||
width: 600px;
|
width: 600px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
&__parent {
|
&__parent {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
&__child {
|
&__child {
|
||||||
&.left {
|
&.left {
|
||||||
top: 17px;
|
top: 17px;
|
||||||
left: 220px;
|
left: 220px;
|
||||||
width: 80px;
|
width: 80px;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
animation-name: cloudLeft;
|
animation-name: cloudLeft;
|
||||||
animation-duration: 2s;
|
animation-duration: 2s;
|
||||||
animation-timing-function: linear;
|
animation-timing-function: linear;
|
||||||
animation-delay: 1s;
|
animation-delay: 1s;
|
||||||
animation-fill-mode: forwards;
|
animation-fill-mode: forwards;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.mid {
|
&.mid {
|
||||||
top: 10px;
|
top: 10px;
|
||||||
left: 420px;
|
left: 420px;
|
||||||
width: 46px;
|
width: 46px;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
animation-name: cloudMid;
|
animation-name: cloudMid;
|
||||||
animation-duration: 2s;
|
animation-duration: 2s;
|
||||||
animation-timing-function: linear;
|
animation-timing-function: linear;
|
||||||
animation-delay: 1.2s;
|
animation-delay: 1.2s;
|
||||||
animation-fill-mode: forwards;
|
animation-fill-mode: forwards;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.right {
|
&.right {
|
||||||
top: 100px;
|
top: 100px;
|
||||||
left: 500px;
|
left: 500px;
|
||||||
width: 62px;
|
width: 62px;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
animation-name: cloudRight;
|
animation-name: cloudRight;
|
||||||
animation-duration: 2s;
|
animation-duration: 2s;
|
||||||
animation-timing-function: linear;
|
animation-timing-function: linear;
|
||||||
animation-delay: 1s;
|
animation-delay: 1s;
|
||||||
animation-fill-mode: forwards;
|
animation-fill-mode: forwards;
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes cloudLeft {
|
@keyframes cloudLeft {
|
||||||
0% {
|
0% {
|
||||||
top: 17px;
|
top: 17px;
|
||||||
left: 220px;
|
left: 220px;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
20% {
|
20% {
|
||||||
top: 33px;
|
top: 33px;
|
||||||
left: 188px;
|
left: 188px;
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
80% {
|
80% {
|
||||||
top: 81px;
|
top: 81px;
|
||||||
left: 92px;
|
left: 92px;
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
100% {
|
100% {
|
||||||
top: 97px;
|
top: 97px;
|
||||||
left: 60px;
|
left: 60px;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes cloudMid {
|
@keyframes cloudMid {
|
||||||
0% {
|
0% {
|
||||||
top: 10px;
|
top: 10px;
|
||||||
left: 420px;
|
left: 420px;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
20% {
|
20% {
|
||||||
top: 40px;
|
top: 40px;
|
||||||
left: 360px;
|
left: 360px;
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
70% {
|
70% {
|
||||||
top: 130px;
|
top: 130px;
|
||||||
left: 180px;
|
left: 180px;
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
100% {
|
100% {
|
||||||
top: 160px;
|
top: 160px;
|
||||||
left: 120px;
|
left: 120px;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes cloudRight {
|
@keyframes cloudRight {
|
||||||
0% {
|
0% {
|
||||||
top: 100px;
|
top: 100px;
|
||||||
left: 500px;
|
left: 500px;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
20% {
|
20% {
|
||||||
top: 120px;
|
top: 120px;
|
||||||
left: 460px;
|
left: 460px;
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
80% {
|
80% {
|
||||||
top: 180px;
|
top: 180px;
|
||||||
left: 340px;
|
left: 340px;
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
100% {
|
100% {
|
||||||
top: 200px;
|
top: 200px;
|
||||||
left: 300px;
|
left: 300px;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.bullshit {
|
.bullshit {
|
||||||
width: 300px;
|
width: 300px;
|
||||||
padding: 30px 0;
|
padding: 30px 0;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
&__oops {
|
&__oops {
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
font-size: 32px;
|
font-size: 32px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
line-height: 40px;
|
line-height: 40px;
|
||||||
color: #1482f0;
|
color: #1482f0;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
animation-name: slideUp;
|
animation-name: slideUp;
|
||||||
animation-duration: 0.5s;
|
animation-duration: 0.5s;
|
||||||
animation-fill-mode: forwards;
|
animation-fill-mode: forwards;
|
||||||
}
|
}
|
||||||
|
|
||||||
&__headline {
|
&__headline {
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
line-height: 24px;
|
line-height: 24px;
|
||||||
color: #222;
|
color: #222;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
animation-name: slideUp;
|
animation-name: slideUp;
|
||||||
animation-duration: 0.5s;
|
animation-duration: 0.5s;
|
||||||
animation-delay: 0.1s;
|
animation-delay: 0.1s;
|
||||||
animation-fill-mode: forwards;
|
animation-fill-mode: forwards;
|
||||||
}
|
}
|
||||||
|
|
||||||
&__info {
|
&__info {
|
||||||
margin-bottom: 30px;
|
margin-bottom: 30px;
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
line-height: 21px;
|
line-height: 21px;
|
||||||
color: grey;
|
color: grey;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
animation-name: slideUp;
|
animation-name: slideUp;
|
||||||
animation-duration: 0.5s;
|
animation-duration: 0.5s;
|
||||||
animation-delay: 0.2s;
|
animation-delay: 0.2s;
|
||||||
animation-fill-mode: forwards;
|
animation-fill-mode: forwards;
|
||||||
}
|
}
|
||||||
|
|
||||||
&__return-home {
|
&__return-home {
|
||||||
display: block;
|
display: block;
|
||||||
float: left;
|
float: left;
|
||||||
width: 110px;
|
width: 110px;
|
||||||
height: 36px;
|
height: 36px;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
line-height: 36px;
|
line-height: 36px;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
background: #1482f0;
|
background: #1482f0;
|
||||||
border-radius: 100px;
|
border-radius: 100px;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
animation-name: slideUp;
|
animation-name: slideUp;
|
||||||
animation-duration: 0.5s;
|
animation-duration: 0.5s;
|
||||||
animation-delay: 0.3s;
|
animation-delay: 0.3s;
|
||||||
animation-fill-mode: forwards;
|
animation-fill-mode: forwards;
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes slideUp {
|
@keyframes slideUp {
|
||||||
0% {
|
0% {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
transform: translateY(60px);
|
transform: translateY(60px);
|
||||||
}
|
}
|
||||||
|
|
||||||
100% {
|
100% {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
transform: translateY(0);
|
transform: translateY(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<div />
|
<div />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
|
|
@ -1,51 +1,51 @@
|
||||||
module.exports = {
|
module.exports = {
|
||||||
// 继承推荐规范配置
|
// 继承推荐规范配置
|
||||||
extends: [
|
extends: [
|
||||||
'stylelint-config-standard',
|
'stylelint-config-standard',
|
||||||
'stylelint-config-recommended-scss',
|
'stylelint-config-recommended-scss',
|
||||||
'stylelint-config-recommended-vue/scss',
|
'stylelint-config-recommended-vue/scss',
|
||||||
'stylelint-config-html/vue',
|
'stylelint-config-html/vue',
|
||||||
'stylelint-config-recess-order',
|
'stylelint-config-recess-order',
|
||||||
],
|
],
|
||||||
// 指定不同文件对应的解析器
|
// 指定不同文件对应的解析器
|
||||||
overrides: [
|
overrides: [
|
||||||
{
|
{
|
||||||
files: ['**/*.{vue,html}'],
|
files: ['**/*.{vue,html}'],
|
||||||
customSyntax: 'postcss-html',
|
customSyntax: 'postcss-html',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
files: ['**/*.{css,scss}'],
|
files: ['**/*.{css,scss}'],
|
||||||
customSyntax: 'postcss-scss',
|
customSyntax: 'postcss-scss',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
// 自定义规则
|
// 自定义规则
|
||||||
rules: {
|
rules: {
|
||||||
'import-notation': 'string', // 指定导入CSS文件的方式("string"|"url")
|
'import-notation': 'string', // 指定导入CSS文件的方式("string"|"url")
|
||||||
'selector-class-pattern': null, // 选择器类名命名规则
|
'selector-class-pattern': null, // 选择器类名命名规则
|
||||||
'custom-property-pattern': null, // 自定义属性命名规则
|
'custom-property-pattern': null, // 自定义属性命名规则
|
||||||
'keyframes-name-pattern': null, // 动画帧节点样式命名规则
|
'keyframes-name-pattern': null, // 动画帧节点样式命名规则
|
||||||
'no-descending-specificity': null, // 允许无降序特异性
|
'no-descending-specificity': null, // 允许无降序特异性
|
||||||
'no-empty-source': null, // 允许空样式
|
'no-empty-source': null, // 允许空样式
|
||||||
// 允许 global 、export 、deep伪类
|
// 允许 global 、export 、deep伪类
|
||||||
'selector-pseudo-class-no-unknown': [
|
'selector-pseudo-class-no-unknown': [
|
||||||
true,
|
true,
|
||||||
{
|
{
|
||||||
ignorePseudoClasses: ['global', 'export', 'deep'],
|
ignorePseudoClasses: ['global', 'export', 'deep'],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
// 允许未知属性
|
// 允许未知属性
|
||||||
'property-no-unknown': [
|
'property-no-unknown': [
|
||||||
true,
|
true,
|
||||||
{
|
{
|
||||||
ignoreProperties: [],
|
ignoreProperties: [],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
// 允许未知规则
|
// 允许未知规则
|
||||||
'at-rule-no-unknown': [
|
'at-rule-no-unknown': [
|
||||||
true,
|
true,
|
||||||
{
|
{
|
||||||
ignoreAtRules: ['apply', 'use', 'forward'],
|
ignoreAtRules: ['apply', 'use', 'forward'],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,33 +1,36 @@
|
||||||
import {
|
import {
|
||||||
defineConfig,
|
defineConfig,
|
||||||
presetAttributify,
|
presetAttributify,
|
||||||
presetIcons,
|
presetIcons,
|
||||||
presetTypography,
|
presetTypography,
|
||||||
presetUno,
|
presetUno,
|
||||||
presetWebFonts,
|
presetWebFonts,
|
||||||
transformerDirectives,
|
transformerDirectives,
|
||||||
transformerVariantGroup,
|
transformerVariantGroup,
|
||||||
} from 'unocss';
|
} from 'unocss';
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
shortcuts: [
|
shortcuts: {
|
||||||
// ...
|
'flex-center': 'flex justify-center items-center',
|
||||||
],
|
'flex-x-between': 'flex items-center justify-between',
|
||||||
theme: {
|
'flex-x-around': 'flex items-center justify-around',
|
||||||
colors: {
|
'flex-y-center': 'flex flex-col flex-wrap justify-center items-center',
|
||||||
// ...
|
},
|
||||||
},
|
theme: {
|
||||||
},
|
colors: {
|
||||||
presets: [
|
// ...
|
||||||
presetUno(),
|
},
|
||||||
presetAttributify(),
|
},
|
||||||
presetIcons(),
|
presets: [
|
||||||
presetTypography(),
|
presetUno(),
|
||||||
presetWebFonts({
|
presetAttributify(),
|
||||||
fonts: {
|
presetIcons(),
|
||||||
// ...
|
presetTypography(),
|
||||||
},
|
presetWebFonts({
|
||||||
}),
|
fonts: {
|
||||||
],
|
// ...
|
||||||
transformers: [transformerDirectives(), transformerVariantGroup()],
|
},
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
transformers: [transformerDirectives(), transformerVariantGroup()],
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,33 +1,36 @@
|
||||||
import { defineConfig } from 'vite';
|
import { defineConfig } from 'vite';
|
||||||
|
|
||||||
|
import { buildEnv } from './build/buildEnv';
|
||||||
|
import { css } from './build/css';
|
||||||
|
import { define } from './build/define';
|
||||||
|
import { exclude, include } from './build/optimize';
|
||||||
import { plugins } from './build/plugins';
|
import { plugins } from './build/plugins';
|
||||||
import { resolve } from './build/resolve';
|
import { resolve } from './build/resolve';
|
||||||
import { buildEnv } from './build/buildEnv';
|
|
||||||
import { define } from './build/define';
|
|
||||||
import { root, wrapperEnv } from './build/utils';
|
|
||||||
import { server } from './build/server';
|
import { server } from './build/server';
|
||||||
import { exclude, include } from './build/optimize';
|
import { root, wrapperEnv } from './build/utils';
|
||||||
|
|
||||||
// https://vite.dev/config/
|
// https://vite.dev/config/
|
||||||
export default defineConfig(({ command, mode, isSsrBuild, isPreview }) => {
|
export default defineConfig(({ command, mode, isSsrBuild, isPreview }) => {
|
||||||
const env = wrapperEnv(mode, 'VITE');
|
const env = wrapperEnv(mode, 'VITE');
|
||||||
|
|
||||||
return {
|
return {
|
||||||
root,
|
root,
|
||||||
base: env.VITE_PUBLIC_PATH,
|
base: env.VITE_PUBLIC_PATH,
|
||||||
define: define(),
|
define: define(),
|
||||||
plugins: plugins(mode),
|
plugins: plugins(mode),
|
||||||
resolve: resolve(),
|
resolve: resolve(),
|
||||||
esbuild: {
|
esbuild: {
|
||||||
jsxFactory: 'h',
|
jsxFactory: 'h',
|
||||||
jsxFragment: 'Fragment',
|
jsxFragment: 'Fragment',
|
||||||
jsxInject: "import { h } from 'vue';",
|
jsxInject: "import { h } from 'vue';",
|
||||||
},
|
},
|
||||||
logLevel: 'info',
|
logLevel: 'info',
|
||||||
// 设为 false 可以避免 Vite 清屏而错过在终端中打印某些关键信息
|
css: css(mode),
|
||||||
clearScreen: false,
|
// 设为 false 可以避免 Vite 清屏而错过在终端中打印某些关键信息
|
||||||
build: buildEnv(),
|
clearScreen: false,
|
||||||
server: server(mode),
|
build: buildEnv(),
|
||||||
preview: server(mode),
|
server: server(mode),
|
||||||
optimizeDeps: { include, exclude },
|
preview: server(mode),
|
||||||
};
|
optimizeDeps: { include, exclude },
|
||||||
|
};
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue