2

Before anyone downvotes, let me clear some things out what the issue is and which information has been gathered about it:

Issue:

I'm currently trying to learn React from this Youtube Tutorial Playlist. This guy is really good at explaining the framework, unfortunately the videos are outdated (2016). Using his files from the lesson-4 Github branch, the final transpiled bundle.js file is way smaller in size as mine.

Inspecting both files, I can see that because of the dependencies he used back in 2016 and the updated ones in 2018, the file sizes have changed a lot. This results that following Warning messages are displayed in my console after the build:

WARNING in asset size limit: The following asset(s) exceed the recommended size limit (244 KiB). This can impact web performance. Assets: bundle.js (248 KiB)

WARNING in entrypoint size limit: The following entrypoint(s) combined asset size exceeds the recommended limit (244 KiB). This can impact web performance. Entrypoints: main (248 KiB) bundle.js

WARNING in webpack performance recommendations: You can limit the size of your bundles by using import() or require.ensure to lazy load some parts of your application. For more info visit https://webpack.js.org/guides/code-splitting/

Here is my webpack.config.js file:

const path = require('path');

module.exports = {
  "mode": "production",

  entry: path.resolve(__dirname, 'src') + '/app/index.js',
  output: {
    path: path.resolve(__dirname, 'dist') + '/app',
    filename: 'bundle.js',
    publicPath: '/app/'
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        include: path.resolve(__dirname, 'src'),
        exclude: /node_modules/,
        loader: 'babel-loader',
        query: {
          presets: ['react', 'es2015']
        }
      }, {
        test: /\.css$/,
        loader: 'style-loader!css-loader'
      }
    ]
  }
};

My /src/app/index.js file:

const React = require("react");
const ReactDom = require("react-dom");

class TodoComponent extends React.Component {
  render() {
    return (<h1>hello</h1>);
  }
}
ReactDom.render(<TodoComponent/>, document.querySelector(".todo-wrapper"));

My package.json file:

{
  "name": "react-tutorial",
  "version": "1.0.0",
  "description": "React tutorial",
  "main": "app.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "npm run build",
    "build": "webpack -d && webpack-dev-server --content-base src/ --inline --hot --port 1234"
  },
  "author": "me",
  "license": "ISC",
  "dependencies": {
    "react": "^16.4.1",
    "react-dom": "^16.4.1"
  },
  "devDependencies": {
    "babel-core": "^6.26.3",
    "babel-loader": "^7.1.5",
    "babel-preset-es2015": "^6.24.1",
    "babel-preset-react": "^6.24.1",
    "webpack": "^4.16.2",
    "webpack-cli": "^3.1.0",
    "webpack-dev-server": "^3.1.5"
  }
}

And my /src/index.html file:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>React Tutorial</title>
</head>

<body>
  <div class="todo-wrapper">

  </div>
  <h2>Its working i guess</h2>

<script src="/app/bundle.js"></script>
</body>
</html>

The transpiled final /dist/app/bundle.js file looks like this: JsFiddle of bundle.js and is 1.7MB big.

I can see that the code part of

./node_modules/react-dom/cjs/react-dom.development.js

inside bundle.js takes most of the space.

Solutions:

After reading up on those links and using Google, I've found following solutions:

  • Ignore these messages with performance hints false
  • minimize and uglify the code Split and/or lazy load the code

Issue with the solutions:

Since I just started learning about React and Webpack, I don't feel comfortable having a such big bundle.js file with just a couple of lines in index.js. Is there some gap that I'm missed out or is this the normal case that using React is by default this big and Webpack has to live with it?

I really hope somebody can bring light to this because I've been trying to put my mind at peace on this since yesterday. Gladly to provide more information if needed. Thanks!

