本文檔詳細說(shuō)明了如何配置項目的打包路徑,包括輸出目錄、靜態(tài)資源路徑、公共路徑等配置選項。
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'path'
export default defineConfig({
plugins: [vue()],
// 構建配置
build: {
// 輸出目錄
outDir: 'dist',
// 靜態(tài)資源目錄
assetsDir: 'assets',
// 生成靜態(tài)資源的存放路徑
rollupOptions: {
output: {
// 分包策略
manualChunks: {
vendor: ['vue', 'vue-router'],
utils: ['lodash', 'axios']
},
// 資源文件命名
assetFileNames: 'assets/[name]-[hash].[ext]',
chunkFileNames: 'js/[name]-[hash].js',
entryFileNames: 'js/[name]-[hash].js'
}
}
},
// 開(kāi)發(fā)服務(wù)器配置
server: {
port: 3000,
open: true
},
// 路徑別名
resolve: {
alias: {
'@': path.resolve(__dirname, 'src'),
'@components': path.resolve(__dirname, 'src/components'),
'@views': path.resolve(__dirname, 'src/views'),
'@utils': path.resolve(__dirname, 'src/utils'),
'@assets': path.resolve(__dirname, 'src/assets')
}
},
// 公共基礎路徑
base: process.env.NODE_ENV === 'production' ? '/your-app/' : '/'
})
{
"compilerOptions": {
"target": "ES2020",
"useDefineForClassFields": true,
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"module": "ESNext",
"skipLibCheck": true,
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "preserve",
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
// 路徑映射
"baseUrl": ".",
"paths": {
"@/*": ["src/*"],
"@components/*": ["src/components/*"],
"@views/*": ["src/views/*"],
"@utils/*": ["src/utils/*"],
"@assets/*": ["src/assets/*"]
}
},
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
"references": [{ "path": "./tsconfig.node.json" }]
}
// vite.config.ts
export default defineConfig({
build: {
// 自定義輸出目錄
outDir: 'build', // 默認: 'dist'
assetsDir: 'static', // 默認: 'assets'
// 清空輸出目錄
emptyOutDir: true
}
})
// 根據環(huán)境設置不同的公共路徑
export default defineConfig({
base: process.env.NODE_ENV === 'production'
? '/production-path/'
: '/',
// 或者根據具體部署環(huán)境
base: process.env.VITE_BASE_URL || '/'
})
export default defineConfig({
build: {
rollupOptions: {
output: {
// 靜態(tài)資源分類(lèi)存放
assetFileNames: (assetInfo) => {
const info = assetInfo.name.split('.')
const extType = info[info.length - 1]
if (/\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/i.test(assetInfo.name)) {
return `media/[name]-[hash].[ext]`
}
if (/\.(png|jpe?g|gif|svg)(\?.*)?$/i.test(assetInfo.name)) {
return `images/[name]-[hash].[ext]`
}
if (/\.(woff2?|eot|ttf|otf)(\?.*)?$/i.test(assetInfo.name)) {
return `fonts/[name]-[hash].[ext]`
}
return `assets/[name]-[hash].[ext]`
}
}
}
}
})
# .env.development
VITE_BASE_URL=/
VITE_API_URL=http://localhost:8080/api
# .env.production
VITE_BASE_URL=/your-app/
VITE_API_URL=https://api.yoursite.com
# .env.staging
VITE_BASE_URL=/staging/
VITE_API_URL=https://staging-api.yoursite.com
export default defineConfig({
base: process.env.VITE_BASE_URL,
define: {
__API_URL__: JSON.stringify(process.env.VITE_API_URL)
}
})
{
"scripts": {
"dev": "vite",
"build": "vue-tsc && vite build",
"build:dev": "vue-tsc && vite build --mode development",
"build:staging": "vue-tsc && vite build --mode staging",
"build:prod": "vue-tsc && vite build --mode production",
"preview": "vite preview",
"analyze": "vite build --mode analyze"
}
}
問(wèn)題: 打包后靜態(tài)資源路徑錯誤
解決: 檢查 base
配置是否正確
// 確保 base 路徑以 / 開(kāi)頭和結尾
base: '/your-app/'
問(wèn)題: 打包后別名路徑無(wú)法解析 解決: 確保 vite.config.ts 和 tsconfig.json 中的路徑配置一致
問(wèn)題: 圖片等靜態(tài)資源無(wú)法正確加載 解決: 使用正確的引用方式
<!-- 正確方式 -->
<img :src="new URL('@/assets/logo.png', import.meta.url).href" alt="logo">
<!-- 或使用 public 目錄 -->
<img src="/logo.png" alt="logo">
server {
listen 80;
server_name your-domain.com;
root /var/www/your-app;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
location /assets/ {
expires 1y;
add_header Cache-Control "public, immutable";
}
}
<VirtualHost *:80>
DocumentRoot /var/www/your-app
ServerName your-domain.com
<Directory /var/www/your-app>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.html [L]
</Directory>
</VirtualHost>
/PulsAdmin/index.html
/PulsAdmin/
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'path'
export default defineConfig({
plugins: [vue()],
// 重要:設置正確的基礎路徑
base: '/PulsAdmin/',
build: {
outDir: 'dist',
assetsDir: 'assets',
rollupOptions: {
output: {
assetFileNames: 'assets/[name]-[hash].[ext]',
chunkFileNames: 'js/[name]-[hash].js',
entryFileNames: 'js/[name]-[hash].js'
}
}
},
resolve: {
alias: {
'@': path.resolve(__dirname, 'src')
}
}
})
# .env.production
VITE_BASE_URL=/PulsAdmin/
VITE_API_URL=你的API地址
import { createRouter, createWebHistory } from 'vue-router'
const router = createRouter({
// 重要:設置正確的基礎路徑
history: createWebHistory('/PulsAdmin/'),
routes: [
// 你的路由配置
]
})
export default router
<!-- 錯誤的方式 -->
<img src="/logo.png" alt="logo">
<!-- 正確的方式 -->
<img src="/PulsAdmin/logo.png" alt="logo">
<!-- 或者使用相對路徑 -->
<img src="./logo.png" alt="logo">
<!-- 推薦使用 import 方式 -->
<img :src="logoUrl" alt="logo">
<script setup>
import logoUrl from '@/assets/logo.png'
</script>
{
"scripts": {
"build:prod": "vue-tsc && vite build --mode production"
}
}
npm run build:prod
將 dist
目錄中的所有文件上傳到服務(wù)器的 /PulsAdmin/
目錄下,確保:
index.html
位于 /PulsAdmin/index.html
/PulsAdmin/assets/
等目錄下server {
listen 80;
server_name your-domain.com;
location /PulsAdmin/ {
alias /var/www/PulsAdmin/;
try_files $uri $uri/ /PulsAdmin/index.html;
index index.html;
}
location /PulsAdmin/assets/ {
alias /var/www/PulsAdmin/assets/;
expires 1y;
add_header Cache-Control "public, immutable";
}
}
dist/index.html
中的資源路徑是否都以 /PulsAdmin/
開(kāi)頭dist/assets/
目錄中的文件路徑引用http://your-domain.com/PulsAdmin/
驗證是否正常base
配置是否正確/PulsAdmin/
前綴history
配置manualChunks
進(jìn)行代碼分割最后更新: 2025/10/2