vite.config.ts
import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
// https://vite.dev/config/
export default defineConfig({
plugins: [
vue(),
],
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url)),
},
},
build: {
minify: true, // 压缩
sourcemap: true, // 使用sourcemap
rollupOptions:{
output:{
chunkFileNames: 'assets/[name]-[hash].js',
entryFileNames: 'assets/[name]-[hash].js',
assetFileNames: 'assets/[ext]/[name]-[hash].[ext]',
manualChunks:{
'vender': ['vue', 'vue-router'], // 将vue和vue-router打包到一起
'element-plus': ['element-plus'], // 将element-plus单独打包
'lodash-es': ['lodash-es'],// 将lodash-es单独打包
}
}
}
},
})
上传sourcemap的vite插件
import fs from 'fs'
import path from 'path'
import axios from 'axios'
type CustomRequest = (payload: {
/**
* 文件名
*/
filename: string
/**
* 文件路径
*/
filePath: string
/**
* 文件内容
*/
sourcemapContent: string
}) => Promise<any>
interface PluginOpts {
/**
* 接口地址
*/
url?: string
/**
* 是否删除上传成功后本地文件 默认true
*/
cleanSourcemapsAfterUpload?: boolean
/**
* 自定义上传请求,是一个promise函数
*/
customRequest?: CustomRequest
}
const TAG = '[vite-plugin-hina-sourcemap]: '
export function vitePluginSourceMap(pluginOpts: PluginOpts = {}) {
let outDir = ''
let sourcemapFiles: string[] = []
pluginOpts = {
url: '',
cleanSourcemapsAfterUpload: true,
...pluginOpts
}
function upload(filePath: string) {
console.log('TAG: ',filePath);
const { url, customRequest } = pluginOpts
return new Promise<void>((resolve, reject): void => {
const fileStream = fs.createReadStream(filePath)
const filename = path.basename(filePath)
let body = ''
fileStream.on('data', (chunk) => {
body += chunk
})
fileStream.on('end', () => {
if (typeof customRequest === 'function') {
customRequest({
filename,
filePath,
sourcemapContent: body
})
.then(() => {
resolve()
})
.catch((err) => {
reject(err)
})
} else {
axios({
url,
method: 'POST',
data: {
filename,
sourcemapContent: body
}
})
.then(() => {
resolve()
})
.catch((err) => {
reject(err)
})
}
})
})
}
return {
name: 'hina-sourcemap',
apply: 'build',
enforce: 'post',
generateBundle(options: any, bundle: any) {
const { dir } = options
outDir = dir
const fileNames = Object.keys(bundle)
sourcemapFiles = fileNames.filter((fileName) =>
fileName.endsWith('.js.map')
)
},
async closeBundle() {
const { url, cleanSourcemapsAfterUpload } = pluginOpts
if (!url) {
console.error(`${TAG}请配置接口地址url`)
return
}
const absoluteFilePaths: string[] = []
for (const filePath of sourcemapFiles) {
const file = path.join(outDir, filePath)
absoluteFilePaths.push(file)
try {
await upload(file)
console.log(`${TAG}${filePath} 上传成功`)
} catch (e) {
console.error(`${TAG}${filePath} 上传失败`)
}
}
console.log(TAG, '所有sourcemap上传完成')
if (cleanSourcemapsAfterUpload) {
absoluteFilePaths.forEach((filePath) => {
fs.unlinkSync(filePath)
})
}
}
}
}
使用
import { vitePluginSourceMap } from 'vite-plugin-sourcemap'
plugins: [
vue(),
vitePluginSourceMap({url:'http:xxx/api/uploadxxxx'}),
]