Introduction

Laravel Mix is a package created by Jeffrey Way, the inventor of Laracasts, that provides a fluent API for constructing webpack build stages for your OstroJs application utilising a variety of CSS and JavaScript pre-processors.

To put it another way, Mix makes compiling and minifying your application's CSS and JavaScript files a breeze. You may define your asset pipeline smoothly using simple method chaining. Consider the following scenario:

mix.js('resources/js/app.js', 'public/js')
    .postCss('resources/css/app.css', 'public/css');

You'll appreciate Laravel Mix if you've ever been puzzled and intimidated about getting started with webpack and asset compilation. However, you are not obligated to utilise it when creating your app; you can use any asset pipeline tool you like, or none at all.

Installation & Setup

Installing Laravel Mix

The only thing left to do is install Laravel Mix. You'll discover a package.json file in the base of your directory structure when you first install OstroJS. Everything you need to get started with Laravel Mix is already in the default package.json file. Consider this file to be similar to composer.json, however instead of NPM requirements, it defines Node dependencies. You may execute the following command to install the requirements it mentions:

npm install

Running Mix

Because Mix is a configuration layer on top of webpack, all you have to do to run your Mix jobs is run one of the NPM scripts supplied in the default OstroJS package.json file. All of your application's CSS and JavaScript assets will be compiled and stored in your application's public directory when you execute the dev or production scripts:

// Run all Mix tasks...
npm run dev

// Run all Mix tasks and minify output...
npm run prod

Watching Assets For Changes

The npm run watch command will keep running in your terminal, watching for changes in any relevant CSS and JavaScript files. When one of these files is changed, Webpack will immediately rebuild your assets:

npm run watch

In some local development settings, Webpack may not be able to detect your file modifications. Consider using the watch-poll command if this is the case on your system:

npm run watch-poll

Working With Stylesheets

The webpack.mix.js file in your application serves as the starting point for asset compilation. Consider it a lightweight configuration wrapper for webpack. Mix tasks can be linked together to specify how your assets should be put together.

PostCSS

Laravel Mix is pre-installed with PostCSS, a powerful tool for modifying CSS. Mix uses the famous Autoprefixer plugin by default to apply the essential CSS3 vendor prefixes automatically. You can, however, use any other plugins that are acceptable for your application.

To use Mix's postCss function, first install the appropriate plugin using NPM and include it in your array of plugins. The first parameter to the postCss function is the path to your CSS file, and the second argument is the directory where the compiled file should be placed:

mix.postCss('resources/css/app.css', 'public/css', [
    require('postcss-custom-properties')
]);

Alternatively, you may use postCss without any other plugins to do simple CSS compilation and minification:

mix.postCss('resources/css/app.css', 'public/css');

Sass

You can compile Sass into CSS that web browsers can understand using the sass technique. The first parameter to the sass method is the path to your Sass file, and the second argument is the directory where the compiled file should be placed:

mix.sass('resources/sass/app.scss', 'public/css');

By invoking the sass function numerous times, you may compile multiple Sass files into their own CSS files and even change the output directory of the resultant CSS:

mix.sass('resources/sass/app.sass', 'public/css')
    .sass('resources/sass/admin.sass', 'public/css/admin');

URL Processing

Because Laravel Mix is built on top of webpack, knowing a few webpack fundamentals is essential. Webpack will rewrite and optimise any url() calls within your stylesheets for CSS compilation. While this may appear unusual at first, it is a very strong piece of functionality. Let's say we wish to generate Sass that includes a relative picture URL:

.example {
    background: url('../images/example.png');
}

Laravel Mix and webpack will look for example.png by default, copy it to your public/images folder, and then rewrite the url() in your output stylesheet. As a result, your compiled CSS will look like this:

.example {
    background: url(/images/example.png?d41d8cd98f00b204e9800998ecf8427e);
}

As valuable as this functionality is, your current folder structure may already be set up the way you want it. If this is the case, you may use the following code to deactivate url() rewriting:

mix.sass('resources/sass/app.scss', 'public/css').options({
    processCssUrls: false
});

Mix will no longer match any url() or copy assets to your public directory once you add this to your webpack.mix.js file. In other words, the produced CSS will appear exactly as you wrote it:

.example {
    background: url("../images/thing.png");
}

Source Maps

Source maps, which are disabled by default, may be enabled by invoking the mix.sourceMaps() method in your webpack.mix.js file. When utilising built assets, this will offer more debugging information to your browser's development tools, albeit it comes at a cost in terms of compile/performance:

