2021-02-01-how-to-set-up-and-use-laravel-mix-with-your-project.md 6.52 KB
Newer Older
Mike Street's avatar
Mike Street committed
1
2
---
title: How to set up and use Laravel Mix with your project
Mike Street's avatar
Mike Street committed
3
date: 2021-02-01
Mike Street's avatar
Mike Street committed
4
updated: 2021-03-25
Mike Street's avatar
Mike Street committed
5
intro: Despite the name, Laravel Mix isn't just for Laravel. It is a tidy, succinct task runner with understandable syntax and a single config file. This tutorial will run through setting it up with your project
Mike Street's avatar
Mike Street committed
6
permalink: "blog/how-to-set-up-and-use-laravel-mix-with-your-project/"
Mike Street's avatar
Mike Street committed
7
8
9
10
11
12
13
14
15
16
tags:
 - Web
 - Front-end Development
 - DevOps
---

Despite the name, Laravel Mix isn't just for Laravel. It is a tidy, succinct task runner with understandable syntax and a single config file. This tutorial will run through setting it up with your project

## Intro

Mike Street's avatar
Mike Street committed
17
I am a massive advocate of Gulp and have used it for years. However, there is a new player in town and. for all my side projects it knocks the socks off Gulp. [Laravel Mix](https://laravel-mix.com/) is a Webpack wrapper - this means it uses its own config files while benefiting from the greatness that is Webpack.
Mike Street's avatar
Mike Street committed
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45

It's created by Jeffery Way, the author of Laravel, which is where I assume it gets its name from but you don't need to have a Laravel powered app to utilise its power. There are plenty of plugins available too. We will set up Laravel Mix with SCSS, ES6 compilation, image optimisation and run it alongside Eleventy.

## Objectives

<div class="note">This blog post uses the command line to install tools via <code>npm</code>, along with using SCSS. It is USEFUL if you are familiar with using these tools.</div>

We are going to:

- Install Laravel Mix
- Compile SCSS and JS
- Copy and optimise images while making `.webp` versions

## TL:DR;

Just want to copy and paste? In a rush and just need the bullet points?

- **Set up**
	- Ensure you have a `package.json` file (`npm init` if not)
	- Install laravel-mix: `npm install laravel-mix --save`
	- Create a `webpack.mix.js` in your project root
	- Make sure your [file structure matches](#file-structure)
- **SCSS and JS compilation**
	- Add the [sass and js compilation](#sass-js) to the file
	- Add the NPM [scripts](#npm-script) to your package.json file
	- Run `npm run prod:assets`
	- Check your compiled assets exist, and include them in your template (`<link rel="stylesheet" href="/assets/css/style.css">`)
- **Image Optimisation**
Mike Street's avatar
Mike Street committed
46
	- Include the [image optimisation](#image-optimisation) config to your `laravel.mix.js` file
Mike Street's avatar
Mike Street committed
47
48
49
50
51
52
53
54
	- Recompile your assets

## Steps

### Laravel Mix Setup

As with any "cool" tech these days, we need to start with `npm`. If you haven't done so already, run the following on the command line (make sure you have `cd`d to the correct directory). If you are unsure whether this is required, look for a `package.json` file in your folder.

Mike Street's avatar
Mike Street committed
55
56
57
```bash
npm init
```
Mike Street's avatar
Mike Street committed
58
59
60
61
62

This will run you through some questions and set up a `package.json` file for you.

Next we need to install `laravel-mix`. This can be done by entering the following command:

Mike Street's avatar
Mike Street committed
63
64
65
```bash
npm install laravel-mix --save
```
Mike Street's avatar
Mike Street committed
66
67
68
69
70

This will take a few minutes to install as it has several dependencies to install itself.

Next, using the your editor, IDE or the command line, create a new file called `webpack.mix.js` in the root of your projects

Mike Street's avatar
Mike Street committed
71
### <a name="file-structure"></a>SCSS and JS file setup
Mike Street's avatar
Mike Street committed
72
73
74

The code below assumes you have the following file structure (if not, you should should adjust the code to suit)

Mike Street's avatar
Mike Street committed
75
76
```
- build/
Mike Street's avatar
Mike Street committed
77
78
79
80
81
82
83
84
	- css/
		- screen.scss
	- js/
		- app.js
- public/
	- index.html (or similar)
	- assets/ (this will be auto generated)
- webpack.mix.js
Mike Street's avatar
Mike Street committed
85
86
- package.json
```
Mike Street's avatar
Mike Street committed
87

Mike Street's avatar
Mike Street committed
88
### <a name="sass-js"></a>SCSS and JS Compilation
Mike Street's avatar
Mike Street committed
89
90
91

Open the `webpack.mix.js` file and put the following in (not forgetting to update the paths if yours are different).

Mike Street's avatar
Mike Street committed
92
93
```js
let mix = require('laravel-mix');
Mike Street's avatar
Mike Street committed
94
95
96

mix
	.sass('build/css/screen.scss', 'public/assets/css/style.css')
Mike Street's avatar
Mike Street committed
97
98
	.js('build/js/app.js', 'public/assets/js/app.js');
```
Mike Street's avatar
Mike Street committed
99
100
101
102
103

This defines a new "mix" (using `laravel-mix`) and then specifies a sass (scss) and JS processor.

Once saved (and the file structure set up) you can run the following command to compile and generate your assets

Mike Street's avatar
Mike Street committed
104
105
106
```bash
NODE_ENV=production node_modules/webpack/bin/webpack.js --progress --hide-modules --env=production --config=node_modules/laravel-mix/setup/webpack.config.js
```
Mike Street's avatar
Mike Street committed
107
108
109

To make this less hassle (and easier to remember), you can create a script in your `package.json` file. Open up the file and replace the `scripts` block with the following:

Mike Street's avatar
Mike Street committed
110
111
112
113
<a name="npm-script"></a>

```json
"scripts": {
Mike Street's avatar
Mike Street committed
114
115
  "prod:assets": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --progress --hide-modules --env=production --config=node_modules/laravel-mix/setup/webpack.config.js",
  "watch:assets": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --watch --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
Mike Street's avatar
Mike Street committed
116
117
}
```
Mike Street's avatar
Mike Street committed
118
119
120

This lets you now run the following instead of that lengthy command:

Mike Street's avatar
Mike Street committed
121
122
123
```bash
npm run prod:assets
```
Mike Street's avatar
Mike Street committed
124
125
126

This will create your assets for production. As a bonus, this also includes a **watcher** script, which will compile as you save either the `scss` or `js` files. This can be activated, by running the command:

Mike Street's avatar
Mike Street committed
127
128
129
```bash
npm run watch:assets
```
Mike Street's avatar
Mike Street committed
130
131
132

With your assets hopefully compiling, they can be included in your template, as you would with other CSS and JS files

Mike Street's avatar
Mike Street committed
133
134
135
```html
<link rel="stylesheet" href="/assets/css/style.css">
```
Mike Street's avatar
Mike Street committed
136

Mike Street's avatar
Mike Street committed
137
### <a name="image-optimisation"></a>Image Optimisation
Mike Street's avatar
Mike Street committed
138
139
140
141
142

The next step is to add image optimisation to our build process. This will minify the jp(e)gs and pngs and also generate webp images. Serving up the webp images can either be hardcoded in your files, templates & content or you can use browser sniffing to serve up the right versions. We'll cover that in another post.

Add the following to your `laravel.mix.js` file, after the JavaScript configuration (included in the snippet below for reference). Be careful of your semi-colons (the one after `js()` has been removed)

Mike Street's avatar
Mike Street committed
143
144
```js
.js('build/js/app.js', 'html/assets/js/app.js')
Mike Street's avatar
Mike Street committed
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
.imagemin({
	from: 'img/**/*'
}, {
	context: 'build'
})
.webpackConfig({
	plugins: [
		new ImageMinWebpWebpackPlugin({
			config: [
				{
					test: /(img).*\.(jpe?g|png)/,
					options: {
						quality: 80
					}
				}
			]
		})
	]
})
.setPublicPath('html/assets');
Mike Street's avatar
Mike Street committed
165
```
Mike Street's avatar
Mike Street committed
166
167
168

`imagemin` has slightly different syntax for the to and from, so if your paths change be sure to update the `context` and the `setPublicPath` paths at the end. With the `context`, this is folder your image folder is in.

Mike Street's avatar
Mike Street committed
169
The `webpackConfig` block in the middle is the WebP generation. If you don't need this then feel free to remove. This optimises any images in `html/assets/img` (which is placed there by the `imagemin` before it).