webpack.prod.js 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. /* eslint-disable */
  2. // Merges webpack.common config with this production config
  3. const merge = require('webpack-merge');
  4. const common = require('./webpack.common.js');
  5. const webpack = require('webpack');
  6. const CleanWebpackPlugin = require('clean-webpack-plugin');
  7. // Optimisations and Compression
  8. const MiniCssExtractPlugin = require('mini-css-extract-plugin');
  9. const TerserPlugin = require('terser-webpack-plugin');
  10. const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
  11. const CompressionPlugin = require('compression-webpack-plugin');
  12. const fs = require('fs');
  13. const glob = require('glob');
  14. var WebpackOnBuildPlugin = require('on-build-webpack');
  15. const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
  16. const path = require('path')
  17. const ExtractTextPlugin = require('extract-text-webpack-plugin')
  18. const PurgecssPlugin = require('purgecss-webpack-plugin')
  19. // Optional
  20. const FaviconsWebpackPlugin = require('favicons-webpack-plugin');
  21. const PATHS = {
  22. src: path.join(__dirname, 'src')
  23. }
  24. module.exports = merge(common, {
  25. mode: 'production',
  26. stats: 'errors-only',
  27. optimization: {
  28. minimizer: [
  29. new TerserPlugin({
  30. test: /\.js(\?.*)?$/i,
  31. exclude: /node_modules/,
  32. cache: true,
  33. parallel: 4,
  34. sourceMap: true,
  35. }),
  36. new OptimizeCSSAssetsPlugin({})
  37. ],
  38. runtimeChunk: 'single',
  39. splitChunks: {
  40. chunks: 'all',
  41. // maxInitialRequests: Infinity,
  42. // minSize: 0,
  43. cacheGroups: {
  44. vendor: {
  45. test: /node_modules/, // you may add "vendor.js" here if you want to
  46. name: "node-modules",
  47. chunks: "initial",
  48. enforce: true
  49. },
  50. }
  51. },
  52. },
  53. plugins: [
  54. new MiniCssExtractPlugin({
  55. filename: 'css/[name].[hash:6].css',
  56. chunkFilename: 'css/[name].[contenthash].css',
  57. }),
  58. new ExtractTextPlugin('[name].css?[hash]'),
  59. new PurgecssPlugin({
  60. paths: glob.sync(`${PATHS.src}/*`),
  61. whitelist: ['whitelisted']
  62. }),
  63. new CleanWebpackPlugin(),
  64. new CompressionPlugin({
  65. test: /\.(js|css|html|svg)$/,
  66. filename: '[path].br[query]',
  67. algorithm: 'brotliCompress',
  68. compressionOptions: { level: 11 },
  69. threshold: 100,
  70. minRatio: 0.8,
  71. deleteOriginalAssets: false
  72. }),
  73. new CompressionPlugin({
  74. filename: '[path].gz[query]',
  75. algorithm: 'gzip',
  76. test: /\.js$|\.css$|\.html$/,
  77. threshold: 100,
  78. minRatio: 0.8,
  79. }),
  80. // new FaviconsWebpackPlugin({
  81. // // Your source logo
  82. // logo: './src/assets/images/200px-ControllerAppIcon.png',
  83. // // // The prefix for all image files (might be a folder or a name)
  84. // //prefix: 'assets/icons_[hash:6]/',
  85. // prefix: 'icons_[hash:6]/',
  86. // // // Emit all stats of the generated icons
  87. // //emitStats: false,
  88. // // // The name of the json containing all favicon information
  89. // // statsFilename: 'iconstats-[hash].json',
  90. // // // Generate a cache file with control hashes and
  91. // // // don't rebuild the favicons until those hashes change
  92. // persistentCache: true,
  93. // // // Inject the html into the html-webpack-plugin
  94. // inject: true,
  95. // // // favicon background color (see https://github.com/haydenbleasel/favicons#usage)
  96. // background: '#fff',
  97. // // // which icons should be generated (see https://github.com/haydenbleasel/favicons#usage)
  98. // icons: {
  99. // // android: false,
  100. // // appleIcon: false,
  101. // favicons: true
  102. // // firefox: true,
  103. // // windows: false
  104. // }
  105. // }),
  106. new WebpackOnBuildPlugin(function(stats) {
  107. var getDirectories = function (src, callback) {
  108. glob(`${src}/**/*(*.gz|favicon-32x32.png)`, callback);
  109. };
  110. console.log('Cleaning up previous builds');
  111. glob(`../../../build/*.S`, function (err, list) {
  112. if (err) {
  113. console.error('Error', err);
  114. } else {
  115. list.forEach(fileName=>{
  116. try {
  117. console.log(`Purging old binary file ${fileName} from C project.`);
  118. fs.unlinkSync(fileName)
  119. //file removed
  120. } catch(ferr) {
  121. console.error(ferr)
  122. }
  123. });
  124. }
  125. }
  126. );
  127. console.log('Generating C include files from webpack build output');
  128. getDirectories('./webpack/dist', function (err, list) {
  129. if (err) {
  130. console.log('Error', err);
  131. } else {
  132. const regex = /^(.*\/)([^\/]*)$/
  133. const relativeRegex = /((\w+(?<!dist)\/){0,1}[^\/]*)$/
  134. const makePathRegex = /([^\.].*)$/
  135. let exportDefHead=
  136. '/***********************************\n'+
  137. 'webpack_headers\n'+
  138. stats+'\n'+
  139. '***********************************/\n'+
  140. '#pragma once\n'+
  141. '#include <inttypes.h>\n'+
  142. 'extern const char * resource_lookups[];\n'+
  143. 'extern const uint8_t * resource_map_start[];\n'+
  144. 'extern const uint8_t * resource_map_end[];\n';
  145. let exportDef= '// Automatically generated. Do not edit manually!.\n'+
  146. '#include <inttypes.h>\n';
  147. let lookupDef='const char * resource_lookups[] = {\n';
  148. let lookupMapStart='const uint8_t * resource_map_start[] = {\n';
  149. let lookupMapEnd='const uint8_t * resource_map_end[] = {\n';
  150. let cMake='';
  151. list.forEach(fileName=>{
  152. let exportName=fileName.match(regex)[2].replace(/[\. \-]/gm,'_');
  153. let relativeName=fileName.match(relativeRegex)[1];
  154. exportDef+= 'extern const uint8_t _'+exportName+'_start[] asm("_binary_'+exportName+'_start");\n'+
  155. 'extern const uint8_t _'+exportName+'_end[] asm("_binary_'+exportName+'_end");\n';
  156. lookupDef+='\t"/'+relativeName+'",\n';
  157. lookupMapStart+='\t_'+ exportName+'_start,\n';
  158. lookupMapEnd+= '\t_'+ exportName+'_end,\n';
  159. cMake+='target_add_binary_data( __idf_wifi-manager ./webapp'+fileName.match(makePathRegex)[1]+' BINARY)\n';
  160. });
  161. lookupDef+='""\n};\n';
  162. lookupMapStart=lookupMapStart.substring(0,lookupMapStart.length-2)+'\n};\n';
  163. lookupMapEnd=lookupMapEnd.substring(0,lookupMapEnd.length-2)+'\n};\n';
  164. try {
  165. fs.writeFileSync('webapp.cmake', cMake);
  166. fs.writeFileSync('webpack.c', exportDef+lookupDef+lookupMapStart+lookupMapEnd);
  167. fs.writeFileSync('webpack.h', exportDefHead);
  168. //file written successfully
  169. } catch (e) {
  170. console.error(e);
  171. }
  172. }
  173. });
  174. console.log('Post build completed.');
  175. }),
  176. new BundleAnalyzerPlugin()
  177. ]
  178. });