1
0

production.js 3.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. // Note: You must restart bin/webpack-dev-server for changes to take effect
  2. const path = require('path');
  3. const { URL } = require('url');
  4. const { merge } = require('webpack-merge');
  5. const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
  6. const OfflinePlugin = require('offline-plugin');
  7. const TerserPlugin = require('terser-webpack-plugin');
  8. const CompressionPlugin = require('compression-webpack-plugin');
  9. const { output } = require('./configuration');
  10. const sharedConfig = require('./shared');
  11. let attachmentHost;
  12. if (process.env.S3_ENABLED === 'true') {
  13. if (process.env.S3_ALIAS_HOST || process.env.S3_CLOUDFRONT_HOST) {
  14. attachmentHost = process.env.S3_ALIAS_HOST || process.env.S3_CLOUDFRONT_HOST;
  15. } else {
  16. attachmentHost = process.env.S3_HOSTNAME || `s3-${process.env.S3_REGION || 'us-east-1'}.amazonaws.com`;
  17. }
  18. } else if (process.env.SWIFT_ENABLED === 'true') {
  19. const { host } = new URL(process.env.SWIFT_OBJECT_URL);
  20. attachmentHost = host;
  21. } else {
  22. attachmentHost = null;
  23. }
  24. module.exports = merge(sharedConfig, {
  25. mode: 'production',
  26. devtool: 'source-map',
  27. stats: 'normal',
  28. bail: true,
  29. optimization: {
  30. minimize: true,
  31. minimizer: [
  32. new TerserPlugin({
  33. cache: true,
  34. parallel: true,
  35. sourceMap: true,
  36. }),
  37. ],
  38. },
  39. plugins: [
  40. new CompressionPlugin({
  41. filename: '[path][base].gz[query]',
  42. cache: true,
  43. test: /\.(js|css|html|json|ico|svg|eot|otf|ttf|map)$/,
  44. }),
  45. new BundleAnalyzerPlugin({ // generates report.html
  46. analyzerMode: 'static',
  47. openAnalyzer: false,
  48. logLevel: 'silent', // do not bother Webpacker, who runs with --json and parses stdout
  49. }),
  50. new OfflinePlugin({
  51. publicPath: output.publicPath, // sw.js must be served from the root to avoid scope issues
  52. safeToUseOptionalCaches: true,
  53. caches: {
  54. main: [':rest:'],
  55. additional: [':externals:'],
  56. optional: [
  57. '**/locale_*.js', // don't fetch every locale; the user only needs one
  58. '**/*_polyfills-*.js', // the user may not need polyfills
  59. '**/*.woff2', // the user may have system-fonts enabled
  60. // images/audio can be cached on-demand
  61. '**/*.png',
  62. '**/*.jpg',
  63. '**/*.jpeg',
  64. '**/*.svg',
  65. '**/*.mp3',
  66. '**/*.ogg',
  67. ],
  68. },
  69. externals: [
  70. '/emoji/1f602.svg', // used for emoji picker dropdown
  71. '/emoji/sheet_10.png', // used in emoji-mart
  72. ],
  73. excludes: [
  74. '**/*.gz',
  75. '**/*.map',
  76. 'stats.json',
  77. 'report.html',
  78. // any browser that supports ServiceWorker will support woff2
  79. '**/*.eot',
  80. '**/*.ttf',
  81. '**/*-webfont-*.svg',
  82. '**/*.woff',
  83. ],
  84. ServiceWorker: {
  85. entry: `imports-loader?additionalCode=${encodeURIComponent(`var ATTACHMENT_HOST=${JSON.stringify(attachmentHost)};`)}!${encodeURI(path.join(__dirname, '../../app/javascript/mastodon/service_worker/entry.js'))}`,
  86. cacheName: 'mastodon',
  87. output: '../assets/sw.js',
  88. publicPath: '/sw.js',
  89. minify: true,
  90. },
  91. }),
  92. ],
  93. });