production.js 3.7 KB

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