May 1, 2022

Webpack vs Laravel Mix

It is very common to compile JavaScript using a bundler like Webpack. Every time I have used Webpack for a project it would take some time to set up. Over time, I would have to maintain this configuration file. When there would be a new Webpack version available, upgrading would never really go smooth. Don't get me wrong I really like Webpack, its features and plugins, but sometimes I just need something simple that is fast to set up and not a pain to maintain.

I ended up using Laravel Mix a lot instead of Webpack. Laravel Mix is basically a wrapper around Webpack that offers a very simple API for compiling your JavaScript or CSS assets. What used to require a very big and complicated Webpack config is now a simple script with a few lines of code.

const mix = require('laravel-mix')

mix.js('src/app.js', 'dist')
mix.css('src/style.css', 'dist')

Here is the documentation for installing laravel-mix in your project.

Not exclusive for Laravel

By default, the Laravel framework uses laravel-mix for bundling assets. Despite the name may suggest it can be used outside of Laravel apps. From now on I will call it Mix.

Examples

Here are a couple examples of how to compile your files with Mix.

// JavaScript
mix.js('src/app.js', 'dist');
// TypeScript
mix.ts('src/app.ts', 'dist');
// React
mix.js('src/app.jsx', 'dist').react();
// Vue
mix.js('src/app.js', 'dist').vue();
// CSS
mix.css('src/app.css', 'dist');
// CSS with PostCSS plugins
mix.postCss('src/app.css', 'dist', [
    require('autoprefixer'),
]);
// TailwindCSS
mix.postCss("resources/css/app.css", "public/css", [
    require("tailwindcss"),
]);
// Sass
mix.sass('src/app.scss', 'dist');

Here you can see some more JavaScript examples. Mix uses PostCSS under the hood for compiling CSS. This makes it easy to add more plugins but also compile two CSS files with different PostCSS plugins.

Invalidating cache

When you update your assets and build them you might run in to cache issues where your JS or CSS changes are not directly visible or only visible once cache has been cleared. This can be easily fixed by adding hashes to your assets. Mix has this feature built in. Here is how to enable it.

mix.version();

When Mix has completed a build it will create a file named mix-manifest.json in the output directory. It has a list of all assets and includes a unique hash for each file that can be used for cache busting.

{
  "app.js": "app.js?id=8e5c48eadbfdd5458ec6"
}

Now when including these assets in your <head> you have to retrieve the filename with hash from mix-manifest.json. In laravel this is done by using the mix() function.

Should you use Mix?

The Mix documentation states that it covers 80% of Webpack use cases. There is a big chance that all your use cases are covered. If that is not the case you can still use Mix and add some custom rules.

Here are some reasons why I would prefer to used Mix over Webpack.

  • It's a fast and reliable bundler that can be quickly setup in your project.
  • Not everyone in your team understands webpack or when you have one person who is the Webpack wizard.
  • You have a project that uses Webpack to do basic things like compile React/Vue/CSS.