🔧工具(deps): build framework

This commit is contained in:
2024-03-21 00:28:41 +08:00
parent dda579424c
commit 1594b21688
17 changed files with 2273 additions and 315 deletions

10
.env
View File

@@ -1,4 +1,10 @@
# 生产环境配置 # 生产环境配置
NODE_ENV= 'production' VITE_NODE_ENV= 'production'
# 生产环境 # 生产环境
VUE_APP_BASE_API = '/api' VITE_APP_BASE_API = '/api'
# 页面 title 前缀
VITE_APP_TITLE=生产环境
# 网络请求公用地址
VITE_API_BASE_URL=''

View File

@@ -1,8 +1,11 @@
# 开发环境配置 # 开发环境配置
NODE_ENV= 'development' VITE_NODE_ENV='development'
# 开发环境 # 开发环境
VUE_APP_BASE_API = '/dev-api' VITE_APP_BASE_API='/dev-api'
# 路由懒加载 # 页面 title 前缀
VUE_CLI_BABEL_TRANSPILE_MODULES = true VITE_APP_TITLE=开发环境
# 网络请求公用地址
VITE_API_BASE_URL=''

View File

@@ -1,4 +1,10 @@
# 生产环境配置 # 生产环境配置
NODE_ENV= 'production' VITE_NODE_ENV= 'production'
# 生产环境 # 生产环境
VUE_APP_BASE_API = '/api' VITE_APP_BASE_API = '/api'
# 页面 title 前缀
VITE_APP_TITLE=生产环境
# 网络请求公用地址
VITE_API_BASE_URL=''

2
.npmrc
View File

@@ -1,3 +1,3 @@
registry=https://registry.npmmirror.com registry=https://registry.npmmirror.com
npm config set registry https://registry.npmmirror.com -g npm config set registry https://registry.npmmirror.com -g
shamefully-hoist = true

3
components.d.ts vendored
View File

@@ -7,8 +7,7 @@ export {}
declare module 'vue' { declare module 'vue' {
export interface GlobalComponents { export interface GlobalComponents {
Echarts: typeof import('./src/components/echarts/ECharts.vue')['default'] ECharts: typeof import('./src/components/echarts/ECharts.vue')['default']
HelloWorld: typeof import('./src/components/HelloWorld.vue')['default']
RouterLink: typeof import('vue-router')['RouterLink'] RouterLink: typeof import('vue-router')['RouterLink']
RouterView: typeof import('vue-router')['RouterView'] RouterView: typeof import('vue-router')['RouterView']
SvgIcon: typeof import('./src/components/svgIcon/SvgIcon.vue')['default'] SvgIcon: typeof import('./src/components/svgIcon/SvgIcon.vue')['default']

View File

@@ -13,6 +13,7 @@
}, },
"dependencies": { "dependencies": {
"@ant-design/icons-vue": "^7.0.1", "@ant-design/icons-vue": "^7.0.1",
"@vueuse/core": "^10.9.0",
"ant-design-vue": "4.1.2", "ant-design-vue": "4.1.2",
"axios": "^1.6.8", "axios": "^1.6.8",
"core-js": "^3.36.1", "core-js": "^3.36.1",
@@ -22,15 +23,17 @@
"nprogress": "^0.2.0", "nprogress": "^0.2.0",
"pinia": "^2.1.7", "pinia": "^2.1.7",
"pinia-plugin-persistedstate": "^3.2.1", "pinia-plugin-persistedstate": "^3.2.1",
"vite-plugin-compression": "^0.5.1",
"vite-plugin-svg-icons": "^2.0.1", "vite-plugin-svg-icons": "^2.0.1",
"vue": "^3.4.21", "vue": "^3.4.21",
"vue-global-api": "^0.4.1",
"vue-i18n": "^9.10.2", "vue-i18n": "^9.10.2",
"vue-router": "4" "vue-router": "4"
}, },
"devDependencies": { "devDependencies": {
"@commitlint/cli": "^19.2.1", "@commitlint/cli": "^19.2.1",
"@commitlint/config-conventional": "^19.1.0", "@commitlint/config-conventional": "^19.1.0",
"@types/node": "^20.11.29", "@types/node": "^20.11.30",
"@types/nprogress": "^0.2.3", "@types/nprogress": "^0.2.3",
"@typescript-eslint/eslint-plugin": "^7.3.1", "@typescript-eslint/eslint-plugin": "^7.3.1",
"@typescript-eslint/parser": "^7.3.1", "@typescript-eslint/parser": "^7.3.1",
@@ -48,15 +51,21 @@
"lint-staged": "^15.2.2", "lint-staged": "^15.2.2",
"postcss-pxtorem": "^6.1.0", "postcss-pxtorem": "^6.1.0",
"prettier": "^3.2.5", "prettier": "^3.2.5",
"terser": "^5.29.2",
"typescript": "^5.2.2", "typescript": "^5.2.2",
"unplugin-auto-import": "^0.17.5", "unplugin-auto-import": "^0.17.5",
"unplugin-vue-components": "^0.26.0", "unplugin-vue-components": "^0.26.0",
"vite": "^5.1.6", "vite": "^5.1.6",
"vite-plugin-imagemin": "^0.6.1",
"vue-tsc": "^1.8.27" "vue-tsc": "^1.8.27"
}, },
"config": { "config": {
"commitizen": { "commitizen": {
"path": "./node_modules/cz-customizable" "path": "./node_modules/cz-customizable"
} }
} },
"browserslist": [
"last 2 Chrome versions",
"last 2 Firefox versions"
]
} }

