21

I tried with fresh install laravel 9.20 and with minimum configuration

in vite.config.js

import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';

export default defineConfig({
    plugins: [
        laravel({
            input: [
                'resources/js/app.js',
            ],
            refresh: true,
        }),
    ],
});

in app.js

import './bootstrap';

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

import '../sass/app.scss';

i have tried with this too

import * as $ from "jquery";
window.$ = window.jQuery = $;

load the assets in blade and i test with this script

@vite(['resources/js/app.js']);

$("#alertbox").alert("test");

but i get the following error in the console:

Uncaught ReferenceError: $ is not defined

I can't make it work, please help

1

4 Answers 4

40

This happens because of Vite's module loading order. You're seeing a race condition, and it's not an issue with the import.

To confirm this, try calling the jQuery code after a timeout as below.

<script>
   setTimeout(function() {
      console.log($);
      $("#alertbox").alert("test");
   }, 5000);
</script>

If there's no error with the above, then it means the code is getting executed in the incorrect order. But adding a timeout is not a good way to solve it, so let's look at the cause of the problem.

If you look at source code you'll see something like this.

<script type="module" src="http://localhost/build/assets/app.342432.js"></script>

This means Vite is loading scripts as modules. And module scripts are always deferred. So if your jQuery script is placed after Vite directive, jQuery code is executed first, before loading jQuery to window - this triggers $ is undefined error.

In best practise, you should move the jQuery code to app.js file, so it stays in it's own module. The other way to handle this is to mark your script tag as a module, then it'll follow the loading order of the document.

Change the script tag as below.

@vite(['resources/js/app.js']);

<script type="module">
   $("#alertbox").alert("test");
</script>
Sign up to request clarification or add additional context in comments.

2 Comments

I would suggest the person who posted this question to mark this answer as correct. It really helped!
Thank you for the explanation, I was wondering why I was getting the error despite setting things up correctly. I struggled for days with this error and I'm glad you curated this solution and explanation.
8

add type = module in tag script

<script type="module">
    code....
</script>

Comments

4

I was facing same issue while generating DataTable using jquery datatable plugins with vite in laravel 10, fixed by

  1. Assigning $ to the window object in app.js
  2. Adding module in script declaration.

resources/js/app.js

import $ from 'jquery';
window.$ = $; // this worked for me
import 'datatables.net';

resources/views/users/index.blade.php

<script type="module">
    $(document).ready(function() {
        $('#websites-table').DataTable({
            // Your code
        });       
    });
</script>

Comments

-3

add jquery from cdn in the blade template

https://cdnjs.com/libraries/jquery

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.3/jquery.min.js" integrity="sha512-STof4xm1wgkfm7heWqFJVn58Hm3EtS31XFaagaa8VMReCXAkQnJZ+jEy8PCC/iT18dFy95WcExNHFTqLyp72eQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

and solve it

1 Comment

Some people are using webpack or vite, so this solution is probably not relevant.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.