0

For the first time I am using Yarn. I have installed the latest version of Laravel Boilerplate (http://laravel-boilerplate.com/) and there is used Yarn.

My need is to include the JS library DataTables (https://datatables.net/). Unfortunately I am new to Yarn and I am not sure if I am making everything right, because I get the error:

[Show/hide message details.] ReferenceError: $ is not defined

which is on the this line:

$(document).ready(function() {
...

This is telling me that it cannot find the jquery library, but it should be there.

Here is the webpack.mix.js code:

const mix = require('laravel-mix');

/*
 |--------------------------------------------------------------------------
 | Mix Asset Management
 |--------------------------------------------------------------------------
 |
 | Mix provides a clean, fluent API for defining some Webpack build steps
 | for your Laravel application. By default, we are compiling the Sass
 | file for the application as well as bundling up all the JS files.
 |
 */

mix.setPublicPath('public');

mix.sass('resources/sass/frontend/app.scss', 'css/frontend/frontend.css')
    .sass('resources/sass/backend/app.scss', 'css/backend/backend.css')
    .js('resources/js/frontend/app.js', 'js/frontend/frontend.js')
    .js([
        'resources/js/backend/before.js',
        'resources/js/backend/app.js',
        'resources/js/backend/after.js'
    ], 'js/backend/backend.js')
    .extract([
        'jquery',
        'datatables.net-dt',
        'bootstrap',
        'popper.js/dist/umd/popper',
        'axios',
        'sweetalert2',
        'lodash',
        '@fortawesome/fontawesome-svg-core',
        '@fortawesome/free-brands-svg-icons',
        '@fortawesome/free-regular-svg-icons',
        '@fortawesome/free-solid-svg-icons'
    ]);

if (mix.inProduction() || process.env.npm_lifecycle_event !== 'hot') {
    mix.version();
}

Every time I call the command "yarn prod" in order to create the CSS and js files, but the DataTables are not working.

Did I miss something?

Thanks in advance!

tk421
  • 5,775
  • 6
  • 23
  • 34
Vince Carter
  • 907
  • 3
  • 14
  • 41

1 Answers1

0

It's not because of yarn. Yarn is a package manager, it doesn't run any part of your application's code so cannot generate an error like yours. Yarn is just for downloading packages and manage their dependencies.

Then comes Laravel Mix for you, which is just a wrapper around Webpack. Webpack reads your application code, handles your require and import commands in your .js files and then generates your bundles.

How to make it work:

I suppose you did run the yarn command (without params) in your project root once when you installed Laravel Boilerplate. There should be a lot of packages inside your node_modules directory (more than 900).

Then you did run yarn add -D datatables.net-dt also. Now you should have a datatables.net and a datatables.net-dt folder inside node_modules.

I see you've added datatables.net-dt in your webpack.mix.js, this is OK! You don't need any other require( 'datatables.net-dt' )( window, $ ); as said in the documentation. That one line in your webpack.mix.js is enough! DataTable will be inside your vendor.js.

Now create an example table with attribute id="example" in your index.blade.php then add this code to the bottom of your resources\js\frontend\app.js:

$(document).ready(function() {
    $('#example').DataTable();
});

Then run yarn dev to let Webpack generate your bundles (compiled js files) and view your site in the browser. Following these, it should be working on a fresh install install of Laravel Boilerplate, without any error. I've just tested id now, works like charm.

Your possible bug:

$ is not defined tells that some part of your code is trying to use jQuery before it has been loaded.

It's important that you must write your codes using jQuery (shortened $) inside your resources\js\frontend\app.js or in a separate .js which is later required/imported into this file! It's because jQuery and other vendor packages like DataTable are stored in vendor.js, which must be loaded before any calls to them.

So don't use custom <script> tags in your html's <head> tag for your app code because that will be loaded and executed before any other defined in the bottom of your <body> tag!

Have a look at this file resources\views\frontend\layouts\app.blade.php. In the bottom of the body tag you'll see this:

<!-- Scripts -->
@stack('before-scripts')
{!! script(mix('js/manifest.js')) !!}
{!! script(mix('js/vendor.js')) !!}
{!! script(mix('js/frontend.js')) !!}
@stack('after-scripts')

Your resources\js\frontend\app.js and all its imported scripts will be compiled to this js/frontend.js file.

How jQuery is imported in Laravel Boilerplate:

This is done well by default, you don't have to bother with it. Open your resources\js\bootstrap.js and see these two lines:

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

This file will then imported by frontend/app.js. So write your code here and you'll be fine...


PS.: If this doesn't helps you to make it work, you should edit your question and provide more info on your sources. A screenshot for example taken from your Chrome DevTools, showing the lines of your JavaScript where the error occurred.

szegheo
  • 4,175
  • 4
  • 31
  • 35
  • thank you @ARS81 I am not sure what was the reason for getting that error, I think everything I have done as you described. The important thing is that now i have checked everything step by step and now is perfect. Many thanks again ! – Vince Carter Oct 14 '18 at 19:08
  • i have one question. I have added also the bootstrap-datepicker package to my backend.css, unfortunately i dont see the styles. I have included one datepicker.css right after my backend.css code, but it doesnt change anything. How should i include some js package css ? Should i mix it, if yes - how is the best practice ? Thanks in advance ! – Vince Carter Oct 15 '18 at 09:21
  • 1
    @VinceCarter Are you sure you want it in your backend/admin UI in your app? Anyway... You shouldn't use an extra `` tag in your `html` to include the css of this new package. Rather than open up your `resources\sass\backend\app.scss` file and add this line to the end `@import '~bootstrap-datepicker/dist/css/bootstrap-datepicker3.css';` Or in `frontend\app.scss` (?) Of course you have it installed like `yarn add -D bootstrap-datepicker` and `bootstrap-datepicker` added in your `webpack.mix.js` like you did it before with `datatables.net-dt` package. Tested and worked well for me. – szegheo Oct 15 '18 at 20:14
  • @VinceCarter of course you have to run `npm run dev` after doing this to re-generate your compiled `js` and `css` files... – szegheo Oct 15 '18 at 20:17
  • thanks again. i have imported the datepicker.css file into to the backend/app.scss and the magic happens :) – Vince Carter Oct 15 '18 at 21:02
  • I have one last question. In the webpack.mix.js there are around 10 includes in the extract() part. But in my node_modules, there are more than 1000 folders. Why is that ? is it possible somehow to remove the unneeded folders ? – Vince Carter Oct 15 '18 at 21:04
  • No. They are needed dependencies. That's how npm works... You use 10 packages but they depends on hundreds of other opensource packages. So never delete or modify anything inside node_modules! – szegheo Oct 15 '18 at 21:14
  • I appreciate your help ! – Vince Carter Oct 15 '18 at 21:22