Home Reference Source

src/services/configurations/browserProductionConfiguration.js

const resolve = require('@rollup/plugin-node-resolve');
const babel = require('rollup-plugin-babel');
const commonjs = require('@rollup/plugin-commonjs');
const sass = require('rollup-plugin-sass');
const html = require('rollup-plugin-html');
const json = require('@rollup/plugin-json');
const { terser } = require('rollup-plugin-terser');
const visualizer = require('rollup-plugin-visualizer');

const { provider } = require('jimple');
const ConfigurationFile = require('../../abstracts/configurationFile');
const {
  compression,
  copy,
  css,
  extraWatch,
  moduleReplace,
  runtimeReplace,
  stats,
  stylesheetAssets,
  stylesheetModulesFixer,
  template,
  urls,
  windowAsGlobal,
} = require('../../plugins');
/**
 * Creates the specifics of a Rollup configuration for a browser target production build.
 * @extends {ConfigurationFile}
 */
class RollupBrowserProductionConfiguration extends ConfigurationFile {
  /**
  * @param {Events} events
  * To reduce the configuration.
  * @param {PathUtils} pathUtils
  * Required by `ConfigurationFile` in order to build the path to the overwrite file.
  * @param {RollupPluginSettingsConfiguration} rollupPluginSettingsConfiguration
  * To get the plugin settings.
  */
  constructor(
    events,
    pathUtils,
    rollupPluginSettingsConfiguration
  ) {
    super(pathUtils, [
      'config/rollup/browser.production.config.js',
      'config/rollup/browser.config.js',
    ]);
    /**
     * A local reference for the `events` service.
     * @type {Events}
     */
    this.events = events;
    /**
     * A local reference for the `rollupPluginSettingsConfiguration` service.
     * @type {RollupPluginSettingsConfiguration}
     */
    this.rollupPluginSettingsConfiguration = rollupPluginSettingsConfiguration;
  }
  /**
   * Creates the complete configuration for a browser target production build.
   * This method uses the reducer events `rollup-browser-production-configuration` and
   * `rollup-browser-configuration`. It sends the configuration, the received `params` and
   * expects a configuration on return.
   * @param {RollupConfigurationParams} params A dictionary generated by the top service building
   *                                           the configuration and that includes things like the
   *                                           target information, its entry settings, output
   *                                           paths, etc.
   * @return {Object}
   */
  createConfig(params) {
    const {
      definitions,
      input,
      output,
      target,
      analyze,
    } = params;
    // Create the `stats` plugin instance.
    const statsPlugin = stats({
      path: `${target.paths.build}/`,
    });
    // Get the plugins settings.
    const pluginSettings = this.rollupPluginSettingsConfiguration.getConfig(
      params,
      statsPlugin.add
    );
    // Define the plugins list.
    const plugins = [
      statsPlugin.reset(),
      resolve(pluginSettings.resolve),
      commonjs(pluginSettings.commonjs),
      babel(pluginSettings.babel),
      windowAsGlobal(),
      runtimeReplace(definitions),
      ...(
        pluginSettings.moduleReplace.instructions.length ?
          [moduleReplace(pluginSettings.moduleReplace)] :
          []
      ),
      extraWatch(pluginSettings.extraWatch),
      sass(pluginSettings.sass),
      css(pluginSettings.css),
      stylesheetAssets(pluginSettings.stylesheetAssets),
      ...(
        target.css.modules ?
          [stylesheetModulesFixer(pluginSettings.stylesheetModulesFixer)] :
          []
      ),
      html(pluginSettings.html),
      json(pluginSettings.json),
      urls(pluginSettings.urls),
      ...(
        target.uglifyOnProduction ?
          [terser(pluginSettings.terser)] :
          []
      ),
      copy(pluginSettings.copy),
      ...(
        analyze ?
          [visualizer(pluginSettings.visualizer)] :
          []
      ),
    ];
    // If the target is not a library, push the template plugin for the HTML file.
    if (!target.library) {
      plugins.push(template(pluginSettings.template));
    }
    /**
     * If the target is not a library or has the compression setting enabled, push the plugin
     * to compress the assets using Gzip.
     */
    if (!target.library || target.libraryOptions.compress) {
      plugins.push(compression(pluginSettings.compression));
    }
    // Finally, push the `stats` _"sub plugin"_ to log the report table.
    plugins.push(statsPlugin.log(pluginSettings.statsLog));
    // Get the list of external dependencies.
    const { external } = pluginSettings.external;
    /**
     * Merge the globals settings with any globals that may have been defined on the `output`
     * object by the parent configuration.
     */
    const globals = output.globals ?
      Object.assign({}, output.globals, pluginSettings.globals) :
      pluginSettings.globals;
    // Define the configuration object.
    const config = {
      input,
      output: Object.assign({}, output, { globals }),
      plugins,
      external,
    };
    // If the watch mode is enabled, add the watch settings.
    if (target.watch.production) {
      config.watch = pluginSettings.watch;
    }
    // Return the reduced configuration.
    return this.events.reduce(
      [
        'rollup-browser-production-configuration',
        'rollup-browser-configuration',
      ],
      config,
      params
    );
  }
}
/**
 * The service provider that once registered on the app container will set an instance of
 * `RollupBrowserProductionConfiguration` as the `rollupBrowserProductionConfiguration` service.
 * @example
 * // Register it on the container
 * container.register(rollupBrowserProductionConfiguration);
 * // Getting access to the service instance
 * const rollupBrowserProdConfig = container.get('rollupBrowserProductionConfiguration');
 * @type {Provider}
 */
const rollupBrowserProductionConfiguration = provider((app) => {
  app.set('rollupBrowserProductionConfiguration', () => new RollupBrowserProductionConfiguration(
    app.get('events'),
    app.get('pathUtils'),
    app.get('rollupPluginSettingsConfiguration')
  ));
});

module.exports = {
  RollupBrowserProductionConfiguration,
  rollupBrowserProductionConfiguration,
};