webpack.renderer.config.js 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. 'use strict'
  2. const IsWeb = process.env.BUILD_TARGET === 'web'
  3. process.env.BABEL_ENV = IsWeb ? 'web' : 'renderer'
  4. const path = require('path')
  5. const { dependencies } = require('../package.json')
  6. const webpack = require('webpack')
  7. const config = require('../config')
  8. const { styleLoaders } = require('./utils')
  9. const CopyWebpackPlugin = require('copy-webpack-plugin')
  10. const MiniCssExtractPlugin = require('mini-css-extract-plugin')
  11. const HtmlWebpackPlugin = require('html-webpack-plugin')
  12. const TerserPlugin = require('terser-webpack-plugin')
  13. // const ESLintPlugin = require('eslint-webpack-plugin');
  14. const { VueLoaderPlugin } = require('vue-loader')
  15. const { getConfig } = require("./utils")
  16. function resolve(dir) {
  17. return path.join(__dirname, '..', dir)
  18. }
  19. /**
  20. * List of node_modules to include in webpack bundle
  21. *
  22. * Required for specific packages like Vue UI libraries
  23. * that provide pure *.vue files that need compiling
  24. * https://simulatedgreg.gitbooks.io/electron-vue/content/en/webpack-configurations.html#white-listing-externals
  25. */
  26. let rendererConfig = {
  27. entry: IsWeb ? { web: path.join(__dirname, '../src/renderer/main.js') } : { renderer: resolve('src/renderer/main.js') },
  28. infrastructureLogging: { level: 'warn' },
  29. stats: 'none',
  30. module: {
  31. rules: [
  32. {
  33. test: /\.vue$/,
  34. loader: "vue-loader",
  35. options: {
  36. babelParserPlugins: [
  37. 'jsx',
  38. 'classProperties',
  39. 'decorators-legacy'
  40. ]
  41. }
  42. },
  43. {
  44. test: /\.jsx$/,
  45. loader: 'babel-loader',
  46. },
  47. {
  48. test: /\.html$/,
  49. use: 'vue-html-loader'
  50. },
  51. {
  52. test: /\.svg$/,
  53. loader: 'svg-sprite-loader',
  54. include: [resolve('src/renderer/icons')],
  55. options: {
  56. symbolId: 'icon-[name]'
  57. }
  58. },
  59. {
  60. test: /\.(png|jpe?g|gif)(\?.*)?$/,
  61. type: "asset/resource",
  62. generator: {
  63. filename: 'imgs/[name]--[hash].[ext]'
  64. }
  65. },
  66. {
  67. test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
  68. type: "asset/resource",
  69. generator: {
  70. filename: 'media/[name]--[hash].[ext]'
  71. }
  72. },
  73. {
  74. test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
  75. type: "asset/resource",
  76. generator: {
  77. filename: 'fonts/[name]--[hash].[ext]'
  78. }
  79. }
  80. ]
  81. },
  82. node: {
  83. __dirname: process.env.NODE_ENV !== 'production',
  84. __filename: process.env.NODE_ENV !== 'production'
  85. },
  86. plugins: [
  87. new VueLoaderPlugin(),
  88. new MiniCssExtractPlugin(),
  89. new webpack.DefinePlugin({
  90. 'process.env.userConfig': JSON.stringify(getConfig),
  91. 'process.env.IS_WEB': IsWeb
  92. }),
  93. new HtmlWebpackPlugin({
  94. filename: 'index.html',
  95. template: resolve('src/index.ejs'),
  96. minify: {
  97. collapseWhitespace: true,
  98. removeAttributeQuotes: true,
  99. removeComments: true,
  100. minifyJS: true,
  101. minifyCSS: true
  102. },
  103. templateParameters(compilation, assets, options) {
  104. return {
  105. compilation: compilation,
  106. webpack: compilation.getStats().toJson(),
  107. webpackConfig: compilation.options,
  108. htmlWebpackPlugin: {
  109. files: assets,
  110. options: options
  111. },
  112. process,
  113. };
  114. },
  115. nodeModules: false
  116. }),
  117. ],
  118. output: {
  119. filename: '[name].js',
  120. path: IsWeb ? path.join(__dirname, '../dist/web') : path.join(__dirname, '../dist/electron')
  121. },
  122. resolve: {
  123. alias: {
  124. '@': resolve('src/renderer'),
  125. 'vue$': 'vue/dist/vue.esm.js'
  126. },
  127. extensions: ['.js', '.vue', '.json', '.css', '.node']
  128. },
  129. target: IsWeb ? 'web' : 'electron-renderer'
  130. }
  131. // 将css相关得loader抽取出来
  132. rendererConfig.module.rules = rendererConfig.module.rules.concat(styleLoaders({ sourceMap: process.env.NODE_ENV !== 'production' ? config.dev.cssSourceMap : false, extract: IsWeb, minifyCss: process.env.NODE_ENV === 'production' }));
  133. (IsWeb || config.UseJsx) ? rendererConfig.module.rules.push({ test: /\.m?[jt]sx$/, use: [{ loader: 'babel-loader', options: { cacheDirectory: true } }] }) : rendererConfig.module.rules.push({ test: /\.m?[jt]s$/, loader: 'esbuild-loader', options: { loader: 'ts', } })
  134. /**
  135. * Adjust rendererConfig for development settings
  136. */
  137. if (process.env.NODE_ENV !== 'production' && !IsWeb) {
  138. rendererConfig.plugins.push(
  139. new webpack.DefinePlugin({
  140. __lib: `"${path.join(__dirname, `../${config.DllFolder}`).replace(/\\/g, '\\\\')}"`
  141. })
  142. )
  143. }
  144. /**
  145. * Adjust rendererConfig for production settings
  146. */
  147. if (process.env.NODE_ENV === 'production') {
  148. rendererConfig.plugins.push(
  149. new CopyWebpackPlugin({
  150. patterns: [
  151. {
  152. from: path.join(__dirname, '../static'),
  153. to: path.join(__dirname, '../dist/electron/static'),
  154. globOptions: {
  155. ignore: ['.*']
  156. }
  157. }
  158. ]
  159. }),
  160. new webpack.DefinePlugin({
  161. 'process.env.NODE_ENV': '"production"',
  162. }),
  163. new webpack.LoaderOptionsPlugin({
  164. minimize: true
  165. })
  166. )
  167. rendererConfig.optimization = {
  168. minimize: true,
  169. minimizer: [
  170. new TerserPlugin({
  171. terserOptions: {
  172. compress: {
  173. drop_console: true,
  174. drop_debugger: true,
  175. pure_funcs: ["console.log", "console.warn"]
  176. }
  177. }
  178. })
  179. ]
  180. }
  181. rendererConfig.optimization.splitChunks = {
  182. chunks: "async",
  183. cacheGroups: {
  184. vendor: { // 将第三方模块提取出来
  185. minSize: 30000,
  186. minChunks: 1,
  187. test: /node_modules/,
  188. chunks: 'initial',
  189. name: 'vendor',
  190. priority: 1
  191. },
  192. commons: {
  193. test: /[\\/]src[\\/]common[\\/]/,
  194. name: 'commons',
  195. minSize: 30000,
  196. minChunks: 3,
  197. chunks: 'initial',
  198. priority: -1,
  199. reuseExistingChunk: true // 这个配置允许我们使用已经存在的代码块
  200. }
  201. }
  202. }
  203. rendererConfig.optimization.runtimeChunk = { name: 'runtime' }
  204. } else {
  205. rendererConfig.devtool = 'eval-source-map'
  206. // eslint
  207. // rendererConfig.plugins.push(new ESLintPlugin(config.dev.ESLintoptions))
  208. }
  209. module.exports = rendererConfig