webpack.config.js 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. /**
  2. * @author oldj
  3. * @blog http://oldj.net
  4. */
  5. 'use strict'
  6. const path = require('path')
  7. const webpack = require('webpack')
  8. const moment = require('moment')
  9. const WebpackNotifierPlugin = require('webpack-notifier')
  10. const MiniCssExtractPlugin = require('mini-css-extract-plugin')
  11. const LESSPluginLists = require('less-plugin-lists')
  12. const TerserPlugin = require('terser-webpack-plugin')
  13. const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin')
  14. const version = require('../app/version').join('.')
  15. const mini_css_loader = {
  16. loader: MiniCssExtractPlugin.loader,
  17. options: {
  18. // you can specify a publicPath here
  19. // by default it uses publicPath in webpackOptions.output
  20. //publicPath: '../',
  21. hmr: process.env.NODE_ENV === 'development'
  22. }
  23. }
  24. module.exports = {
  25. mode: 'production',
  26. entry: {
  27. app: './app-ui/index.jsx'
  28. //, vendor: ['react', 'antd']
  29. },
  30. devtool: 'source-map',
  31. output: {
  32. path: path.join(__dirname, '..', 'app', 'ui'),
  33. filename: '[name].js',
  34. sourceMapFilename: '[name].js.map'
  35. },
  36. resolve: {
  37. extensions: ['.js', '.jsx']
  38. },
  39. module: {
  40. rules: [
  41. {
  42. test: /\.jsx?$/,
  43. //exclude: [/node_modules/],
  44. use: ['babel-loader?sourceMap']
  45. },
  46. {
  47. test: /\.css$/,
  48. exclude: /(codemirror|animate\.css)/,
  49. loader: [
  50. mini_css_loader,
  51. {
  52. loader: 'css-loader',
  53. options: {
  54. importLoaders: 1,
  55. sourceMap: true
  56. }
  57. }
  58. ]
  59. },
  60. {
  61. test: /\.less$/,
  62. exclude: /(node_modules|antd)/,
  63. loader: [
  64. mini_css_loader,
  65. //'css-loader?minimize&modules&sourceMap&localIdentName=[path][name]--[local]',
  66. //'style-loader',
  67. {
  68. loader: 'css-loader',
  69. options: {
  70. importLoaders: 2,
  71. //modules: true,
  72. //camelCase: true,
  73. //javascriptEnabled: true,
  74. sourceMap: true,
  75. modules: {
  76. mode: 'local',
  77. //context: path.resolve(__dirname, 'src'),
  78. //hashPrefix: 'wonderpen-',
  79. //localIdentName: '[path][name]__[local]--[hash:base64:5]',
  80. localIdentName: '[folder]__[name]__[local]'
  81. }
  82. }
  83. },
  84. {
  85. loader: 'less-loader?outputStyle=expanded',
  86. options: {
  87. javascriptEnabled: true,
  88. plugins: [
  89. new LESSPluginLists({advanced: true})
  90. ]
  91. }
  92. }
  93. ]
  94. },
  95. {
  96. test: /codemirror\b.*\.css|animate\.css$/,
  97. loader: [
  98. mini_css_loader,
  99. {
  100. loader: 'css-loader',
  101. options: {
  102. importLoaders: 1,
  103. sourceMap: true
  104. }
  105. }
  106. ]
  107. },
  108. {
  109. test: /antd\.less$/,
  110. loader: [
  111. mini_css_loader,
  112. //'css-loader?minimize&sourceMap',
  113. {
  114. loader: 'css-loader',
  115. options: {
  116. //importLoaders: 1,
  117. sourceMap: true
  118. }
  119. },
  120. {
  121. loader: 'less-loader',
  122. options: {
  123. javascriptEnabled: true
  124. }
  125. }
  126. ]
  127. },
  128. {
  129. test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
  130. use: [
  131. {
  132. loader: 'babel-loader'
  133. },
  134. {
  135. loader: '@svgr/webpack',
  136. options: {
  137. babel: false,
  138. icon: true,
  139. replaceAttrValues: {
  140. '#000000': 'currentColor',
  141. '#000': 'currentColor'
  142. }
  143. }
  144. }
  145. ]
  146. },
  147. {
  148. test: /\.(eot|woff|woff2|ttf|png|jpg|svg\?bg)$/,
  149. //use: 'url-loader?limit=30000&name=[name]-[hash].[ext]'
  150. use: [
  151. {
  152. loader: 'url-loader',
  153. options: {
  154. limit: 30000,
  155. name: '[name]-[hash].[ext]'
  156. }
  157. }
  158. ]
  159. }
  160. ],
  161. noParse: [/\bAgent\b/]
  162. },
  163. optimization: {
  164. minimizer: [
  165. new TerserPlugin({
  166. terserOptions: {
  167. output: {
  168. ecma: 5,
  169. comments: false,
  170. ascii_only: true
  171. }
  172. },
  173. parallel: true,
  174. cache: true,
  175. sourceMap: true
  176. }),
  177. new OptimizeCSSAssetsPlugin({})
  178. ]
  179. },
  180. plugins: [
  181. new webpack.DefinePlugin({
  182. 'process.env': {
  183. NODE_ENV: JSON.stringify('production')
  184. }
  185. }),
  186. new MiniCssExtractPlugin({
  187. // Options similar to the same options in webpackOptions.output
  188. // both options are optional
  189. filename: '[name].css',
  190. chunkFilename: '[id].css'
  191. }),
  192. new webpack.DllReferencePlugin({
  193. context: __dirname,
  194. manifest: require('../tmp/manifest.json')
  195. }),
  196. new webpack.IgnorePlugin(new RegExp('^(electron|fs|path)$')),
  197. new WebpackNotifierPlugin({
  198. title: 'SwitchHosts!',
  199. alwaysNotify: true,
  200. excludeWarnings: true
  201. }),
  202. new webpack.BannerPlugin(`SwitchHosts! [file] v${version}, ${moment().format('YYYY-MM-DD HH:mm:ss')}`)
  203. ]
  204. }