All files / packages/design-system/scripts/compile webpack.config.js

0% Statements 0/13
0% Branches 0/6
0% Functions 0/2
0% Lines 0/13

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128                                                                                                                                                                                                                                                               
// Copyright (c) 2015-present, salesforce.com, inc. All rights reserved
// Licensed under BSD 3-Clause - see LICENSE.txt or git.io/sfdc-license
 
const I = require('immutable');
const path = require('path');
const esbuild = require('esbuild');
const MinimizerPlugin = require('minimizer-webpack-plugin');
const webpack = require('webpack');
 
const paths = require('../helpers/paths');
 
// Minify with esbuild rather than webpack's default Terser, which took ~8s of
// the library build. The plugin's built-in `esbuildMinify` leaves license
// comments inline, so this adapter hands them back to the plugin to extract
// into `[file].LICENSE.txt`, as it does for Terser.
const esbuildMinify = async (input, sourceMap, { ecma, module, ...options }) => {
  const [[sourcefile, code]] = Object.entries(input);
  const result = await esbuild.transform(code, {
    ...options,
    // The plugin adds Terser's `ecma`/`module`; esbuild only understands `format`
    ...(module ? { format: 'esm' } : {}),
    minify: true,
    legalComments: 'external',
    sourcefile,
    sourcemap: Boolean(sourceMap),
    sourcesContent: false,
  });
  return {
    code: result.code,
    map: result.map ? JSON.parse(result.map) : undefined,
    warnings: result.warnings.map((warning) => warning.text),
    extractedComments: result.legalComments ? [result.legalComments.trim()] : [],
  };
};
Object.assign(esbuildMinify, MinimizerPlugin.esbuildMinify);
 
module.exports = I.fromJS({
  mode: 'production',
  module: {
    rules: [
      {
        test: /\.jsx?$/,
        use: [
          {
            loader: 'thread-loader',
            options: {
              workerNodeArgs: ['--max-old-space-size=1024'],
            },
          },
          {
            loader: 'babel-loader',
            options: {
              babelrc: false,
              presets: ['@babel/preset-env', ['@babel/preset-react', { runtime: 'classic' }]],
            },
          },
        ],
      },
      {
        test: /\.scss$/,
        use: [
          { loader: 'style-loader' },
          { loader: 'css-loader' },
          {
            loader: 'sass-loader',
            options: {
              // sass-loader v17 removed the `legacy` API; `modern` is the
              // default. The modern API needs load paths declared explicitly
              // (legacy implicitly searched CWD/node_modules).
              api: 'modern',
              sassOptions: {
                loadPaths: [paths.root, paths.ui, paths.node_modules],
              },
            },
          },
        ],
      },
      {
        test: /\.mdx$/,
        use: [
          {
            loader: 'thread-loader',
            options: {
              workerNodeArgs: ['--max-old-space-size=1024'],
            },
          },
          {
            loader: 'babel-loader',
            options: {
              babelrc: false,
              presets: ['@babel/preset-env', ['@babel/preset-react', { runtime: 'classic' }]],
            },
          },
          {
            loader: path.resolve(paths.root, 'scripts/compile/mdx-loader.js'),
          },
        ],
      },
    ],
  },
  optimization: {
    minimizer: [
      new MinimizerPlugin({
        minify: esbuildMinify,
        // Worker processes receive `minify` as source text, which would drop
        // this closure. In-process loses nothing: esbuild runs its own threads,
        // and the plugin then dispatches every asset at once.
        parallel: false,
        // Match Terser's output, which babel already lowers to ES5
        terserOptions: { target: 'es5' },
      }),
    ],
  },
  output: {
    globalObject: 'this',
    path: paths.dist,
    publicPath: '/assets/scripts/bundle/',
  },
  plugins: [
    new webpack.optimize.LimitChunkCountPlugin({
      maxChunks: 1, // Ensures only one chunk is generated
    }),
  ],
  resolve: {
    extensions: ['.js', '.jsx'],
  },
});