Original address: Laravel Mix Docs

Ps: This version is a 3.0 document, with most features consistent with 4.0

An overview of

Basic example

Larave-mix is a neat configuration layer at the top of WebPack. Using Laravel Mix 80% of the time makes operations very simple. Although WebPack is very powerful, most people agree that WebPack is very expensive to learn. But what if you don’t have to worry about that anymore?

Looking at the basic webpack.mix.js file, let’s imagine that we now only need to compile javascript(ES6) and sass files:

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

mix.sass('src/app.sass'.'dist')
   .js('src/app.js'.'dist');
Copy the code

How was it? Was it easy?

/ SRC /app.sass to./dist/app.css 2. Package all js(including any dependencies) in./ SRC /app.js to./dist/app.js.

Using this configuration file, you can trigger the Webpack directive on the command line: node_modules/bin/webpack

In development mode, there is no need to compress the output file. If you execute webpack with the environment variable export NODE_ENV=production && webpack, the file will be compressed automatically

less ?

But what if you prefer Less to Sass? No problem, just replace mix.sass() with mix.less().

With Laravel-Mix, you’ll find that most WebPack tasks will become more manageable

The installation

Although Laravel-Mix is optimal for Laravel use, it can also be used for any application.

Laravel project

Laravel has everything you need in simple steps:

1. Install laravel

2. Run NPM install

3. Check the webpack.mix.js file and you are ready to use it.

You can run NPM Run Watch on the command line to monitor your previous resource changes and then recompile.

There is no webpack.config.js configuration file in the project root directory, and Laravel points to it by default. If you need to configure it, you can copy it to the root directory, modify the package at the same time, the NPM in json script: cp node_modules/laravel – mix/setup/webpack config. Js. /.

Independent project

First install Laravel-mix using NPM or Yarn, and then copy the sample configuration file to the project root directory

mkdir my-app && cd my-app
npm init -y
npm install laravel-mix --save-dev
cp -r node_modules/laravel-mix/setup/webpack.mix.js ./
Copy the code

Now you will have the following directory structure

node_modules/
package.json
webpack.mix.js
Copy the code

Webpack.mix.js is your configuration file on top of WebPack, and most of the time it is this file that you need to modify

First take a look at the webpack.mix.js file

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

mix.js('src/app.js'.'dist')
   .sass('src/app.scss'.'dist')
   .setPublicPath('dist');
Copy the code

Note the path of the source file, and then create a matching directory structure (you can change it to whatever structure you like). Now that everything is ready, run node_modules/.bin/webpack on the command line to compile all the files, and you will see:

  • dist/app.css
  • dist/app.js
  • dist/mix-manifest.json(Your asset output file, discussed later)

Well done! Now it’s time to get to work.

NPM Scripts

To speed things up, add the following NPM script to your package.json file, which was included with the laravel installation

"scripts": {
    "dev": "NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"."watch": "NODE_ENV=development node_modules/webpack/bin/webpack.js --watch --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"."hot": "NODE_ENV=development webpack-dev-server --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js"."production": "NODE_ENV=production node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"
  }
Copy the code

Laravel workflow

Let’s review the common workflow so you can adopt it on your own projects

1. Install Laravel

laravel new my-app
Copy the code

2. Install Node dependencies

npm install
Copy the code

**3. Configure webpack.mix.js **

The entry point for compiling all front-end resources for this file

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

mix.js('resources/assets/js/app.js'.'public/js');
mix.sass('resources/assets/sass/app.scss'.'public/css');
Copy the code

JavaScript ES2017 + module binding is enabled by default, just as it is for SASS compilation.

4. Compile

Compile with the following command

node_modules/.bin/webpack
Copy the code

You can also use the NPM script in package.json:

npm run dev
Copy the code

You will then see the compiled file:

  • ./public/js/app.js
  • ./public/css/app.css

Monitor front-end resource changes:

npm run watch
Copy the code

Laravel. Comes with a/resources/assets/js/components/Example vue file, run after the completion of the there will be a notification system.

5. Update the view

Laravel comes with a welcome page, which we can modify as an example:


      
<html lang="en">
    <head>
        <meta charset="utf-8">
        <title>Laravel</title>

        <link rel="stylesheet" href="{{ mix('css/app.css') }}">
    </head>
    <body>
        <div id="app">
            <example></example>
        </div>

        <script src="{{ mix('js/app.js') }}"></script>
    </body>
</html>
Copy the code

Refresh the page. Nice job!

Q&A

Does Laravel-Mix have to be used under Laravel?

No, it works best under Laravel, but it can be used on any other project

My code is not compressed

It is compressed only when the Node environment variable is in production, which speeds up the build process but is not necessary during development. Here is an example of running WebPack in a build environment

