vite.config.ts 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. import { defineConfig, loadEnv } from 'vite'
  2. import vue from '@vitejs/plugin-vue'
  3. import path from 'path'
  4. import { fileURLToPath } from 'url'
  5. import vueDevTools from 'vite-plugin-vue-devtools'
  6. import viteCompression from 'vite-plugin-compression'
  7. import Components from 'unplugin-vue-components/vite'
  8. import AutoImport from 'unplugin-auto-import/vite'
  9. import ElementPlus from 'unplugin-element-plus/vite'
  10. import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
  11. import { VantResolver } from '@vant/auto-import-resolver'
  12. import tailwindcss from '@tailwindcss/vite'
  13. // import { visualizer } from 'rollup-plugin-visualizer'
  14. export default ({ mode }: { mode: string }) => {
  15. const root = process.cwd()
  16. const env = loadEnv(mode, root)
  17. const { VITE_VERSION, VITE_PORT, VITE_BASE_URL, VITE_API_URL, VITE_API_PROXY_URL } = env
  18. console.log(`🚀 API_URL = ${VITE_API_URL}`)
  19. console.log(`🚀 VERSION = ${VITE_VERSION}`)
  20. return defineConfig({
  21. define: {
  22. __APP_VERSION__: JSON.stringify(VITE_VERSION)
  23. },
  24. base: VITE_BASE_URL,
  25. server: {
  26. port: Number(VITE_PORT),
  27. proxy: {
  28. '/api': {
  29. target: VITE_API_PROXY_URL,
  30. changeOrigin: true
  31. },
  32. // Web端接口代理 - 转发到后端 /api 前缀
  33. '/web': {
  34. target: 'http://192.168.2.178:8000/api',
  35. changeOrigin: true,
  36. rewrite: (path) => `/api${path}`
  37. },
  38. // 小程序端接口代理
  39. '/mini': {
  40. target: 'http://192.168.2.178:8000/api',
  41. changeOrigin: true,
  42. rewrite: (path) => `/api${path}`
  43. }
  44. },
  45. host: true
  46. },
  47. // 路径别名
  48. resolve: {
  49. alias: {
  50. '@': fileURLToPath(new URL('./src', import.meta.url)),
  51. '@views': resolvePath('src/views'),
  52. '@imgs': resolvePath('src/assets/images'),
  53. '@icons': resolvePath('src/assets/icons'),
  54. '@utils': resolvePath('src/utils'),
  55. '@stores': resolvePath('src/store'),
  56. '@styles': resolvePath('src/assets/styles')
  57. }
  58. },
  59. build: {
  60. target: 'es2015',
  61. outDir: 'dist',
  62. chunkSizeWarningLimit: 2000,
  63. // 关闭构建末尾 gzip 体积统计,避免大项目在该阶段 OOM
  64. reportCompressedSize: false,
  65. minify: 'terser',
  66. terserOptions: {
  67. compress: {
  68. // 生产环境去除 console
  69. drop_console: true,
  70. // 生产环境去除 debugger
  71. drop_debugger: true
  72. }
  73. },
  74. dynamicImportVarsOptions: {
  75. warnOnError: true,
  76. exclude: [],
  77. include: ['src/views/**/*.vue']
  78. }
  79. },
  80. plugins: [
  81. vue(),
  82. tailwindcss(),
  83. // 自动按需导入 API
  84. AutoImport({
  85. imports: ['vue', 'vue-router', 'pinia', '@vueuse/core'],
  86. dts: 'src/types/import/auto-imports.d.ts',
  87. resolvers: [ElementPlusResolver()],
  88. eslintrc: {
  89. enabled: true,
  90. filepath: './.auto-import.json',
  91. globalsPropValue: true
  92. }
  93. }),
  94. // 自动按需导入组件
  95. Components({
  96. dts: 'src/types/import/components.d.ts',
  97. resolvers: [
  98. (componentName) => {
  99. if (componentName === 'ElTag') {
  100. return { name: 'default', from: '@/utils/patch-el-tag-empty' }
  101. }
  102. },
  103. ElementPlusResolver(),
  104. VantResolver()
  105. ]
  106. }),
  107. // 按需定制主题配置
  108. ElementPlus({
  109. useSource: true
  110. }),
  111. // 压缩
  112. viteCompression({
  113. verbose: false, // 是否在控制台输出压缩结果
  114. disable: false, // 是否禁用
  115. algorithm: 'gzip', // 压缩算法
  116. ext: '.gz', // 压缩后的文件名后缀
  117. threshold: 10240, // 只有大小大于该值的资源会被处理 10240B = 10KB
  118. deleteOriginFile: false // 压缩后是否删除原文件
  119. }),
  120. vueDevTools()
  121. // 打包分析
  122. // visualizer({
  123. // open: true,
  124. // gzipSize: true,
  125. // brotliSize: true,
  126. // filename: 'dist/stats.html' // 分析图生成的文件名及路径
  127. // }),
  128. ],
  129. // 依赖预构建:避免运行时重复请求与转换,提升首次加载速度
  130. optimizeDeps: {
  131. include: [
  132. 'echarts/core',
  133. 'echarts/charts',
  134. 'echarts/components',
  135. 'echarts/renderers',
  136. 'xlsx',
  137. 'xgplayer',
  138. 'crypto-js',
  139. 'file-saver',
  140. 'vue-img-cutter',
  141. 'element-plus/es',
  142. 'element-plus/es/components/*/style/css',
  143. 'element-plus/es/components/*/style/index'
  144. ]
  145. },
  146. css: {
  147. preprocessorOptions: {
  148. // sass variable and mixin
  149. scss: {
  150. additionalData: `
  151. @use "@styles/core/el-light.scss" as *;
  152. @use "@styles/core/mixin.scss" as *;
  153. `
  154. }
  155. },
  156. postcss: {
  157. plugins: [
  158. {
  159. postcssPlugin: 'internal:charset-removal',
  160. AtRule: {
  161. charset: (atRule) => {
  162. if (atRule.name === 'charset') {
  163. atRule.remove()
  164. }
  165. }
  166. }
  167. }
  168. ]
  169. }
  170. }
  171. })
  172. }
  173. function resolvePath(paths: string) {
  174. return path.resolve(__dirname, paths)
  175. }