Vite的优化

46 阅读1分钟

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'}),
  ]