export NODE_ENV=production && webpack --progress --hide-modules
Copy the code

It is highly recommended that you add the following NPM scripts to your package.json file, note that Laravel already includes them

"scripts": {
    "dev": "NODE_ENV=development webpack --progress --hide-modules"."watch": "NODE_ENV=development webpack --watch --progress --hide-modules"."hot": "NODE_ENV=development webpack-dev-server --inline --hot"."production": "NODE_ENV=production webpack --progress --hide-modules"
},
Copy the code

I am using a VM and WebPack cannot detect my file changes

If you run NPM run dev under VM, you will find that WebPack will not be able to monitor your file changes. If so, there are two ways to solve this

  1. Configure WebPack to detect file system changes. Note: Detecting file systems is a resource-intensive operation and takes a lot of battery life.
  2. Forward files by using a similarvagrant-fsnotifySomething like that sends notifications to the VM. Note that this is a Vagrant plugin only.

To detect VM file system changes, modify your NPM script to use the –watch-poll and –watch tags like this:

"scripts": {
    "watch": "NODE_ENV=development webpack --watch --watch-poll",}Copy the code

To push file changes to the VM, install vagrant- FSnotify on the host

vagrant plugin install vagrant-fsnotify
Copy the code

Now you can configure VarGrant to use this plugin, in Homestead, in your Homestead.yaml file like this

folders:
    -
        map: /Users/jeffrey/Code/laravel
        to: /home/vagrant/Code/laravel
        options:
            fsnotify: true
            exclude:
                - node_modules
                - vendor
Copy the code

Once your Vagrant machine is up, just run Vagrant FSnotify on the host to push changes to the VM, and then run NPM Run Watch inside the VM to detect the changes.

If you still have problems, take a walk here.

Why is the image in my CSS file not found in node_modules

You may be using relative paths, but in your resources/assets/sass/app. Does not exist in the CSS:

body {
    background: url('.. /img/example.jpg');
}
Copy the code

