vue.config.js 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. /**
  2. * @description vue.config.js全局配置
  3. */
  4. const path = require('path')
  5. const {
  6. /* baseURL, */
  7. publicPath,
  8. assetsDir,
  9. outputDir,
  10. transpileDependencies,
  11. title,
  12. abbreviation,
  13. devPort,
  14. providePlugin,
  15. build7z,
  16. buildGzip,
  17. imageCompression,
  18. } = require('./src/config')
  19. // const rely = require('vue-plugin-rely')
  20. const { webpackBarName, webpackBanner } = require('./vab.config')
  21. const { version, author } = require('./package.json')
  22. const Webpack = require('webpack')
  23. const WebpackBar = require('webpackbar')
  24. const FileManagerPlugin = require('filemanager-webpack-plugin')
  25. const dayjs = require('dayjs')
  26. const dateTime = dayjs().format('YYYY-M-D HH:mm:ss')
  27. const CompressionWebpackPlugin = require('compression-webpack-plugin')
  28. const productionGzipExtensions = ['html', 'js', 'css', 'svg']
  29. process.env.VUE_APP_TITLE = title
  30. process.env.VUE_APP_AUTHOR = author
  31. process.env.VUE_APP_RANDOM = `${dayjs()}-${process.env.VUE_GITHUB_USER_NAME}`
  32. process.env.VUE_APP_UPDATE_TIME = dateTime
  33. process.env.VUE_APP_VERSION = version
  34. // process.env.VUE_APP_RELY = rely
  35. const resolve = (dir) => {
  36. return path.join(__dirname, dir)
  37. }
  38. const microServiceProxyPrefix = '/micro-srv-proxy'
  39. const restApiProxyPrefix = '/api'
  40. const richTextUploadProxyPrefix = '/weed_filer'
  41. const isHttpUrl = (url) => /^https?:\/\//i.test(url || '')
  42. const proxy = {}
  43. if (isHttpUrl(process.env.VUE_APP_MicroSrvProxy_API)) {
  44. proxy[restApiProxyPrefix] = {
  45. target: process.env.VUE_APP_MicroSrvProxy_API,
  46. ws: false,
  47. changeOrigin: true,
  48. pathRewrite: {
  49. [`^${restApiProxyPrefix}`]: '',
  50. },
  51. }
  52. proxy[microServiceProxyPrefix] = {
  53. target: process.env.VUE_APP_MicroSrvProxy_API,
  54. ws: true,
  55. changeOrigin: true,
  56. pathRewrite: {
  57. [`^${microServiceProxyPrefix}`]: '',
  58. },
  59. }
  60. }
  61. if (isHttpUrl(process.env.VUE_APP_RICHTEXT_UPLOAD_TARGET)) {
  62. proxy[richTextUploadProxyPrefix] = {
  63. target: process.env.VUE_APP_RICHTEXT_UPLOAD_TARGET,
  64. ws: false,
  65. changeOrigin: true,
  66. pathRewrite: {
  67. [`^${richTextUploadProxyPrefix}`]: '',
  68. },
  69. }
  70. }
  71. module.exports = {
  72. publicPath,
  73. assetsDir,
  74. outputDir,
  75. lintOnSave: false,
  76. transpileDependencies,
  77. devServer: {
  78. hot: true,
  79. port: devPort,
  80. open: true,
  81. noInfo: false,
  82. overlay: {
  83. warnings: true,
  84. errors: true,
  85. },
  86. // 开发环境代理:当前端和后端端口不一致时,统一经由 devServer 转发,避免浏览器 CORS 限制
  87. proxy,
  88. },
  89. configureWebpack() {
  90. return {
  91. resolve: {
  92. alias: {
  93. '~': resolve('.'),
  94. '@': resolve('src'),
  95. },
  96. },
  97. plugins: [
  98. new Webpack.ProvidePlugin(providePlugin),
  99. new WebpackBar({
  100. name: webpackBarName,
  101. }),
  102. ],
  103. }
  104. },
  105. chainWebpack(config) {
  106. config.resolve.symlinks(true)
  107. config.module.rule('svg').exclude.add(resolve('src/icon'))
  108. config.module
  109. .rule('vabIcon')
  110. .test(/\.svg$/)
  111. .include.add(resolve('src/icon'))
  112. .end()
  113. .use('svg-sprite-loader')
  114. .loader('svg-sprite-loader')
  115. .options({ symbolId: 'vab-icon-[name]' })
  116. config.when(process.env.NODE_ENV === 'development', (config) => {
  117. config.devtool('source-map')
  118. })
  119. config.when(process.env.NODE_ENV === 'production', (config) => {
  120. config.performance.set('hints', false)
  121. config.devtool('none')
  122. config.optimization.splitChunks({
  123. automaticNameDelimiter: '-',
  124. chunks: 'all',
  125. cacheGroups: {
  126. chunk: {
  127. name: 'vab-chunk',
  128. test: /[\\/]node_modules[\\/]/,
  129. minSize: 131072,
  130. maxSize: 524288,
  131. chunks: 'async',
  132. minChunks: 2,
  133. priority: 10,
  134. },
  135. vue: {
  136. name: 'vue',
  137. test: /[\\/]node_modules[\\/](vue(.*)|core-js)[\\/]/,
  138. chunks: 'initial',
  139. priority: 20,
  140. },
  141. elementUI: {
  142. name: 'element-ui',
  143. test: /[\\/]node_modules[\\/]element-ui(.*)[\\/]/,
  144. priority: 30,
  145. },
  146. extra: {
  147. name: 'vab-extra',
  148. test: resolve('src/extra'),
  149. priority: 40,
  150. },
  151. // 根据使用模块抽取公共代码
  152. // echarts: {
  153. // name: 'echarts',
  154. // test: /[\\/]node_modules[\\/](echarts|zrender|tslib)[\\/]/,
  155. // priority: 50,
  156. // },
  157. },
  158. })
  159. config.plugin('banner').use(Webpack.BannerPlugin, [`${webpackBanner}${dateTime}`])
  160. if (imageCompression)
  161. config.module
  162. .rule('images')
  163. .use('image-webpack-loader')
  164. .loader('image-webpack-loader')
  165. .options({
  166. bypassOnDebug: true,
  167. })
  168. .end()
  169. if (buildGzip)
  170. config.plugin('compression').use(CompressionWebpackPlugin, [
  171. {
  172. filename: '[path][base].gz[query]',
  173. algorithm: 'gzip',
  174. test: new RegExp('\\.(' + productionGzipExtensions.join('|') + ')$'),
  175. threshold: 8192,
  176. minRatio: 0.8,
  177. },
  178. ])
  179. if (build7z)
  180. config.plugin('fileManager').use(FileManagerPlugin, [
  181. {
  182. events: {
  183. onEnd: {
  184. archive: [
  185. {
  186. source: `./${outputDir}`,
  187. destination: `./${outputDir}/${abbreviation}_${dayjs().unix()}.zip`,
  188. },
  189. ],
  190. },
  191. },
  192. },
  193. ])
  194. })
  195. },
  196. runtimeCompiler: true,
  197. productionSourceMap: false,
  198. css: {
  199. requireModuleExtension: true,
  200. sourceMap: true,
  201. loaderOptions: {
  202. sass: {
  203. sassOptions: { outputStyle: 'expanded' },
  204. additionalData(content, loaderContext) {
  205. const { resourcePath, rootContext } = loaderContext
  206. const relativePath = path.relative(rootContext, resourcePath)
  207. if (relativePath.replace(/\\/g, '/') !== 'src/vab/styles/variables/variables.scss')
  208. return '@import "~@/vab/styles/variables/variables.scss";' + content
  209. return content
  210. },
  211. },
  212. },
  213. },
  214. }