vue.config.js 7.0 KB

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