Webpack/Laravel Mix with Drupal

Webpack/Laravel Mix with Drupal

Problems with getting webpack setup for Drupal 7 or Drupal 8?

Modern frontend development is a pain -it's never ending "stuff" you don't understand and have to learn

Laravel Mix is one of the easiest and quickest way to do the basics - compile SCSS/LESS & Javascript. Laravel Mix is an elegant wrapper around basic Webpack tasks. Laravel Mix was created for Laravel - but it can be used stand alone and on any application - I frequently use it on Wordpress & Drupal website

Last Updated: 11-Jan-2021 - Updated to include information on Laravel Mix 6

Laravel Mix 6.0.0

Laravel mix 6+ makes life much easier to up & running -

Drupal 8

Start by navigation to the root of your project. Then using Yarn or NPM install laravel-mix - I will demonstrate using NPM but Yarn works much the same way.

npm init -y
npm install laravel-mix --save-dev

Next step is to create the mix configuration file,

touch webpack.mix.js

If you check the root directory you will see webpack.mix.js file, node_modules folder & package.json folder.

In the webpack.mix.js folder add the following; Remember to change the theme name and if you wish to customise the path

// REPLACE THE THEME NAME
var themename = "THEME_NAME_HERE";
const themePath = 'web/themes/' + themename + '';
// Source files eg uncompiled js & scss will be in the theme under /src folder
// within src folder there will be /js/ and /scss/ folder
const resources = themePath + '/src';

// Public path is where the files will be created
// assets/css/app.css
// assets/js/app.js
mix.setPublicPath(`${themePath}/assets`);
mix.sass(`${resources}/scss/app.scss`, `${themePath}/assets/css`).sourceMaps();
mix.js(`${resources}/js/app.js`, `${themePath}/assets/js`)
// Uncomment for browser sync
//mix.browserSync('https://mywebsite.test');

My preference is my source files in a directory called /src that then compiles to a directory called /assets/

Laravel Mix works with many different options, if you prefer to use Less or PostCSS - you just need to change the mix function - for example for LESS you can use

mix.less(`${resources}/scss/app.scss`, `${themePath}/assets/css`);

Once your config file is setup to your liking - to compile your CSS & Javascript just enter the following command in your terminal

npx mix

However, in reality, you will often want to let mix "watch" for file changes - to do this run

npx mix watch

This will recompile on any changes - Laravel Mix also works with Browser Sync, so you can set it up so you don't even have to refresh your browser.

Finally, by default Laravel Mix compiles but doesn't minify - if you want to minify your files before pushing to production - you just run the following command

npx mix --production


Drupal 7

You can follow the same instructions as Drupal 8, the key difference is the path needs updated to use Drupal 7.

// REPLACE THE THEME NAME
var themename = "THEME_NAME_HERE";
const themePath = 'sites/all/themes/' + themename + '';
// Source files eg uncompiled js & scss will be in the theme under /src folder
// within src folder there will be /js/ and /scss/ folder
const resources = themePath + '/src';

// Public path is where the files will be created
// assets/css/app.css
// assets/js/app.js
mix.setPublicPath(`${themePath}/assets`);
mix.sass(`${resources}/scss/app.scss`, `${themePath}/assets/css`).sourceMaps();
mix.js(`${resources}/js/app.js`, `${themePath}/assets/js`)
// Uncomment for browser sync
//mix.browserSync('https://mywebsite.test');

After your setup you, in the terminal run

npx mix watch

if you want to minify your files before pushing to production - you just run the following command

npx mix --production

Laravel Mix before v6.0.0

Drupal 8 Theme

When building Drupal 8 websites, I often turn to Laravel Mix - here is how I set it up

First I go to the root directory of the Drupal Install

npm init -y npm install laravel-mix --save-dev cp node_modules/laravel-mix/setup/webpack.mix.js ./

It will generate the following

  • package.json

  • webpack.mix.js

  • node_modules/

Open up the webpack.mix.js, modify the "theme name" on line 4

My personal preference to store the my "raw" SCSS & Javascript in a folder in the theme called src/ - with a folder for each

Which will compile to

 /web/themes/THEMENAME/css/app.css /web/themes/THEMENAME/js/app.js

Next to make things easier, I update the the package.json - as Laravel Mix recommends to make it easy to run the process

    "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"
    },

If using these scripts, you will need to "npm install cross-env --save-dev"

Finally, with all that done - you just need run the script

npm run watch or npm run prod

Problems?

Since I wrote this article sass-loader 8.0 had a breaking change this Laravel Mix - you can uninstall 8.x and rollbacking to 7.x using the following commands

npm uninstall --save-dev sass-loader
npm install --save-dev sass-loader@7.1.0

Drupal 7

To use it for Drupal 7 - you just need to update the paths to the theme to use /sites/all/themes - example below

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

// EDIT THEME NAME
var themename = "THEME_NAME_HERE";
// Path to Theme
const themePath = 'sites/all/themes/' + themename + '';

// Path to 'Raw' Source files
// sites/all/themes/THEME_NAME/src
const resources = themePath + '/src';

// auto-prefixer for last 2 versions and safari >8 - Bootstrap 4 requires
mix.options({
    postCss: [
        require('autoprefixer')({
            remove: false,
            browsers: ['last 2 versions', 'safari >= 8']
        })
    ]
});


// sites/all/themes/THEME_NAME/src/scss/app.css  TO  sites/all/themes/THEME_NAME/css/app.css 
mix.sass(`${resources}/scss/app.scss`, `${themePath}/css`, {
    includePaths: ['node_modules']
}).sourceMaps();

// sites/all/themes/THEME_NAME/src/js/app.js  TO  sites/all/themes/THEME_NAME/js/app.js 
mix.js(`${resources}/js/app.js`, `${themePath}/js`)

About Fraser Clark

I've been a professional developer for over 10 years. I've been consulting and developing websites & software for small businesses, multi-nationals & governments.

I'm an expert in WordPress, Drupal, Laravel & a whole host of other platforms.

More about Fraser | Get in touch