laravel-mix: jQuery autoloading apparently not working

  • Laravel Mix Version: 0.9.2
  • Node Version (node -v): v6.9.5
  • NPM Version (npm -v): 3.10.10
  • OS: VM Homestead

Description:

I can’t load jQuery using laravel-mix. I’ve added this snippet to webpack.mix.js :

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

as shown here: https://github.com/JeffreyWay/laravel-mix/blob/master/docs/autoloading.md

In any blade template, I can add something like this

<script>
    $(document).ready(function () {
        alert("jQuery loaded");
    });
</script>

But the $ is not recognised (browser error: ReferenceError: Can't find variable: $)

In case it was an issue with the setup of my project, I’ve created a new laravel project from scratch, and I have the same issue.

Steps To Reproduce:

laravel new testsite edit welcome.blade.php and add the script snippet mentioned above npm run dev open testsite, browser shows error mentioned above

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Comments: 15

Most upvoted comments

Be careful with script defer attribute also. That will make your autoloaded jQuery unavailable in blade files

@MladenJanjetovic the whole setup seems confusing to me as a Laravel newcomer, but the way I finally made it work correctly was:

  1. Loading my external js files that need JQuery with Mix (file webpack.mix.js). Example:
mix.autoload({
  jquery: ['$', 'window.jQuery', 'jQuery'],
  moment: 'moment'
});

mix.js(['resources/assets/js/app.js', 'a-module-path/a-jquery-dependant-script.js'], 'public/js')
   .sass('resources/assets/sass/app.scss', 'public/css');

That way, $ is available later on when you require it in a blade template.

@jnanin

Yes, many people say the following code to solve it.

window.$ = require('jquery');

However, this makes the autoload function pointless.

So I am still wandering.

Oh ok, I missread that, sorry.

However, I still don’t see how to make it work. In a clean laravel installation, by default webpack.mix.js points to the javascript file: mix.js('resources/assets/js/app.js', 'public/js')

which requires bootstrap.js: require('./bootstrap')

where what you suggest is already done: window.$ = window.jQuery = require('jquery');

So, it should work out of the box then; shouldn’t it? But it doesn’t

Keeping in mind that I missread the doc file, there is a big chance that this is my fault; but I’ve been going through it for hours and I can’t pinpoint what am I doing wrong… So that’s what led me to believe me that it might be an issue.

Forget about it… I finally understood what’s going on:

  1. In the new laravel installation, the example blade file welcome.blade.php does not load by default the javascript file -> <script src="/js/app.js"></script>

  2. In my project, the issue comes from the loading order: I load <script src="/js/app.js"></script> after yielding the content - @yield('content') - so at the moment the jQuery script is evaluated; it’s normal that it fails because hasn’t been loaded yet.

Thanks

@JRRodriguez88 I actually solved it now by removing the defer attribute and moving the <script> tag to the bottom such that it is the last element in the body-tag. That worked.

Yes @jnanin

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

did the trick for the missing selectors in laravel 5.6