Laravel Mix in a Non-Laravel Project
Recently, I've been looking to make a Craft CMS powered site a full single page app using Vue JS. Typically for these kind of SPAs there are generators like Vue Cli (or Create React App for React) that will scaffold the app for you and configure things like Vue Router etc. However, I needed to use Craft's templating language for some parts in lieu of a fully restful API.
I've had good mileage with Vue Cli myself but as soon as I've wanted my tooling to do something (like integrate BrowserSync for instance) then I've quickly become bogged down in understanding the Webpack configuration.
Laravel Mix makes things much simpler.
Have a quick watch of the video below to get an idea of what Mix is and what it can do.
So, how am I using this with Craft and what for?
Previously, I had a set of Gulp tasks that would compile Sass, JavaScript and watch for changes in Twig templates and refresh via BrowserSync. A pretty common scenario. However, starting to write ES6 (or ECMAScript 2015 Language) JavaScript meant that I needed to transpile for browsers that didn't support it. Enter Mix.
First steps
If you don't already have one defined, initialise an npm project. You will need to have Node and NPM installed globally for this.
That should then give you
- node_modules/
- package.json
- webpack.config.js
- webpack.mix.js
Next, I need to configure some actual npm build scripts. Inside my package.json
- amend your scripts
object
All of this info (and more) can be found on the Github install options for Mix.
The tasks above mean I can do npm run dev
to get a dev version of CSS & JS, npm run watch
listens for changes in my source Sass and JS and builds them, npm run hot
give me Hot Module Reloading which I'll touch on later and npm run production
compiles a production build of assets.
From here I don't need to change anything other than my webpack.mix.js
file. That looks like:
So what does this actually do? let buildPath = 'build/'
sets the output path relative to our public path in my case public
- the default webroot for Craft that we then define on line 6.
From there, I set my JS task to transpile app.js
to the same filename in my build directory and our app.sass
to the same place (inside respective js
and css
directories).
I've then added BrowserSync telling it to listen to my virtualhost and refresh on changes to any Twig templates.
Of course, I still haven't let Craft know about my new JS and CSS. I wanted to use Webpack's Hot Module
Reloading that watches changes and injects them into the page without a refresh and so I got a little stuck at this point.
For this to work, I had to define my _master.twig
Craft layout file like so:
http://localhost:8080
is the Webpack dev server instance that runs during npm run hot
but the way that works means that your JS and CSS don't actually exist in your build directories until you either npm run dev
or npm run production
.
That's all there is to it. I find much simpler than having a bunch of Gulp tasks defined.
I will have some other posts coming up that focus on writing a single page app with Vue.js and Craft, so stay tuned for those.