webpack.config.js 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. const path = require('path');
  2. // Generates a path to the output bundle to be loaded in the browser.
  3. const getOutputPath = (app, filename) => {
  4. let appLabel = `wagtail${app}`;
  5. // Exceptions
  6. if (app === 'documents') {
  7. appLabel = 'wagtaildocs';
  8. } else if (app === 'contrib/table_block') {
  9. appLabel = 'table_block';
  10. }
  11. return path.join('wagtail', app, 'static', appLabel, 'js', filename);
  12. };
  13. // Mapping from package name to exposed global variable.
  14. const exposedDependencies = {
  15. 'focus-trap-react': 'FocusTrapReact',
  16. 'react': 'React',
  17. 'react-dom': 'ReactDOM',
  18. 'react-transition-group/CSSTransitionGroup': 'CSSTransitionGroup',
  19. 'draft-js': 'DraftJS',
  20. };
  21. module.exports = function exports() {
  22. const entrypoints = {
  23. 'admin': [
  24. 'core',
  25. 'date-time-chooser',
  26. 'draftail',
  27. 'expanding_formset',
  28. 'filtered-select',
  29. 'hallo-bootstrap',
  30. 'hallo-plugins/hallo-hr',
  31. 'hallo-plugins/hallo-requireparagraphs',
  32. 'hallo-plugins/hallo-wagtaillink',
  33. 'lock-unlock-action',
  34. 'modal-workflow',
  35. 'page-chooser-modal',
  36. 'page-chooser',
  37. 'page-editor',
  38. 'privacy-switch',
  39. 'task-chooser-modal',
  40. 'task-chooser',
  41. 'telepath/blocks',
  42. 'telepath/telepath',
  43. 'telepath/widgets',
  44. 'userbar',
  45. 'wagtailadmin',
  46. 'workflow-action',
  47. 'workflow-status',
  48. ],
  49. 'images': [
  50. 'image-chooser',
  51. 'image-chooser-telepath',
  52. ],
  53. 'documents': [
  54. 'document-chooser',
  55. 'document-chooser-telepath',
  56. ],
  57. 'snippets': [
  58. 'snippet-chooser',
  59. 'snippet-chooser-telepath',
  60. ],
  61. 'contrib/table_block': [
  62. 'table',
  63. ],
  64. };
  65. const entry = {};
  66. for (const [appName, moduleNames] of Object.entries(entrypoints)) {
  67. moduleNames.forEach(moduleName => {
  68. entry[moduleName] = {
  69. import: [`./client/src/entrypoints/${appName}/${moduleName}.js`],
  70. filename: getOutputPath(appName, moduleName) + '.js',
  71. };
  72. // Add polyfills to all bundles except userbar
  73. // polyfills.js imports from node_modules, which adds a dependency on vendor.js (produced by splitChunks)
  74. // Because userbar is supposed to run on peoples frontends, we code it using portable JS so we don't need
  75. // to pull in all the additional JS that the vendor bundle has (such as React).
  76. if (moduleName !== 'userbar') {
  77. entry[moduleName].import.push('./client/src/utils/polyfills.js');
  78. }
  79. });
  80. }
  81. return {
  82. entry: entry,
  83. output: {
  84. path: path.resolve('.'),
  85. publicPath: '/static/js/'
  86. },
  87. resolve: {
  88. extensions: ['.ts', '.tsx', '.js'],
  89. // Some libraries import Node modules but don't use them in the browser.
  90. // Tell Webpack to provide empty mocks for them so importing them works.
  91. fallback: {
  92. fs: false,
  93. net: false,
  94. tls: false,
  95. },
  96. },
  97. externals: {
  98. jquery: 'jQuery',
  99. },
  100. module: {
  101. rules: [
  102. {
  103. test: /\.(js|ts)x?$/,
  104. loader: 'ts-loader',
  105. exclude: /node_modules/,
  106. },
  107. ].concat(Object.keys(exposedDependencies).map((name) => {
  108. const globalName = exposedDependencies[name];
  109. // Create expose-loader configs for each Wagtail dependency.
  110. return {
  111. test: require.resolve(name),
  112. use: [
  113. {
  114. loader: 'expose-loader',
  115. options: {
  116. exposes: globalName,
  117. },
  118. },
  119. ],
  120. };
  121. }))
  122. },
  123. optimization: {
  124. splitChunks: {
  125. cacheGroups: {
  126. vendor: {
  127. name: getOutputPath('admin', 'vendor'),
  128. chunks: 'initial',
  129. minChunks: 2,
  130. reuseExistingChunk: true,
  131. },
  132. },
  133. },
  134. },
  135. // See https://webpack.js.org/configuration/devtool/.
  136. devtool: 'source-map',
  137. // For development mode only.
  138. watchOptions: {
  139. poll: 1000,
  140. aggregateTimeout: 300,
  141. },
  142. // Disable performance hints – currently there are much more valuable
  143. // optimizations for us to do outside of Webpack
  144. performance: {
  145. hints: false
  146. },
  147. stats: {
  148. // Add chunk information (setting this to `false` allows for a less verbose output)
  149. chunks: false,
  150. // Add the hash of the compilation
  151. hash: false,
  152. // `webpack --colors` equivalent
  153. colors: true,
  154. // Add information about the reasons why modules are included
  155. reasons: false,
  156. // Add webpack version information
  157. version: false,
  158. },
  159. };
  160. };