8

I find common vendor for my project is very big.

I'm tring to see which module is responsible for the big size, and found semantic-ui-react is taking 1.74M by itself.

react-vendor.js 1.74 MB 2 [emitted] [big] react-vendor

'react-vendor': [
   'semantic-ui-react',
 ],

  new CommonsChunkPlugin({
    name: "react-vendor",
    filename: "react-vendor.js",
    minChunks: Infinity,
  }),

Is there something I could do to make the file size smaller?

eugene
  • 33,301
  • 47
  • 188
  • 382

3 Answers3

9

Step 1

By default, importing the library will import every component. If you are using webpack 1, then you can follow the directions shown here in the usage section for bundlers:

http://react.semantic-ui.com/usage#bundlers

The example configuration shows how you can use babel-plugin-lodash (despite the name) to automatically transform your import statements to individual component imports. Explicitly importing individual components will ensure that you are only bundling the components you are using. Unused components will not be included in your bundle.

Step 2

Every component includes a propTypes definition. These are only useful in development. They are also quite large and verbose. We wrap our prop type definitions so that they are automatically removed during minification with dead code elimination, provided that process.env.NODE_ENV is set to "production" and exposed as a global.

You should already be doing this as it is required by react to bundle in production mode. Just in case, here are the instructions on how to do this: How to turn on/off ReactJS 'development mode'?

Removing prop type definitions will save additional space.

Step 3

With the source code cut down to only include the components you are using, and those components cut down to production code only, you should now minify and compress your bundle.

Check the webpack docs for enabling production as this will minified your code and use dead code elimination, it is very straightforward. You can then compress your bundle with: https://github.com/webpack-contrib/compression-webpack-plugin.

Conclusion

There have been some updates to the library since I did this, but I achieved 81.8 kB for the entire library in UMD format, which has slightly larger overhead.

PR here showing the full setup: https://github.com/webpack-contrib/compression-webpack-plugin

Stats here: https://github.com/Semantic-Org/Semantic-UI-React/blob/3aa72bc76aac05c526e2b14a6ed4687995cd11af/stats-library.md

Community
  • 1
  • 1
levithomason
  • 300
  • 2
  • 3
2

Because there are some issues with Webpack 2 so it's not supporting tree shaking to optimize the import, I'm temporarily using below setup to deal with the issue:

webpack.config.js

plugins: [
  new webpack.DefinePlugin({
    'process.env': {
      NODE_ENV: JSON.stringify('production')
    }
  }),
  new webpack.LoaderOptionsPlugin({
    minimize: true,
    debug: false
  }),
  new webpack.optimize.UglifyJsPlugin(), // Minify everything
  new webpack.optimize.AggressiveMergingPlugin() // Merge chunks
]

.babelrc

  "plugins": [
    "transform-react-jsx",
    [
      "lodash",
      {
        "id": [
          "lodash",
          "semantic-ui-react"
        ]
      }
    ]
  ]
haotang
  • 5,052
  • 30
  • 43
2

In typescript when targeting es5 the recipes above don't work (because it doesn't follow es module system in this case).

You can create a file which will pull all semantic-ui-react modules you are using one by one and reexport them. Than in your code you just bring modules from the helper file rather than from the library itself.

Like this:

import Button = require('semantic-ui-react/dist/es/elements/Button');
import Icon = require('semantic-ui-react/dist/es/elements/Icon');
import Image = require('semantic-ui-react/dist/es/elements/Image');
import Input = require('semantic-ui-react/dist/es/elements/Input');
import Label = require('semantic-ui-react/dist/es/elements/Label');

import Form = require('semantic-ui-react/dist/es/collections/Form');
import Menu = require('semantic-ui-react/dist/es/collections/Menu');
import Message = require('semantic-ui-react/dist/es/collections/Message');
import Table = require('semantic-ui-react/dist/es/collections/Table');

import Checkbox = require('semantic-ui-react/dist/es/modules/Checkbox');
import Dropdown = require('semantic-ui-react/dist/es/modules/Dropdown');
import Modal = require('semantic-ui-react/dist/es/modules/Modal');

import Confirm = require('semantic-ui-react/dist/es/addons/Confirm');
import TextArea = require('semantic-ui-react/dist/es/addons/TextArea');

import { DropdownItemProps, CheckboxProps, InputProps,
  MenuItemProps, ModalProps, TextAreaProps } from 'semantic-ui-react/index.d';


export { Button, Dropdown, Confirm, Icon, Input, Modal, Label,
  Table, Checkbox, TextArea, Form, Menu, Image, Message };
export { DropdownItemProps, CheckboxProps, InputProps, MenuItemProps, ModalProps, TextAreaProps };
Daniel Khoroshko
  • 2,213
  • 12
  • 21