1910
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -30,13 +30,3 @@ const svgClass = computed(() => {
<use :xlink:href="iconName" /> <use :xlink:href="iconName" />
</svg> </svg>
</template> </template>
<style lang="less" scoped>
.svg-icon {
// svg 图标默认宽高,根据个人使用情况自行调整
width: 20px;
height: 20px;
fill: currentColor;
overflow: hidden;
}
</style>

7
src/interface/user/user.d.ts vendored Normal file
View File

@@ -0,0 +1,7 @@
// 测试
export interface IUser {
token: string
userId: number
LOADING: false
userInfo: unknown
}

View File

@@ -0,0 +1 @@
# 布局

View File

@@ -10,10 +10,10 @@ import '@/polyfill/polyfill'
import '@/style/scroll-bar.less' import '@/style/scroll-bar.less'
// 国际化 // 国际化
import i18n from '../locales' import i18n from '../locales'
// svg 相关 // svg 相关
import 'virtual:svg-icons-register' import 'virtual:svg-icons-register'
import SvgIcon from './components/svgIcon/SvgIcon.vue' import SvgIcon from './components/svgIcon/SvgIcon.vue'
import 'vue-global-api'
const app = createApp(App) const app = createApp(App)
const store = createPinia() const store = createPinia()

View File

@@ -1,20 +1,14 @@
import { defineStore } from 'pinia' import { defineStore } from 'pinia'
// 加载storage模块获取token存储token import { ref } from 'vue'
import {getItem, setItem} from "@/utils/storage/storage"; import { IUser } from '@/interface/user/user'
const TOKEN_KEY: String = "X-Token"; export const useAuthStore = defineStore(
'user',
() => {
const user = ref<IUser>()
export const useAuthStore = defineStore('user', () => { function setUser(data: IUser) {
const user = ref<any>({
token: getItem(TOKEN_KEY) ? getItem(TOKEN_KEY) : null,
userId: Number,
LOADING: false,
userInfo: Object
})
function setUser(data: any) {
user.value = data user.value = data
setItem(TOKEN_KEY, user.value.token);
} }
function getUser() { function getUser() {
@@ -22,31 +16,17 @@ export const useAuthStore = defineStore('user', () => {
} }
function clearUser() { function clearUser() {
user.value = { user.value = void 0
token: null,
userId: null,
isLogin: false,
userInfo: {}
}
}
function showLoading() {
user.value.LOADING = true;
}
function hideLoading() {
user.value.LOADING = false;
} }
return { return {
user, user,
setUser, setUser,
getUser, getUser,
clearUser, clearUser
showLoading,
hideLoading
} }
}, { },
{
// 开启数据持久化 // 开启数据持久化
persist: true persist: true
} }

View File

@@ -2,10 +2,8 @@ import axios from 'axios'
import useStore from '@/store' import useStore from '@/store'
import * as process from 'process' import * as process from 'process'
// import { BASE_URL } from "@/config";
// console.log(BASE_URL) // console.log(BASE_URL)
const BaseURL: any = process.env.VUE_APP_BASE_API const BaseURL: any = process.env['VITE_APP_BASE_API ']
// 数据返回的接口 // 数据返回的接口
// 定义请求响应参数不含data // 定义请求响应参数不含data
interface Result { interface Result {
@@ -52,7 +50,7 @@ class RequestHttp {
*/ */
this.service.interceptors.request.use( this.service.interceptors.request.use(
(config: any) => { (config: any) => {
const token = useStore().user.getUser().token const token = useStore().user.getUser()?.token
if (token) { if (token) {
return { return {
...config, ...config,

View File

@@ -0,0 +1,32 @@
// cookie.ts
/**
* cookie 浏览器缓存
*/
const domain = ''
// 时间单位为秒
export function setCookie(c_name: string, value: any, expire?: any) {
const date: any = new Date()
date.setSeconds(date.getSeconds() + expire)
document.cookie =
c_name + '=' + escape(value) + '; expires=' + date.toGMTString() + '; domain=' + domain + ';path=/'
}
export function getCookie(c_name: string) {
let c_start: number
let c_end: number
if (document.cookie.length > 0) {
c_start = document.cookie.indexOf(c_name + '=')
if (c_start != -1) {
c_start = c_start + c_name.length + 1
c_end = document.cookie.indexOf(';', c_start)
if (c_end == -1) c_end = document.cookie.length
return unescape(document.cookie.substring(c_start, c_end))
}
}
return ''
}
export function delCookie(c_name: string) {
setCookie(c_name, '', -1)
}

7
src/vite-env.d.ts vendored
View File

@@ -1,5 +1,12 @@
/// <reference types="vite/client" /> /// <reference types="vite/client" />
interface ImportMetaEnv {
readonly VITE_NODE_ENV: string //定义提示信息 数据是只读的无法被修改
readonly VITE_APP_BASE_API: string
readonly VITE_APP_TITLE: string
readonly VITE_API_BASE_URL: string
}
declare module '*.vue' { declare module '*.vue' {
import type { DefineComponent } from 'vue' import type { DefineComponent } from 'vue'
const component: DefineComponent<{}, {}, any> const component: DefineComponent<{}, {}, any>

View File

@@ -2,7 +2,7 @@
"compilerOptions": { "compilerOptions": {
"typeRoots": [ "typeRoots": [
"node_modules/@types", "node_modules/@types",
"src/types" "src/types",
], ],
"target": "ES2020", "target": "ES2020",
"useDefineForClassFields": true, "useDefineForClassFields": true,

View File

@@ -1,7 +1,7 @@
import { defineConfig } from 'vite' import { defineConfig, loadEnv } from 'vite'
import vue from '@vitejs/plugin-vue' import vue from '@vitejs/plugin-vue'
import * as path from 'path' import * as path from 'path'
import legacyPlugin from '@vitejs/plugin-legacy' import legacy from '@vitejs/plugin-legacy'
// 自动导入vue中hook reactive ref等 // 自动导入vue中hook reactive ref等
import AutoImport from 'unplugin-auto-import/vite' import AutoImport from 'unplugin-auto-import/vite'
@@ -15,9 +15,14 @@ import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'
import autoprefixer from 'autoprefixer' import autoprefixer from 'autoprefixer'
import legacy from '@vitejs/plugin-legacy'
export default defineConfig({ import viteCompression from 'vite-plugin-compression'
import viteImagemin from 'vite-plugin-imagemin'
export default defineConfig(({ mode, command }) => {
const env = loadEnv(mode, process.cwd())
return {
resolve: { resolve: {
//设置别名 //设置别名
alias: { alias: {
@@ -33,17 +38,59 @@ export default defineConfig({
] ]
} }
}, },
esbuild: {
// configure this value when the browser version of the development environment is lower
// minimum support es2015
// https://esbuild.github.io/api/#target
target: 'es2015',
include: /\.(ts|jsx|tsx)$/
},
plugins: [ plugins: [
vue(), vue(),
viteImagemin({
gifsicle: { // gif图片压缩
optimizationLevel: 3, // 选择1到3之间的优化级别
interlaced: false // 隔行扫描gif进行渐进式渲染
// colors: 2 // 将每个输出GIF中不同颜色的数量减少到num或更少。数字必须介于2和256之间。
},
optipng: { // png
optimizationLevel: 7 // 选择0到7之间的优化级别
},
mozjpeg: {// jpeg
quality: 20 // 压缩质量范围从0(最差)到100(最佳)。
},
pngquant: {// png
quality: [0.8, 0.9], // Min和max是介于0(最差)到1(最佳)之间的数字类似于JPEG。达到或超过最高质量所需的最少量的颜色。如果转换导致质量低于最低质量图像将不会被保存。
speed: 4 // 压缩速度1(强力)到11(最快)
},
svgo: { // svg压缩
plugins: [
{
name: 'removeViewBox'
},
{
name: 'removeEmptyAttrs',
active: false
}
]
}
}),
viteCompression({
verbose: true, // 是否在控制台中输出压缩结果
disable: false,
threshold: 10240, // 如果体积大于阈值将被压缩单位为b体积过小时请不要压缩以免适得其反
algorithm: 'gzip', // 压缩算法,可选['gzip'' brotliccompress ''deflate ''deflateRaw']
ext: '.gz',
deleteOriginFile: true // 源文件压缩后是否删除
}),
// 修改 svg 相关配置 // 修改 svg 相关配置
createSvgIconsPlugin({ createSvgIconsPlugin({
// 指定需要缓存的图标文件夹 // 指定需要缓存的图标文件夹
iconDirs: [path.resolve(__dirname, './src/assets/svg')] iconDirs: [path.resolve(__dirname, './src/assets/svg')]
}), }),
legacy({ legacy({
targets: ['cover 99.5%'] renderLegacyChunks: true,
}), modernPolyfills: true,
legacyPlugin({
targets: ['chrome 52'], // 需要兼容的目标列表 targets: ['chrome 52'], // 需要兼容的目标列表
additionalLegacyPolyfills: ['regenerator-runtime/runtime'] // 面向IE11时需要此插件 additionalLegacyPolyfills: ['regenerator-runtime/runtime'] // 面向IE11时需要此插件
}), }),
@@ -64,12 +111,57 @@ export default defineConfig({
}, },
server: { server: {
proxy: { proxy: {
'/dev-api': { '/api': {
//target是代理的目标路径 //target是代理的目标路径
target: '', target: env.VITE_API_BASE_URL,
changeOrigin: true, //必须要开启跨域 changeOrigin: true, //必须要开启跨域
rewrite: (path) => path.replace(/\/dev-api/, '') // 路径重写 rewrite: (path) => path.replace(/\/api/, '') // 路径重写
}
}
},
build: {
// target: ['es2015'], // 设置最终构建的浏览器兼容目标
moduleResolution: 'node', // 决定如何处理模块。
outDir: 'dist', // 指定输出路径
assetsDir: 'assets', // 指定生成静态文件目录
assetsInlineLimit: '4096', // 小于此阈值的导入或引用资源将内联为 base64 编码
cssCodeSplit: true, // 启用 CSS 代码拆分
// cssTarget: '', // 允许用户为 CSS 的压缩设置一个不同的浏览器 target 与 build.target 一致
sourcemap: false, // 构建后是否生成 source map 文件
// lib: {}, // 构建为库
manifest: false, // 当设置为 true构建后将会生成 manifest.json 文件
ssrManifest: false, // 构建不生成 SSR 的 manifest 文件
ssr: undefined, // 生成面向 SSR 的构建
minify: 'terser', // 指定使用哪种混淆器
// 传递给 Terser 的更多 minify 选项
terserOptions: {
compress: {
drop_console: true,
drop_debugger: true
}
},
write: true, // 启用将构建后的文件写入磁盘
emptyOutDir: true, // 构建时清空该目录
brotliSize: true, // 启用 brotli 压缩大小报告
chunkSizeWarningLimit: 2000, // chunk 大小警告的限制
watch: null, // 设置为 {} 则会启用 rollup 的监听器
rollupOptions: { // 自定义底层的 Rollup 打包配置
output: {
chunkFileNames: 'js/[name]-[hash].js', // 引入文件名的名称
entryFileNames: 'js/[name]-[hash].js', // 包的入口文件名称
assetFileNames: '[ext]/[name]-[hash].[ext]' // 资源文件像 字体,图片等
}
}
},
output: {
// 最小化拆分包
manualChunks(id) {
if (id.includes('node_modules')) {
return id.toString().split('node_modules/')[1].split('/')[0].toString()
} }
} }
} }
}
}) })