webpack.base.babel.js 19.2 KB
Newer Older
1 2 3 4 5
/* eslint-disable no-underscore-dangle */
/* eslint-disable no-undef */
/* eslint-disable no-shadow */
/* eslint-disable global-require */
/* eslint-disable prettier/prettier */
6
const { deepmerge, createDebug, winPath, resolve } = require('@umijs/utils');
邓晓峰's avatar
邓晓峰 committed
7
const { ESBuildPlugin, ESBuildMinifyPlugin } = require('esbuild-loader');
8
const fs = require('fs');
dengxiaofeng's avatar
dengxiaofeng committed
9 10
const path = require('path');
const webpack = require('webpack');
11
const Config = require('webpack-chain');
邓晓峰's avatar
邓晓峰 committed
12
const lodash = require('lodash');
邓晓峰's avatar
邓晓峰 committed
13
const { getTargetsAndBrowsersList, getBabelPresetOpts, getBabelOpts } = require('@umijs/bundler-utils');
邓晓峰's avatar
邓晓峰 committed
14 15 16
const { join } = require('lodash');
const terserOptions = require('./terserOptions');
const { css, createCSSRule } = require('./css');
邓晓峰's avatar
邓晓峰 committed
17
const pkg = require('../../package.json');
邓晓峰's avatar
邓晓峰 committed
18
const ASSET_PATH = process.env.ASSET_PATH || '/';
邓晓峰's avatar
邓晓峰 committed
19
const { ThemeColorReplacer, themePluginOption } = require('../../config/plugin.config');
20 21 22
let defineConfig = require('../../config/config');
const resolveDefine = require('./resolveDefine');
const { getPkgPath, shouldTransform } = require('./pkgMatch');
邓晓峰's avatar
邓晓峰 committed
23
const { TYPE_ALL_EXCLUDE, isMatch, excludeToPkgs, es5ImcompatibleVersionsToPkg } = require('./nodeModulesTransform');
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

