Actions

Laravel Mix

From Han Wiki

Notes on Laravel Mix


ALWAYS use mix('js/app.js') to refer to assets managed via Laravel Mix in HTML/Blade files e.g. <script src="{{ mix('js/bundle.js') }}"></script>


This will accommodate for hot module replacement (aka hot reloading), versioning (to bust the cache), and other Laravel Mix features.


JavaScript

// 1. single src & output path

mix.js('src/app.js', 'public/js/app.js');


// 2. for additional src files that should be bundled together

mix.js(['src/app.js','src/another.js'],'public/js/app.js'):


// 3. for multiple entry/output points

mix.js('src/app.js','public/js1/').
    js('src/forum.js','public/js2/');


React Support

mix.react('resources/js/app.jsx', 'public/js/app.js');


TypeScript Support

mix.ts('resources/assets/js/app.ts','public/js/app.js');


Library Code Splitting

mix.extract();
or
mix.extract(['vue','jquery']); // for long-term caching


when using .extract() at the end of HTML file add:

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


BrowserSync

automatically inject changes real-time

mix.browserSync('test.unm.edu');

// https://browsersync.io/docs/options/
mix.browserSync({
    proxy: 'test.unm.edu'
});

the dev server: $ npm run watch // automatically compiles upon any changes


Hot Module Replacement

fire up Node server: $ npm run hot


and then reference the server for script sources:

<script src="http://localhost:8080/js/bundle.js"></script>
</body>


to serve over HTTPS add --https flags to hot option command within package.json


to use own certificates add: e.g.
--key /path/to/server.key --cert /path/to/server.crt --cacert /path/to/ca.pem


to use different host or port:

mix.options({
    hmrOptions: {
        host: 'example.com',
        port: 8080
    }
})


Versioning

Usually to bust the cache

mix.js('resources/js/app.js', 'public/js')
    .sass('resources/sass/app.sass', 'public/css')
    .version();


Versioning extra files

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


Optionally versioning files

Usually on production.

if (mix.inProduction()) {
    mix.version();
}


CSS Preprocessors

mix.sass('src', 'output', pluginOptions);
mix.less('src', 'output', pluginOptions);
mix.stylus('src', 'output', pluginOptions);
mix.postCss('src', 'output', [require('precss')()]);

mix.sass('src/app.scss', 'dist/') // creates 'dist/app.css'
   .sass('src/forum.scss', 'dist/'); // creates 'dist/forum.css'
<source lang="js">


== CSS url() Rewriting ==

<source lang="css">
.example {
    background: url('../images/thing.png');
}


will be compiled into

.example {
    background: url('/images/thing.png?df2343dfdf34343');
}


to override automatic rewriting:

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


PostCSS Plugins

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

to disable autoprefixer entirely:

mix.sass('resources/sass/app.scss', 'public/css')
   .options({ autoprefixer: false });


running additional PostCSS plugins:

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

passing optional parameters:

mix.sass('resources/sass/app.scss', 'public/css')
    .options({
        postCss: [
            require('postcss-custom-properties')({
                preserve: false
            })
        ]
    });


PostCSS without Sass or Less

mix.postCss('resources/css/main.css', 'public/css', [
    require('precss')()
]);


Copying Files

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


System notifications

disable notifications:

mix.disableNotifications();


only display errors:

mix.disableSuccessNotifications();


  1. Concatenation and Minification
mix.combine(['src', 'files'], 'destination');
mix.babel(['src', 'files'], destination);
mix.minify('src');
mix.minify(['src']);

.combine() will automatically minify during a production build.

minification is only available for CSS and JavaScript files.


  1. Autoloading

e.g.

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

"This snippet specifies that webpack should prepend var $ = require('jquery') to every location that it encounters either the global $ identifier, or window.jQuery."

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

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

Stats object: https://github.com/webpack/docs/wiki/node.js-api#stats

https://github.com/webpack/docs/wiki/node.js-api#stats


Quick Webpack Configuration

e.g. Laravel Spark

mix.webpackConfig({
    resolve: {
        modules: [
            'node_modules',
            path.resolve(__dirname, 'vendor/laravel/spark/resources/js')
        ]
    }
});

Using a Callback Function

"alternatively access webpack and all of its properties by passing a callback function"


Extending Mix

https://laravel-mix.com/docs/4.1/extending-mix

Extensions: https://laravel-mix.com/extensions

e.g.

// webpack.mix.js;
const 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');

e.g. a full component class

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

        dependencies() {}

        webpackRules() {}

        webpackPlugins() {}

        // ...
    }()
)