When citing relative paths, according to the current file path to search, likewise, webpack will first search ` resources/assets/img/example. JPG, if can’t find, will continue to search for files, including node_modules, if still can’t find, to an error:

ERROR  Failed to compile with 1 errors

This dependency was not found in node_modules:
Copy the code

There are two solutions:

1. Let the resources/assets/img/example. The JPG is the file.

2. Add the following option when compiling CSS to disable URL processing:

mix.sass('resources/assets/sass/app.scss'.'public/css')
   .options({
        processCssUrls: false
   });
Copy the code

It’s especially useful for older projects, because your folder structure is already fully created.

I don’t want to put mix-manifest.json in the project root directory

If you are not using Laravel, your mist-manifest.json file will be placed in the project root directory. If you don’t like it, you can call mix.setpublicPath (‘dist/’) and the manifest file will be placed in the dist directory.

How to use WebPack to automatically load modules

Webpack uses the ProvidePlugin to load the required modules. A common example is to load jQuery:

new webpack.ProvidePlugin({
  $: 'jquery',
  jQuery: 'jquery'
});

// in a module
$('#item'); // <= just works
jQuery('#item'); // <= just works
// $ is automatically set to the exports of module "jquery"
Copy the code

When laravel-mix automatically loads a module (as mentioned above), you can call the mix.autoload() method if you want to disable it (passing an empty object) or override it with your own module:

mix.autoload({
  jquery: ['$'.'window.jQuery'.'jQuery'], // more than one
  moment: 'moment' // only one
});
Copy the code

Why do I see a “Vue Packages version mismatch” error

If you update your dependencies, you have the following compile failure message

Module build failed: Error:

Vue packages version mismatch:

* [email protected]
* [email protected]
Copy the code

This means that your VUE and vue-template-compiler dependencies are not synchronized, and the version number must be the same for every vUE update. Update to fix the error

NPM update vue // or NPM install [email protected]Copy the code

debugging

I have an error updating/installing mix

Unfortunately, there are countless reasons why your dependencies might not be installed correctly. A common root cause is installing older versions of Node(nod-v) and NPM (npm-v). First, visit nodejs.org and update them.

Otherwise, it is usually associated with incorrectly locked files that need to be deleted. Let this series of commands try to install everything from scratch

rm -rf node_modules
rm package-lock.json yarn.lock
npm cache clear --force
npm install
Copy the code

Why can’t WebPack find my app.js entry file?

If you get a failure message like this…

These dependencies were not found:

* /Users/you/Sites/folder/resources/assets/js/app.js
Copy the code

. You might use NPM 5.2 (npm-v). This release introduced an error that caused installation errors. This issue has been fixed in NPM 5.3. Please upgrade and then reinstall

rm -rf node_modules
rm package-lock.json yarn.lock
npm cache clear --force
npm install
Copy the code

API

Javascript

mix.js(src|[src], output)
Copy the code

With a single line of code, Larave Mix can do a lot of important things

  • ES2017+ module compilation
  • Create and compile the VUE component (byvue-loader)
  • Module hot Replacement (HMR)
  • Tree-shaking packaging technology, new in WebPack2 (removing useless libraries)
  • Extract and split vendor libraries (viamix.extract()Method) to make long-term caching easier
  • Automatic versioning (file hashing), passedmix.version()

usage

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

// 1. A single src and output path.
mix.js('src/app.js'.'dist/app.js');


// 2. For additional src files that should be
// bundled together:
mix.js([
    'src/app.js'.'src/another.js'].'dist/app.js');


// 3. For multiple entry/output points:
mix.js('src/app.js'.'dist/')
   .js('src/forum.js'.'dist/');
Copy the code

Laravel sample

When considering the typical laravel default installation will locate entry in the/resources/assets/js/app. Js, so let’s prepare a webpack. Mix. Js the app. Js compilation to the/public/js/app. Js.

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

mix.js('resources/assets/js/app.js'.'public/js');
Copy the code

Now you can use all of the above items, just call one method.

Call NPM run dev on the command line to perform the compilation.

Vue components

Laravel Mix includes all kinds of things. It supports vUE compilation, which you can ignore if you don’t use vue.

The single-file component is the most important feature of VUE. Define templates, scripts, and stylesheets for a component in a file.

./resources/assets/js/app.js

import Vue from 'vue';
import Notification from './components/Notification.vue'; 

new Vue({
    el: '#app'.components: { Notification }
});
Copy the code

Above, we import vue(first you need to run NPM install vue –save-dev to install vue), then introduce a vUE component called Notification and register the root Vue instance.

./resources/asset/js/components/Notification.vue

<template>
    <div class="notification">
        {{ body }}
    </div>
</template>

<script>
    export default {
        data() {
            return {
                body: 'I am a notification.'
            }
        }
    }
</script>
<style>
    .notification {
        background: grey;
    }
</style>
Copy the code

If you know Vue, all of this is familiar to you. Go ahead.

./webpack.mix.js

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

mix.js('resources/assets/js/app.js'.'public/js');
Copy the code

Run the NPM run dev command to compile the file. This will simply create an HTML file, import the./js/app.js file, and view it in the browser.

The React to support

Laravel Mix also loads basic React support, just change mix.js() to mix.react() and use the same arguments. At the bottom, Mix will reference any Babel plug-ins that React needs.

mix.react('resources/assets/js/app.jsx'.'public/js/app.js');
Copy the code

Of course, you’ll still need to install React and reactDOM using NPM, but do so carefully.

Library code separation

mix.js(src, output)
   .extract(['any'.'vendor'.'library']);
Copy the code

Packing all your JS files into one file comes with the potential risk that even a small portion of your project will break the cache of all users each time you update it, which means your third-party libraries will have to be downloaded and cached again. That’s not good.

One solution is to separate or extract your library files.

  • Application code: app.js
  • Vendor libraries: vendor.js
  • Manifest(webpack runtime): manifest.js
mix.extract(['vue'.'jquery']);
Copy the code

The extract method accepts an array of libraries that you want to extract from the package. Using this method, both Vue and jQuery source code are placed in vvendor. If you need to make minor changes to your application code in the future, the large vendor libraries will not be affected, and they will remain in the long-term cache.

Once you execute the WebPack package, you’ll find three new files that you can refer to in the HTML page.

<script src="/js/manifest.js"></script>
<script src="/js/vendor.js"></script>
<script src="/js/app.js"></script>
Copy the code

In fact, we are paying the price of some HTTP requests (i.e. more requests) in exchange for the long-term cache improvement.

What is a Manifest file

Webpack is compiled with some run-time code to help it work. If you don’t use mix.extract(), you won’t see this code, it will be in the package. However, if we separate the code and allow long-term caching, at some point this run-time code will be needed, so mix will extract it, so that, Both the Vendor library and the manifest file are cached for a long time.

Automatic browser refresh

mix.browserSync('my-site.test');
Copy the code

BrowserSync automatically monitors file changes and notifies the browser of your changes — no manual refreshing required at all. You can turn this on by calling the mix.browsersync () method:

mix.browserSync('my-domain.test');

// Or:

// https://browsersync.io/docs/options/
mix.browserSync({
    proxy: 'my-domain.test'
})
Copy the code

Arguments can be passed either strings (proxy) or objects (BrowserSync Settings). The domain name you declare as a proxy is very important, Browsersync will output to your webpack Dev Server via the proxy url.

Other options are available from Browsersync Documentation

Now, start dev Server (NPM Run Watch) and proceed to the next step.

Module hot replacement

Laravel Mix provides seamless support for hot replacement of modules.

Module hot replace (or hot load) means that you can maintain the state of the component while javascript changes to refresh the page. For example, there is a counter now. If you press a button, the counter will increase by one. The browser will react to your changes in real time, leaving the counter unchanged. The counter will not be reset. That’s where hot loading comes in.

In laravel

Laravel worked with Laravel to abstract out the complexities of hot loading.

Look at the package.json file in Laravel. In the scripts module, you can see:

"scripts": {
    "dev": "cross-env NODE_ENV=development webpack --progress --hide-modules"."watch": "cross-env NODE_ENV=development webpack --watch --progress --hide-modules"."hot": "cross-env NODE_ENV=development webpack-dev-server --inline --hot"."production": "cross-env NODE_ENV=production webpack --progress --hide-modules"
}
Copy the code

This is where you need to go. Running NPM run hot on the command line will start a Node server and monitor your bundle files. Next, open your Laravel app in a browser, usually http://my-app.test.

It’s important to make sure that all script resources refer to the node server url you started earlier: http://localhost:8080. Now you can manually update your HTML Blade file:

<body>
    <div id="app">... </div> <script src="http://localhost:8080/js/bundle.js"></script>
</body>
Copy the code

Suppose you have some components and try to change their status in the browser and then update their template file. You can see that the browser immediately reacts to your update, but the status is not changed.

However, updating urls manually in a development deployment environment can be a burden, so Laravel provides a mix() method that dynamically builds js or stylesheet references and outputs them. The above code can therefore be changed to:

<body>
    <div id="app"></div>

    <script src="{{ mix('js/bundle.js') }}"></script>
</body>
Copy the code

After the adjustment, Laravel will do the job for you. If you run NPM run hot to enable hot loading, this function sets the necessary http://localhost:8080 as the URL. Instead, if you use NPM Run dev or NPM Run Pro, it will use the domain name as the base URL.

If you are developing your application over an Https connection, your hot-load scripts and styles must also be used through the Https service. To do this, add the –HTTPS flag to the hot options command in package.json.

"scripts": {
    "hot": "NODE_ENV=development webpack-dev-server --inline --hot --https",}Copy the code

With the above setup, webpack-dev-server will generate a self-signed certificate. If you want to use your own certificate, you can use the following Settings:

 "hot": "NODE_ENV=development webpack-dev-server --inline --hot --https --key /path/to/server.key --cert /path/to/server.crt --cacert /path/to/ca.pem".Copy the code

It is now available in your Html/Blade file

<script src="https://localhost:8080/js/bundle.js"></script>
Copy the code

or

<script src="{{ mix('js/bundle.js') }}"></script>
Copy the code

It’s used in spa

Laravel Mix includes the popular Vue-Loader package, which means that if it’s a single page application, you don’t need to do anything, it’s right out of the box.

versioning

mix.js('src'.'output')
   .version([]);
Copy the code

To help with long-term caching, Laravel Mix provides the mix.version() method, which supports file hashing. Such as app. Js? Id = 8 e5c48eadbfdd5458ec6. This is useful for clearing the cache. Suppose your server automatically caches a year’s worth of scripts to improve performance. That’s fine, but every time you make changes to your application code, you need some way to tell the user to update the cache, which is usually done by using a query string or file hash.

With versioning enabled, a new hash query string file is generated each time the code changes. Look at the following webpack.mix.js file

When compiled, you’ll see/CSS /app.css? In mix-manifest.json. Id = 5 ee7141a759a5fb7377a and/js/app. Js? Id = 0441 ad4f65d54589aea5. Of course, your particular hash will be unique. Every time you tweak JavaScript, the compiled file will receive a new hash name, which will effectively break the cache once it is pushed into production.

For example, try webpack – Watch, and modify your JavaScript. You will immediately see a newly generated package file and style sheet.

Importing a Version File

This begs the question: How do we include these versioned scripts and stylesheets in HTML if the names are constantly changing? Yes, it’s tricky. The answer will depend on the type of application you’re building. For SPA, you can dynamically read the manifest.json file generated by Laravel Mix, extract the file names (which will be updated to reflect the new version file), and then generate the HTML.

Laravel user

For the Laravel project, a solution is out of the box. Just call the global mix() function, and you’re done! We will calculate the appropriate file name for the import. Here’s an example:

<! DOCTYPE html> <html lang="en">
    <head>
        <meta charset="utf-8">
        <title>App</title>
        <link rel="stylesheet" href="{{ mix('css/app.css') }}">
    </head>
    <body>
        <div id="app">
            <h1>Hello World</h1>
        </div>

        <script src="{{ mix('js/app.js') }}"></script>
    </body>
</html>
Copy the code

Pass the unhashed file path to the mix() function, and at the back end, we’ll figure out which script or style sheet to import. Note that you can/should use this function even if you are not versioning the file.

Versioning additional files

Mix.version () will automatically generate compiled JavaScript, Sass/Less, or merged files. However, if you also want to include additional files as part of the build, simply pass the path or an array of paths, like this:

mix.version(['public/js/random.js']);
Copy the code

Now, we’ll versionize any associated compilation files, but we’ll also append a query string, public/js/random.js? {hash} and update the mix-manifest.json file.

Css preprocessor

mix.sass('src'.'output', pluginOptions);
mix.standaloneSass('src'.'output', pluginOptions); // Isolated from Webpack build.
mix.less('src'.'output', pluginOptions);
mix.stylus('src'.'output', pluginOptions);
mix.postCss('src'.'output', [ require('precss') (the)])Copy the code

A single method call allows you to compile your Sass, Less, or Stylus files while automatically applying the CSS3 prefix.

While WebPack can insert all the CSS directly into the bound JavaScript, Laravel Mix automatically performs the necessary steps to extract it into your desired output path.

How to build

If you need to compile more than one top-level file, you can call mix.sass()(or any of the preprocessor variants) as needed. For each call, WebPack outputs a new file containing the related content.

mix.sass('src/app.scss'.'dist/') // creates 'dist/app.css'
   .sass('src/forum.scss'.'dist/'); // creates 'dist/forum.css'
Copy the code

example

Let’s look at an example

webpack.mix.js

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

mix.sass('resources/assets/sass/app.sass'.'public/css');
Copy the code

./resources/assets/sass/app.sass

$primary: grey

.app
    background: $primary
Copy the code

Tip: For Sass compilation, you can use.sass and.scss syntax

Run NPM Run Webpack as usual to compile. You’ll find the./public/ CSS /app.css file contained

.app {
  background: grey;
}
Copy the code

Plug-in options

When compiling, Laravel Mix first compiles your Sass and Less files by calling Nodes-sass, Less, and Slylus, respectively. Sometimes, you may need to override the default options we passed to them. You can supply them as a third argument to mix.sass(), mix.less(), and mix.stylus().

  • Node – Sass options: Github.com/sass/node-s…
  • Less options: Github.com/webpack-con…

If you use Stylus, you may want to install additional plugins, such as Rupture. Run NPM install rupture to install the plugin, then call it in your mix.stylus(), for example:

mix.stylus('resources/assets/stylus/app.styl'.'public/css', {
    use: [
        require('rupture') (the)]});Copy the code

If you want to go a step further and automatically import the plug-in globally, you can use the import option. Here’s an example:

mix.stylus('resources/assets/stylus/app.styl'.'public/css', {
    use: [
        require('rupture')(),
        require('nib')(),
        require('jeet')()
    ],
    import: [
        '~nib/index.styl'.'~jeet/jeet.styl']});Copy the code

That’s what it looks like!

CSS () rewrite the url

A key Webpack concept is that it will rewrite any URL () in your stylesheet. While this may sound strange at first, it is a very powerful feature.

A case in point

Suppose we want to compile some Sass that contains the relative URL of an image.

.example {
    background: url('.. /images/thing.png');
}
Copy the code

Tip: The absolute path to URL () will be excluded from URL rewriting. As a result, the url (‘/images/thing. PNG ‘) or a url (‘ http://example.com/images/thing.png ‘) will not be changed.

Notice, we’re talking about relative urls, right? By default, Laravel Mix and Webpack will find things.png, copy it into the public/images folder, and then rewrite the URL () in the generated stylesheet. Therefore, the compiled CSS will be:

.example { background: url(/images/thing.png? d41d8cd98f00b204e9800998ecf8427e);
}
Copy the code

This is also a cool feature of WebPack. However, it does have a tendency to confuse people who don’t understand how WebPack and CSS-Loader plug-ins work. Your folder structure may already be what you want, and you don’t want to change those urls (). If so, we do provide a way to cover:

mix.sass('src/app.scss'.'dist/')
   .options({
      processCssUrls: false
   });
Copy the code

Add this to your webpack.mix.js file and we will no longer match urls () or copy resources to your public directory. Therefore, the compiled CSS will look exactly as you typed it:

.example {
  background: url(".. /images/thing.png");
}
Copy the code

The benefit of this is that your Webpack, Sass compilation and extraction can compile faster when URL processing is disabled.

PostCSS plug-in

By default, Mix links all CSS files through the popular Autoprefixer PostCSS Plugin. So feel free to use the latest CSS 3 syntax and understand that we will automatically apply any necessary browser prefixes. In most cases, the default Settings should do the job, but if you need to adjust the underlying autofix configuration, do something like this:

mix.sass('resources/assets/sass/app.scss'.'public/css')
   .options({
        autoprefixer: {
            options: {
                browsers: [
                    'last 6 versions',]}}});Copy the code

Also, if you want to disable it entirely — or rely on a PostCSS plugin that already includes automatic prefixes:

mix.sass('resources/assets/sass/app.scss'.'public/css')
   .options({ autoprefixer: false });
Copy the code

However, you may want to apply additional PostCSS plug-ins to your build. Just install the required plug-ins in NPM and then reference them in the webpack.mix.js file, as shown below:

mix.sass('resources/assets/sass/app.scss'.'public/css')
   .options({
       postCss: [
            require("postcss-custom-properties")]});Copy the code

Done! Now you can use and compile custom CSS properties (if this is your thing). For example, if the resources/assets/sass/app. The SCSS contains…

:root {
    --some-color: red;
}

.example {
    color: var(--some-color);
}
Copy the code

When the compilation is complete it will be

.example {
  color: red;
}
Copy the code

The PostCss does not apply to Sass/Less

Or, if you prefer to skip the Sass/Less/Stylus compilation step and use PostCSS instead, you can do this with the mix.postcss () method.

mix.postCss('resources/assets/css/main.css'.'public/css', [
   require('precss'()));Copy the code

Note that the third parameter is the array that should be applied to the PostCSS plug-ins you build.

Independent Sass builds

If you don’t want Mix and Webpack to handle your Sass files in any way, you can use mix.standalonesass (), which will greatly improve the build time of your application. Remember: If you choose this route, Webpack won’t touch your CSS. It does not rewrite urls, copy resources (via file-loader), or apply automatic image optimization or CSS cleaning. If these features are not necessary for your application, be sure to use this option instead of mix.sass().

mix.standaloneSass('resources/assets/sass/app.scss'.'public/css');
Copy the code

Note: If you are using standaloneSass, when making file changes with NPM Run Watch, you will need to prefix imported files with an underscore to mark them as dependent files (for example, _header.scss _alert.scss). Failure to do so will result in Sass compilation errors and/or additional CSS files.

Copying files

mix.copy(from, to);
mix.copy('from/regex/**/*.txt', to);
mix.copy([path1, path2], to);
mix.copyDirectory(fromDir, toDir);
Copy the code

Sometimes you need to copy one or more files as part of the build process. No problem, it’s a piece of cake. Use the mix.copy() method to specify the source file or folder, and then specify the target folder/file you want

mix.copy('node_modules/vendor/acme.txt'.'public/js/acme.txt');
Copy the code

At compile time, the ‘acme’ file will be copied to ‘public/js/acme.txt’. This is a common use case when you want to install a set of fonts into a public directory via NPM.

The system informs

By default, Laravel Mix displays system notifications for each build. This way, you can quickly see if there are any errors to look for. However, in some cases this is not desirable (such as compiling on a production server). If this happens, they can be disabled from your webpack.mix.js file.

mix.js(src, output)
   .disableNotifications();
Copy the code

File combination and minimization

mix.combine(['src'.'files'].'destination');
mix.babel(['src'.'files'], destination);
mix.minify('src');
mix.minify(['src']);
Copy the code

If used properly, Laravel Mix and WebPack should be responsible for all necessary module bundling and minimization. However, you may have some legacy code or third-party libraries that need to be connected and minimized, and this is not an issue.

Composite file

Consider the following code snippet:

mix.combine(['one.js'.'two.js'].'merged.js');
Copy the code

This naturally merges one.js and two-.js into a separate file called merge.js. As usual, the merged files will remain uncompressed during development. However, for production (export NODE_ENV=production), this command will minimize merged.

Composite files compiled with Babel.

If you need to combine JavaScript files written using ES2015 methods, you can update mix.combine() by calling mix.babel(). Method signatures are the same. The only difference is that after combining the files, Laravel Mix babels the results, turning the code into JavaScript code that all browsers can understand.

mix.babel(['one.js'.'two.js'].'merged.js');
Copy the code

Minimize file

Similarly, you can use the mix.minify() command to shrink one or more files.

mix.minify('path/to/file.js');
mix.minify(['this/one.js'.'and/this/one.js']);
Copy the code

Here are some things to note:

  • This method will create an additional*.min.extFile. So compressionapp.jsWill be generatedapp.min.js.
  • Again, compression only happens during production. (export NODE_ENV=production).
  • You don’t need to callmix.combine(['one.js', 'two.js'], 'merged.js').minify('merged.js');, only use a singlemix.combine()The call. It does both.

Important: Please note that compression only applies to CSS and JavaScript files. Minifier does not understand any of the other file types provided.

Automatic loading

mix.autoload({
   jquery: ['$'.'window.jQuery']});Copy the code

Webpack provides the necessary functionality to use one module as a variable in each module required by Webpack. If you are using a specific plugin or library that relies on a global variable, such as jQuery, mix.autoload() may be useful for you.

Consider the following example:

mix.autoload({
   jquery: ['$'.'window.jQuery']});Copy the code

This code fragment specifies that WebPack should add var $= require(‘jquery’) to any global $identifier it encounters or window.jquery. Beautiful!

Event hooks

mix.then(function () {});
Copy the code

You may want to listen for events every time WebPack finishes compiling. You may need to manually apply some logic that is appropriate for your application. If so, you can register any callback function using the mix.then() method. Here’s an example:

mix.js('resources/assets/js/app.js'.'public/js')
   .then(() => {
        console.log('webpack has finished building! ');
   });
Copy the code

The callback function will pass the Webpack Stats object, allowing the compilation to be checked:

mix.js('resources/assets/js/app.js'.'public/js')
   .then((stats) => {
        // array of all asset paths output by webpack
        console.log(Object.keys(stats.compilation.assets));
   });
Copy the code

The official documentation for the Stats object can be found here: github.com/webpack/doc…

Fast WebPack configuration

mix.webpackConfig({} || cb);
Copy the code

Of course, you can freely edit the provided webpack.config.js file, and in some Settings, it’s easier to modify or override the default Settings directly from your webpack.mix.js. This is especially true for Laravel applications, which by default do not have webpack.config.js in the project root folder.

For example, you might want to add a custom array of modules that are automatically loaded by WebPack. In this scenario, you have two options:

  • Edit yours as neededwebpack.config.jsfile
  • In yourwebpack.mix.jsIn the callmix.webpackConfig()File and pass the override parameter. The blend will then undergo a deep merge. Next, as an example, we will add a custom module path for Laravel Spark.
mix.webpackConfig({
    resolve: {
        modules: [
            'node_modules',
            path.resolve(__dirname, 'vendor/laravel/spark/resources/assets/js')]}});Copy the code

Use the callback function

When passing a callback function, you can access WebPack and all of its properties.

mix.webpackConfig(webpack => {
    return {
        plugins: [
            new webpack.ProvidePlugin({
                $: 'jquery',
                jQuery: 'jquery'.'window.jQuery': 'jquery'}})]; });Copy the code

Extend the Mix.

The component-based system Mix uses scenarios to build its API, which you can also access – whether to extend Mix for your project, or to distribute to the world as a reusable package.

example

// webpack.mix.js;
let mix = require('laravel-mix');

mix.extend('foo'.function(webpackConfig, ... args) { console.log(webpackConfig); // the compiled webpack configuration object. console.log(args); // the values passed to mix.foo(); - ['some-value']}); mix.js('src'.'output').foo('some-value');
Copy the code

In the example above, we can see that mix.extend() takes two arguments: the name that should be used when defining the component, and a callback function or class that registers and organizes the necessary WebPack logic. In the background, Mix fires this callback once the underlying WebPack configuration object has been built. This will give you a chance to insert or override any necessary Settings.

While simple callback functions can be useful for rapid extension, in most cases you may want to build a complete component class, such as:

mix.extend(
    'foo',
    new class {
        register(val) {
            console.log('mix.foo() was called with ' + val);
        }

        dependencies() {}

        webpackRules() {}

        webpackPlugins() {}

        // ...
    }()
);
Copy the code

When extending Mix, you usually need to trigger some instructions:

  • Install these dependencies.
  • Add this rule/loader to WebPack.
  • Include this WebPack plug-in.
  • Fully covers this part of the WebPack configuration.
  • Add this configuration to Babel.
  • And so on.

Any of these operations are associated with systems with Mix components.

Component interfaces

  • Name: What should be used as the method name when calling the component. (Default is the class name.)
  • Dependencies: Lists all NPM dependencies that should be installed by Mix.
  • Register: When your component is called, all user parameters are immediately passed to this method.
  • Boot: starts the component. This method is triggered after the user’s webpack.mix. The js file has been loaded.
  • WebpackEntry: Attached to the main mixed WebPack entry object.
  • WebpackRules: Rules that are merged with the main WebPack loader.
  • Webpackplugin: Plug-in that merges with the main WebPack configuration.
  • WebpackConfig: Overrides the generated WebPack configuration.
  • BabelConfig: Additional Babel configurations should be merged with the default values of Mix.

Here is a sample/virtual component that will give you a better idea of how to build your own components. For more examples, see the components used in background Mix.

class Example {
    /**
     * The optional name to be used when called by Mix.
     * Defaults to the class name, lowercased.
     *
     * Ex: mix.example();
     *
     * @return {String|Array}
     */
    name() {
        // Example:
        // return 'example';
        // return ['example'.'alias'];
    }

    /**
     * All dependencies that should be installed by Mix.
     *
     * @return {Array}
     */
    dependencies() {
        // Example:
        // return ['typeScript'.'ts'];
    }

    /**
     * Register the component.
     *
     * When your component is called, all user parameters
     * will be passed to this method.
     *
     * Ex: register(src, output) {}
     * Ex: mix.yourPlugin('src/path'.'output/path'); * * @param {*} ... params * @return {void}
     *
     */
    register() {
        // Example:
        // this.config = { proxy: arg };
    }

    /**
     * Boot the component. This method is triggered after the
     * user's webpack.mix.js file has executed. */ boot() { // Example: // if (Config.options.foo) {} } /** * Append to the master Mix webpack entry object. * * @param {Entry} entry * @return {void} */ webpackEntry(entry) { // Example: // entry.add('foo', 'bar'); } /** * Rules to be merged with the master webpack loaders. * * @return {Array|Object} */ webpackRules() { // Example: // return { // test: /\.less$/, // loaders: ['.'] / /}); } /* * Plugins to be merged with the master webpack config. * * @return {Array|Object} */ webpackPlugins() { // Example:  // return new webpack.ProvidePlugin(this.aliases); } /** * Override the generated webpack configuration. * * @param {Object} webpackConfig * @return {void} */ webpackConfig(webpackConfig) { // Example: // webpackConfig.resolve.extensions.push('.ts', '.tsx'); } /** * Babel config to be merged with Mix's defaults.
     *
     * @return {Object}
     */
    babelConfig() {
        // Example:
        // return { presets: ['react']}; }Copy the code

Note that each method in the above example is optional. In some cases, your component might just need to add a WebPack loader and/or tweak the mixed Babel configuration. Omit the rest of the interface if there is no problem.

class Example {
    webpackRules() {
        return {
            test: /\.test$/, loaders: [] }; }}Copy the code

Now, when the underlying webpack Mix structure configuration, your rule will be included in the generated webpackConfig. The module. The rules in the array.

use

Once you’ve built or installed the component you want, just grab it from webpack.mix.js and you’re ready to go.

// foo-component.js

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

class Example {
    webpackRules() {
        return {
            test: /\.test$/,
            loaders: []
        };
    }
}

mix.extend('foo', new Example());
Copy the code
// webpack.mix.js

let mix = require('laravel-mix');
require('./foo-component');

mix
    .js('src'.'output')
    .sass('src'.'output')
    .foo();
Copy the code

Custom method

LiveReload

While Laravel Mix and Browsersync are already supported out of the box, you may prefer to use LiveReload, which will automatically monitor your files and refresh pages when changes are detected.

Install webpack livereload — the plugin

npm install webpack-livereload-plugin@1 --save-dev
Copy the code

Configuration webpack. Mix. Js

Add the following lines to the bottom of webpack.mix.js.

var LiveReloadPlugin = require('webpack-livereload-plugin');

mix.webpackConfig({
    plugins: [
        new LiveReloadPlugin()
    ]
});
Copy the code

LiveReload has a nice default, but here’s a list of available plug-in options.

Install LiveReload. Js

Finally, we need to install livereload.js. You can add the following code with the LiveReload Chrome plugin, or before the closing tag on your main site template:

@if(config('app.env') == 'local')
    <script src="http://localhost:35729/livereload.js"></script>
@endif
Copy the code

Run the dev server

npm run watch
Copy the code

Now, LiveReload will automatically monitor your files and refresh the page when necessary. Enjoy!

Jquery UI

JQuery UI is a toolkit for rendering common components such as Datepickers, draggables, and so on. No adjustments need to be made to make it work with Laravel Mix.

Build the webpack.mix.js configuration

mix.js('resources/assets/js/app.js'.'public/js')
   .sass('resources/assets/sass/app.scss'.'public/css');
Copy the code

Install the jquery UI

npm install jquery-ui --save-dev
Copy the code

Loading necessary plug-ins

// resources/assets/js/app.js

import $ from 'jquery';
window.$ = window.jQuery = $;

import 'jquery-ui/ui/widgets/datepicker.js';
Copy the code

Load the CSS

// resources/assets/sass/app.scss

@import '~jquery-ui/themes/base/all.css';
Copy the code

Trigger UI components

// resources/assets/js/app.js
$('#datepicker').datepicker();
Copy the code

Advanced configuration

Laravel Mix Indicates the configuration item

mix.options({
    extractVueStyles: false,
    processCssUrls: true,
    uglify: {},
    purifyCss: false,
    //purifyCss: {},
    postCss: [require('autoprefixer')],
    clearConsole: false
});

Copy the code

You can use some blending and overwriting options if you need to. Note the options above, and their default values. Here’s a quick overview:

  • Extract extractVueStyles:.vueComponent styles (CSS in