vite.config.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. import { fileURLToPath, URL } from 'node:url'
  2. import { userInfo } from 'node:os'
  3. import { defineConfig } from 'vite'
  4. import vue from '@vitejs/plugin-vue'
  5. import path from 'path'
  6. import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'
  7. import vueJsx from '@vitejs/plugin-vue-jsx'
  8. import AutoImport from 'unplugin-auto-import/vite' // 自动导入ref等api
  9. // import Components from 'unplugin-vue-components/vite'
  10. // import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
  11. import rollupPluginVisualizer from 'rollup-plugin-visualizer'
  12. import vitePluginCompression from 'vite-plugin-compression'
  13. import vitePluginCdnImport, { autoComplete } from 'vite-plugin-cdn-import'
  14. import { ViteImageOptimizer } from 'vite-plugin-image-optimizer'
  15. // https://vitejs.dev/config/
  16. export default defineConfig(async ({ command, mode }) => {
  17. // 根据当前工作目录中的 `mode` 加载 .env 文件
  18. // 设置第三个参数为 '' 来加载所有环境变量,而不管是否有 `VITE_` 前缀。
  19. // const env = loadEnv(mode, process.cwd(), '')
  20. // const { ENV, VITE_BASE, VITE_BASE_API } = env
  21. process.env.VUE_APP_ENV = mode
  22. let { env } = await import('./env.js')
  23. // let env = envs[mode]
  24. // console.log(1, import.meta.env) // undefined
  25. // console.log(0, env)
  26. // process.env.VITE_APP_TITLE = env.SYSTEM_NAME_ALL
  27. return {
  28. define: {
  29. 'process.env.VUE_APP_ENV': JSON.stringify(mode),
  30. __PACK_DATETIME__: JSON.stringify(new Date().toLocaleString()),
  31. __PACK_USER__: JSON.stringify(userInfo().username),
  32. // __BASE_API__: JSON.stringify(env.BASE_API),
  33. },
  34. // 部署生产环境和开发环境下的URL。
  35. // 默认情况下,vite 会假设你的应用是被部署在一个域名的根路径上
  36. // 例如 https://www.admin.vip/。如果应用被部署在一个子路径上,你就需要用这个选项指定这个子路径。例如,如果你的应用被部署在 https://www.admin.vip/admin/,则设置 baseUrl 为 /admin/。
  37. // base: ENV === 'production' ? '/' : '/',
  38. base: env.BASE_URL || '/',
  39. resolve: {
  40. // https://cn.vitejs.dev/config/#resolve-alias
  41. alias: {
  42. '@': fileURLToPath(new URL('./src', import.meta.url)),
  43. '/@': fileURLToPath(new URL('./src', import.meta.url)),
  44. '~': fileURLToPath(new URL('./src/components', import.meta.url)),
  45. // vue: '@vue/compat',
  46. },
  47. // https://cn.vitejs.dev/config/#resolve-extensions
  48. extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json', '.vue'],
  49. },
  50. // vite 相关配置
  51. server: {
  52. port: { development: 1024, test: 1025 }[mode],
  53. host: true,
  54. open: true,
  55. proxy: {
  56. // https://cn.vitejs.dev/config/#server-proxy
  57. '/api': {
  58. target: env.BASE_API,
  59. changeOrigin: true,
  60. rewrite: (p) => p.replace(/^\/api/, ''),
  61. },
  62. },
  63. },
  64. // esbuild: {
  65. // jsxFactory: 'h',
  66. // jsxFragment: 'Fragment',
  67. // include: 'render.js',
  68. // exclude: '**/**.vue',
  69. // },
  70. build: {
  71. // outDir: 'pc',
  72. minify: 'terser',
  73. reportCompressedSize: false, // 启用/禁用 gzip 压缩大小报告
  74. // modulePreload: false, // { polyfill: false }
  75. // modulePreload: { polyfill: false },
  76. terserOptions: {
  77. compress: {
  78. //生产环境时移除console
  79. drop_console: mode == 'production',
  80. drop_debugger: mode == 'production',
  81. },
  82. },
  83. rollupOptions: {
  84. output: {
  85. assetFileNames: 'assets/[ext]/[name]-[hash][extname]',
  86. chunkFileNames: 'assets/js/[name]-[hash].js',
  87. manualChunks: (id) => {
  88. // 可以在这里打印看一下id的值,这里将node_modules中的包打包为 chunk-libs 文件
  89. // console.log(id)
  90. // if (
  91. // id.includes('node_modules') &&
  92. // (id.includes('@vue/dist/vue') || id.includes('pinia') || id.includes('vue-router'))
  93. // ) {
  94. // return 'vue-modules'
  95. // } else
  96. if (id.includes('assets/icons/svg')) {
  97. return 'icons-svg'
  98. }
  99. // if (id.includes('benz-amr-recorder')) {
  100. // return 'benz-amr-recorder'
  101. // } else if (id.includes('cos-js-sdk-v5')) {
  102. // return 'cos-js-sdk-v5'
  103. // } else if (id.includes('aliyun-oss-sdk')) {
  104. // return 'aliyun-oss-sdk'
  105. // } else if (id.includes('fabric')) {
  106. // return 'fabric'
  107. // } else if (id.includes('echarts')) {
  108. // return 'echarts'
  109. // } else if (id.includes('element-plus')) {
  110. // return 'element-plus'
  111. // } else
  112. else if (['quill-image-resize-module', 'Quill'].some((e) => id.includes(e))) {
  113. return 'quill-image-resize-module'
  114. } else if (id.includes('node_modules')) {
  115. return id.split('node_modules/')[1].split('/')[0]
  116. }
  117. // else if (id.includes('src/components')) {
  118. // return 'chunk-components'
  119. // }
  120. // else if (id.includes('views/')) {
  121. // let first = id.split('views/')[1]
  122. // if (first.includes('/')) {
  123. // return first.match(/(\w+)\/(\w+)/)[0].replace('/', '-') // a/b/c... a-b
  124. // }
  125. // return first.split('.')[0] // a.vue a
  126. // }
  127. },
  128. },
  129. },
  130. },
  131. plugins: [
  132. // '@vue/babel-plugin-jsx',
  133. vue({
  134. // template: {
  135. // compilerOptions: {
  136. // compatConfig: {
  137. // MODE: 2,
  138. // },
  139. // },
  140. // },
  141. // reactivityTransform: true,
  142. }),
  143. createSvgIconsPlugin({
  144. iconDirs: [path.resolve(process.cwd(), 'src/assets/icons/svg')],
  145. symbolId: 'icon-[dir]-[name]',
  146. }),
  147. ViteImageOptimizer({
  148. png: {
  149. // https://sharp.pixelplumbing.com/api-output#png
  150. quality: 100,
  151. },
  152. jpeg: {
  153. quality: 100,
  154. },
  155. jpg: {
  156. quality: 100,
  157. },
  158. }),
  159. AutoImport({
  160. imports: [
  161. 'vue',
  162. 'vue-router',
  163. // {
  164. // vuex: ['useStore'],
  165. // },
  166. ],
  167. // // 可以选择auto-import.d.ts生成的位置
  168. // dts: 'src/auto-import.d.ts',
  169. // resolvers: [ElementPlusResolver()],
  170. }),
  171. // Components({
  172. // resolvers: [ElementPlusResolver()],
  173. // }),
  174. vueJsx({
  175. // include: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.vue'],
  176. }),
  177. vitePluginCompression({
  178. disable: !env._ISGZIP, // 是否禁用压缩,默认为 false
  179. threshold: 10000, // 启用压缩的文件大小限制,单位是字节,默认为 0, 对大于 10kb 的文件进行压缩
  180. // filter:过滤器,对哪些类型的文件进行压缩,默认为 ‘/.(js|mjs|json|css|html)$/i’
  181. // verbose: true:是否在控制台输出压缩结果,默认为 true
  182. // deleteOriginFile:压缩后是否删除原文件,默认为 false
  183. // algorithm:采用的压缩算法,默认是 gzip
  184. // ext:生成的压缩包后缀
  185. }),
  186. env._ISCDN &&
  187. vitePluginCdnImport({
  188. prodUrl: 'https://unpkg.com/{name}@{version}/{path}',
  189. // prodUrl: 'https://cdn.bootcdn.net/ajax/libs/{name}/{version}/{path}',
  190. modules: [
  191. // autoComplete('vue'),
  192. // autoComplete('axios'),
  193. {
  194. name: 'axios', // 包名
  195. var: 'axios', // 对应cdn包导出的变量,如jQuery导出的是$
  196. version: '1.4.0',
  197. path: 'dist/axios.min.js',
  198. },
  199. {
  200. name: 'clipboard',
  201. var: 'ClipboardJS',
  202. version: '2.0.11',
  203. // path: 'https://cdn.bootcdn.net/ajax/libs/clipboard.js/2.0.11/clipboard.min.js',
  204. path: 'https://unpkg.com/clipboard@2.0.11/dist/clipboard.min.js',
  205. },
  206. {
  207. name: 'jsencrypt',
  208. var: 'JSEncrypt',
  209. version: '3.3.2',
  210. path: 'bin/jsencrypt.min.js',
  211. },
  212. {
  213. name: 'crypto-js',
  214. var: 'CryptoJS',
  215. version: '4.1.1',
  216. // path: 'crypto-js.min.js',
  217. path: 'crypto-js.js',
  218. },
  219. {
  220. name: 'nprogress',
  221. var: 'NProgress',
  222. version: '0.2.0',
  223. // path: 'nprogress.min.js',
  224. // css: 'nprogress.min.css',
  225. path: 'nprogress.js',
  226. css: 'nprogress.css',
  227. },
  228. // {
  229. // name: 'element-plus',
  230. // var: 'ElementPlus',
  231. // version: '2.3.6',
  232. // path: 'dist/index.full.js',
  233. // css: 'dist/index.css',
  234. // },
  235. // {
  236. // name: '@element-plus/icons-vue',
  237. // var: 'ElementPlusIconsVue',
  238. // version: '2.1.0',
  239. // path: 'dist/index.iife.min.js',
  240. // },
  241. {
  242. name: 'ali-oss',
  243. var: 'OSS',
  244. path: 'https://gosspublic.alicdn.com/aliyun-oss-sdk-6.17.1.min.js',
  245. },
  246. {
  247. name: 'echarts',
  248. var: 'echarts',
  249. version: '5.4.2',
  250. path: 'dist/echarts.min.js',
  251. },
  252. ],
  253. }),
  254. process.env.npm_config_report &&
  255. rollupPluginVisualizer({
  256. emitFile: false, //使用 emitFile 生成文件。 属性为 true,打包后的分析文件会出现在打包好的文件包下;设置为 false ,则会出现在项目根目录下
  257. filename: 'report.html', //生成分析网页文件名
  258. open: false, //在默认用户代理中打开生成的文件
  259. gzipSize: true, //从源代码中收集 gzip 大小并将其显示在图表中
  260. // brotliSize: true, //从源代码中收集 brotli 大小并将其显示在图表中
  261. }),
  262. ],
  263. // optimizedeps: {
  264. // esbuildoptions: {
  265. // target: 'es2020',
  266. // },
  267. // },
  268. // css: {
  269. // preprocessorOptions: {
  270. // scss: {
  271. // additionalData: `@use "@/styles/element-var.scss" as *;`,
  272. // },
  273. // },
  274. // },
  275. }
  276. })