Header Ads

Minify CSS and Javascript On The Fly Using Laravel Mix

Today we're going to discuss one of my favorite feature in Laravel, the Laravel Mix. If you're a Front-end web developer this will save you a lot of time compiling your CSS & JavaScript. Laravel Mix served as a wrapper to simplify the sometimes confusing and overwhelming module bundler called Webpack. For example:
mix.js('resources/assets/js/app.js', 'public/js')
   .sass('resources/assets/sass/app.scss', 'public/css');
The code above will compile your app.js and app.scss file and save it to public/js directory for the Javascript and public/css for the CSS.

Installation & Setup

Before anything else, make sure you have Node.js and NPM installed in your machine. Run the following commands in your terminal:
node -v
npm -v
You can install the latest version of Node and NPM by downloading their installer here.

After installing Node and NPM, you can simply run npm install command if you have a fresh installation of Laravel, because by it's already included in package.json by default. Otherwise you have to manually add it:
"devDependencies": {
    "laravel-mix": "^0.8.3",    
  }

The Laravel Mix API

Tha entry point of all your assets compilations can be found in webpack.mix.js file. You can chained Mix methods together depending on how your assets should be compiled.

Less

If you want to compile Less CSSS pre-processor, you can use the less method:
mix.less('resources/assets/less/app.less', 'public/css');

Compiling Multiple less files:
mix.less('resources/assets/less/app.less', 'public/css')
   .less('resources/assets/less/admin.less', 'public/css');

Passing a full file path as a second argument to the less method will customize the file name of the compiled CSS.
mix.less('resources/assets/less/app.less', 'public/stylesheets/styles.css');

If you want to override the Less loader options, you may pass an object as the third argument to the less method:
mix.less('resources/assets/less/app.less', 'public/css', {
    strictMath: true
});

Sass

If you want to compile Sass CSSS pre-processor, you can use the sass method:
mix.sass('resources/assets/less/app.scss', 'public/css');

Compiling Multiple sass files:
mix.sass('resources/assets/less/app.scss', 'public/css')
   .less('resources/assets/less/admin.scss', 'public/css');

Like the less method, passing a full file path as a second argument to the sass method will also customize the file name of the compiled CSS.
mix.sass('resources/assets/less/app.sass', 'public/stylesheets/styles.css');

If you also want to override the Node-Sass plug-in options, you may also pass an object as the third argument to the sass method:
mix.less('resources/assets/less/app.scss', 'public/css', {
    precision: 5
});

Stylus

Like Less and Sass, you can also compile Stylus into CSS using the stylus method:
mix.stylus('resources/assets/less/app.styl', 'public/css');

It's also possible to add some Stylus plug-ins like Rupture. First, install the plug-in through NPM (npm install rupture) and then require it into the use array property in the object that's being passed in the third argument of the stylus method:
mix.stylus('resources/assets/stylus/app.styl', 'public/css', {
    use: [
        require('rupture')()
    ]
});

PostCSS

Below is how to add a PostCSS plug-ins in Laravel Mix. Simply install the desired plug-in through NPM and then reference it in your webpack.mix.js file. Please take note that PostCSS, a powerful tool for transforming your CSS, is included out of the box.
mix.less('resources/assets/sass/app.less', 'public/css')
   .options({
        postCss: [
            require('postcss-css-variables')()
        ]
   });

Plain CSS

Use styles method for concatenating some plain CSS stylesheets into a single file:
mix.styles([
    'public/css/vendor/dropzone.css',
    'public/css/vendor/sweetalert.css'
], 'public/css/vendor.css');

URL Processing

Below is how to disable URL processing in Laravel Mix:
mix.sass('resources/assets/app/app.scss', 'public/css')
   .options({
      processCssUrls: false
   });

Source Maps

Source maps is disabled by default in Laravel Mix, but you can enable it using sourceMaps method:
mix.sass('resources/assets/app/app.scss', 'public/css')
   .options({
      processCssUrls: false
   })
   .sourceMaps();

JavaScript

Below is how to compile your JavaScript using Laravel Mix:
mix.js('resources/assets/js/app.js', 'public/js');
The benefits you get with this single line of code:
  • ES2015 syntax.
  • Modules
  • Compilation of .vue files.
  • Minification for production environments.

Vendor Extraction

It's a good practice to use long-term caching for your vendor libraries, so that every time you made an update to your application, only those affected files will be re-downloaded by the browser. You can use the extract method in this situation, which accepts an array of all libraries that you wish to extract into a vendor.js file.
mix.js('resources/assets/js/app.js', 'public/js')
   .extract(['vue'])
The above code will generate the following files:
  • public/js/manifest.js: The Webpack manifest runtime
  • public/js/vendor.js: Your vendor libraries
  • public/js/app.js: Your application code

Make sure to load these files in the proper order to avoid errors:
<script src="/js/manifest.js"></script>
<script src="/js/vendor.js"></script>
<script src="/js/app.js"></script>

React

Mix also support React:
mix.react('resources/assets/js/app.jsx', 'public/js');

Vanilla JavaScript

Similar to styles method that combine stylesheets, you can also combine and minify your JavaScript files using scripts method:
mix.scripts([
    'public/js/home.js',
    'public/js/payment.js'
], 'public/js/all.js');
If your script is using a ES2015 syntax, you can combine them using babel method instead of scripts.

Custom Webpack Configuration

This is how to add Webpack configuration in Laravel Mix:
mix.webpackConfig({
    resolve: {
        modules: [
            path.resolve(__dirname, 'vendor/laravel/spark/resources/assets/js')
        ]
    }
});

Copying Files & Directories

You can also copy files in Laravel Mix:
mix.copy('node_modules/foo/bar.css', 'public/css/bar.css');

Versioning / Cache Busting

Sometime caching your assets can cause inconvenience, specially in development. Mix provide a method called version to automatically append a unique hash to the filenames of all compiled files for convenient cache busting:
mix.js('resources/assets/js/app.js', 'public/js')
   .version();

You can also enable versioning in production build only:
mix.js('resources/assets/js/app.js', 'public/js');

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

When using the version method, it's required to use Laravel's mix global function in your views, to avoid hunting down the new filename every time you make changes:
<link rel="stylesheet" href="{{ mix('/css/app.css') }}"> 

Browsersync Reloading

Laravel Mix also support BrowserSync:
mix.browserSync('my-domain.dev');

// Or...

// https://browsersync.io/docs/options
mix.browserSync({
    proxy: 'my-domain.dev'
});

Notifications

To disable notifications in your machine:
mix.disableNotifications();

Conclusion

Laravel Mix makes our lives more easy, at least in terms of our CSS and JavaScript compilation and minification. I'm very thankful to those people who spend their times making this awesome tools. For more understanding on this topic, you can visit the official documentation here thanks!.


No comments