Combining Multiple Files with Laravel Mix Combining Multiple Files with Laravel Mix laravel laravel

Combining Multiple Files with Laravel Mix


I'd say there are 3 main things you have to consider here (they are not all equal):

  • Size - The amount of space your resources are going to take up and the file sizes that are being downloaded.
  • Number of requests - How many files are being loaded in to the page.
  • Browser Cache - Files will be pulled from the cache rather than the server.

In your particular situation it would depend on how big your app.js file is on it's own, how big your page specific files would be without the code the code from app.js, how many page specific files you have and if you're using some of the same resources in your different file e.g. requiring the same package(s) in the different files.


One File

If your page specific files are fairly small then I would just included them in your main app.js file:

require('./index/index')require('./about/about')//etc

webpack.mix.js:

.js('resources/assets/js/app.js', 'public/js')

This would mean that you're only storing one compiled file on your server, only one request is being made for your javascript and it should be cached for every subsequent page load across the site.


A main file and a page specific file

If you have a large number of page specific files or your page specific files aren't that small then I would suggest compiling your app.js independently of your page specific files. Don't forget to compare the results of this approach with the One file approach as the One File approach might still be more efficient.

webpack.min.js

.js('resources/assets/js/app.js', 'public/js').js('resources/assets/js/index/index.js', 'public/js/index').js('resources/assets/js/about/about.js', 'public/js/about')

This will mean that the main bulk of your code (app.js) will still be getting cached and that only one request is being made for page specific code (which should then be cache for each subsequent load of that page).

Please note that if you are requiring packages in both your app.js file and page specific file they will not be shared across the 2 so it will increase the overall size for those requests. Packages that can be added to the window object (e.g. jQuery) should only be included in your app.js.

One way to get around this would be to use Vendor Extraction (Laravel Mix docs):

.extract(['jquery'])

This will produce two extra files that you'll need to include in your html:

<script src="/js/manifest.js"></script><script src="/js/vendor.js"></script> 

One main file and a few page specific file

If you have one or two page specific files that are fairly big but the rest aren't you could compile the majority of your page specific files in to app.js and have the larger ones compile to their own files.


All page specific files

I would only go down this route if all your page specific file are quite large, your app.js file wasn't that big and the code/logic in your page specific files couldn't be refactored so that it could be shared across different files.

This way would similar to the example in your question, however, instead of having:

webpack.min.js

mix.js([    'resources/assets/js/app.js',    'resources/assets/js/index/index.js'], 'public/js/index/index.js').version();

you would have:

resources/assets/js/index/index.js

require('../app.js')//rest of file

webpack.min.js

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

I would never reach for this approach straightaway though and there are very few situations where it would be the most efficient.


Summary

I would always reach for the One File approach and then look at optimising later (unless something really suck out during development) as premature optimisation can lead to code smell and harder maintainability.

This might be a good article for you as well https://medium.com/@asyncmax/the-right-way-to-bundle-your-assets-for-faster-sites-over-http-2-437c37efe3ff