webpack.config.js 4.6 KB

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