提交 f5d9ac8a authored 作者: zengzhe's avatar zengzhe

feat: update

上级 fd0495f5
# title
VITE_GLOB_APP_TITLE = '智慧教育后台管理系统'
PUBLIC_GLOB_APP_TITLE = '智慧教育后台管理系统'
# 本地运行端口号
VITE_PORT = 5173
PUBLIC_PORT = 5173
# 启动时自动打开浏览器
VITE_OPEN = false
PUBLIC_OPEN = false
# 打包后是否生成包分析文件
VITE_REPORT = false
PUBLIC_REPORT = false
......@@ -7,22 +7,22 @@
# Copyright(c)2024 by 好老师教育科技有限公司 All right Reserved.
###
# 本地环境
VITE_USER_NODE_ENV = development
PUBLIC_USER_NODE_ENV = development
# 公共基础路径
VITE_PUBLIC_PATH = /
PUBLIC_PUBLIC_PATH = /
# 打包时是否删除 console
VITE_DROP_CONSOLE = true
PUBLIC_DROP_CONSOLE = true
# 开发环境接口地址
VITE_API_URL = http://api.iep.casdio.com
PUBLIC_API_URL = http://api.iep.casdio.com
# 汪洋
# VITE_API_URL = http://172.16.3.197:8095
# PUBLIC_API_URL = http://172.16.3.197:8095
# 邹琪涛
# VITE_API_URL = https://e28e-14-105-62-130.ngrok-free.app
# PUBLIC_API_URL = https://e28e-14-105-62-130.ngrok-free.app
# 开发环境跨域代理,支持配置多个
VITE_PROXY = []
PUBLIC_PROXY = []
###
# @Author: zengzhe
# @Date: 2024-12-27 11:15:21
# @LastEditors: zengzhe
# @LastEditTime: 2024-12-27 14:53:30
# @Description:
###
# 线上环境
VITE_USER_NODE_ENV = production
PUBLIC_USER_NODE_ENV = production
# 公共基础路径
VITE_PUBLIC_PATH = /
PUBLIC_PUBLIC_PATH = /
# 是否启用 gzip 或 brotli 压缩打包,如果需要多个压缩规则,可以使用 “,” 分隔
# Optional: gzip | brotli | none
VITE_BUILD_COMPRESS = none
PUBLIC_BUILD_COMPRESS = none
# 打包压缩后是否删除源文件
VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE = false
PUBLIC_BUILD_COMPRESS_DELETE_ORIGIN_FILE = false
# 打包时是否删除 console
VITE_DROP_CONSOLE = true
PUBLIC_DROP_CONSOLE = true
# 线上环境接口地址
VITE_API_URL = "https://api.iep.seevin.com"
PUBLIC_API_URL = "https://api.iep.seevin.com"
......@@ -7,20 +7,20 @@
# Copyright(c)2024 by 好老师教育科技有限公司 All right Reserved.
###
# 测试环境
VITE_USER_NODE_ENV = test
PUBLIC_USER_NODE_ENV = test
# 公共基础路径
VITE_PUBLIC_PATH = /
PUBLIC_PUBLIC_PATH = /
# 是否启用 gzip 或 brotli 压缩打包,如果需要多个压缩规则,可以使用 “,” 分隔
# Optional: gzip | brotli | none
VITE_BUILD_COMPRESS = none
PUBLIC_BUILD_COMPRESS = none
# 打包压缩后是否删除源文件
VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE = false
PUBLIC_BUILD_COMPRESS_DELETE_ORIGIN_FILE = false
# 打包时是否删除 console
VITE_DROP_CONSOLE = true
PUBLIC_DROP_CONSOLE = true
# 测试环境接口地址
VITE_API_URL = http://api.iep.casdio.com
PUBLIC_API_URL = http://api.iep.casdio.com
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
npm run lint-staged
/*
* @Author: zhanyoulin<zhanyoulin456@163.com>
* @Date: 2023-06-23 11:04:27
* @LastEditors: zhanyoulin
* @LastEditTime: 2023-06-23 13:49:05
* @LastEditors: zengzhe
* @LastEditTime: 2024-12-27 15:27:57
* @Description:
*/
import path from 'path'
......@@ -23,25 +23,34 @@ export function isTestFn(mode: string): boolean {
* Whether to generate package preview
*/
export function isReportMode(): boolean {
return process.env.VITE_REPORT === 'true'
return process.env.PUBLIC_REPORT === 'true'
}
// Read all environment variable configuration files to process.env
export function wrapperEnv(envConf: Recordable): ViteEnv {
const ret: any = {}
export function wrapperEnv(envConf: Recordable): Recordable {
const ret: Recordable = {}
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) {
console.log(error)
// 只处理 process.env 开头的配置
if (envName.startsWith('process.env.')) {
// 移除 process.env. 前缀
const key = envName.replace('process.env.', '')
// 移除值两端的引号
let value = envConf[envName].replace(/^["'](.+)["']$/, '$1')
// 转换特定类型的值
value = value === 'true' ? true : value === 'false' ? false : value
if (value === 'null') {
value = null
}
if (!isNaN(Number(value))) {
value = Number(value)
}
ret[key] = value
}
ret[envName] = realName
}
return ret
}
......
import { resolve } from 'path'
import { PluginOption } from 'vite'
import { visualizer } from 'rollup-plugin-visualizer'
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'
import viteCompression from 'vite-plugin-compression'
import Components from 'unplugin-vue-components/vite'
import AutoImport from 'unplugin-auto-import/vite'
import { TDesignResolver } from 'unplugin-vue-components/resolvers'
import legacy from '@vitejs/plugin-legacy' // polyfill低版本谷歌浏览器
import checker from 'vite-plugin-checker'
/**
* 创建 vite 插件
* @param viteEnv
*/
export const createVitePlugins = (viteEnv: ViteEnv): (PluginOption | PluginOption[])[] => {
const { VITE_GLOB_APP_TITLE, VITE_REPORT } = viteEnv
return [
vue(),
// vue 可以使用 jsx/tsx 语法
vueJsx(),
// 创建打包压缩配置
createCompression(viteEnv),
// eslintPlugin(),
// 注入变量到 html 文件
createHtmlPlugin({
inject: {
data: { title: VITE_GLOB_APP_TITLE }
}
}),
// 使用 svg 图标
createSvgIconsPlugin({
iconDirs: [resolve(process.cwd(), 'src/assets/icons')],
symbolId: 'icon-[dir]-[name]'
}),
// 是否生成包预览,分析依赖包大小做优化处理
VITE_REPORT && (visualizer({ filename: 'stats.html', gzipSize: true, brotliSize: true }) as PluginOption),
AutoImport({
imports: ['vue', 'vue-router'],
resolvers: [
TDesignResolver({
library: 'vue-next'
})
],
dts: 'src/autoImport.d.ts'
}),
Components({
// allow auto load markdown components under `./src/components/`
extensions: ['vue', 'md'],
// allow auto import and register components used in markdown
include: [/\.vue$/, /\.vue\?vue/, /\.md$/],
resolvers: [
TDesignResolver({
library: 'vue-next'
})
],
dts: 'src/components.d.ts'
}),
legacy({
targets: ['defaults', 'not IE 11', 'chrome 68']
}),
checker({
typescript: true
})
]
}
/**
* @description 根据 compress 配置,生成不同的压缩规则
* @param viteEnv
*/
const createCompression = (viteEnv: ViteEnv): PluginOption | PluginOption[] => {
const { VITE_BUILD_COMPRESS = 'none', VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE } = viteEnv
const compressList = VITE_BUILD_COMPRESS.split(',')
const plugins: PluginOption[] = []
if (compressList.includes('gzip')) {
plugins.push(
viteCompression({
ext: '.gz',
algorithm: 'gzip',
deleteOriginFile: VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE
})
)
}
if (compressList.includes('brotli')) {
plugins.push(
viteCompression({
ext: '.br',
algorithm: 'brotliCompress',
deleteOriginFile: VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE
})
)
}
return plugins
}
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
}
/*
* @Author: zengzhe
* @Date: 2024-12-27 11:54:24
* @LastEditors: zengzhe
* @LastEditTime: 2024-12-27 17:00:00
* @Description:
*/
import { pluginBabel } from '@rsbuild/plugin-babel'
import { pluginVue } from '@rsbuild/plugin-vue'
import { pluginVueJsx } from '@rsbuild/plugin-vue-jsx'
import { pluginLess } from '@rsbuild/plugin-less'
import { pluginTypeCheck } from '@rsbuild/plugin-type-check'
import { pluginSvgSpriteLoader } from 'rsbuild-plugin-svg-sprite-loader'
import AutoImport from 'unplugin-auto-import/rspack'
import Components from 'unplugin-vue-components/rspack'
import { TDesignResolver } from 'unplugin-vue-components/resolvers'
import { join } from 'path'
export const createPlugins = () => {
return [
pluginBabel({
include: /\.(?:jsx|tsx)$/
}),
pluginVue(),
pluginVueJsx(),
pluginLess()
]
return {
plugins: [
pluginBabel({
include: /\.(?:jsx|tsx)$/
}),
pluginVue(),
pluginVueJsx(),
pluginLess(),
pluginTypeCheck(),
pluginSvgSpriteLoader({
path: join(__dirname, '../src/assets/icons'),
symbolId: 'icon-[name]'
})
],
tools: {
rspack: {
plugins: [
AutoImport({
imports: ['vue', 'vue-router'],
resolvers: [
TDesignResolver({
library: 'vue-next'
})
],
dts: 'src/autoImport.d.ts'
}),
Components({
// allow auto load markdown components under `./src/components/`
extensions: ['vue', 'md'],
// allow auto import and register components used in markdown
include: [/\.vue$/, /\.vue\?vue/, /\.md$/],
resolvers: [
TDesignResolver({
library: 'vue-next'
})
],
dts: 'src/components.d.ts'
})
]
}
}
}
}
......@@ -55,6 +55,7 @@
"@rsbuild/core": "^1.1.13",
"@rsbuild/plugin-babel": "^1.0.3",
"@rsbuild/plugin-less": "^1.1.0",
"@rsbuild/plugin-type-check": "^1.2.0",
"@rsbuild/plugin-vue": "^1.0.5",
"@rsbuild/plugin-vue-jsx": "^1.1.0",
"@rushstack/eslint-patch": "^1.8.0",
......@@ -75,6 +76,9 @@
"postcss-less": "^6.0.0",
"prettier": "^3.3.3",
"rollup-plugin-visualizer": "^5.12.0",
"rsbuild-plugin-svg": "^0.0.2",
"rsbuild-plugin-svg-sprite-loader": "^0.0.2",
"rsbuild-svg-sprite-loader": "^0.0.1",
"stylelint": "~16.2.1",
"stylelint-config-standard": "^36.0.0",
"stylelint-order": "~6.0.4",
......
差异被折叠。
......@@ -2,31 +2,23 @@
* @Author: zengzhe
* @Date: 2024-12-27 11:48:34
* @LastEditors: zengzhe
* @LastEditTime: 2024-12-27 14:43:43
* @LastEditTime: 2024-12-27 17:00:41
* @Description:
*/
import { resolve } from 'path'
import { defineConfig, loadEnv } from '@rsbuild/core'
import { createPlugins } from './build/rsbuild-plugins'
import pkg from './package.json'
const { dependencies, devDependencies, name, version } = pkg
import dayjs from 'dayjs'
import AutoImport from 'unplugin-auto-import/rspack'
import Components from 'unplugin-vue-components/rspack'
import { TDesignResolver } from 'unplugin-vue-components/resolvers'
const { publicVars } = loadEnv({ prefixes: ['VITE_'] })
const __APP_INFO__ = {
pkg: { dependencies, devDependencies, name, version },
lastBuildTime: dayjs().format('YYYY-MM-DD HH:mm:ss'),
importMeta: 'import.meta'
}
import { wrapperEnv } from './build/getEnv'
const { publicVars } = loadEnv({ prefixes: ['PUBLIC_'] })
const Envs = wrapperEnv(publicVars)
export default defineConfig({
root: process.cwd(),
server: {
base: '/',
host: '0.0.0.0',
port: 3000,
open: true,
base: Envs.PUBLIC_PUBLIC_PATH,
port: Envs.PUBLIC_PORT,
open: Envs.PUBLIC_OPEN,
cors: true
},
resolve: {
......@@ -35,16 +27,10 @@ export default defineConfig({
}
},
html: {
title: publicVars.VITE_APP_TITLE,
title: '',
template: './index.html'
},
source: {
define: {
__APP_INFO__: JSON.stringify(__APP_INFO__),
// 启用生产环境构建下激活不匹配的详细警告
__VUE_PROD_HYDRATION_MISMATCH_DETAILS__: 'false',
...publicVars
},
entry: {
index: './src/main.ts'
}
......@@ -55,32 +41,9 @@ export default defineConfig({
},
minify: true
},
plugins: createPlugins(),
tools: {
rspack: {
plugins: [
AutoImport({
imports: ['vue', 'vue-router'],
resolvers: [
TDesignResolver({
library: 'vue-next'
})
],
dts: 'src/autoImport.d.ts'
}),
Components({
// allow auto load markdown components under `./src/components/`
extensions: ['vue', 'md'],
// allow auto import and register components used in markdown
include: [/\.vue$/, /\.vue\?vue/, /\.md$/],
resolvers: [
TDesignResolver({
library: 'vue-next'
})
],
dts: 'src/components.d.ts'
})
]
}
plugins: createPlugins().plugins,
tools: createPlugins().tools,
performance: {
removeConsole: true
}
})
......@@ -25,7 +25,7 @@ export interface CustomAxiosRequestConfig extends InternalAxiosRequestConfig {
const config = {
// 默认地址请求地址,可在 .env.** 文件中修改
baseURL: import.meta.env.VITE_API_URL as string,
baseURL: import.meta.env.PUBLIC_API_URL as string,
// 设置超时时间
timeout: ResultEnum.TIMEOUT as number,
paramsSerializer: function (params: any) {
......
<!--
* @Author: xiejiang
* @Date: 2023-03-08 16:51:55
* @LastEditors: xiejiang
* @LastEditTime: 2024-11-13 17:09:40
* @LastEditors: zengzhe
* @LastEditTime: 2024-12-27 15:38:09
* @Description: 密码风险等级
* Copyright(c)2023 by 好老师教育科技有限公司 All right Reserved.
-->
......
/// <reference types="vite/client" />
/*
* @Author: zengzhe
* @Date: 2024-12-27 11:15:21
* @LastEditors: zengzhe
* @LastEditTime: 2024-12-27 15:10:51
* @Description:
*/
/// <reference types="@rsbuild/core/types" />
export interface ImportMetaEnv {
/** 项目标题 */
readonly VITE_GLOB_APP_TITLE: string
readonly PUBLIC_GLOB_APP_TITLE: string
/** 项目 本地端口 */
readonly VITE_PORT: number
readonly PUBLIC_PORT: number
/** 是否自动打开浏览器 */
readonly VITE_OPEN: boolean
readonly PUBLIC_OPEN: boolean
/** 打包后是否生成包分析文件 */
readonly VITE_REPORT: boolean
readonly PUBLIC_REPORT: boolean
/** # 线上环境 */
readonly VITE_USER_NODE_ENV: 'development' | 'production' | 'test'
readonly PUBLIC_USER_NODE_ENV: 'development' | 'production' | 'test'
/** # 公共基础路径 */
readonly VITE_PUBLIC_PATH: string
readonly PUBLIC_PUBLIC_PATH: string
/** # 打包压缩算法 */
readonly VITE_BUILD_COMPRESS: 'gzip' | 'brotli' | 'gzip,brotli' | 'none'
readonly PUBLIC_BUILD_COMPRESS: 'gzip' | 'brotli' | 'gzip,brotli' | 'none'
/**打包时是否删除 console */
readonly VITE_DROP_CONSOLE: boolean
readonly PUBLIC_DROP_CONSOLE: boolean
/** # 接口地址 */
readonly VITE_API_URL: string
readonly PUBLIC_API_URL: string
/** # 接口代理 */
readonly VITE_PROXY: [string, string][]
readonly PUBLIC_PROXY: [string, string][]
}
......@@ -57,7 +57,7 @@ router.beforeEach(async (to, from, next) => {
NProgress.start()
// 2.动态设置标题
const title = import.meta.env.VITE_GLOB_APP_TITLE
const title = import.meta.env.PUBLIC_GLOB_APP_TITLE
document.title = to.meta.title ? `${to.meta.title} - ${title}` : title
// 3.判断是访问登陆页,有 Token 就在当前页面,没有 Token 重置路由到登陆页
......
......@@ -65,17 +65,17 @@ declare namespace File {
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_PUBLIC_PATH: string
VITE_API_URL: string
VITE_PROXY: [string, string][]
PUBLIC_USER_NODE_ENV: 'development' | 'production' | 'test'
PUBLIC_GLOB_APP_TITLE: string
PUBLIC_PORT: number
PUBLIC_OPEN: boolean
PUBLIC_REPORT: boolean
PUBLIC_BUILD_COMPRESS: 'gzip' | 'brotli' | 'gzip,brotli' | 'none'
PUBLIC_BUILD_COMPRESS_DELETE_ORIGIN_FILE: boolean
PUBLIC_DROP_CONSOLE: boolean
PUBLIC_PUBLIC_PATH: string
PUBLIC_API_URL: string
PUBLIC_PROXY: [string, string][]
}
interface ImportMetaEnv extends ViteEnv {
......@@ -113,5 +113,3 @@ declare type NullableOrUndefined<T> = T | null | undefined
// 将对象中的属性部分变为可选
declare type Optional<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>
<!--
* @Author: xiejiang
* @Date: 2024-11-05 10:14:56
* @LastEditors: xiejiang
* @LastEditTime: 2024-12-11 22:15:15
* @LastEditors: zengzhe
* @LastEditTime: 2024-12-30 14:27:25
* @Description: 登录
* Copyright(c)2024 by 好老师教育科技有限公司 All right Reserved.
-->
......@@ -70,7 +70,6 @@
</div>
</div>
</div>
<Dialog
:dialog-visible="isShowPuzzleVcode"
title="请拖动滑块完成拼图"
......@@ -94,7 +93,6 @@ import { HOME_URL } from '@/config'
// import logo from '@/assets/images/logo.png'
import welcome from '@/assets/images/welcome.png'
import welcomeInfo from '@/assets/images/welcome-info.png'
onMounted(() => {})
const validateTelePhone: CustomValidator = async val => {
......
......@@ -4,7 +4,6 @@
"useDefineForClassFields": true,
"module": "ESNext",
"moduleResolution": "Node",
"types": ["vite/client"],
/* Strict Type-Checking Options */
"strict": true /* Enable all strict type-checking options. */,
// "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
......
/*
* @Author: zhanyoulin<zhanyoulin456@163.com>
* @Date: 2023-06-13 09:41:18
* @LastEditors: xiejiang
* @LastEditTime: 2024-12-11 19:24:03
* @Description:
*/
import { defineConfig, loadEnv, ConfigEnv, UserConfig } from 'vite'
import dayjs from 'dayjs'
import { resolve } from 'path'
import { wrapperEnv } from './build/getEnv'
import { createProxy } from './build/proxy'
import { createVitePlugins } from './build/plugins'
import pkg from './package.json'
const { dependencies, devDependencies, name, version } = pkg
const __APP_INFO__ = {
pkg: { dependencies, devDependencies, name, version },
lastBuildTime: dayjs().format('YYYY-MM-DD HH:mm:ss'),
importMeta: 'import.meta'
}
// @see: https://vitejs.dev/config/
export default defineConfig(({ mode }: ConfigEnv): UserConfig => {
const root = process.cwd()
const env = loadEnv(mode, root)
const viteEnv = wrapperEnv(env)
return {
base: viteEnv.VITE_PUBLIC_PATH,
root,
resolve: {
alias: {
'@': resolve(__dirname, './src')
}
},
define: {
__APP_INFO__: JSON.stringify(__APP_INFO__),
// 启用生产环境构建下激活不匹配的详细警告
__VUE_PROD_HYDRATION_MISMATCH_DETAILS__: 'false'
},
css: {
preprocessorOptions: {
scss: {
// additionalData: `@use "@/styles/element/index.scss" as *;`
// api: 'modern-compiler'
}
}
},
server: {
host: '0.0.0.0',
port: viteEnv.VITE_PORT,
open: viteEnv.VITE_OPEN,
cors: true,
// Load proxy configuration from .env.development
proxy: createProxy(viteEnv.VITE_PROXY)
},
plugins: createVitePlugins(viteEnv),
esbuild: {
pure: viteEnv.VITE_DROP_CONSOLE ? ['console.log', 'debugger'] : []
},
build: {
outDir: 'dist',
minify: 'esbuild',
// esbuild 打包更快,但是不能去除 console.log,terser打包慢,但能去除 console.log
// minify: "terser",
// terserOptions: {
// compress: {
// drop_console: viteEnv.VITE_DROP_CONSOLE,
// drop_debugger: true
// }
// },
// 禁用 gzip 压缩大小报告,可略微减少打包时间
reportCompressedSize: false,
// 规定触发警告的 chunk 大小
chunkSizeWarningLimit: 2000,
rollupOptions: {
output: {
// Static resource classification and packaging
chunkFileNames: 'assets/js/[name]-[hash].js',
entryFileNames: 'assets/js/[name]-[hash].js',
assetFileNames: 'assets/[ext]/[name]-[hash].[ext]'
}
}
}
}
})
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论