Home Reference Source

src/services/configurations/nodeProductionConfiguration.js

  1. const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
  2. const CopyWebpackPlugin = require('copy-webpack-plugin');
  3. const ExtraWatchWebpackPlugin = require('extra-watch-webpack-plugin');
  4. const {
  5. NoEmitOnErrorsPlugin,
  6. } = require('webpack');
  7. const { provider } = require('jimple');
  8. const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
  9. const ConfigurationFile = require('../../abstracts/configurationFile');
  10. /**
  11. * Creates the specifics of a Webpack configuration for a Node target production build.
  12. * @extends {ConfigurationFile}
  13. */
  14. class WebpackNodeProductionConfiguration extends ConfigurationFile {
  15. /**
  16. * Class constructor.
  17. * @param {Events} events To reduce the configuration.
  18. * @param {PathUtils} pathUtils Required by `ConfigurationFile`
  19. * in order to build the path to
  20. * the overwrite file.
  21. * @param {WebpackBaseConfiguration} webpackBaseConfiguration The configuration this one will
  22. * extend.
  23. */
  24. constructor(
  25. events,
  26. pathUtils,
  27. webpackBaseConfiguration
  28. ) {
  29. super(
  30. pathUtils,
  31. [
  32. 'config/webpack/node.production.config.js',
  33. 'config/webpack/node.config.js',
  34. ],
  35. true,
  36. webpackBaseConfiguration
  37. );
  38. /**
  39. * A local reference for the `events` service.
  40. * @type {Events}
  41. */
  42. this.events = events;
  43. }
  44. /**
  45. * Create the configuration with the `entry`, the `output` and the plugins specifics for a
  46. * Node target production build.
  47. * This method uses the reducer events `webpack-node-production-configuration` and
  48. * `webpack-node-configuration`. It sends the configuration, the received `params` and expects
  49. * a configuration on return.
  50. * @param {WebpackConfigurationParams} params A dictionary generated by the top service building
  51. * the configuration and that includes things like the
  52. * target information, its entry settings, output
  53. * paths, etc.
  54. * @return {object}
  55. */
  56. createConfig(params) {
  57. const {
  58. entry,
  59. target,
  60. output,
  61. copy,
  62. additionalWatch,
  63. analyze,
  64. } = params;
  65. const config = {
  66. entry,
  67. output: {
  68. path: `./${target.folders.build}`,
  69. filename: output.js,
  70. chunkFilename: output.jsChunks,
  71. publicPath: '/',
  72. },
  73. plugins: [
  74. // To avoid pushing assets with errors.
  75. new NoEmitOnErrorsPlugin(),
  76. // To optimize the SCSS and remove repeated declarations.
  77. new OptimizeCssAssetsPlugin(),
  78. // Copy the files the target specified on its settings.
  79. new CopyWebpackPlugin(copy),
  80. // If there are additionals files to watch, add the plugin for it.
  81. ...(
  82. additionalWatch.length ?
  83. [new ExtraWatchWebpackPlugin({ files: additionalWatch })] :
  84. []
  85. ),
  86. // If the the bundle should be analyzed, add the plugin for it.
  87. ...(
  88. analyze ?
  89. [new BundleAnalyzerPlugin()] :
  90. []
  91. ),
  92. ],
  93. target: 'node',
  94. node: {
  95. // Avoid getting an empty `__dirname`.
  96. __dirname: false,
  97. },
  98. mode: 'production',
  99. watch: target.watch.production,
  100. };
  101. // If the target has source maps enabled...
  102. if (target.sourceMap.production) {
  103. // ...configure the devtool
  104. config.devtool = 'source-map';
  105. }
  106. // Reduce the configuration.
  107. return this.events.reduce(
  108. [
  109. 'webpack-node-production-configuration',
  110. 'webpack-node-configuration',
  111. ],
  112. config,
  113. params
  114. );
  115. }
  116. }
  117. /**
  118. * The service provider that once registered on the app container will set an instance of
  119. * `WebpackNodeProductionConfiguration` as the `webpackNodeProductionConfiguration` service.
  120. * @example
  121. * // Register it on the container
  122. * container.register(webpackNodeProductionConfiguration);
  123. * // Getting access to the service instance
  124. * const webpackNodeProdConfig = container.get('webpackNodeProductionConfiguration');
  125. * @type {Provider}
  126. */
  127. const webpackNodeProductionConfiguration = provider((app) => {
  128. app.set(
  129. 'webpackNodeProductionConfiguration',
  130. () => new WebpackNodeProductionConfiguration(
  131. app.get('events'),
  132. app.get('pathUtils'),
  133. app.get('webpackBaseConfiguration')
  134. )
  135. );
  136. });
  137.  
  138. module.exports = {
  139. WebpackNodeProductionConfiguration,
  140. webpackNodeProductionConfiguration,
  141. };