Laravel mix Uncaught ReferenceError: jQuery is not defined
Asked Answered
S

3

8

I am using laravel mix to bundle my js libraries and codes. I am trying to use ES6 style of importing and use ES6 codes if possible. I need to also import jQuery and it's library.

So, i have imported jQuery and bootstrap like this:

import "jquery";
import "bootstrap";

At first when i import them i was getting:

Uncaught ReferenceError: jQuery is not defined
    at Object../node_modules/bootstrap/js/transition.js (vendor.js?id=74f7f0c463b407c6bdf5:2449)

which is due to the bootstrap not getting jQuery.

To solve this i have added this configuration to replace $, jQuery with jquery

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

This works for every scripts and libraries that requires jQuery.

Now the problem is with the other scripts that we add without mixing using a single js or using blade section.

@section('scripts')
    <script type="application/javascript">
        window.onload = function() {
            if (window.jQuery) {
                // jQuery is loaded
                console.log("Yeah!");
            } else {
                // jQuery is not loaded
                console.log("Doesn't Work");
            }
        }
       $().ready(function () {
        console.log('works');
      })
    </script>
@endsection

The console error shows:

datatables:125 Uncaught ReferenceError: $ is not defined
    at datatables:125
(anonymous) @ datatables:125
vendor.js?id=2b5ccc814110031408ca:21536 jQuery.Deferred exception: $(...).uniform is not a function TypeError: $(...).uniform is not a function
    at HTMLDocument.<anonymous> (http://localhost/assets/admin/app.js?id=da888f45698c53767fca:18419:18)
    at mightThrow (http://localhost/assets/admin/vendor.js?id=2b5ccc814110031408ca:21252:29)
    at process (http://localhost/assets/admin/vendor.js?id=2b5ccc814110031408ca:21320:12) undefined
jQuery.Deferred.exceptionHook @ vendor.js?id=2b5ccc814110031408ca:21536
process @ vendor.js?id=2b5ccc814110031408ca:21324
setTimeout (async)
(anonymous) @ vendor.js?id=2b5ccc814110031408ca:21358
fire @ vendor.js?id=2b5ccc814110031408ca:20986
fireWith @ vendor.js?id=2b5ccc814110031408ca:21116
fire @ vendor.js?id=2b5ccc814110031408ca:21124
fire @ vendor.js?id=2b5ccc814110031408ca:20986
fireWith @ vendor.js?id=2b5ccc814110031408ca:21116
ready @ vendor.js?id=2b5ccc814110031408ca:21596
completed @ vendor.js?id=2b5ccc814110031408ca:21606
datatables:122 Doesn't Work
vendor.js?id=2b5ccc814110031408ca:21545 Uncaught TypeError: $(...).uniform is not a function
    at HTMLDocument.<anonymous> (app.js?id=da888f45698c53767fca:18419)
    at mightThrow (vendor.js?id=2b5ccc814110031408ca:21252)
    at process (vendor.js?id=2b5ccc814110031408ca:21320)

The problem gets solved when i compile and mix the scripts using laravel mix but when i write same scripts in the blade or use without mixing it shows the jQuery / $ is not defined error.

What is the best way in this case?

The master page looks like this:

<body>
    @yield('body')

    <script src="{{ mix('/assets/admin/manifest.js') }}"></script>
    <script src="{{ mix('/assets/admin/vendor.js') }}"></script>
    <script src="{{ mix('/assets/admin/app.js') }}"></script>

    @section('scripts')
    @show

    @yield('footer')
</body>
Strother answered 18/3, 2018 at 18:25 Comment(2)
Thanks for the configuration to replace $, jQuery with jquery. It solved my problem of missing jQuery.Marty
Same here, it solved my problem when use vendor extraction on jquery, but I can't reproduce your mentioned problem (run script in blade). I use laravel-mix 2.1.14Fleabag
A
15

According to this answer you need to import jquery this way

window.$ = window.jQuery = require('jquery');
Auten answered 20/4, 2019 at 7:46 Comment(0)
E
3

before:

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

after:

<script src="{{ asset('js/app.js') }}" ></script>

in layout worked for me.

Environs answered 24/3, 2021 at 8:16 Comment(0)
B
-2

It's an old question, however, this may help others finding answer for this.

The vendor js takes time to load and the inline javascript we use in blade templates fires before vendor js is completely loaded.

To fix this, wrap inline javascript in setTimeout function like below:

@push('scripts-or-whatever')
<script>
    setTimeout(function(){
       // $, jQuery, Vue is all ready to use now
       $(document).ready(function(){ // code here })
    }, 100)
</script>
@endpush
Bubaline answered 30/12, 2019 at 10:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.