What is Laravel Mix?

Laravel Mix provides a fluent API for defining Webpack build steps for your Laravel application using several common CSS and JavaScript pre-processors.

But before we dive into learning to use Laravel Mix with Webpack, a little intro about Webpack will be helpful.

What is Webpack?

It is a module bundler used for all modern and leading JavaScript applications like ReactJS, AngularJs, CommonJS, etc.

Webpack takes modules with dependencies and generates static assets for those modules. For different tasks, we need different loader modules and plugins. It has a number of plugins for almost all type of tasks.

Webpack enables the use of loaders to pre-process files. While loaders are used to pre-process certain types of modules, plugins can be leveraged to perform a wider range of tasks like bundle optimization, asset management, handling minification of the files, hot reloading and injection of environment variables. For example- style-loader will add CSS to the DOM by injecting a <style> tag.

Note: Webpack v4+ will minify your code by default in production mode.

Do check the documentation and learn more about its uses.

All is good and fine when you are configuring Webpack for projects. But sometimes it feels too complicated or slow.

Let's see how we can use laravel-mix to skip whole configuration thing and fast forward the development without worrying about all the environment setup.

Why Laravel Mix

To start a project in just 5 minutes with all the basic development environment, use Laravel mix.

Mix is just a configuration layer or thinks as a wrapper on top of Webpack which very easy to use. Laravel mix needs minimal configuration.

If you are working with Laravel 5.4+ Laravel mix is already there.

Since the laravel-mix is just a configuration layer on Webpack, it is not bound to Laravel development only but can be used in developing any project.

We can use Mix for any non-Laravel projects to compile our assets. Compare to Webpack configuration, Laravel mix is easy to configure and takes just 4 steps to create the development ready environment same as Webpack.

Okay, let's do this.

NPM and Node is the only requirement to get started. To verify that you have NPM and Node is already installed, run the following in terminal.

node -v
npm -v


Step 1: Open terminal in the root of your application

mkdir my-awesome-app
cd my-awesome-app
npm init -y


This will create a package.json file with some basic information like app name, version, etc.

Step 2: Install laravel-mix

npm install laravel-mix --save-dev


This will create a directory node_modules which takes a barely 2 minute and adds the laravel-mix in package.json under devDependencies.

Step 3: Get webpack.mix.js

cp -r node_modules/laravel-mix/setup/webpack.mix.js ./


This will create webpack.mix.js file in the app directory. Open this file

let mix = require('laravel-mix');

/*
|--------------------------------------------------------------------------
| Mix Asset Management
|--------------------------------------------------------------------------
|
| Mix provides a clean, fluent API for defining some Webpack build steps
| for your Laravel application. By default, we are compiling the Sass
| file for your application, as well as bundling up your JS files.
|
*/

mix.js('src/app.js', 'dist/').sass('src/app.scss', 'dist/');


This is the default path to write our assets and compiled assets .js,.css will be in /dist.

But we can change the assets source and distribution path as we like to.

I like to keep the scripts file in js and style file in CSS directory respectively. So I updated the path to -

let mix = require('laravel-mix');

/*
|--------------------------------------------------------------------------
| Mix Asset Management
|--------------------------------------------------------------------------
|
| Mix provides a clean, fluent API for defining some Webpack build steps
| for your Laravel application. By default, we are compiling the Sass
| file for your application, as well as bundling up your JS files.
|
*/
mix.setPublicPath('dist');

mix.js('src/js/app.js', 'dist/js/')
.sass('src/sass/app.scss', 'dist/css/');

Now, the updated path will put the compiled js file in dist/js directory and CSS will be in dist/css directory.

Step 4: Install cross-env

This will allow having a single command without worrying about setting or using the environment variable properly for the platform

npm install --save-dev cross-env


This will add a new cross-env under devDependencies.

open package.json and add -

{
  "scripts": {
    "dev": "npm run development",
    "development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js -- 
    progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
    "watch": "npm run development -- --watch",
    "watch-poll": "npm run watch -- --watch-poll",
    "hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack- 
    dev-server.js --inline --hot --config=node_modules/laravel- 
    mix/setup/webpack.config.js",
    "prod": "npm run production",
    "production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js -- 
    no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"
  },
  "devDependencies": {
  "cross-env": "^5.2.0",
  "laravel-mix": "^2.0"
  }
}

 

Explanation -

npm run dev - builds the assets without minifying or a production-ready build.

npm run watch - Same as npm run dev but it actively watches for changes to the assets and automatically compiles them if any changes observed. Run this command while you are working.

npm run hot - refreshes the page when a piece of JavaScript code is changed and will also maintain the current state of the component in the browser.

npm run production - compiles all the assets and output a production-ready build. It will run all Mix tasks and minify the output ready to deploy.

Now we are ready to start developing our app. While our app is in development we run watch command and our assets will be watched for changes.

Once the development is done run production to optimize the output.