Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
Size: Mime:
/* eslint-disable global-require */
/* eslint-disable no-case-declarations */
const merge = require('webpack-merge');

const createCommonConfig = require('./webpack/webpack.common');

/**
 * @typedef {object} AppParameters
 *
 * @property {string} publicPath The path in which the frontend will be exposed, excluding the "/"
 * @property {object} appConfig The global app configuration that will be injected in the main HTML template
 * @property {string=} pageTitle The title of the HTML page
 * @property {string=} manifestDescription The description of the purpose of the frontend
 * @property {MocksConfiguration=} mocks The configuration for the dev environment mocks
 */
const defaultAppParameters = {
  dev: {
    publicPath: '',
    pageTitle: '(dev) Doodle',
    manifestDescription: 'Doodle development frontend',
    appConfig: {},
    mocks: {},
  },
  prod: {
    publicPath: '',
    pageTitle: 'Doodle',
    manifestDescription: 'Doodle',
    appConfig: {},
  },
};

/**
 * Merges default and override app parameters.
 * @param {object} defaults
 * @param {object} overrides
 */
function mergeAppParameters(defaults, overrides) {
  return {
    ...defaults,
    ...overrides,
    dev: {
      ...defaults.dev,
      ...overrides.dev,
      appConfig: {
        ...defaults.dev.appConfig,
        ...(overrides.dev ? overrides.dev.appConfig : {}),
      },
      mocks: {
        ...defaults.dev.mocks,
        ...(overrides.dev ? overrides.dev.mocks : {}),
      },
    },
    prod: {
      ...defaults.prod,
      ...overrides.prod,
      appConfig: {
        ...defaults.prod.appConfig,
        ...(overrides.prod ? overrides.prod.appConfig : {}),
      },
    },
  };
}

/**
 * @typedef {object} MocksConfiguration
 * @description The configuration for the mocks used in development. The swagger json must be
 * passed. It can optionally contain a map of custom handlers with keys in the form '<method> <endpoint>'
 * (e.g. 'GET /foo'). Note: method+endpoint combination MUST be present in the swagger json, otherwise
 * the custom handler will be ignored!
 * @property {string|object} swaggerJson The swagger definitions object or path to the json file, used to generate the mocks in dev mode
 * @property {object<string,function>=} routeHandlers A map of custom route handlers.
 * @see https://expressjs.com/en/api.html#router
 */

/**
 * Default configuration for React frontends.
 *
 * How to use:
 * Create a webpack.config.js file in your project and extend this configuration as
 * shown in the following example.
 *
 * @example
 * // File: web-my-frontend/webpack.config.js
 * const { generateWebpackConfig } = require('@doodle/frontend-config/webpack');
 *
 * module.exports = generateWebpackConfig({
 *  customOptions: {
 *    // custom webpack options
 *  },
 *  parameters: {
 *    dev: {
 *      publicPath: 'my-frontend',
 *      pageTitle: 'My Frontend',
 *      manifestDescription: 'My test frontend used to show how webpack configuration works',
 *      appConfig: {
 *        sentryEnvironment: 'local',
 *        // ... and more app parameters
 *      },
 *      mocks: {
 *        swaggerJson: path.resolve(__dirname, 'swagger.json'),
 *      },
 *    }
 *  }
 * });
 */
module.exports = {
  /**
   * @param {object} customWebpackOptions Custom webpack options to merge to the default configuration
   * @param {AppParameters<string,object>} appParameters Map of app parameters, per environment (i.e. 'dev' and 'prod')
   */
  generateWebpackConfig: async ({ customWebpackOptions, appParameters }) => {
    const mergedAppParameters = mergeAppParameters(defaultAppParameters, appParameters);

    switch (process.env.npm_lifecycle_event) {
      case 'start':
        const createDevConfig = require('./webpack/webpack.dev');
        return merge(
          await createCommonConfig({ babelTargetEnv: 'modern' }),
          await createDevConfig(mergedAppParameters.dev),
          customWebpackOptions
        );
      case 'build':
        const createProdConfig = require('./webpack/webpack.prod');
        return [
          merge(
            await createCommonConfig({ babelTargetEnv: 'modern' }),
            await createProdConfig({ babelTargetEnv: 'modern', ...mergedAppParameters.prod }),
            customWebpackOptions
          ),
          merge(
            await createCommonConfig({ babelTargetEnv: 'fallback' }),
            await createProdConfig({ babelTargetEnv: 'fallback', ...mergedAppParameters.prod }),
            customWebpackOptions
          ),
        ];
      default:
        break;
    }
  },
};