function getUserLibDir({ library }) {
  if (
    (pkg.dependencies && pkg.dependencies[library]) ||
    (pkg.devDependencies && pkg.devDependencies[library]) ||
    // egg project using `clientDependencies` in ali tnpm
    (pkg.clientDependencies && pkg.clientDependencies[library])
  ) {
    return winPath(
      path.dirname(
        // 通过 resolve 往上找,可支持 lerna 仓库
        // lerna 仓库如果用 yarn workspace 的依赖不一定在 node_modules,可能被提到根目录,并且没有 link
        resolve.sync(`${library}/package.json`, {
          basedir: process.cwd(),
        }),
      ),
    );
  }
  return null;
}
const defaultConfig = {
  autoprefixer: {
    flexbox: 'no-2009',
  },
  cssnano: { mergeRules: false, minifyFontValues: { removeQuotes: false } },
  nodeModulesTransform: {
    type: 'all',
    exclude: [],
  },
邓晓峰's avatar
邓晓峰 committed
53
  hash: true,
54 55 56 57 58 59 60 61
  targets: {
    node: true,
    chrome: 49,
    firefox: 64,
    safari: 10,
    edge: 13,
    ios: 10,
    ie: 11,
邓晓峰's avatar
邓晓峰 committed
62
  },
63 64 65 66 67
};
module.exports = options => {
  const chainConfig = new Config();
  chainConfig.mode(options.mode);
  defineConfig = Object.assign(defineConfig, defaultConfig);
邓晓峰's avatar
邓晓峰 committed
68
  const { env } = process;
69 70 71 72
  const isDev = process.env.NODE_ENV === 'development';
  const isProd = process.env.NODE_ENV === 'production';
  const disableCompress = process.env.COMPRESS === 'none';
  const isWebpack5 = webpack.version.startsWith('5');
73
  const cwd = process.cwd();
74 75
  const devtool = options.devtool || false;

邓晓峰's avatar
邓晓峰 committed
76
  chainConfig.devtool(isDev ? (devtool === false ? false : devtool || 'cheap-module-source-map') : devtool);
邓晓峰's avatar
邓晓峰 committed
77
  const { mfsu } = defineConfig;
78
  const useHash = defineConfig.hash && isProd;
邓晓峰's avatar
邓晓峰 committed
79

80
  const absOutputPath = process.env.npm_config_releasepath
邓晓峰's avatar
邓晓峰 committed
81
    ? path.resolve(process.env.npm_config_releasepath, pkg.name.toLocaleLowerCase())
82 83 84 85 86
    : path.resolve(process.cwd(), pkg.name.toLocaleLowerCase());

  chainConfig.output
    .path(absOutputPath)
    .filename(useHash ? `[name].[contenthash:8].js` : `[name].js`)
邓晓峰's avatar
邓晓峰 committed
87
    .chunkFilename(useHash ? `[name].[contenthash:8].async.js` : `[name].js`)
88
    .publicPath(`/${pkg.name.toLocaleLowerCase()}/`)
邓晓峰's avatar
邓晓峰 committed
89
    // .futureEmitAssets(true)
90 91 92
    .crossOriginLoading('anonymous')
    .pathinfo(isDev || disableCompress);

邓晓峰's avatar
邓晓峰 committed
93 94 95 96
  if (!isWebpack5) {
    chainConfig.output.futureEmitAssets(true);
  }
  if (isWebpack5) {
邓晓峰's avatar
邓晓峰 committed
97 98 99
    chainConfig.cache({
      type: 'filesystem',
      buildDependencies: {
邓晓峰's avatar
邓晓峰 committed
100
        config: [__filename, path.join(process.cwd(), 'package.json')],
邓晓峰's avatar
邓晓峰 committed
101
      },
邓晓峰's avatar
邓晓峰 committed
102 103 104 105
      cacheDirectory: path.resolve(process.cwd(), 'node_modules/.cache'),
      compression: 'gzip',
      version: `${process.env.GIT_REV}`,
    });
邓晓峰's avatar
邓晓峰 committed
106
  }
107 108 109 110
  chainConfig.resolve.modules
    .add('node_modules')
    .add('src')
    .end()
邓晓峰's avatar
邓晓峰 committed
111
    .extensions.merge([
邓晓峰's avatar
邓晓峰 committed
112 113 114
      '.js',
      '.jsx',
      '.react.js',
邓晓峰's avatar
邓晓峰 committed
115 116 117 118 119 120 121 122 123 124
      '.web.js',
      '.wasm',
      '.mjs',
      '.js',
      '.web.jsx',
      '.jsx',
      '.web.ts',
      '.ts',
      '.web.tsx',
      '.tsx',
邓晓峰's avatar
邓晓峰 committed
125
      '.json',
邓晓峰's avatar
邓晓峰 committed
126
    ])
127 128 129 130
    .end()
    .mainFields.merge(['browser', 'jsnext:main', 'main']);

  const libraries = [
dengxiaofeng's avatar
dengxiaofeng committed
131
    {
132 133
      name: 'react',
      path: path.dirname(require.resolve(`react/package.json`)),
dengxiaofeng's avatar
dengxiaofeng committed
134
    },
135 136 137 138 139 140 141
    {
      name: 'react-dom',
      path: path.dirname(require.resolve(`react-dom/package.json`)),
    },
  ];

  libraries.forEach(library => {
邓晓峰's avatar
邓晓峰 committed
142
    chainConfig.resolve.alias.set(library.name, getUserLibDir({ library: library.name }) || library.path);
143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
  });

  chainConfig.resolve.alias.set('@', path.join(__dirname, '../../', 'src'));

  if (defineConfig.alias) {
    Object.keys(defineConfig.alias).forEach(key => {
      chainConfig.resolve.alias.set(key, defineConfig.alias[key]);
    });
  }

  chainConfig.target('web');

  const { targets, browserslist } = getTargetsAndBrowsersList({
    config: defineConfig,
    type: 'csr',
  });

邓晓峰's avatar
邓晓峰 committed
160
  const presetOpts = getBabelPresetOpts({
161 162
    config: defineConfig,
    env: process.env.NODE_ENV,
邓晓峰's avatar
邓晓峰 committed
163
    targets,
164 165
  });

邓晓峰's avatar
邓晓峰 committed
166
  // eslint-disable-next-line global-require
邓晓峰's avatar
邓晓峰 committed
167
  const preset = require('./babel-preset');
168 169 170 171 172 173 174 175 176 177 178 179 180
  const getPreset = preset({
    ...presetOpts,
    env: {
      useBuiltIns: 'entry',
      corejs: 3,
      modules: false,
    },
    react: {
      development: isDev,
    },
    reactRemovePropTypes: isProd,
    reactRequire: true,
    lockCoreJS3: {},
邓晓峰's avatar
邓晓峰 committed
181
    // import: (presetOpts.import || []).concat([{ libraryName: 'antd', libraryDirectory: 'es', style: true }]),
182
  });
邓晓峰's avatar
邓晓峰 committed
183
  const babelOpts = {
184 185 186
    sourceType: 'unambiguous',
    babelrc: false,
    presets: [...getPreset.presets, ...(defineConfig.extraBabelPresets || [])],
邓晓峰's avatar
邓晓峰 committed
187
    plugins: [...getPreset.plugins, ...(defineConfig.extraBabelPlugins || [])].filter(Boolean),
188
    env: getPreset.env,
邓晓峰's avatar
邓晓峰 committed
189
    compact: false,
190 191 192 193 194
  };

  chainConfig.module
    .rule('js')
    .test(/\.(js|mjs|jsx|ts|tsx)$/)
邓晓峰's avatar
邓晓峰 committed
195
    .include.add([cwd, ...(process.env.APP_ROOT ? [process.cwd()] : [])])
邓晓峰's avatar
邓晓峰 committed
196 197 198
    .end()
    .exclude.add(/node_modules/)
    .add(/\.mfsu/)
199 200
    .end()
    .use('babel-loader')
201
    .loader(require.resolve('@umijs/deps/compiled/babel-loader'))
202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224
    .options(babelOpts);

  if (defineConfig.extraBabelIncludes) {
    defineConfig.extraBabelIncludes.forEach((include, index) => {
      const rule = `extraBabelInclude_${index}`;
      chainConfig.module
        .rule(rule)
        .test(/\.(js|mjs|jsx)$/)
        .include.add(a => {
          if (path.isAbsolute(include)) {
            return path.isAbsolute(include);
          }
          if (!a.includes('node_modules')) return false;
          const pkgPath = getPkgPath(a);
          return shouldTransform(pkgPath, include);
        })
        .end()
        .use('babel-loader')
        .loader(require.resolve('babel-loader'))
        .options(babelOpts);
    });
  }

225 226
  const staticDir = mfsu ? 'mf-static' : 'static';

227 228 229 230 231 232 233
  chainConfig.module
    .rule('images')
    .test(/\.(png|jpe?g|gif|webp|ico)(\?.*)?$/)
    .use('url-loader')
    .loader(require.resolve('url-loader'))
    .options({
      limit: defineConfig.inlineLimit || 10000,
234
      name: `${staticDir}/[name].[hash:8].[ext]`,
235 236 237 238 239
      // require 图片的时候不用加 .default
      esModule: false,
      fallback: {
        loader: require.resolve('file-loader'),
        options: {
240
          name: `${staticDir}/[name].[hash:8].[ext]`,
241
          esModule: false,
dengxiaofeng's avatar
dengxiaofeng committed
242 243
        },
      },
244
    });
邓晓峰's avatar
邓晓峰 committed
245

246 247 248 249
  chainConfig.module
    .rule('avif')
    .test(/\.(avif)(\?.*)?$/)
    .use('file-loader')
邓晓峰's avatar
邓晓峰 committed
250 251 252 253 254
    .loader(require.resolve('file-loader'))
    .options({
      name: `${staticDir}/[name].[hash:8].[ext]`,
      esModule: false,
    });
255

256 257 258 259
  chainConfig.module
    .rule('svg')
    .test(/\.(svg)(\?.*)?$/)
    .use('file-loader')
邓晓峰's avatar
邓晓峰 committed
260
    .loader(require.resolve('@umijs/deps/compiled/file-loader'))
261
    .options({
262
      name: `${staticDir}/[name].[hash:8].[ext]`,
263 264 265 266 267 268 269 270 271 272
      esModule: false,
    })
    .end();

  chainConfig.module
    .rule('fonts')
    .test(/\.(eot|woff|woff2|ttf)(\?.*)?$/)
    .use('file-loader')
    .loader(require.resolve('file-loader'))
    .options({
273
      name: `${staticDir}/[name].[hash:8].[ext]`,
274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292
      esModule: false,
    });

  chainConfig.module
    .rule('mdeia')
    .test(/\.(mp4|webm)$/)
    .use('url-loader')
    .loader(require.resolve('url-loader'))
    .options({
      limit: 10000,
      outputPath: 'static',
    });

  chainConfig.module
    .rule('plaintext')
    .test(/\.(txt|text|md)$/)
    .use('raw-loader')
    .loader(require.resolve('raw-loader'));

邓晓峰's avatar
邓晓峰 committed
293
  if (defineConfig.workerLoader) {
294 295 296 297
    chainConfig.module
      .rule('worker')
      .test(/.*worker.(ts|js)/)
      .use('worker-loader')
邓晓峰's avatar
邓晓峰 committed
298 299 300
      .loader(require.resolve('@umijs/deps/compiled/worker-loader'))
      .options(defineConfig.workerLoader);
  }
301

302 303 304 305 306 307 308 309 310 311 312 313 314 315
  css({
    type: 'csr',
    config: defineConfig,
    webpackConfig: chainConfig,
    isDev,
    disableCompress,
    browserslist,
    miniCSSExtractPluginPath: '',
    miniCSSExtractPluginLoaderPath: '',
  });

  if (defineConfig.externals) {
    chainConfig.externals(defineConfig.externals);
  }
邓晓峰's avatar
邓晓峰 committed
316
  if (!isWebpack5) {
邓晓峰's avatar
邓晓峰 committed
317 318 319 320 321 322 323 324 325 326 327 328 329 330
    chainConfig.node.merge({
      setImmediate: false,
      module: 'empty',
      dns: 'mock',
      http2: 'empty',
      process: 'mock',
      dgram: 'empty',
      fs: 'empty',
      net: 'empty',
      tls: 'empty',
      child_process: 'empty',
      ...options.node,
    });
  }
331 332 333

  if (defineConfig.ignoreMomentLocale) {
    chainConfig.plugin('ignore-moment-locale').use(webpack.IgnorePlugin, [
dengxiaofeng's avatar
dengxiaofeng committed
334
      {
335 336
        resourceRegExp: /^\.\/locale$/,
        contextRegExp: /moment$/,
dengxiaofeng's avatar
dengxiaofeng committed
337
      },
338 339 340 341 342 343 344 345 346 347 348 349 350
    ]);
  }

  chainConfig.plugin('define').use(webpack.DefinePlugin, [
    resolveDefine({
      define: Object.assign(defineConfig.define || {}, {
        'process.env.ASSET_PATH': JSON.stringify(ASSET_PATH),
        'process.env.MOCK': JSON.stringify(true),
        paths: {
          cwd: process.cwd(),
          absNodeModulesPath: path.join(process.cwd(), 'node_modules'),
          absSrcPath: path.join(process.cwd(), 'src'),
          absPagesPath: path.join(process.cwd(), 'src/pages'),
dengxiaofeng's avatar
dengxiaofeng committed
351
        },
352
      }),
dengxiaofeng's avatar
dengxiaofeng committed
353
    }),
354 355 356 357 358 359
  ]);

  const baseHtmlOptions = {
    inject: true,
    template: 'src/index.ejs',
    favicon: defineConfig.favicon ? defineConfig.favicon : false,
邓晓峰's avatar
邓晓峰 committed
360
    title: defineConfig.title && defineConfig.title !== false ? defineConfig.title : '',
361 362 363
    chunks: defaultConfig.chunks ? defaultConfig.chunks : 'all',
  };
  const htmlPluginOptions = isDev
364 365
    ? { ...babelOpts }
    : { ...baseHtmlOptions, minify: { removeComments: true, collapseWhitespace: true, removeRedundantAttributes: true, useShortDoctype: true, removeEmptyAttributes: true, removeStyleLinkTypeAttributes: true, keepClosingSlash: true, minifyJS: true, minifyCSS: true, minifyURLs: true }};
366

邓晓峰's avatar
邓晓峰 committed
367
  chainConfig.plugin('htmlPlugins').use(require.resolve('html-webpack-plugin'), [htmlPluginOptions]);
368

邓晓峰's avatar
邓晓峰 committed
369 370 371 372 373
  chainConfig.plugin('updateHtmlParams').use(require.resolve('./plugins/HtmlGenerator'), [
    {
      config: defineConfig,
    },
  ]);
374

邓晓峰's avatar
邓晓峰 committed
375
  chainConfig.plugin('replaceTheme').use(ThemeColorReplacer, [themePluginOption]);
376 377 378 379

  const copyPatterns = [
    fs.existsSync(path.join(process.cwd(), 'public')) && {
      from: path.join(cwd, 'public'),
邓晓峰's avatar
邓晓峰 committed
380
      to: path.resolve(process.env.npm_config_releasepath || process.cwd(), pkg.name.toLocaleLowerCase()),
381 382 383
    },
    ...(defineConfig.copy
      ? defineConfig.copy.map(item => {
邓晓峰's avatar
邓晓峰 committed
384
        if (typeof item === 'string') {
385
          return {
邓晓峰's avatar
邓晓峰 committed
386
            from: path.join(cwd, item),
邓晓峰's avatar
邓晓峰 committed
387
            to: path.resolve(process.env.npm_config_releasepath || process.cwd(), pkg.name.toLocaleLowerCase()),
388
          };
邓晓峰's avatar
邓晓峰 committed
389 390 391 392 393
        }
        return {
          from: path.join(cwd, item.from),
          to: path.resolve(
            process.env.npm_config_releasepath || process.cwd(),
邓晓峰's avatar
邓晓峰 committed
394
            `${pkg.name.toLocaleLowerCase()}/${item.to}`,
邓晓峰's avatar
邓晓峰 committed
395 396 397
          ),
        };
      })
398 399 400 401
      : []),
  ].filter(Boolean);

  if (copyPatterns.length) {
邓晓峰's avatar
邓晓峰 committed
402
    chainConfig.plugin('copy').use(require.resolve('copy-webpack-plugin'), [copyPatterns]);
403 404 405 406 407 408 409
  }

  if (isDev && defineConfig.fastRefresh) {
    const debug = createDebug('civ:preset-build-in:fastRefresh');
    chainConfig
      .plugin('fastRefresh')
      .after('hmr')
邓晓峰's avatar
邓晓峰 committed
410
      .use(require('@pmmmwh/react-refresh-webpack-plugin'), [{ overlay: false }]);
411 412 413 414 415 416 417 418 419
    debug('FastRefresh webpack loaded');
  }

  if (chainConfig.extraBabelIncludes) {
    chainConfig.extraBabelIncludes.forEach((include, index) => {
      const rule = `extraBabelInclude_${index}`;
      // prettier-ignore
      chainConfig.module
        .rule(rule)
邓晓峰's avatar
邓晓峰 committed
420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436
        .test(/\.(js|mjs|jsx)$/)
        .include
        .add((a) => {
          // 支持绝对路径匹配
          if (path.isAbsolute(include)) {
            return path.isAbsolute(include);
          }

          // 支持 node_modules 下的 npm 包
          if (!a.includes('node_modules')) return false;
          const pkgPath = getPkgPath(a);
          return shouldTransform(pkgPath, include);
        })
        .end()
        .use('babel-loader')
        .loader(require.resolve('babel-loader'))
        .options(babelOpts);
437 438 439 440 441 442 443 444 445 446 447 448
    });
  }

  chainConfig.module
    .rule('ts-in-node_modules')
    .test(/\.(jsx|ts|tsx)$/)
    .include.add(/node_modules/)
    .end()
    .use('babel-loader')
    .loader(require.resolve('babel-loader'))
    .options(babelOpts);

邓晓峰's avatar
邓晓峰 committed
449
  const rule = chainConfig.module.rule('js-in-node_modules').test(/\.(js|mjs)$/);
450 451 452 453 454 455
  const nodeModulesTransform = defineConfig.nodeModulesTransform || {
    type: 'all',
    exclude: [],
  };

  if (nodeModulesTransform.type === 'all') {
邓晓峰's avatar
邓晓峰 committed
456
    const exclude = lodash.uniq([...TYPE_ALL_EXCLUDE, ...(nodeModulesTransform.exclude || [])]);
457 458 459 460
    const pkgs = excludeToPkgs({ exclude });
    rule.include
      .add(/node_modules/)
      .end()
邓晓峰's avatar
邓晓峰 committed
461
      .exclude.add(path => isMatch({ path, pkgs }))
462 463 464 465 466 467 468
      .end();
  } else {
    const pkgs = {
      ...es5ImcompatibleVersionsToPkg(),
      ...excludeToPkgs({ exclude: nodeModulesTransform.exclude || [] }),
    };
    rule.include
邓晓峰's avatar
邓晓峰 committed
469 470
      .add(path =>
        isMatch({
471 472
          path,
          pkgs,
邓晓峰's avatar
邓晓峰 committed
473 474
        }),
      )
475 476 477
      .end();
  }

邓晓峰's avatar
邓晓峰 committed
478 479 480 481
  // rule
  //   .use('babel-loader')
  //   .loader(require.resolve('@umijs/deps/compiled/babel-loader'))
  //   .options(babelOpts);
482

483 484
  if ((isProd && defineConfig.analyze) || process.env.ANALYZE) {
    const mergeAnalyze = Object.assign(
邓晓峰's avatar
邓晓峰 committed
485
      {
486 487 488 489 490 491 492
        analyzerMode: process.env.ANALYZE_MODE || 'server',
        analyzerPort: process.env.ANALYZE_PORT || 8888,
        openAnalyzer: process.env.ANALYZE_OPEN !== 'none',
        generateStatsFile: !!process.env.ANALYZE_DUMP,
        statsFilename: process.env.ANALYZE_DUMP || 'stats.json',
        logLevel: process.env.ANALYZE_LOG_LEVEL || 'info',
        defaultSizes: 'parsed', // stat  // gzip
邓晓峰's avatar
邓晓峰 committed
493
      },
494 495 496 497
      defineConfig.analyze,
    );
    chainConfig
      .plugin('bundle-analyzer')
邓晓峰's avatar
邓晓峰 committed
498
      .use(require('umi-webpack-bundle-analyzer').BundleAnalyzerPlugin, [mergeAnalyze || {}]);
499 500 501
  }

  if (process.env.PROGRESS !== 'none') {
502
    chainConfig.plugin('progress').use(require.resolve('webpackbar'), [
邓晓峰's avatar
邓晓峰 committed
503 504
      mfsu
        ? {
505 506 507
          name: 'MFSU',
          color: '#facc00',
        }
邓晓峰's avatar
邓晓峰 committed
508
        : defineConfig.ssr
509
          ? {
邓晓峰's avatar
邓晓峰 committed
510 511
            name: type === 'ssr' ? 'Server' : 'Client',
          }
512
          : {},
513
    ]);
514 515
  }

516 517 518 519 520 521 522 523 524
  // if (process.env.FRIENDLY_ERROR !== 'none') {
  //   chainConfig
  //     .plugin('friendly-error')
  //     .use(require.resolve('friendly-errors-webpack-plugin'), [
  //       {
  //         clearConsole: false,
  //       },
  //     ]);
  // }
525 526 527 528

  if (process.env.WEBPACK_PROFILE) {
    chainConfig.profile(true);
    const statsInclude = ['verbose', 'normal', 'minimal'];
邓晓峰's avatar
邓晓峰 committed
529
    chainConfig.stats(statsInclude.includes(process.env.WEBPACK_PROFILE) ? process.env.WEBPACK_PROFILE : 'verbose');
530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549
    const StatsPlugin = require('stats-webpack-plugin');
    chainConfig.plugin('stats-webpack-plugin').use(
      new StatsPlugin('stats.json', {
        chunkModules: true,
      }),
    );
  }

  chainConfig.when(
    isDev,
    chainConfig => {
      if (isDev) {
        chainConfig.plugin('hmr').use(webpack.HotModuleReplacementPlugin);
      }
    },
    chainConfig => {
      chainConfig.optimization.noEmitOnErrors(true);
      chainConfig.performance.hints(false);

      if (!isWebpack5) {
邓晓峰's avatar
邓晓峰 committed
550
        chainConfig.plugin('hash-module-ids').use(webpack.HashedModuleIdsPlugin, []);
551
      }
552
      chainConfig.optimization.minimize(process.env.NODE_ENV === 'production');
553 554 555
      if (disableCompress) {
        chainConfig.optimization.minimize(false);
      } else if (!options.__disableTerserForTest) {
邓晓峰's avatar
邓晓峰 committed
556 557 558 559 560 561 562
        chainConfig.optimization.minimizer('terser').use(require.resolve('terser-webpack-plugin'), [
          {
            terserOptions: deepmerge(terserOptions, defineConfig.terserOptions || {}),
            parallel: true,
            extractComments: false,
          },
        ]);
563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578
      }
    },
  );

  function createCSSRuleFn(opts) {
    createCSSRule({
      webpackConfig: chainConfig,
      config: defineConfig,
      isDev,
      type: 'csr',
      browserslist,
      miniCSSExtractPluginLoaderPath: '',
      ...opts,
    });
  }

邓晓峰's avatar
邓晓峰 committed
579 580 581 582 583
  if (defineConfig.esbuild) {
    const { target = 'es2015' } = defineConfig.esbuild || {};
    const optsMap = {
      csr: {
        minify: true,
邓晓峰's avatar
邓晓峰 committed
584
        target,
邓晓峰's avatar
邓晓峰 committed
585 586 587 588 589
      },
    };
    const opt = optsMap.csr;
    chainConfig.optimization.minimize = true;
    chainConfig.optimization.minimizer = [new ESBuildMinifyPlugin(opt)];
邓晓峰's avatar
邓晓峰 committed
590
    chainConfig.plugin('es-build').use(new ESBuildPlugin());
邓晓峰's avatar
邓晓峰 committed
591
  }
592

593 594 595
  if (defineConfig.chainWebpack) {
    defineConfig.chainWebpack(chainConfig, {
      type: 'csr',
596
      // mfsu,
597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621
      env: process.env,
      webpack,
      createCSSRule: createCSSRuleFn,
    });
  }

  // if (defineConfig.chunks) {
  //   chainConfig
  //     .plugin('htmlPlugins')
  //     .use(require('html-webpack-plugin'))
  //     .tap(options => {
  //       options.chunks = defineConfig.chunks;
  //       return options;
  //     });
  // }

  let ret = chainConfig.toConfig();

  // speed-measure-webpack-plugin
  if (process.env.SPEED_MEASURE) {
    const SpeedMeasurePlugin = require('speed-measure-webpack-plugin');
    const smpOption =
      process.env.SPEED_MEASURE === 'CONSOLE'
        ? { outputFormat: 'human', outputTarget: console.log }
        : {
邓晓峰's avatar
邓晓峰 committed
622
          outputFormat: 'json',
623
          outputTarget: join(process.cwd(), 'speed-measure.json'),
邓晓峰's avatar
邓晓峰 committed
624
        };
625 626 627 628
    const smp = new SpeedMeasurePlugin(smpOption);
    ret = smp.wrap(ret);
  }

邓晓峰's avatar
邓晓峰 committed
629
  const { entry } = options;
630 631 632 633
  if (defineConfig.runtimePublicPath) {
    entry.push(require.resolve('./runtimePublicPathEntry'));
  }

邓晓峰's avatar
邓晓峰 committed
634
  const nodeLibs = require('node-libs-browser');
635
  // const ProvidePlugin = webpack.ProvidePlugin;
邓晓峰's avatar
邓晓峰 committed
636
  if (isWebpack5) {
邓晓峰's avatar
邓晓峰 committed
637 638
    ret.plugins.push(
      new webpack.ProvidePlugin({
邓晓峰's avatar
邓晓峰 committed
639
        process: nodeLibs.process,
邓晓峰's avatar
邓晓峰 committed
640
      }),
邓晓峰's avatar
邓晓峰 committed
641 642 643 644
    );
    ret.resolve.fallback = {
      ...ret.resolve.fallback,
      ...Object.keys(nodeLibs).reduce((memo, key) => {
邓晓峰's avatar
邓晓峰 committed
645 646
        if (nodeLibs[key]) {
          memo[key] = nodeLibs[key];
邓晓峰's avatar
邓晓峰 committed
647
        } else {
邓晓峰's avatar
邓晓峰 committed
648 649 650
          memo[key] = false;
        }
        return memo;
邓晓峰's avatar
邓晓峰 committed
651 652 653
      }, {}),
      http: false,
      https: false,
654 655
      zlib: false,
      url: false
邓晓峰's avatar
邓晓峰 committed
656
    };
657
    ret.resolve.mainFiles = ['index', 'Cesium'];
邓晓峰's avatar
邓晓峰 committed
658
  }
659

660 661 662
  ret = {
    ...ret,
    // mode: options.mode,
邓晓峰's avatar
邓晓峰 committed
663
    entry,
664 665 666 667 668 669 670 671 672
    plugins: options.plugins.concat([...ret.plugins]),
    optimization: {
      ...options.optimization,
      ...ret.optimization,
    },
    performance: options.performance || {},
  };
  return ret;
};