The original link

Follow up with Webpack configuration notes

The sub-contract strategy

Start the YARN Analyze script on the branch feature/optimize_webpack and the subcontracting policy is as follows:

First screen load comparison

Original first screen loading

Loading after Upgrade

Subcontracting optimization steps

Echarts only extracts the required packages

app\components\ECharts\component.js

import echarts from 'echarts/lib/echarts';
import 'echarts/lib/chart/bar';
import 'echarts/lib/chart/line';
import 'echarts/lib/chart/pie';

import 'echarts/lib/component/tooltip';
import 'echarts/lib/component/legendScroll';
Copy the code

Immutable points to the same copy, avoiding duplicate packaging of draft and ANTD

internals/webpack/webpack.base.babel.js

'immutable': path.resolve(process.cwd(), 'node_modules/immutable'),
Copy the code

Large module rewriting method

According to the road

The original route reference module is already in the form of import().then(), so I added the following policy to splitChunks in the Webpack

internals/webpack/webpack.prod.babel.js

splitChunks: {
  chunks: 'all'.// Split files regardless of whether they are dynamically loaded or not. All packages are introduced when the page first loads
  maxInitialRequests: 10.// Maximum number of initial requests
  minSize: 0.// Default 30000, in order not to merge chunks
  cacheGroups: {
    vendor: {
      test: /[\\/]node_modules[\\/]/.name(module) {
        const packageName = module.context.match(
          /[\\/]node_modules[\\/](.*?) (/ / \ \ | $) /,)1];
        return `npm.${packageName.replace(The '@'.' ')}`; // Extract each third-party component, only when needed}},}},Copy the code

As you experiment, you can see that each page loads only the required packages

By component

React-player /draft/echarts is used for lazy loading of large components

One of the big problems is that lazy loading components cannot reference ref. After many experiments, the writing method is changed as follows

import React from 'react'; import Loadable from 'react-loadable'; const LoaderCache = new Map(); export default function loadComponent(loader, options) { let component = LoaderCache.get(loader); if (! component) { component = Loadable({ loader, loading: (props) => { if (props.error) {// eslint-disable-line console.error('[chunk loader]', props.error); // eslint-disable-line } return <div />; }, render: (loaded, props) => { const Component = loaded.default; const { withRef, ... rest } = props; // eslint-disable-line return (<Component ref={(r) => { withRef && withRef(r); }} {... rest} />); },... options, }); LoaderCache.set(loader, component); // component.preload(); } return component; }Copy the code

Usage:

app\components\GraphHintTextArea\index.js

import loadComponent from 'utils/loader';

export default loadComponent(() = > import(/* webpackChunkName: "c-graph-hint-text-area" */'./component'), null);
Copy the code
<GraphHintTextArea
  withRef={(r) = > { this.graphHintTextArea = r; }} / >Copy the code

Antd only loads the ICONS needed

internals/webpack/webpack.base.babel.js

'@ant-design/icons/lib/dist$': path.resolve('app/icons'),
Copy the code

app/icons/index.js

// fill
export {
  default as ExclamationCircleFill,
} from '@ant-design/icons/lib/fill/ExclamationCircleFill';
// outline
export {
  default as QuestionCircleOutline,
} from '@ant-design/icons/lib/outline/QuestionCircleOutline';
// twotone
export {
  default as ProfileTwoTone,
} from '@ant-design/icons/lib/twotone/ProfileTwoTone';
Copy the code