Weight problem compiling with WebPack

0

Friends, I'm working on an application with ReactJS using es6. I started using browserify for the conversion and compilation of es6 to es5. But I realized that my "bundle" file after the transformation weighs 1.3mb, which is logically too much weight . My src folder with all the scripts in es6 only weighs 200kb . In principle, I thought that browserify was including either all the dependencies (including ones that I did not need) or that I was repeating the files. This is because as you know, in es6 I must use lines like

import Config from .'/config.js';

For the inclusion of files you need and this, in turn I do it in each file. Therefore, I decided to change to webPack because I read that it was in charge of analyzing what it included and precisely avoiding the repetition of code (For me these tools are new). But my compiled file still has a weight of 1.3mb Here I add my dummy file from browserify

var path = require('path');
var webpack = require('webpack');

module.exports = {
    entry: './js/src/index.js',
    devtool: 'cheap-module-source-map',
    output: { path: __dirname, filename: 'bundle.js' },
    "plugins":[
        new webpack.optimize.DedupePlugin()
    ],
    module: {
        loaders: [
            {
                test: /.jsx?$/,
                loader: 'babel-loader',
                exclude: /node_modules|libs/,

                query: {
                    presets: ['es2015', 'react']
                }
            }
        ]
    },
};

With that I generated a map file and there are files that appear multiple times, with which I corroborate that this is the reason why the bundle file weighs so much. Does anyone have any idea how I can solve that?

Regarding the development structure, I am using React and React-router. Therefore, I have an index.js file where I include all the "routes" files to register the routes and then I have a .jsx file for each route, where I import the files I may need.

Update

Reading in documentation, they recommend that the include be used and not the exclude in the loaders. therefore I tried testing in the following way:

module.exports = {
    entry: './js/src/index.js',
    devtool: 'cheap-module-source-map',
    output: {
        path: __dirname,
        filename: 'bundle.js'
    },
    "plugins": [
        new webpack.optimize.DedupePlugin()
    ],
    module: {
        loaders: [
            {
                test: /.jsx?$/,
                loader: 'babel-loader',
                /*  exclude: [
                 NPM_DIR,
                 BOWER_DIR
                 ],
                 */
                query: {
                    presets: ['es2015', 'react']
                },
                include: [

                    path.join(__dirname, 'src/Clases'),
                    path.join(__dirname, 'src/components'),
                    path.join(__dirname, 'src/elements')
                ]

            }
        ]
    },
};

But making that adjustment, I get an error as if I did not recognize the presets, throws the following error:

You may need an appropriate loader to handle this file type.
SyntaxError: Unexpected token (129:12)

That line is where the react render method starts, for that the presets are included in the query segment, I had passed before and I solved it like this and now using the key include happens again.

Thank you very much to anyone who can help me because I still do not see light.

    
asked by jrodriguez 05.02.2017 в 15:30
source

2 answers

0

I did a article on Medium (I'm going to copy-paste here) about the bundle in production, although it was not clear to me if in bundle you are going to add react or not. What I do to save, is the following:

Before applying it, it is necessary to install the plugins for babel

$ npm -i -D babel-plugins-transform-react-inline-elements babel-plugins-transform-react-constant-elements

that should only be used in production, then modify your webpack.config.js so you can use the $NODE_ENV=production , the file that I use is very similar to this

var webpack = require('webpack')
//En lugar de usar un archivo .babelrc, agregamos la configuración de babelQuery aquí
var babelQuery = {presets: ["react", "es2015"], plugins:[]};
var webpackConfig = {
  entry: './app/mainEntry.js',
  output: {
    path: "./public",
    filename: 'bundle.js'
  },
  module: {
      loaders:[
        {
          test: /\.js$/,
        exclude: /node_modules/,
        loader:"babel",
        //BORRAME: Agregamos la babelQuery 
        query: babelQuery
      }
      ]
  },
  resolve: {
    extensions: ['', '.js', '.jsx']
  }
}
if (process.env.NODE_ENV === 'production') {
  //El SourceMap más simple que se puede hacer, sin columnas de mapeo, sino simple líneas
  webpackConfig.devtool = 'cheap-module-source-map'
  // Este plugin es para que todos los módulos de node_modules se lean con la variable NODE_ENV = production
  // y no manden las alertas de desarrollo
  webpackConfig.plugins.push(new webpack.DefinePlugin({
    'process.env': {
      'NODE_ENV': JSON.stringify(process.env.NODE_ENV)
    }
  })
  );
  //Ignoramos ayudas para IE8
  webpackConfig.plugins.push(new webpack.optimize.UglifyJsPlugin({
    compress: {
      screw_ie8: true
    }
  })
  );
  /*
  transform-react-inline-elements
  Esto sólo es necesario si utilizamos la forma
  class App extends React.Component {
    render() {
      return (
        <h1>Soy App </h1>
      )
    }
  }
  Ya que hace una versión optimizada del código mucho mejor que React.createClass
  transform-react-constant-elements
  Reduce los llamados a React.createElement, evita repeticiones
  */
  babelQuery.plugins.push("transform-react-inline-elements","transform-react-constant-elements");
}
module.exports = webpackConfig

If you use babel for other things (as in my case I use it with Express) then you have to remove all the babelQuery from the code above and use the following line in your file .babelrc :

... ,
  "env": {
    "production": {
      "plugins": ["transform-react-constant-elements","transform-react-inline-elements"]
    }
  }

To finish you have to run like @Guz you have to run webpack with -p so react remove all development alerts

$ NODE_ENV=production; webpack -p 

If by pure chance you use fish-shell like me, then

$ set -x NODE_ENV production; webpack -p

With the App that I am currently doing with Redux, React-Router and React my development bundle weighs 1.19 MB but with the configuration above it is reduced to 288 KB I hope this applies and solves your problem.

    
answered by 15.02.2017 / 20:03
source
0

That's nothing, my bundle of my application made in Vue.js weighs 2.6MB and with source maps, but in development. There are several reasons why the bundle size increases, but mainly due to dependencies . For example, the package babel-standalone has a weight of + 2MB , lodash more than 600KB and react around 600KB . If you add this, you have more than 3MB in dependencies.

Webpack

It is important that you generate your bundles for production and not for development. You can do this by defining a Webpack plugin:

plugins: [
  new webpack.DefinePlugin({
    'process.env': {
      'NODE_ENV': JSON.stringify('production')
    }
  })
]

Now run webpack:

webpack -p

And you will get a bundle of much less weight.

Gzip

Generally, in the static production, tablets are sent using Gzip. For example, if you compress lodash you will get a much smaller weight:

gz lodash.js
Original: 504040 bytes
Gzipped: 89746 bytes (17.81%)

Generating a bundle for production and use Gzip on your server, you will achieve great improvements regarding the weight of your bundle and thus, a faster response from the server.

    
answered by 05.02.2017 в 16:55