webpack.config.js 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. const utils = require("./utils");
  2. const path = require("path");
  3. const { VueLoaderPlugin } = require('vue-loader');
  4. const MiniCssExtractPlugin = require('mini-css-extract-plugin');
  5. const HtmlWebpackPlugin = require("html-webpack-plugin");
  6. function resolve(dir) {
  7. return path.join(__dirname, "..", dir);
  8. }
  9. module.exports = (env) => {
  10. console.log("process.env.NODE_ENV", env.NODE_ENV);
  11. return {
  12. mode: 'production',
  13. entry: {
  14. app: './src/index.js'
  15. },
  16. context: utils.pathResolve(),
  17. output: {
  18. filename: 'static/js/[name].js',
  19. path: utils.pathResolve("dist"),
  20. },
  21. resolve: {
  22. extensions: [".js", ".vue", ".json", ".scss"],
  23. alias: {
  24. "@": utils.pathResolve("src"),
  25. }
  26. },
  27. externals: {
  28. vue: "Vue",
  29. lodash: "_",
  30. echarts: "echarts",
  31. "xlsx-js-style": "XLSX",
  32. "maplibre-gl": "maplibregl",
  33. },
  34. module: {
  35. rules: [
  36. {
  37. test: /\.vue$/,
  38. loader: "vue-loader",
  39. options: {
  40. esModule: false,
  41. }
  42. },
  43. {
  44. test: /\.js$/,
  45. loader: 'babel-loader'
  46. },
  47. {
  48. test: "/\.css$/",
  49. use: [
  50. env.NODE_ENV !== 'production'
  51. ? 'vue-style-loader'
  52. : MiniCssExtractPlugin.loader,
  53. 'css-loader'
  54. ]
  55. },
  56. {
  57. test: /\.s[ac]ss$/i,
  58. use: [
  59. env.NODE_ENV !== 'production'
  60. ? 'vue-style-loader'
  61. : MiniCssExtractPlugin.loader,
  62. // 将 CSS 转化成 CommonJS 模块
  63. {
  64. loader: 'css-loader',
  65. options: { importLoaders: 1 }
  66. },
  67. // 将 Sass 编译成 CSS
  68. {
  69. loader: 'sass-loader',
  70. options: {
  71. sassOptions: {
  72. quietDeps: true,
  73. outputStyle: 'compressed'
  74. }
  75. }
  76. }
  77. ],
  78. },
  79. {
  80. test: /\.md$/,
  81. use: ["text-loader"],
  82. },
  83. {
  84. test: /\.svg$/,
  85. loader: "svg-sprite-loader",
  86. include: [resolve("src/icons")],
  87. options: {
  88. symbolId: "icon-[name]",
  89. },
  90. },
  91. {
  92. test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
  93. loader: "url-loader",
  94. exclude: [resolve("src/icons")],
  95. options: {
  96. limit: 1,
  97. name: utils.assetsPath("img/[name].[hash:7].[ext]"),
  98. },
  99. },
  100. {
  101. test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
  102. loader: "url-loader",
  103. options: {
  104. limit: 10000,
  105. name: utils.assetsPath("media/[name].[hash:7].[ext]"),
  106. },
  107. },
  108. {
  109. test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
  110. loader: "url-loader",
  111. options: {
  112. limit: 10000,
  113. name: utils.assetsPath("fonts/[name].[hash:7].[ext]"),
  114. },
  115. },
  116. {
  117. test: require.resolve("lodash"),
  118. loader: "expose-loader",
  119. options: {
  120. exposes: {
  121. globalName: "_",
  122. moduleLocalName: "lodash",
  123. },
  124. },
  125. },
  126. {
  127. test: require.resolve("moment"),
  128. loader: "expose-loader",
  129. options: {
  130. exposes: {
  131. globalName: "moment",
  132. moduleLocalName: "moment",
  133. },
  134. },
  135. }
  136. ]
  137. },
  138. // 优化
  139. optimization: {
  140. splitChunks: {
  141. // 提高到50KB
  142. minSize: 50000,
  143. // 最大尺寸约240KB
  144. minSizeReduction: 50000,
  145. // 设置最大尺寸约240KB
  146. maxSize: 244000,
  147. cacheGroups: {
  148. vendors: {
  149. test: /[\\/]node_modules[\\/](vue|element-ui|moment)[\\/]/,
  150. name: 'vendors',
  151. chunks: 'all',
  152. },
  153. // 添加common组提取公共模块
  154. common: {
  155. minChunks: 2,
  156. priority: -20,
  157. reuseExistingChunk: true,
  158. name: 'common'
  159. }
  160. }
  161. },
  162. // 添加其他优化配置
  163. removeEmptyChunks: true,
  164. mergeDuplicateChunks: true
  165. },
  166. plugins: [
  167. // 请确保引入这个插件!
  168. new VueLoaderPlugin(),
  169. new HtmlWebpackPlugin({
  170. inject: true,
  171. template: "index.html",
  172. title: "分区计量漏损控制系统",
  173. minify: {
  174. removeComments: true,
  175. collapseWhitespace: true,
  176. removeAttributeQuotes: true,
  177. },
  178. chunks: ["manifest", "vendor", "app"],
  179. }),
  180. ]
  181. }
  182. };