打包工具更换为vite
Co-authored-by: Copilot <copilot@github.com>
This commit is contained in:
parent
893cfe6a39
commit
bcc09d7064
@ -8,5 +8,6 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="app"></div>
|
<div id="app"></div>
|
||||||
|
<script type="module" src="/src/main.ts"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
11504
package-lock.json
generated
11504
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
18
package.json
18
package.json
@ -2,8 +2,9 @@
|
|||||||
"name": "blog-admin-web",
|
"name": "blog-admin-web",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vue-cli-service serve",
|
"dev": "vite",
|
||||||
"build": "vue-cli-service build"
|
"build": "vite build",
|
||||||
|
"preview": "vite preview"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@element-plus/icons-vue": "^2.3.2",
|
"@element-plus/icons-vue": "^2.3.2",
|
||||||
@ -20,21 +21,16 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^25.6.0",
|
"@types/node": "^25.6.0",
|
||||||
"@vue/cli-plugin-babel": "~5.0.0",
|
"@vitejs/plugin-vue": "^5.2.4",
|
||||||
"@vue/cli-plugin-router": "~5.0.0",
|
|
||||||
"@vue/cli-plugin-typescript": "~5.0.0",
|
|
||||||
"@vue/cli-plugin-vuex": "~5.0.0",
|
|
||||||
"@vue/cli-service": "~5.0.0",
|
|
||||||
"less": "^4.6.4",
|
"less": "^4.6.4",
|
||||||
"less-loader": "^8.0.0",
|
|
||||||
"typescript": "^5.4.0",
|
"typescript": "^5.4.0",
|
||||||
"unplugin-auto-import": "^0.12.1",
|
"unplugin-auto-import": "^0.12.1",
|
||||||
"unplugin-vue-components": "^0.22.12"
|
"unplugin-vue-components": "^0.22.12",
|
||||||
|
"vite": "^5.4.19"
|
||||||
},
|
},
|
||||||
"overrides": {
|
"overrides": {
|
||||||
"postcss": ">=8.4.31",
|
"postcss": ">=8.4.31",
|
||||||
"serialize-javascript": ">=7.0.5",
|
"serialize-javascript": ">=7.0.5"
|
||||||
"webpack-dev-server": ">=5.2.1"
|
|
||||||
},
|
},
|
||||||
"browserslist": [
|
"browserslist": [
|
||||||
"> 1%",
|
"> 1%",
|
||||||
|
|||||||
@ -8,16 +8,16 @@ const routes: Array<RouteRecordRaw> = [
|
|||||||
{ path: '/login', name: 'Login', component: Login },
|
{ path: '/login', name: 'Login', component: Login },
|
||||||
{ path: '/', name: 'Home', component: Home, children: [
|
{ path: '/', name: 'Home', component: Home, children: [
|
||||||
{ path: '/', name: 'Welcome', component: Welcome },
|
{ path: '/', name: 'Welcome', component: Welcome },
|
||||||
{ path: '/system/user', name: 'SystemUser', component: () => import( /* webpackChunkName: "system" */ '@/views/system/SystemUser.vue'), meta: { title: '用户管理' } },
|
{ path: '/system/user', name: 'SystemUser', component: () => import('@/views/system/SystemUser.vue'), meta: { title: '用户管理' } },
|
||||||
{ path: '/system/role', name: 'SystemRole', component: () => import( /* webpackChunkName: "system" */ '@/views/system/SystemRole.vue'), meta: { title: '角色管理' } },
|
{ path: '/system/role', name: 'SystemRole', component: () => import('@/views/system/SystemRole.vue'), meta: { title: '角色管理' } },
|
||||||
{ path: '/system/config', name: 'SystemConfig', component: () => import( /* webpackChunkName: "system" */ '@/views/system/SystemConfig.vue'), meta: { title: '系统配置' } },
|
{ path: '/system/config', name: 'SystemConfig', component: () => import('@/views/system/SystemConfig.vue'), meta: { title: '系统配置' } },
|
||||||
{ path: '/system/article', name: 'Article', component: () => import( /* webpackChunkName: "system" */ '@/views/system/Article.vue'), meta: { title: '博客文章' } },
|
{ path: '/system/article', name: 'Article', component: () => import('@/views/system/Article.vue'), meta: { title: '博客文章' } },
|
||||||
{ path: '/system/statistics', name: 'Statistics', component: () => import( /* webpackChunkName: "system" */ '@/views/system/Statistics.vue'), meta: { title: '分析统计' } },
|
{ path: '/system/statistics', name: 'Statistics', component: () => import('@/views/system/Statistics.vue'), meta: { title: '分析统计' } },
|
||||||
|
|
||||||
{ path: '/api/music', name: 'Music', component: () => import( /* webpackChunkName: "api" */ '@/views/api/Music.vue'), meta: { title: '歌曲库' } },
|
{ path: '/api/music', name: 'Music', component: () => import('@/views/api/Music.vue'), meta: { title: '歌曲库' } },
|
||||||
{ path: '/api/hitokoto', name: 'Hitokoto', component: () => import( /* webpackChunkName: "api" */ '@/views/api/Hitokoto.vue'), meta: { title: '一言' } },
|
{ path: '/api/hitokoto', name: 'Hitokoto', component: () => import('@/views/api/Hitokoto.vue'), meta: { title: '一言' } },
|
||||||
{ path: '/api/photoWall', name: 'PhotoWall', component: () => import( /* webpackChunkName: "api" */ '@/views/api/PhotoWall.vue'), meta: { title: '照片墙' } },
|
{ path: '/api/photoWall', name: 'PhotoWall', component: () => import('@/views/api/PhotoWall.vue'), meta: { title: '照片墙' } },
|
||||||
{ path: '/api/sourceImage', name: 'SourceImage', component: () => import( /* webpackChunkName: "api" */ '@/views/api/SourceImage.vue'), meta: { title: '图片资源库' } },
|
{ path: '/api/sourceImage', name: 'SourceImage', component: () => import('@/views/api/SourceImage.vue'), meta: { title: '图片资源库' } },
|
||||||
]}
|
]}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import store from '@/store'
|
|||||||
import { router } from '@/router'
|
import { router } from '@/router'
|
||||||
|
|
||||||
const http = axios.create({
|
const http = axios.create({
|
||||||
baseURL: process.env.VUE_APP_API_BASE,
|
baseURL: import.meta.env.VUE_APP_API_BASE,
|
||||||
timeout: 10000,
|
timeout: 10000,
|
||||||
paramsSerializer: {
|
paramsSerializer: {
|
||||||
indexes: null
|
indexes: null
|
||||||
|
|||||||
@ -92,7 +92,7 @@ const store = useStore()
|
|||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
|
|
||||||
const version = process.env.VERSION
|
const version = __APP_VERSION__
|
||||||
const currentYear = new Date().getFullYear()
|
const currentYear = new Date().getFullYear()
|
||||||
const defaultActiveMenuKey = ref<string | null>(null)
|
const defaultActiveMenuKey = ref<string | null>(null)
|
||||||
const openMenuNames = ref<string[]>([])
|
const openMenuNames = ref<string[]>([])
|
||||||
|
|||||||
@ -210,7 +210,7 @@ class MusicPage extends Page {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const store = useStore()
|
const store = useStore()
|
||||||
const apiBase = process.env.VUE_APP_API_BASE as string
|
const apiBase = import.meta.env.VUE_APP_API_BASE
|
||||||
const { loading, modalLoading, total, search, setLoadData, loadDataBase, reset, pageChange, pageSizeChange } = useBaseList(new MusicPage())
|
const { loading, modalLoading, total, search, setLoadData, loadDataBase, reset, pageChange, pageSizeChange } = useBaseList(new MusicPage())
|
||||||
const currentRow = ref<MusicModel | null>(null)
|
const currentRow = ref<MusicModel | null>(null)
|
||||||
const libIdSelected = ref<string | null>(null)
|
const libIdSelected = ref<string | null>(null)
|
||||||
|
|||||||
@ -105,7 +105,7 @@ class PhotoWallPage extends Page {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const store = useStore()
|
const store = useStore()
|
||||||
const apiBase = process.env.VUE_APP_API_BASE as string
|
const apiBase = import.meta.env.VUE_APP_API_BASE
|
||||||
const { loading, total, search, setLoadData, loadDataBase, reset, pageChange, pageSizeChange } = useBaseList(new PhotoWallPage())
|
const { loading, total, search, setLoadData, loadDataBase, reset, pageChange, pageSizeChange } = useBaseList(new PhotoWallPage())
|
||||||
|
|
||||||
const allowUploadExt = ['jpg', 'jpeg', 'png']
|
const allowUploadExt = ['jpg', 'jpeg', 'png']
|
||||||
|
|||||||
@ -87,7 +87,7 @@ import { SourceImageModel } from '@/model/api/source-image'
|
|||||||
import http from '@/utils/http'
|
import http from '@/utils/http'
|
||||||
|
|
||||||
const store = useStore()
|
const store = useStore()
|
||||||
const apiBase = process.env.VUE_APP_API_BASE as string
|
const apiBase = import.meta.env.VUE_APP_API_BASE
|
||||||
const { loading, total, search, setLoadData, pageChange, pageSizeChange, datetimeFormat } = useBaseList(new Page())
|
const { loading, total, search, setLoadData, pageChange, pageSizeChange, datetimeFormat } = useBaseList(new Page())
|
||||||
|
|
||||||
const allowUploadExt = ['jpg', 'jpeg', 'png', 'svg', 'ico']
|
const allowUploadExt = ['jpg', 'jpeg', 'png', 'svg', 'ico']
|
||||||
|
|||||||
@ -4,10 +4,11 @@
|
|||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed } from 'vue'
|
import { computed } from 'vue'
|
||||||
|
|
||||||
const props = defineProps<{type: string}>()
|
const props = defineProps<{type: string}>()
|
||||||
const requireAssets = require.context('../assets', false, /\.svg$/)
|
const svgModules = import.meta.glob('../assets/*.svg', { eager: true, import: 'default' }) as Record<string, string>
|
||||||
const SVGs = requireAssets.keys().reduce((svgs: {[propName:string]: string}, path: string) => {
|
|
||||||
const svgFile = requireAssets(path)
|
const SVGs = Object.entries(svgModules).reduce((svgs: {[propName:string]: string}, [path, svgFile]) => {
|
||||||
const fileNameMatch = path.match(/^.*\/(.+?)\.svg$/)
|
const fileNameMatch = path.match(/^.*\/(.+?)\.svg$/)
|
||||||
if (fileNameMatch) {
|
if (fileNameMatch) {
|
||||||
svgs[fileNameMatch[1]] = svgFile
|
svgs[fileNameMatch[1]] = svgFile
|
||||||
|
|||||||
@ -66,6 +66,7 @@
|
|||||||
import MusicList from './components/aplayer-list.vue'
|
import MusicList from './components/aplayer-list.vue'
|
||||||
import Controls from './components/aplayer-controller.vue'
|
import Controls from './components/aplayer-controller.vue'
|
||||||
import Lyrics from './components/aplayer-lrc.vue'
|
import Lyrics from './components/aplayer-lrc.vue'
|
||||||
|
import Hls from 'hls.js'
|
||||||
import { warn } from './utils'
|
import { warn } from './utils'
|
||||||
|
|
||||||
// mutex playing instance
|
// mutex playing instance
|
||||||
@ -667,8 +668,6 @@
|
|||||||
if (this.audio.canPlayType('application/x-mpegURL') || this.audio.canPlayType('application/vnd.apple.mpegURL')) {
|
if (this.audio.canPlayType('application/x-mpegURL') || this.audio.canPlayType('application/vnd.apple.mpegURL')) {
|
||||||
this.audio.src = src
|
this.audio.src = src
|
||||||
} else {
|
} else {
|
||||||
try {
|
|
||||||
const Hls = require('hls.js')
|
|
||||||
if (Hls.isSupported()) {
|
if (Hls.isSupported()) {
|
||||||
if (!this.hls) {
|
if (!this.hls) {
|
||||||
this.hls = new Hls()
|
this.hls = new Hls()
|
||||||
@ -679,10 +678,6 @@
|
|||||||
warn('HLS is not supported on your browser')
|
warn('HLS is not supported on your browser')
|
||||||
this.audio.src = src
|
this.audio.src = src
|
||||||
}
|
}
|
||||||
} catch (e) {
|
|
||||||
warn('hls.js is required to support m3u8')
|
|
||||||
this.audio.src = src
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.audio.src = src
|
this.audio.src = src
|
||||||
|
|||||||
@ -111,11 +111,17 @@ import { useStore } from 'vuex'
|
|||||||
import hyperdown from 'hyperdown'
|
import hyperdown from 'hyperdown'
|
||||||
import { ArticleModel, TreeNodeData, TreeNodeSource } from '@/model/system/article'
|
import { ArticleModel, TreeNodeData, TreeNodeSource } from '@/model/system/article'
|
||||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||||
import { Node } from 'element-plus/lib/components/tree/src/model/node'
|
|
||||||
import { useBaseList } from '@/model/baselist'
|
import { useBaseList } from '@/model/baselist'
|
||||||
import { Page } from '@/model/common.dto'
|
import { Page } from '@/model/common.dto'
|
||||||
import http from '@/utils/http'
|
import http from '@/utils/http'
|
||||||
|
|
||||||
|
type ArticleTreeNode = {
|
||||||
|
level: number
|
||||||
|
data: Pick<TreeNodeData, 'name'>
|
||||||
|
}
|
||||||
|
|
||||||
|
type TreeDataResolver = (data: TreeNodeData[]) => void
|
||||||
|
|
||||||
class ArticlePage extends Page {
|
class ArticlePage extends Page {
|
||||||
title?: string
|
title?: string
|
||||||
createDate?: [Date, Date]
|
createDate?: [Date, Date]
|
||||||
@ -193,7 +199,7 @@ const treeProps = {
|
|||||||
children: 'children',
|
children: 'children',
|
||||||
isLeaf: 'isLeaf',
|
isLeaf: 'isLeaf',
|
||||||
}
|
}
|
||||||
async function loadTreeData(node: Node, resolve: Function) {
|
async function loadTreeData(node: ArticleTreeNode, resolve: TreeDataResolver) {
|
||||||
const childItems: TreeNodeSource[] = await http.get('/article/tree', {params: {deep: node.level, parent: node.data.name}})
|
const childItems: TreeNodeSource[] = await http.get('/article/tree', {params: {deep: node.level, parent: node.data.name}})
|
||||||
resolve(childItems.map((childItem): TreeNodeData => {
|
resolve(childItems.map((childItem): TreeNodeData => {
|
||||||
const treeNode: TreeNodeData = {
|
const treeNode: TreeNodeData = {
|
||||||
|
|||||||
12
src/vite-env.d.ts
vendored
Normal file
12
src/vite-env.d.ts
vendored
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
/// <reference types="vite/client" />
|
||||||
|
|
||||||
|
interface ImportMetaEnv {
|
||||||
|
readonly VUE_APP_API_BASE: string
|
||||||
|
readonly VUE_APP_PROXY_TARGET?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ImportMeta {
|
||||||
|
readonly env: ImportMetaEnv
|
||||||
|
}
|
||||||
|
|
||||||
|
declare const __APP_VERSION__: string
|
||||||
85
vite.config.ts
Normal file
85
vite.config.ts
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
import { execSync } from 'node:child_process'
|
||||||
|
import { fileURLToPath } from 'node:url'
|
||||||
|
import vue from '@vitejs/plugin-vue'
|
||||||
|
import AutoImport from 'unplugin-auto-import/vite'
|
||||||
|
import Components from 'unplugin-vue-components/vite'
|
||||||
|
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
|
||||||
|
import { defineConfig, loadEnv } from 'vite'
|
||||||
|
|
||||||
|
const srcDir = fileURLToPath(new URL('./src', import.meta.url))
|
||||||
|
|
||||||
|
function resolveCommitInfo() {
|
||||||
|
try {
|
||||||
|
return execSync('git show -s --format=%cs(%h)', { stdio: ['ignore', 'pipe', 'ignore'] }).toString().trim()
|
||||||
|
} catch {
|
||||||
|
return 'unknown'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default defineConfig(({ mode }) => {
|
||||||
|
const env = loadEnv(mode, process.cwd(), '')
|
||||||
|
const proxyTarget = env.VUE_APP_PROXY_TARGET || env.VITE_APP_PROXY_TARGET
|
||||||
|
|
||||||
|
return {
|
||||||
|
base: './',
|
||||||
|
envPrefix: ['VITE_', 'VUE_APP_'],
|
||||||
|
plugins: [
|
||||||
|
vue(),
|
||||||
|
AutoImport({
|
||||||
|
dts: './auto-imports.d.ts',
|
||||||
|
resolvers: [ElementPlusResolver()]
|
||||||
|
}),
|
||||||
|
Components({
|
||||||
|
dts: './components.d.ts',
|
||||||
|
resolvers: [ElementPlusResolver()]
|
||||||
|
})
|
||||||
|
],
|
||||||
|
resolve: {
|
||||||
|
alias: {
|
||||||
|
'@': srcDir
|
||||||
|
}
|
||||||
|
},
|
||||||
|
define: {
|
||||||
|
__APP_VERSION__: JSON.stringify(resolveCommitInfo())
|
||||||
|
},
|
||||||
|
server: {
|
||||||
|
port: 8080,
|
||||||
|
proxy: proxyTarget ? {
|
||||||
|
'/api': {
|
||||||
|
target: proxyTarget,
|
||||||
|
changeOrigin: true
|
||||||
|
}
|
||||||
|
} : undefined
|
||||||
|
},
|
||||||
|
build: {
|
||||||
|
sourcemap: false,
|
||||||
|
rollupOptions: {
|
||||||
|
output: {
|
||||||
|
manualChunks(id) {
|
||||||
|
if (id.includes('/node_modules/vue/') || id.includes('/node_modules/vue-router/') || id.includes('/node_modules/vuex/')) {
|
||||||
|
return 'vue'
|
||||||
|
}
|
||||||
|
if (id.includes('/node_modules/element-plus/') || id.includes('/node_modules/@element-plus/')) {
|
||||||
|
return 'element-plus'
|
||||||
|
}
|
||||||
|
if (id.includes('/node_modules/echarts/')) {
|
||||||
|
return 'echarts'
|
||||||
|
}
|
||||||
|
if (id.includes('/node_modules/hls.js/')) {
|
||||||
|
return 'media'
|
||||||
|
}
|
||||||
|
if (id.includes('/node_modules/')) {
|
||||||
|
return 'vendor'
|
||||||
|
}
|
||||||
|
if (id.includes('/src/views/system/')) {
|
||||||
|
return 'system'
|
||||||
|
}
|
||||||
|
if (id.includes('/src/views/api/')) {
|
||||||
|
return 'api'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
@ -1,61 +0,0 @@
|
|||||||
const path = require('path')
|
|
||||||
const AutoImport = require('unplugin-auto-import/webpack')
|
|
||||||
const Components = require('unplugin-vue-components/webpack')
|
|
||||||
const { ElementPlusResolver } = require('unplugin-vue-components/resolvers')
|
|
||||||
const { defineConfig } = require('@vue/cli-service')
|
|
||||||
const { DefinePlugin } = require('webpack')
|
|
||||||
const { execSync } = require('child_process')
|
|
||||||
|
|
||||||
const commitInfo = execSync('git show -s --format=%cs(%h)').toString().trim()
|
|
||||||
|
|
||||||
module.exports = defineConfig({
|
|
||||||
publicPath: './',
|
|
||||||
transpileDependencies: true,
|
|
||||||
productionSourceMap: false,
|
|
||||||
configureWebpack: {
|
|
||||||
resolve: {
|
|
||||||
alias: { '@': path.resolve(__dirname, './src') }
|
|
||||||
},
|
|
||||||
plugins: [
|
|
||||||
AutoImport({
|
|
||||||
resolvers: [ElementPlusResolver()],
|
|
||||||
}),
|
|
||||||
Components({
|
|
||||||
resolvers: [ElementPlusResolver()],
|
|
||||||
}),
|
|
||||||
new DefinePlugin({
|
|
||||||
'process.env.VERSION': `'${commitInfo}'`
|
|
||||||
})
|
|
||||||
]
|
|
||||||
},
|
|
||||||
chainWebpack: config => {
|
|
||||||
// fork-ts-checker-webpack-plugin v6 与 TypeScript 5 不兼容(无法覆写只读的 performance.mark)
|
|
||||||
// 类型检查改由 tsc --noEmit 承担
|
|
||||||
config.plugins.delete('fork-ts-checker')
|
|
||||||
|
|
||||||
// Element Plus 按需导入时,不同路由 chunk 的 CSS 导入顺序不一致,
|
|
||||||
// 但这不影响最终样式(specificity 规则优先),忽略该警告
|
|
||||||
// extract-css 仅在生产构建时存在,dev 模式下跳过
|
|
||||||
if (config.plugins.has('extract-css')) {
|
|
||||||
config.plugin('extract-css').tap(args => {
|
|
||||||
args[0].ignoreOrder = true
|
|
||||||
return args
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
devServer: {
|
|
||||||
port: 8080,
|
|
||||||
client: {
|
|
||||||
overlay: {
|
|
||||||
// ResizeObserver loop 是浏览器规范允许的良性通知,不是真实错误,过滤掉避免干扰开发
|
|
||||||
runtimeErrors: (err) => err?.message !== 'ResizeObserver loop completed with undelivered notifications.'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
proxy: {
|
|
||||||
'^/api': {
|
|
||||||
target: process.env.VUE_APP_PROXY_TARGET,
|
|
||||||
changeOrigin: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
Loading…
x
Reference in New Issue
Block a user