You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

webpack.config.js 4.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. const cssnano = require('cssnano');
  2. const fastGlob = require('fast-glob');
  3. const FixStyleOnlyEntriesPlugin = require('webpack-fix-style-only-entries');
  4. const MiniCssExtractPlugin = require('mini-css-extract-plugin');
  5. const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
  6. const PostCSSPresetEnv = require('postcss-preset-env');
  7. const PostCSSSafeParser = require('postcss-safe-parser');
  8. const TerserPlugin = require('terser-webpack-plugin');
  9. const VueLoaderPlugin = require('vue-loader/lib/plugin');
  10. const { resolve, parse } = require('path');
  11. const { SourceMapDevToolPlugin } = require('webpack');
  12. const themes = {};
  13. for (const path of fastGlob.sync(resolve(__dirname, 'web_src/less/themes/*.less'))) {
  14. themes[parse(path).name] = [path];
  15. }
  16. module.exports = {
  17. mode: 'production',
  18. entry: {
  19. index: [
  20. resolve(__dirname, 'web_src/js/index.js'),
  21. resolve(__dirname, 'web_src/less/index.less'),
  22. ],
  23. swagger: [
  24. resolve(__dirname, 'web_src/js/swagger.js'),
  25. ],
  26. jquery: [
  27. resolve(__dirname, 'web_src/js/jquery.js'),
  28. ],
  29. ...themes,
  30. },
  31. devtool: false,
  32. output: {
  33. path: resolve(__dirname, 'public'),
  34. filename: 'js/[name].js',
  35. chunkFilename: 'js/[name].js',
  36. },
  37. optimization: {
  38. minimize: true,
  39. minimizer: [
  40. new TerserPlugin({
  41. sourceMap: true,
  42. extractComments: false,
  43. terserOptions: {
  44. output: {
  45. comments: false,
  46. },
  47. },
  48. }),
  49. new OptimizeCSSAssetsPlugin({
  50. cssProcessor: cssnano,
  51. cssProcessorOptions: {
  52. parser: PostCSSSafeParser,
  53. },
  54. cssProcessorPluginOptions: {
  55. preset: [
  56. 'default',
  57. {
  58. discardComments: {
  59. removeAll: true,
  60. },
  61. },
  62. ],
  63. },
  64. }),
  65. ],
  66. splitChunks: {
  67. chunks: 'async',
  68. name: (_, chunks) => chunks.map((item) => item.name).join('-'),
  69. }
  70. },
  71. module: {
  72. rules: [
  73. {
  74. test: /\.vue$/,
  75. exclude: /node_modules/,
  76. loader: 'vue-loader',
  77. },
  78. {
  79. test: /\.js$/,
  80. exclude: /node_modules/,
  81. use: [
  82. {
  83. loader: 'babel-loader',
  84. options: {
  85. presets: [
  86. [
  87. '@babel/preset-env',
  88. {
  89. useBuiltIns: 'usage',
  90. corejs: 3,
  91. },
  92. ],
  93. ],
  94. plugins: [
  95. [
  96. '@babel/plugin-transform-runtime',
  97. {
  98. regenerator: true,
  99. }
  100. ],
  101. '@babel/plugin-proposal-object-rest-spread',
  102. ],
  103. },
  104. },
  105. ],
  106. },
  107. {
  108. test: /\.(less|css)$/i,
  109. use: [
  110. {
  111. loader: MiniCssExtractPlugin.loader,
  112. },
  113. {
  114. loader: 'css-loader',
  115. options: {
  116. importLoaders: 2,
  117. url: false,
  118. }
  119. },
  120. {
  121. loader: 'postcss-loader',
  122. options: {
  123. plugins: () => [
  124. PostCSSPresetEnv(),
  125. ],
  126. },
  127. },
  128. {
  129. loader: 'less-loader',
  130. },
  131. ],
  132. },
  133. ],
  134. },
  135. plugins: [
  136. new VueLoaderPlugin(),
  137. // needed so themes don't generate useless js files
  138. new FixStyleOnlyEntriesPlugin({
  139. silent: true,
  140. }),
  141. new MiniCssExtractPlugin({
  142. filename: 'css/[name].css',
  143. chunkFilename: 'css/[name].css',
  144. }),
  145. new SourceMapDevToolPlugin({
  146. filename: 'js/[name].js.map',
  147. include: [
  148. 'js/index.js',
  149. ],
  150. }),
  151. ],
  152. performance: {
  153. maxEntrypointSize: 512000,
  154. maxAssetSize: 512000,
  155. assetFilter: (filename) => {
  156. if (filename.endsWith('.map')) return false;
  157. if (['js/swagger.js', 'js/highlight.js'].includes(filename)) return false;
  158. return true;
  159. },
  160. },
  161. resolve: {
  162. symlinks: false,
  163. },
  164. };