mix.js('resources/js/app.js', 'public/js')
    .sourceMaps();

Style Of Source Mapping

Webpack has a number of source mapping styles to choose from. Mix's source mapping style is set to eval-source-map by default, which ensures a quick rebuild time. If you wish to alter the mapping style, use the sourceMaps method to do so:

let productionSourceMaps = false;

mix.js('resources/js/app.js', 'public/js')
    .sourceMaps(productionSourceMaps, 'source-map');

Working With JavaScript

Compiling current ECMAScript, module bundling, minification, and concatenating plain JavaScript files are just a few of the capabilities Mix offers to assist you interact with your JavaScript files. Even better, it all works without a hitch, and it doesn't require any unique configuration:

mix.js('resources/js/app.js', 'public/js');

With this single line of code, you may now take advantage of:

  • The latest EcmaScript syntax.
  • Modules
  • Minification for production environments.

Vue

When utilising the vue method, Mix will automatically install the Babel plugins required for Vue single-file component compilation functionality. There is no need for any additional configuration:

mix.js('resources/js/app.js', 'public/js')
   .vue();

After your JavaScript has been built, you may use it in your application by referencing it as follows:

<head>
    <!-- ... -->

    <script src="/js/app.js"></script>
</head>

React

Mix may install the Babel plugins required for React compatibility automatically. Add a call to the react function to get started:

mix.js('resources/js/app.jsx', 'public/js')
   .react();

Mix will download and install the babel-preset-react Babel plugin behind the scenes. After your JavaScript has been built, you may use it in your application by referencing it as follows:

<head>
    <!-- ... -->

    <script src="/js/app.js"></script>
</head>

Vendor Extraction

One disadvantage of bundling all of your application-specific JavaScript with vendor frameworks like React and Vue is that long-term caching becomes more challenging. For example, even if your application code hasn't changed, a single modification to your application code will compel the browser to re-download all of your vendor libraries.

If you plan to make regular JavaScript updates to your application, consider extracting all of your vendor libraries into their own file. This manner, if you make a modification to your application code, the caching of your huge vendor.js file will not be affected. The extract mechanism used by Mix makes this a breeze:

<head>
    <!-- ... -->

    <script src="/js/app.js"></script>
</head>

The extract function takes an array of libraries or modules to be extracted into a vendor.js file. Mix will produce the following files using the excerpt above as an example:

  • public/js/manifest.js: The Webpack manifest runtime
  • public/js/vendor.js: Your vendor libraries
  • public/js/app.js: Your application code

To avoid JavaScript issues, make sure these files are loaded in the correct order:

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

Custom Webpack Configuration

It's possible that you'll need to change the underlying Webpack settings manually on occasion. You could, for example, have a custom loader or plugin that has to be referenced.

Mix has a webpackConfig function that you may use to combine any short Webpack configuration customizations. This is especially tempting because it eliminates the need to duplicate and maintain your own webpack.config.js file. The webpackConfig function takes an object that contains any Webpack-specific configuration you want to use.

mix.webpackConfig({
    resolve: {
        modules: [
            path.resolve(__dirname, 'resources/assets/js')
        ]
    }
});

Versioning / Cache Busting

Many developers add a date or a unique token to their built assets to encourage browsers to provide current assets rather than stale versions of the code. Using the version technique, Mix can handle this for you automatically.

All compiled files' filenames will be appended with a unique hash by the version method, enabling for easier cache busting:

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

You won't know the precise filename after producing the versioned file. To load the right hashed asset, you should utilise OstroJS's global mix method within your views. The current name of the hashed file will be determined automatically by the mix function:

<script src="{{ helpers.mix('/js/app.js') }}"></script>

Because versioned files are rarely used in development, you may tell npm to only conduct the versioning procedure during npm run prod:

mix.js('resources/js/app.js', 'public/js');

if (mix.inProduction()) {
    mix.version();
}

Custom Mix Base URLs

You'll need to update the base URL generated by the mix function if your Mix built assets are pushed to a CDN distinct from your application. You may do so by adding a mix url configuration option to the config/app.js configuration file for your application:

'mix_url' => env('MIX_ASSET_URL', null)

When creating URLs for assets after specifying the Mix URL, the mix function will prefix the configured URL with:

https://cdn.example.com/js/app.js?id=1964becbdd96414518cd

Notifications

Mix will display OS alerts during building if they are available, providing you fast feedback on whether the compilation was successful or not. There may be times, though, when you might want to turn off these notifications. Triggering Mix on your production server is one such example. The disableNotifications function may be used to turn off notifications:

mix.disableNotifications();