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    
@doodle/frontend-config / webpack / webpack.common.js
Size: Mime:
/* eslint-disable import/no-dynamic-require */
const path = require('path');
const { ContextReplacementPlugin } = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');

const getDoodleDependencies = require('./getDoodleDependencies');
const resolveDirName = require('./resolveDirName');

const workspaceModulePaths = {
  // These react and redux aliases are needed to force the usage of the library versions defined
  // by the main project, and prevent duplicate modules in the final bundle.
  // This happens because some of our imported modules rely on a version of react and redux that
  // is different from the one in the main project. This aliases won't be necessary anymore as
  // soon as we loosen the dependency versions on the imported libraries.
  react: resolveDirName('react'),
  'react-dom': resolveDirName('react-dom'),
  'react-redux': resolveDirName('react-redux'),
  'redux-saga': path.dirname(resolveDirName('redux-saga')),
};

const packageJson = require(path.resolve('package.json'));
const { resolvedDoodleDependenciesPaths } = getDoodleDependencies(packageJson);
const doodleDependenciesBabelifyBlacklist = [
  '@doodle/ab-connector',
  '@doodle/tagmanager',
  '@doodle/users-api-connector',
];

/**
 * This is the default webpack configuration for Doodle frontends.
 * Note: changes to this file affect all the frontends that use it.
 *
 * @param {WebpackAppParameters} parameters See {@link ../webpack.js}
 */
module.exports = parameters => {
  const { babelTargetEnv, pageTitle, manifestDescription, templateOptions } = parameters;

  const entryPoint = packageJson.main.replace(/\.js$/, `.${babelTargetEnv}.js`);

  return {
    name: babelTargetEnv,
    entry: { index: [path.resolve(entryPoint)] },
    devtool: 'source-map',
    resolve: {
      alias: {
        // Alias to the translated labels
        i18n: path.resolve('i18n'),
        ...workspaceModulePaths,
      },
    },
    module: {
      rules: [
        {
          /**
           * This section handles the processing of Javascript files. The source folder
           * and node modules scoped as "@doodle" will be transpiled using babel.
           * Refer to the babel configuration for more details.
           */
          test: /\.js$/,
          // Doodle modules expose source code, so they should *not* be excluded
          exclude: pkgPath => {
            const doodleDependenciesToBabelify = resolvedDoodleDependenciesPaths.filter(
              resolvedPath => !doodleDependenciesBabelifyBlacklist.some(dep => resolvedPath.includes(dep))
            );

            if (doodleDependenciesToBabelify.some(resolvedPath => pkgPath.startsWith(resolvedPath))) {
              // the `pkgPath` we are testing is a @doodle dependency → include it by returning `false`
              return false;
            }

            // by default, use the default `exclude`:
            return /node_modules/.test(pkgPath);
          },
          loader: 'babel-loader',
          options: {
            envName: babelTargetEnv,
          },
        },
        {
          /**
           * This section handles the processing of CSS files present in node modules that
           * are scoped as "@doodle". CSS is processed with PostCSS (refer to the dedicated
           * configuration).
           */
          test: /\.css$/,
          include: resolvedDoodleDependenciesPaths,
          use: [
            {
              loader: 'style-loader',
            },
            {
              loader: 'css-loader',
              options: {
                importLoaders: 1, // 1 loader before css-loader: style-loader
                modules: false, // use CSS Modules
              },
            },
            {
              loader: 'postcss-loader',
              options: {
                config: {
                  path: process.cwd(),
                },
              },
            },
          ],
        },
        {
          /**
           * This section handles the processing of CSS files present in the source folder of
           * the project where webpack is run. CSS is processed with PostCSS (refer to the
           * dedicated configuration).
           */
          test: /\.css$/,
          include: path.resolve('src'),
          use: [
            {
              loader: 'style-loader',
            },
            {
              loader: 'css-loader',
              options: {
                importLoaders: 1, // 1 loader before css-loader: style-loader
                modules: true, // use CSS Modules
                camelCase: 'dashes',
                localIdentName: '[local]__[hash]',
              },
            },
            {
              loader: 'postcss-loader',
              options: {
                config: {
                  path: process.cwd(),
                },
              },
            },
          ],
        },
        {
          /**
           * This section exposes svg files as require-able dependencies.
           */
          test: /\.svg/,
          loader: 'svg-react-loader',
        },
        {
          /**
           * This section exposes generic files as require-able dependencies. Add here any
           * additional resource type.
           */
          test: /\.(png|jpg|gif|ico)$/,
          loader: 'file-loader',
        },
      ],
    },
    optimization: {
      // Named modules for better debugging
      namedModules: true,
    },
    plugins: [
      /**
       * Reduces the react-intl dependencies to only the languages that we support,
       * so that the resulting bundle is smaller.
       */
      new ContextReplacementPlugin(/react-intl[/\\]locale-data$/, /da|de|en-GB|en-US|en|es|fi|fr|it|nl|no|pt-BR|pt|sv/),
      /**
       * https://webpack.js.org/plugins/html-webpack-plugin
       */
      new HtmlWebpackPlugin({
        title: pageTitle,
        // An entrypoint template must be present in the frontend project
        template: 'src/index.ejs',
        filename: 'index.html',
        description: manifestDescription,
        // custom options to configure HtmlWebpackPlugin or to expose variables in the template
        ...templateOptions,
      }),
    ],
  };
};