Menasheh
Menasheh

Reputation: 3708

Why is webpack spitting out 10,000 extra lines?

I'm using webpack via the default laravel setup after having run npm install, with the default config.

In webpack.mix.js, I have the following:

mix.js('resources/assets/js/init.js', 'public/js');

And resources/assets/js/init.js contains the following:

(function ($) {
    $(function () {
        $('.button-collapse').sideNav();
    }); // end of document ready
})(jQuery);

Why, then, does webpack emit a whopping 10,000+ lines for this file?!:

Here's the output in a gist.

Did I completely misunderstand webpack, or is a laravel or webpack default messed up? I expect basically a copy of the JS, as npm run dev is not supposed to minify and it doesn't have any ES6 syntax in it... So what is this? The same thing works perfectly to compile scss to css if I add the appropriate line to the mix.

Upvotes: 1

Views: 203

Answers (1)

Kyle Fahringer
Kyle Fahringer

Reputation: 294

Short Answer

As best I can tell from what code you've given - yep, that's right.

Long Answer

What webpack does isn't just to compile your app to ES5. Rather, what is designed to do is package every dependency together in a single file so the end user downloads a single JS file.

In your original file, I assume at some point you define jQuery using require or some other method. (I'm not familiar with mix, but I assume at some point jQuery must be defined.) When you use require('jquery'), webpack transforms that into all of the jQuery source code - which is likely where almost all of the 10,000 lines of code are from.

We see your original code at the very end of the webpack bundle, starting at line 10,302:

/* WEBPACK VAR INJECTION */(function(jQuery) {(function ($) {
    $(function () {
        $('.button-collapse').sideNav();
    }); // end of document ready
})(jQuery);
/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(1)))

As you can see, it's basically what you wrote, but now it defines jQuery using the previous 10,000 lines of code. This way, it's not referencing any external files.

Splitting your code

If you don't want your webpack bundle to have a bunch of jQuery at the top, you can split your code into vendor and app files. According to the laravel docs, that's done like this:

mix.js('resources/assets/js/init.js', 'public/js')
  .extract(['jquery'])

Then, your bundle will output three files instead of one - one file containing the webpack manifest, one file containing all of the libraries (such as jQuery in this case), and one file containing the main app code (the five lines you wrote in resources/assets/js/init.js).

Upvotes: 1

Related Questions