Laravel 8 + Jetstream 2 + Livewire + Mix + NPM + Datatables

A post for Google’s crawler as this took me far too long to get working and the many many many Google hits on the topic all proved mostly unhelpful.

On a simple Laravel + Jetstream (Livewire version) installation, I needed DataTables to work. This also means jQuery needs to be installed.

What follows are the various changes to the default files to make this work:

package.json (versions as at Jan 2022, run npm install after updating file):

    "devDependencies": {
        ...
        "datatables.net-dt": "^1.11.3",
        "jquery": "^3.4.1",
        ...

webpack.mix.js – Alpine.js has an idiosyncrasy which causes issues for jQuery – it is loaded via <script src="" defer> – emphasis on the defer. This means that jQuery won’t be available for your scripts within the Blade templates and, specifically, $(document).ready() will throw an exception because the jQuery function, $, will not be defined as yet. To solve this, we create a second new js file by adding the following line:

mix.js( "resources/js/alpine.js", "public/js" )

resources/js/app.js – we need to remove the Alpine.js lines from here and place them in a new file, resources/js/alpine.js. Specifically – move the following lines:

import Alpine from 'alpinejs';
window.Alpine = Alpine;
Alpine.start();

resources/js/bootstrap.js – I added the following bolded lines:

window._ = require('lodash');

/**
 * We'll load jQuery and the Bootstrap jQuery plugin which provides
 * support for JavaScript based Bootstrap features such as modals 
 * and tabs. This code may be modified to fit the specific needs of
 * your application.
 */

window.$ = window.jQuery = require('jquery');


// Datatables
window.DataTable = require('datatables.net-dt');

...

Lastly, edit the template to not defer app.js and to load your new alpine.js file. In resources/views/layouts/app.blade.php, remove the script line for app.js and replace it with the following two lines:

<script src="{{ mix('js/app.js') }}"></script>
<script src="{{ mix('js/alpine.js') }}" defer></script>

I think the biggest confusion here was that there were no changes required to webpack.mix.js specifically for DataTables despite many online resources making changes there. Perhaps it was earlier versions of Mix? The second confusing issue was Alpine.js and the effects of ‘defer’ring app.js.

With the above, DataTables (and jQuery) are now available as usual in your Blade templates:

<script>
    $(document).ready(function () {
        $('#clients-table').DataTable();
    });
</script>

Single-Page Applications – New Laravel Frameworks

Single-page applications (SPAs) are web-based applications that rewrite the current browser DOM rather than doing full page reloads. They look and feel responsive and crisp but are pretty complex to write. At least differently complex – the balance of developer knowledge moves from backend templates and view logic to pretty heavy frontend JavaScript. It’s also quite hard to migrate traditional web-based applications.

Some of the more popular SPA frameworks include Vue.js with Vue Router; Ember.js; and AngularJS. For anyone coming across this for the first time, Vue.js looks really interesting.

There’s a new framework that works with Laravel and tries to bridge the gap between the traditional full page reload model and the new SPA model called Inertia.js. Jonathan’s stated goal with this is:

I wanted to blend the best parts of classic server-side apps (routing, controllers, and ORM database access) with the best parts of single-page apps (JavaScript rendering and no full page reloads).

There’s also a second new framework that’s in this between-two-houses-mould but still quite different called Livewire. It really is best to look at the code to see how this works – it really is different but also very interesting.