Advena
  • 1,664
  • 2
  • 24
  • 45
  • 1
    As a learner this is why I quit setting up my Webpack configuration while I am trying to learn React itself. I tried, really, but nearly in every tutorial I had to go to Webpack documentation and fixed the legacy settings or do some search as in your situation. Most of the time I solved the issues but lost time. Have I learned Webpack so much, no. I've already forgot most of the configuration. Now, I fire a CRA and go with that. I know this does not solve your problem but take that a note from a learner to another one. – devserkan Jul 29 '18 at 14:56
  • 1
    @devserkan I also thought about ignoring the setup, using the react and babbel js files and concentrate more on React itself. However, I'm somebody who will not be at peace until i figured out what the heck is going on here. Might be a bug, wouldn't be the first time i stumbled upon one while learning new Frameworks. – Advena Jul 29 '18 at 15:00
  • 1
    I see your point. Then you need to look for optimization configuration for Webpack I think. This size is not normal. Minifying, uglifying and some other options help to reduce file size. Also, probably it includes source maps, they occupy lots of space. – devserkan Jul 29 '18 at 15:23

2 Answers2

2

One strategy I’ve used, and which you already mention, would be breaking your bundle into separate files.

For example, create a base file containing everything required to paint your landing page and then individual files, one for each “feature”, that can be loaded either asynchronously or even on demand.

Also it should be noted that asset bundling is an expedient to improve performance of production code.

As others have also noted, while you’re learning the ropes of React development, asset bundling (via webpack or other strategies), is really a waste of your time and will only interfere with your stated goal.

Rob Raisch
  • 17,040
  • 4
  • 48
  • 58
  • I'll guess I'll stick to a CRA or build in – Advena Jul 30 '18 at 08:19
1

Update

After testing your webpack setup I came to conclusion that the scripts in package.json forcing webpack to run in development mode. CLI arguments have precedence over the mode: production property in webpck config.

The solution is to adjust the start and build scripts as follows:

"start": "webpack --mode development --watch", "build": "webpack --mode production"


From webpack docs:

Tree shaking is a term commonly used in the JavaScript context for dead-code elimination. It relies on the static structure of ES2015 module syntax, i.e. import and export.

In your /src/app/index.js:

import React from 'react;
import ReactDom from 'react-dom;

class TodoComponent extends React.Component {
  render() {
    return (<h1>hello</h1>);
  }
}

ReactDom.render(<TodoComponent/>, document.querySelector(".todo-wrapper"));

So, Tree shaking won't work if you stay with require.


Some good threads that would get you going you can find here and here

External resources that are worth reading: bundle-size and analyzing-bundle

yotke
  • 1,170
  • 2
  • 12
  • 26
  • 2
    There is no difference between `{“mode”: “production”}` and `{mode: ”production”}` so that is not “wrong” at all. – Rob Raisch Jul 29 '18 at 17:16
  • 1
    Then I wander why react script that is included is the development one. Webpack should take care of that if it recognizes production mode if I recall correctly. – yotke Jul 29 '18 at 17:20
  • 2
    Not sure what you’re saying here. From the perspective of the JavaScript runtime, there is no difference between quoted or unquoted property keys. The only reason to quote a key would be if it contained characters that are illegal in JavaScript symbols, like “this is a key” or “key-with-hyphens”. – Rob Raisch Jul 29 '18 at 17:36
  • I'm saying, even though I agree qoutes should not be a problem, I suspect the mode is not recognized and thus including react.development.js in the bundle. But I will have to test it myself to be sure of what is going on. – yotke Jul 29 '18 at 17:39
  • I corrected from "mode" to mode as you mentioned and the file size didn't change a bit. Thanks, you provided some nice additional material on how to opimize the use of Webpack. But I'm still wondering why this is needed for a couple of lines of codes. Excuse me my ignorance but it seems like a very bad node package if the core functionalities build this huge file sizes... – Advena Jul 30 '18 at 08:17
  • @devserkan I think i figured it out. In `package.json` the build script is building webpack in development mode - `webpack -d`. Actually the start and build scripts is incorrect. Change start task to: `webpack --mode development` and build script to: `webpack --mode production`. That should fix it. Please update your result. – yotke Jul 30 '18 at 09:19