You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

269 lines
10 KiB

1 week ago
  1. import { defineConfig, loadEnv } from 'vite'
  2. import vue from '@vitejs/plugin-vue'
  3. import path from 'path'
  4. import viteCompression from 'vite-plugin-compression'
  5. import Components from 'unplugin-vue-components/vite'
  6. import AutoImport from 'unplugin-auto-import/vite'
  7. import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
  8. import { fileURLToPath } from 'url'
  9. // import viteImagemin from 'vite-plugin-imagemin'
  10. // import { visualizer } from 'rollup-plugin-visualizer'
  11. // https://devtools.vuejs.org/getting-started/introduction
  12. import vueDevTools from 'vite-plugin-vue-devtools'
  13. export default ({ mode }: { mode: string }) => {
  14. const root = process.cwd()
  15. const env = loadEnv(mode, root)
  16. const { VITE_VERSION, VITE_PORT, VITE_BASE_URL, VITE_API_URL } = env
  17. console.log(`🚀 API_URL = ${VITE_API_URL}`)
  18. console.log(`🚀 VERSION = ${VITE_VERSION}`)
  19. return defineConfig({
  20. define: {
  21. __APP_VERSION__: JSON.stringify(VITE_VERSION)
  22. },
  23. base: VITE_BASE_URL,
  24. server: {
  25. port: parseInt(VITE_PORT),
  26. proxy: {
  27. '/api': {
  28. target: VITE_API_URL,
  29. changeOrigin: true,
  30. rewrite: (path) => path.replace(/^\/api/, '')
  31. }
  32. },
  33. host: true
  34. },
  35. // 路径别名
  36. resolve: {
  37. alias: {
  38. '@': fileURLToPath(new URL('./src', import.meta.url)),
  39. '@views': resolvePath('src/views'),
  40. '@imgs': resolvePath('src/assets/img'),
  41. '@icons': resolvePath('src/assets/icons'),
  42. '@utils': resolvePath('src/utils'),
  43. '@stores': resolvePath('src/store'),
  44. '@plugins': resolvePath('src/plugins'),
  45. '@styles': resolvePath('src/assets/styles')
  46. }
  47. },
  48. build: {
  49. target: 'es2015',
  50. outDir: 'dist',
  51. chunkSizeWarningLimit: 2000,
  52. minify: 'terser',
  53. terserOptions: {
  54. compress: {
  55. drop_console: true, // 生产环境去除 console
  56. drop_debugger: true // 生产环境去除 debugger
  57. }
  58. },
  59. rollupOptions: {
  60. output: {
  61. manualChunks: {
  62. vendor: ['vue', 'vue-router', 'pinia', 'element-plus']
  63. }
  64. }
  65. },
  66. dynamicImportVarsOptions: {
  67. warnOnError: true,
  68. exclude: [],
  69. include: ['src/views/**/*.vue']
  70. }
  71. },
  72. plugins: [
  73. vue(),
  74. // 自动导入 components 下面的组件,无需 import 引入
  75. Components({
  76. deep: true,
  77. extensions: ['vue'],
  78. dirs: ['src/components'], // 自动导入的组件目录
  79. resolvers: [ElementPlusResolver()],
  80. dts: 'src/types/components.d.ts' // 指定类型声明文件的路径
  81. }),
  82. AutoImport({
  83. imports: ['vue', 'vue-router', '@vueuse/core', 'pinia'],
  84. resolvers: [ElementPlusResolver()],
  85. dts: 'src/types/auto-imports.d.ts',
  86. eslintrc: {
  87. // 这里先设置成true然后pnpm dev 运行之后会生成 .auto-import.json 文件之后,在改为false
  88. enabled: true,
  89. filepath: './.auto-import.json',
  90. globalsPropValue: true
  91. }
  92. }),
  93. // 打包分析
  94. // visualizer({
  95. // open: true,
  96. // gzipSize: true,
  97. // brotliSize: true,
  98. // filename: 'dist/stats.html' // 分析图生成的文件名及路径
  99. // }),
  100. // 压缩
  101. viteCompression({
  102. verbose: true, // 是否在控制台输出压缩结果
  103. disable: false, // 是否禁用
  104. algorithm: 'gzip', // 压缩算法,可选 [ 'gzip' , 'brotliCompress' ,'deflate' , 'deflateRaw']
  105. ext: '.gz', // 压缩后的文件名后缀
  106. threshold: 10240, // 只有大小大于该值的资源会被处理 10240B = 10KB
  107. deleteOriginFile: false // 压缩后是否删除原文件
  108. }),
  109. // 图片压缩
  110. // viteImagemin({
  111. // verbose: true, // 是否在控制台输出压缩结果
  112. // // 图片压缩配置
  113. // // GIF 图片压缩配置
  114. // gifsicle: {
  115. // optimizationLevel: 4, // 优化级别 1-7,7为最高级别压缩
  116. // interlaced: false // 是否隔行扫描
  117. // },
  118. // // PNG 图片压缩配置
  119. // optipng: {
  120. // optimizationLevel: 4 // 优化级别 0-7,7为最高级别压缩
  121. // },
  122. // // JPEG 图片压缩配置
  123. // mozjpeg: {
  124. // quality: 60 // 压缩质量 0-100,值越小压缩率越高
  125. // },
  126. // // PNG 图片压缩配置(另一个压缩器)
  127. // pngquant: {
  128. // quality: [0.8, 0.9], // 压缩质量范围 0-1
  129. // speed: 4 // 压缩速度 1-11,值越大压缩速度越快,但质量可能会下降
  130. // },
  131. // // SVG 图片压缩配置
  132. // svgo: {
  133. // plugins: [
  134. // {
  135. // name: 'removeViewBox' // 移除 viewBox 属性
  136. // },
  137. // {
  138. // name: 'removeEmptyAttrs', // 移除空属性
  139. // active: false // 是否启用此插件
  140. // }
  141. // ]
  142. // }
  143. // })
  144. vueDevTools()
  145. ],
  146. // 预加载项目必需的组件
  147. optimizeDeps: {
  148. include: [
  149. 'vue',
  150. 'vue-router',
  151. 'pinia',
  152. 'axios',
  153. '@vueuse/core',
  154. 'echarts',
  155. '@wangeditor/editor',
  156. '@wangeditor/editor-for-vue',
  157. 'vue-i18n',
  158. 'element-plus/es/components/form/style/css',
  159. 'element-plus/es/components/form-item/style/css',
  160. 'element-plus/es/components/button/style/css',
  161. 'element-plus/es/components/input/style/css',
  162. 'element-plus/es/components/input-number/style/css',
  163. 'element-plus/es/components/switch/style/css',
  164. 'element-plus/es/components/upload/style/css',
  165. 'element-plus/es/components/menu/style/css',
  166. 'element-plus/es/components/col/style/css',
  167. 'element-plus/es/components/icon/style/css',
  168. 'element-plus/es/components/row/style/css',
  169. 'element-plus/es/components/tag/style/css',
  170. 'element-plus/es/components/dialog/style/css',
  171. 'element-plus/es/components/loading/style/css',
  172. 'element-plus/es/components/radio/style/css',
  173. 'element-plus/es/components/radio-group/style/css',
  174. 'element-plus/es/components/popover/style/css',
  175. 'element-plus/es/components/scrollbar/style/css',
  176. 'element-plus/es/components/tooltip/style/css',
  177. 'element-plus/es/components/dropdown/style/css',
  178. 'element-plus/es/components/dropdown-menu/style/css',
  179. 'element-plus/es/components/dropdown-item/style/css',
  180. 'element-plus/es/components/sub-menu/style/css',
  181. 'element-plus/es/components/menu-item/style/css',
  182. 'element-plus/es/components/divider/style/css',
  183. 'element-plus/es/components/card/style/css',
  184. 'element-plus/es/components/link/style/css',
  185. 'element-plus/es/components/breadcrumb/style/css',
  186. 'element-plus/es/components/breadcrumb-item/style/css',
  187. 'element-plus/es/components/table/style/css',
  188. 'element-plus/es/components/tree-select/style/css',
  189. 'element-plus/es/components/table-column/style/css',
  190. 'element-plus/es/components/select/style/css',
  191. 'element-plus/es/components/option/style/css',
  192. 'element-plus/es/components/pagination/style/css',
  193. 'element-plus/es/components/tree/style/css',
  194. 'element-plus/es/components/alert/style/css',
  195. 'element-plus/es/components/radio-button/style/css',
  196. 'element-plus/es/components/checkbox-group/style/css',
  197. 'element-plus/es/components/checkbox/style/css',
  198. 'element-plus/es/components/tabs/style/css',
  199. 'element-plus/es/components/tab-pane/style/css',
  200. 'element-plus/es/components/rate/style/css',
  201. 'element-plus/es/components/date-picker/style/css',
  202. 'element-plus/es/components/notification/style/css',
  203. 'element-plus/es/components/image/style/css',
  204. 'element-plus/es/components/statistic/style/css',
  205. 'element-plus/es/components/watermark/style/css',
  206. 'element-plus/es/components/config-provider/style/css',
  207. 'element-plus/es/components/text/style/css',
  208. 'element-plus/es/components/drawer/style/css',
  209. 'element-plus/es/components/color-picker/style/css',
  210. 'element-plus/es/components/backtop/style/css',
  211. 'element-plus/es/components/message-box/style/css',
  212. 'element-plus/es/components/skeleton/style/css',
  213. 'element-plus/es/components/skeleton/style/css',
  214. 'element-plus/es/components/skeleton-item/style/css',
  215. 'element-plus/es/components/badge/style/css',
  216. 'element-plus/es/components/steps/style/css',
  217. 'element-plus/es/components/step/style/css',
  218. 'element-plus/es/components/avatar/style/css',
  219. 'element-plus/es/components/descriptions/style/css',
  220. 'element-plus/es/components/descriptions-item/style/css',
  221. 'element-plus/es/components/checkbox-group/style/css',
  222. 'element-plus/es/components/progress/style/css',
  223. 'element-plus/es/components/image-viewer/style/css',
  224. 'element-plus/es/components/empty/style/css',
  225. 'element-plus/es/components/segmented/style/css',
  226. 'element-plus/es/components/calendar/style/css',
  227. 'element-plus/es/components/message/style/css',
  228. 'xlsx',
  229. 'file-saver',
  230. 'element-plus/es/components/timeline/style/css',
  231. 'element-plus/es/components/timeline-item/style/css',
  232. 'vue-img-cutter'
  233. ]
  234. },
  235. css: {
  236. preprocessorOptions: {
  237. // sass variable and mixin
  238. scss: {
  239. api: 'modern-compiler',
  240. additionalData: `
  241. @use "@styles/variables.scss" as *; @use "@styles/mixin.scss" as *;
  242. `
  243. }
  244. },
  245. postcss: {
  246. plugins: [
  247. {
  248. postcssPlugin: 'internal:charset-removal',
  249. AtRule: {
  250. charset: (atRule) => {
  251. if (atRule.name === 'charset') {
  252. atRule.remove()
  253. }
  254. }
  255. }
  256. }
  257. ]
  258. }
  259. }
  260. })
  261. }
  262. function resolvePath(paths: string) {
  263. return path.resolve(__dirname, paths)
  264. }