React/Redux bundle.js is too big
Solution 1
There are a couple of things that you can do. I suggest to create two configurations of webpack. First for development where we don't care about bundle size and second for production where bundle will be optimized.
Remove completely source-map (delete devtool line). You don't need it in production mode.
-
Use production mode. Add this entry to plugins
plugins: [ new webpack.DefinePlugin({ 'process.env': { 'NODE_ENV': JSON.stringify('production') } }) ],
Use
webpack -p
for building-
To minimize size of libraries you should only import functions that you use. For example if you need a few functions from lodash like
forEach, orderBy, map
.import forEach from 'lodash/forEach' import orderBy from 'lodash/orderBy' import map from 'lodash/map'
Solution 2
Your bundle is huge because of the source map. When creating the bundle, remove this line:
devtool: 'inline-source-map'
This will also remove the source map during development however, so can do something like this in package.json:
"scripts": { "dev": "webpack-dev-server --colors", "build": "webpack -p" },
Webpack -p will start the build mode for webpack, and will also minify your code, making it smaller.
And in your webpack.config.js:
const args = require('yargs').argv;
const build = args.p;
devtool: build ? undefined : 'inline-source-map',
This will remove the source map when building.
There are better methods to identify build, such as NODE_ENV, and you should look at the devtool options, if you need a source map in production.
Solution 3
You are using 'inline-source-map' as devtool option. This adds sourcemaps inside your bundle, which are actually bigger than code itself. Try another option from webpack documentation.
Solution 4
This may still be of interest to some people so I'll throw in an additional answer...
React functional components, aka React hooks, introduced in V16 use less code than class-based components so that's another option
Dustin Sun
Programmer turned Mortgage Loan Officer. Need mortgage loan in Florida?
Updated on June 04, 2022Comments
-
Dustin Sun almost 2 years
I have a small React project. The bundle.js generated by Webpack is 6.3Mb. How can I decrease the size to be <2.0Mb? (2Mb is still big but acceptable). Complete source code is at github
webpack.config.js
module.exports = { devtool: 'inline-source-map', entry: [ './app/components/app.jsx' ], output: { path: './public', filename: 'bundle.js' }, resolve: { modulesDirectories: ['node_modules', 'app'], extensions: ['', '.js', '.jsx', '.scss'] }, module: { loaders: [ { test: /\.jsx?$/, exclude: /node_modules/, loaders: ['happypack/loader'] }, { test: /\.scss$/, loaders: [ 'style', 'css', 'autoprefixer?browsers=last 3 versions', 'sass?outputStyle=expanded' ] }, { test: /\.(jpe?g|png|gif|svg)$/i, loaders: [ 'url?limit=8192', 'img' ] } ] }, plugins: [ new webpack.HotModuleReplacementPlugin(), new webpack.NoErrorsPlugin(), new HtmlWebpackPlugin({ title: 'Fullstack Rebel', template: './app/templates/index_template.ejs' }), new HappyPack({ loaders: ['babel?presets[]=react,presets[]=es2015'] }) ] };
package.json
{ "name": "fullstackcms", "version": "0.0.1", "description": "A Content Management System Made of NodeJS, MongoDB, React, Redux and Bootstrap", "main": "index.js", "scripts": { "dev": "webpack-dev-server --colors" }, "repository": { "type": "git", "url": "https://github.com/dsun29/fullstackcms" }, "keywords": [], "author": "", "license": "ISC", "dependencies": { "autoprefixer-loader": "^3.1.0", "body-parser": "^1.14.2", "connect-mongo": "^1.3.2", "css-loader": "^0.24.0", "express": "^4.13.3", "express-session": "^1.14.1", "file-loader": "^0.9.0", "history": "^1.17.0", "img-loader": "^1.2.2", "immutable": "^3.7.6", "jquery": "^3.1.0", "lodash": "^4.0.0", "mongodb": "^2.2.10", "node-sass": "^3.4.2", "node-twitter-api": "^1.8.0", "react": "^15.3.1", "react-bootstrap": "^0.30.3", "react-dom": "^15.3.1", "react-google-login": "^2.5.1", "react-modal-dialog": "^3.0.2", "react-redux": "^4.0.6", "react-router": "^2.7.0", "react-tinymce": "^0.5.1", "react-twitter-widgets": "^0.2.4", "redux": "^3.0.5", "redux-thunk": "^2.1.0", "reqwest": "^2.0.5", "routes": "^2.1.0", "sass-loader": "^4.0.1", "style-loader": "^0.13.0", "url-loader": "^0.5.7" }, "engines": { "node": "0.12.0" }, "devDependencies": { "babel": "^6.5.2", "babel-cli": "^6.4.0", "babel-core": "^6.17.0", "babel-eslint": "^6.1.2", "babel-loader": "^6.2.5", "babel-plugin-transform-runtime": "^6.15.0", "babel-polyfill": "^6.16.0", "babel-preset-es2015": "^6.16.0", "babel-preset-react": "^6.16.0", "babel-preset-stage-3": "^6.11.0", "babel-regenerator-runtime": "^6.5.0", "babel-register": "^6.16.3", "babel-runtime": "^6.11.6", "chai": "^3.4.1", "chai-immutable": "^1.5.3", "eslint": "^3.4.0", "eslint-config-airbnb": "^10.0.1", "eslint-plugin-import": "^1.14.0", "eslint-plugin-jsx-a11y": "^2.2.1", "eslint-plugin-react": "^6.2.0", "happypack": "^2.2.1", "html-webpack-plugin": "^2.22.0", "mocha": "^3.0.2", "react-hot-loader": "^3.0.0-beta.3", "webpack": "^1.13.2", "webpack-dev-server": "^1.14.0" } }
Some results from webpack-bundle-size-analyzer
active-event-stack: 402.98 KB (17.3%) lodash: 401.81 KB (99.7%) <self>: 1.17 KB (0.292%) react-bootstrap: 382.86 KB (16.4%) warning: 1.76 KB (0.461%) <self>: 381.1 KB (99.5%) react-router: 156.83 KB (6.73%) history: 49.02 KB (31.3%) warning: 1.76 KB (3.60%) <self>: 47.26 KB (96.4%) warning: 1.76 KB (1.13%) query-string: 1.45 KB (0.922%) hoist-non-react-statics: 1.35 KB (0.864%) <self>: 103.24 KB (65.8%) immutable: 139.14 KB (5.98%) react-overlays: 69.06 KB (2.97%) warning: 1.76 KB (2.56%) <self>: 67.29 KB (97.4%) dynamics.js: 60.12 KB (2.58%) react-tinymce: 49.09 KB (2.11%) lodash: 43.66 KB (88.9%) <self>: 5.43 KB (11.1%) babel-runtime: 45.11 KB (1.94%) core-js: 40.78 KB (90.4%) <self>: 4.33 KB (9.59%) jss: 42.23 KB (1.81%) fbjs: 32.61 KB (1.40%) react-modal-dialog: 26.36 KB (1.13%) redux: 22.36 KB (0.960%) react-redux: 19.37 KB (0.832%) reqwest: 18.76 KB (0.806%) dom-helpers: 15.56 KB (0.668%) lodash: 12.9 KB (0.554%) uncontrollable: 9.57 KB (0.411%) style-loader: 6.99 KB (0.300%) css-vendor: 6.11 KB (0.263%) react-prop-types: 6.04 KB (0.260%) react-center-component: 5.87 KB (0.252%) react-jss: 5.34 KB (0.229%) node-libs-browser: 5.17 KB (0.222%) process: 5.17 KB (100%) <self>: 0 B (0.00%) react-google-login: 3.99 KB (0.171%) deep-equal: 3.8 KB (0.163%) keycode: 2.7 KB (0.116%) object-assign: 1.95 KB (0.0836%) invariant: 1.48 KB (0.0636%) css-loader: 1.47 KB (0.0632%) jss-vendor-prefixer: 1.39 KB (0.0596%) jss-nested: 1.18 KB (0.0506%) jss-camel-case: 1.13 KB (0.0484%) hoist-non-react-statics: 1.09 KB (0.0470%) classnames: 1.08 KB (0.0462%) symbol-observable: 1.07 KB (0.0461%) jss-px: 936 B (0.0393%) redux-thunk: 529 B (0.0222%) webpack: 251 B (0.0105%) strict-uri-encode: 182 B (0.00763%) react-dom: 63 B (0.00264%) is-browser: 22 B (0.000923%) reqwest xhr2: 15 B (0.000629%) <self>: 119.37 KB (5.13%)
-
Dustin Sun over 7 yearschanged from inline-source-map to source-map. Size is 2.53Mb now from 6.5Mb. Many thanks!! Any more suggestion to make it even smaller?