vue.config.js 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. const fs = require('fs')
  2. const path = require('path')
  3. const webpack = require('webpack')
  4. const createThemeColorReplacerPlugin = require('./config/plugin.config')
  5. // gzip 压缩
  6. const compressionWebpackPlugin = require('compression-webpack-plugin')
  7. // js,css 压缩
  8. const TerserPlugin = require('terser-webpack-plugin')
  9. // 版本自动生成
  10. const WebpackVersionPlugin = require('webpack-version-plugin')
  11. const versionConfig = require(resolve('public/version.json'))
  12. function resolve (dir) {
  13. return path.join(__dirname, dir)
  14. }
  15. /**
  16. * check production or preview(pro.loacg.com only)
  17. * @returns {boolean}
  18. */
  19. function isProd () {
  20. return process.env.NODE_ENV === 'production'
  21. }
  22. // 项目部署基础
  23. // 默认情况下,我们假设你的应用将被部署在域的根目录丄1�7
  24. // 例如:https://www.my-app.com/
  25. // 默认$1�7/'
  26. // 如果您的应用程序部署在子路径中,则需要在这指定子路径
  27. // 例如:https://www.foobar.com/my-app/
  28. // 霄1�7要将它改丄1�7/my-app/'
  29. const BASE_URL = isProd ? '/' : '/'
  30. const assetsCDN = {
  31. css: [],
  32. // https://unpkg.com/browse/vue@2.6.10/
  33. js: [
  34. BASE_URL + 'js/vue.min.js',
  35. BASE_URL + 'js/vue-router.min.js',
  36. BASE_URL + 'js/vuex.min.js',
  37. BASE_URL + 'js/axios.min.js',
  38. BASE_URL + 'js/echarts.min.js'
  39. ]
  40. }
  41. // webpack build externals
  42. const prodExternals = {
  43. vue: 'Vue',
  44. 'vue-router': 'VueRouter',
  45. vuex: 'Vuex',
  46. axios: 'axios',
  47. echarts: 'echarts',
  48. // lodash : {
  49. // commonjs: "lodash",
  50. // amd: "lodash",
  51. // root: "_" // indicates global variable
  52. // },
  53. 'mockjs2': 'Mock'
  54. }
  55. // vue.config.js
  56. const vueConfig = {
  57. runtimeCompiler: true, // 动��1�7�编译组仄1�7
  58. publicPath: BASE_URL,
  59. configureWebpack: {
  60. optimization: isProd() ? {
  61. minimize: true,
  62. minimizer: [new TerserPlugin({
  63. test: /\.js(\?.*)?$/i, // 匹配参与压缩的文仄1�7
  64. parallel: true, // 使用多进程并发运衄1�7
  65. terserOptions: { // Terser 压缩配置
  66. output: { comments: false },
  67. compress: {// console删除
  68. pure_funcs: ['console.log']
  69. }
  70. },
  71. extractComments: true // 将注释剥离到单独的文件中
  72. })]
  73. } : {},
  74. // webpack plugins
  75. plugins: [
  76. // Ignore all locale files of moment.js
  77. new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
  78. new compressionWebpackPlugin({
  79. // [file] 会被替换成原始资源��1�7�[path] 会被替换成原始资源的路径$1�7[query] 会被替换成查询字符串。默认��1�7�是 "[path].gz[query]"〄1�7
  80. filename: '[path].gz[query]', // 提示compression-webpack-plugin@3.0.0的话asset改为filename
  81. // 可以昄1�7function(buf, callback) 或��1�7�字符串。对于字符串来说依照 zlib 的算泄1�7或��1�7�1�7zopfli 的算泄1�7。默认��1�7�是 "gzip"〄1�7
  82. algorithm: 'gzip',
  83. // 扄1�7有匹配该正则的资源都会被处理。默认��1�7�是全部资源〄1�7
  84. test: new RegExp('\\.(' + ['js', 'css'].join('|') + ')$'),
  85. // 只有大小大于该��1�7�的资源会被处理。单位是 bytes。默认��1�7�是 0〄1�7
  86. threshold: 10240,
  87. // 只有压缩率小于这个��1�7�的资源才会被处理��1�7�默认��1�7�是 0.8〄1�7
  88. minRatio: 0.8
  89. }),
  90. new WebpackVersionPlugin({
  91. // You must set the cb option
  92. cb: function (hashMap) {
  93. if (!isProd()) {
  94. versionConfig.version = new Date().getTime()
  95. fs.writeFileSync(resolve('./public/version.json'), JSON.stringify(versionConfig, null, 2))
  96. }
  97. }
  98. })
  99. ],
  100. // if prod is on, add externals
  101. externals: isProd() ? prodExternals : {}
  102. },
  103. chainWebpack: (config) => {
  104. config.resolve.alias
  105. .set('@$', resolve('src'))
  106. const svgRule = config.module.rule('svg')
  107. svgRule.uses.clear()
  108. svgRule
  109. .oneOf('inline')
  110. .resourceQuery(/inline/)
  111. .use('vue-svg-icon-loader')
  112. .loader('vue-svg-icon-loader')
  113. .end()
  114. .end()
  115. .oneOf('external')
  116. .use('file-loader')
  117. .loader('file-loader')
  118. .options({
  119. name: 'assets/[name].[hash:8].[ext]'
  120. })
  121. // if prod is on
  122. // assets require on cdn
  123. if (isProd()) {
  124. config.plugin('html').tap(args => {
  125. args[0].cdn = assetsCDN
  126. return args
  127. })
  128. }
  129. config.optimization && config.optimization.splitChunks({
  130. // 拆包配置
  131. chunks: 'all', // 三��1�7�一$1�7initial" 初始化,"all"(默认就是all)$1�7async"(动态加载)
  132. minSize: 30000, // 形成丄1�7个新代码块最小的体积,只有 >= minSize 的bundle会被拆分出来 30000
  133. maxSize: 0, // 拆分之前朄1�7大的数��1�7�,默认丄1�7�即不做限制
  134. minChunks: 1, // 引入次数,如果为2 那么丄1�7个资源最少被引用两次才可以被拆分出来
  135. maxAsyncRequests: 5, // 按需加载的最大并行请求数
  136. maxInitialRequests: 4, // 丄1�7个入口最大并行请求数
  137. automaticNameDelimiter: '~', // 文件名的连接笄1�7
  138. name: true,
  139. cacheGroups: {
  140. // node_modules模块匄1�7
  141. vendors: {
  142. test: /[\\/]node_modules[\\/]/,
  143. name: 'chunk-vendors',
  144. // name(module) {
  145. // const packageName = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)[1];
  146. // return `chunk.${packageName.replace('@', '')}`;
  147. // },
  148. chunks: 'all',
  149. priority: -10
  150. },
  151. // UI库单独拆匄1�7
  152. antDesign: {
  153. name: 'chunk-antDesign',
  154. priority: 19, // the weight needs to be larger than libs and app or it will be packaged into libs or app
  155. test: /[\\/]node_modules[\\/]_?@ant-design(.*)/
  156. },
  157. antDesignVue: {
  158. name: 'chunk-antDesignVue',
  159. priority: 20, // the weight needs to be larger than libs and app or it will be packaged into libs or app
  160. test: /[\\/]node_modules[\\/]_?ant-design-vue(.*)/
  161. },
  162. // 共享模块
  163. common: {
  164. name: 'chunk-common',
  165. minChunks: 2,
  166. maxSize: 1024, // 拆分之前朄1�7大的数��1�7�,默认丄1�7�即不做限制
  167. priority: -20,
  168. reuseExistingChunk: true
  169. }
  170. }
  171. })
  172. // 分析打包大小
  173. if (process.env.npm_config_report) {
  174. config.plugin('webpack-bundle-analyzer')
  175. .use(require('webpack-bundle-analyzer').BundleAnalyzerPlugin)
  176. .end()
  177. }
  178. },
  179. css: {
  180. sourceMap: false,
  181. loaderOptions: {
  182. less: {
  183. modifyVars: {
  184. // less vars锛宑ustomize ant design theme
  185. 'primary-color': process.env.VUE_APP_THEME_COLOR,
  186. 'link-color': process.env.VUE_APP_THEME_COLOR
  187. // 'border-radius-base': '4px'
  188. },
  189. // do not remove this line
  190. javascriptEnabled: true
  191. }
  192. }
  193. },
  194. devServer: {
  195. // development server port 8000
  196. port: 8000,
  197. disableHostCheck: true,
  198. // If you want to turn on the proxy, please remove the mockjs /src/main.jsL11
  199. proxy: {
  200. '/api': {
  201. // target: 'http://192.168.2.10:8503/qpls-md',
  202. target: 'https://p.iscm.360arrow.com/qpls-md',
  203. // ws: false,
  204. ws: true,
  205. changeOrigin: true,
  206. pathRewrite: {
  207. '^/api': ''
  208. }
  209. }
  210. },
  211. watchOptions: {
  212. ignored: [/node_modules/, /public/]
  213. }
  214. },
  215. // disable source map in production
  216. productionSourceMap: false,
  217. assetsDir: 'static',
  218. lintOnSave: undefined,
  219. // babel-loader no-ignore node_modules/*
  220. transpileDependencies: []
  221. }
  222. // preview.pro.loacg.com only do not use in your production;
  223. if (process.env.VUE_APP_PREVIEW === 'true') {
  224. console.log('VUE_APP_PREVIEW', true)
  225. // add `ThemeColorReplacer` plugin to webpack plugins
  226. vueConfig.configureWebpack.plugins.push(createThemeColorReplacerPlugin())
  227. }
  228. module.exports = vueConfig