giviz's avatar
Level 3

ReferenceError: $ is not defined using Mix

Hi guys,

I've spend a couple of hours trying to figure out why I get this error when I'm trying to use jQuery:

Uncaught ReferenceError: $ is not defined at home:203

For some really basic code :

<input type="text" id="test" value="test"/>
<script>
alert($('#test').value);
</script>

Some files :

package.json

{
  "private": true,
  "scripts": {
    "dev": "node node_modules/cross-env/bin/cross-env.js NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
    "watch": "node node_modules/cross-env/bin/cross-env.js NODE_ENV=development node_modules/webpack/bin/webpack.js --watch --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
    "hot": "node node_modules/cross-env/bin/cross-env.js NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js",
    "production": "node node_modules/cross-env/bin/cross-env.js NODE_ENV=production node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"
  },
  "devDependencies": {
    "axios": "^0.15.2",
    "bootstrap-sass": "^3.3.7",
    "jquery": "^3.1.0",
    "laravel-mix": "^0.5.0",
    "lodash": "^4.16.2",
    "vue": "^2.0.1"
  },
  "dependencies": {
    "babel-preset-es2015": "^6.22.0",
    "babel-preset-react": "^6.23.0",
    "datatables.net": "^1.10.13",
    "datatables.net-dt": "^1.10.13"
  }
}

bootstrap.js

window._ = require('lodash');

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

webpack.mix.js

mix.js('resources/assets/js/app.js', 'public/js')
    .extract([
        'jquery',
        'vue'
    ])
   .sass('resources/assets/sass/app.scss', 'public/css');

Loaded in head

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

Loaded before body close

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

Any idea of what and I can be missing here ?

0 likes
11 replies
giviz's avatar
giviz
OP
Best Answer
Level 3

So, this one is a tricky one, the issue is with DataTables.

In order to get the things working, I have to have jquery loaded just before DataTables, otherwise there is jquery errors all over the place.

The solution is to remove jquery from mix and load it the old fashion way with a cdn link.

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.js"></script>
<script type="text/javascript" charset="utf8" src="//cdn.datatables.net/1.10.13/js/jquery.dataTables.js"></script>

But even there, jquery has to be loaded just before dataTables, if there is other scripts loaded in between the two, I got some errors showing up.

If any one managed to get jquery + datatables loaded from npm, please share how !

1 like
Yamen's avatar

I manage to get it work with npm with those steps:

1- In your project directory run npm install datatables.net --save-dev.

2- In resources/assets/js/bootstrap.js

window.$ = window.jQuery = require('jquery'); 
window.dt = require('datatables.net'); 

3- npm run dev.

Hope this helps.

3 likes
Daniel-Pablo's avatar

@Yamen thanks I use your code but for another npm pack and it works men! thanks for making the comment in this forum really help me

window.waxjs = require('@waxio/waxjs/dist');

also inside the bootstrap.js

1 like
Yamen's avatar

Some times it's because the defer attribute in the source tag as mentioned in other comments.

rchl2's avatar

Use autoload. In your webpack.mix.js:

mix.autoload({
   jquery: ['$', 'window.jQuery']
});
1 like
nadiyapara's avatar

In tag, there is by default script file "app.js" file included.

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

Remove "defer" attribute.

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

It will works!

7 likes
FrenchFryNinja's avatar

If anyone else has this issue, I had to solve it this way:

in bootstrap.js change "window" to "global." Now I don't know why this fixes things, but it does... Please tell me if this is terrible. Otherwise I could never get $ to be recognized:

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

Behinder's avatar

Imagine , it is still the deafult in Laravel 6 using "defer". It brings lot of confusion to users

Please or to participate in this conversation.