Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

why material-ui takes too much space?

I am using webpack to bundle my react project. My project depends on material-ui for below component:

material-ui/Dialog
material-ui/styles/getMuiTheme
material-ui/styles/MuiThemeProvider
material-ui/FlatButton
material-ui/TextField

webpack-bundle-size-analyzer reports material-ui takes 1.07MB size. Below is my webpack config file:

const webpack = require('webpack');
const path = require('path');
const NpmInstallPlugin = require('npm-install-webpack-plugin');
const WebpackShellPlugin = require('webpack-shell-plugin');
var CompressionPlugin = require("compression-webpack-plugin");

const PATHS = {
  react: path.join(__dirname, 'node_modules', 'react', 'dist', 'react.min.js'),
  app: path.join(__dirname, 'src'),
  build: path.join(__dirname, './dist')
};

module.exports = {
  entry: {
    app: './app/index.jsx',
    android: './app/utils/platform_android.js',
    ios: './app/utils/platform_ios.js',
    web: './app/utils/platform_web.js',
    vendor: [
      'axios',
      'react',
      'react-dom',
      'react-redux',
      'react-router',
      'react-router-redux',
      'redux',
      'redux-thunk',
      'react-alert',
      'sha1',
      'moment',
      'nuka-carousel',
      'react-cookie',
      'material-ui',
      'react-spinkit',
      'react-tap-event-plugin',
      'react-tappable',
      'history',
    ],
  },
  output: {
    path: PATHS.build,
    filename: '[name].bundle.js',
  },
  watch: false,
  devtool: 'source-map',
  relativeUrls: true,
  resolve: {
    extensions: ['', '.js', '.jsx', '.css', '.less'],
    modulesDirectories: ['node_modules'],
    alias: {
      normalize_css: __dirname + '/node_modules/normalize.css/normalize.css',
    }
  },
  module: {
    preLoaders: [

      {
        test: /\.js$/,
        loader: "source-map-loader"
      },
      // {
      //   test: /\.js$/,
      //   exclude: /node_modules/,
      //   loader: 'jshint-loader'

      // }
    ],
    loaders: [

      {
        test: /\.html$/,
        loader: 'file?name=[name].[ext]',
      },
      {
        test: /\.jsx?$/,
        exclude: /node_modules/,
        loader: 'babel-loader?presets=es2015',
      },
      {
        test: /\.less$/,
        loader: "style!css!less",
      },
      {test: /\.css$/, loader: 'style-loader!css-loader'},
      {test: /\.png$/, loader: "url-loader?limit=100000"},
      // {test: /\.(jpe?g|png|gif|svg)$/i, loader: "file-loader?name=/public/icons/[path]/[name].[ext]"},
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loaders: ['babel-loader?presets=es2015']
      },
      {
        test: /\.svg$/,
        loader: 'svg-sprite',
        include: /public\/icons/
      }
    ]
  },
  plugins: [
    new webpack.optimize.UglifyJsPlugin({
      compress: {
        warnings: false,
      },
      output: {
        comments: false,
      },
      minimize: true
    }),
    new NpmInstallPlugin({
      save: true // --save
    }),
    new webpack.DefinePlugin({
      "process.env": {
        NODE_ENV: JSON.stringify("production")
      }
    }),
    new WebpackShellPlugin({
      onBuildStart: ['echo "Webpack Start"'],
      onBuildEnd: [
        'cp ./dist/*.js ../assets/dist/;rm -fr dist/web;' +
        'mkdir -p dist/web/dist;cp ./dist/*.js ./dist/web/dist/;cp ./index.html ./dist/web/;cp -r public dist/web/',
      ]
    }),
    new CompressionPlugin({
      asset: "[path].gz[query]",
      algorithm: "gzip",
      test: /\.js$|\.html$/,
      threshold: 10240,
      minRatio: 0.8
    }),
    new webpack.optimize.CommonsChunkPlugin(/* chunkName= */["vendor"], /* filename= */"[name].bundle.js", Infinity),
  ],
  devServer: {
    colors: true,
    contentBase: __dirname,
    historyApiFallback: true,
    hot: true,
    inline: true,
    port: 9093,
    progress: true,
    stats: {
      cached: false
    }
  }
}

I already tried to use CompressionPlugin, UglifyJsPlugin to optimize my bundle files but it still takes more than 1MB. How can I reduce its size? I don't want to use gzip since my app is running on webview on mobile device and some of them doesn't support gzip encoding.

like image 981
Joey Yi Zhao Avatar asked Aug 19 '16 14:08

Joey Yi Zhao


1 Answers

Finally I figured out what the problem. In my webpack config file, I separate all vendor js into a different js bundle file. And I listed 'material-ui' there. When package my app, the whole 'material-ui' library will be packaged into vendor.js. I have to remove the material-ui from vendor list, in this way only the components required by my source code will be packaged.

like image 84
Joey Yi Zhao Avatar answered Oct 07 '22 17:10

Joey Yi Zhao