babel-plugin-import icon indicating copy to clipboard operation
babel-plugin-import copied to clipboard

Fix vendor / commonchunks / code splitting problems with antd

Open andriijas opened this issue 7 years ago • 3 comments

When using babel-plugin-import with antd it currently cant be used with vendor splitting or commonchunks. Can we investigate if we can get this working?

using webpack analyzer shows that most antd apps with chunks and code splitting rebundle a lot of antd with every chunk which creates overhead. We can use ant-design/ant-design-pro#278 as example.

andriijas avatar Nov 23 '17 08:11 andriijas

Any solution?

cameronb23 avatar Dec 21 '17 02:12 cameronb23

Its possible, just need to use the full path in your vendor config

vendors: { "antd/es/modal", "rc-dialog" }

andriijas avatar Dec 21 '17 05:12 andriijas

For folks finding this in the future I got this 'mostly' fixed by trial and error. This is what has worked best for me so far.

It is tree-shaking both antd and @ant-design/icons with babel-plugin-imports and then chunking the tree-shaked modules into a named chunk. The vendors chunk excludes antd/ant-design (and optionally react is chunked separately too).

image

In webpack.prod.js

optimization: {
  splitChunks: {
    chunks: 'all',
    name: true, // using named keeps the modules together for some reason
    minSize: 0,
    cacheGroups: {
      // not necessary but helps
      react: {
        test: /[\\/]node_modules[\\/](react|react-dom)[\\/]/,
        name: 'react',
        chunks: 'all',
        reuseExistingChunk: true,
      },
      // chunk all antd/ant-design modules into a named module
      antd: {
        test(module) {
          return module.resource && (module.resource.includes('antd') || module.resource.includes('ant-design'));
        },
        name: 'antd',
        chunks: 'all',
        reuseExistingChunk: true,
      },
      // chunk all non antd/ant-design modules into vendors
      vendors: {
        reuseExistingChunk: true,
        test(module, chunks) {
          // https://github.com/ant-design/babel-plugin-import#note
          return module.resource
            && module.resource.includes('node_modules')
            && !module.resource.includes('antd')
            && !module.resource.includes('ant-design');
        },
      },
    },
  },
  ...
}

In webpack.base.js (babel-plugin-import config)

  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
          options: {
            plugins: [
              ['import', {
                libraryName: 'antd',
                libraryDirectory: 'lib', // lib works better than es
                style: true, // used when importing less or modifying theme variables
              }, 'antd'],
              [
                // only need if also using ant-design icons
                "import",
                {
                  // this was the best combination
                  libraryName: '@ant-design/icons',
                  libraryDirectory: '', 
                  camel2DashComponentName: false
                },
                '@ant-design/icons'
              ],
            ],
          },
        },
      },
      // https://medium.com/@GeoffMiller/how-to-customize-ant-design-with-react-webpack-the-missing-guide-c6430f2db10f
      // only needed if using less and modifying variables
      {
        test: /\.less$/,
        use: [
          { loader: 'style-loader' },
          { loader: 'css-loader' },
          {
            loader: 'less-loader',
            options: {
              javascriptEnabled: true,
              modifyVars: {
                'hack': `true; @import "${themeOverrideLocation}";`
              }
            },
          },
        ],
      },

FoxxMD avatar Jul 01 '20 04:07 FoxxMD