$ 未在具有 make:auth 个脚手架和默认值 app.js 的 Laravel 5.6 个项目中定义

$ is not defined in Laravel 5.6 projects with make:auth scaffolding and default app.js

我有两个独立的 Laravel 5.6 项目,由于某些原因我无法在其中任何一个上使用 jQuery。

HTML

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <!-- CSRF Token -->
    <meta name="csrf-token" content="masked">

    <title>Title</title>

    <!-- Scripts -->
    <script src="/js/app.js" defer>    </script>

    <!-- Fonts -->
    <link rel="dns-prefetch" href="https://fonts.gstatic.com">
    <link href="https://fonts.googleapis.com/css?family=Raleway:300,400,600" rel="stylesheet" type="text/css">

    <!-- Styles -->
    <link href="/css/app.css" rel="stylesheet">

    <script>
        $(document).ready(function() {

            $(".clickable-row").click(function() {
                window.location = $(this).data("href");
            });

        });
    </script>

</head>
<body>

...

</body>
</html>

根据网络检查器,所有资源都在正常加载。我试过将脚本块移动到主体的末尾,但这没有帮助。我也试过像这样调用 jQuery,但无济于事:

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

    $(".clickable-row").click(function() {
        window.location = $(this).data("href");
    });

});

我检查了 app.js,看起来不错。我检查了 bootstrap.js,看起来不错。

app.js

/**
 * First we will load all of this project's JavaScript dependencies which
 * includes Vue and other libraries. It is a great starting point when
 * building robust, powerful web applications using Vue and Laravel.
 */

require('./bootstrap');

window.Vue = require('vue');

/**
 * Next, we will create a fresh Vue application instance and attach it to
 * the page. Then, you may begin adding components to this application
 * or customize the JavaScript scaffolding to fit your unique needs.
 */

Vue.component('example-component', require('./components/ExampleComponent.vue'));

const app = new Vue({
    el: '#app'
});

bootstrap.js

window._ = require('lodash');
window.Popper = require('popper.js').default;

/**
 * We'll load jQuery and the Bootstrap jQuery plugin which provides support
 * for JavaScript based Bootstrap features such as modals and tabs. This
 * code may be modified to fit the specific needs of your application.
 */

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

    require('bootstrap');
} catch (e) {}

/**
 * We'll load the axios HTTP library which allows us to easily issue requests
 * to our Laravel back-end. This library automatically handles sending the
 * CSRF token as a header based on the value of the "XSRF" token cookie.
 */

window.axios = require('axios');

window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';

/**
 * Next we will register the CSRF Token as a common header with Axios so that
 * all outgoing HTTP requests automatically have it attached. This is just
 * a simple convenience so we don't have to attach every token manually.
 */

let token = document.head.querySelector('meta[name="csrf-token"]');

if (token) {
    window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content;
} else {
    console.error('CSRF token not found: https://laravel.com/docs/csrf#csrf-x-csrf-token');
}

/**
 * Echo exposes an expressive API for subscribing to channels and listening
 * for events that are broadcast by Laravel. Echo and event broadcasting
 * allows your team to easily build robust real-time web applications.
 */

// import Echo from 'laravel-echo'

// window.Pusher = require('pusher-js');

// window.Echo = new Echo({
//     broadcaster: 'pusher',
//     key: process.env.MIX_PUSHER_APP_KEY,
//     cluster: process.env.MIX_PUSHER_APP_CLUSTER,
//     encrypted: true
// });

为什么每次我尝试使用时 jQuery 都未定义?

webpack.mix.js

let mix = require('laravel-mix');
let webpack = require('webpack');

mix.js('resources/assets/js/app.js', 'public/js')
   .sass('resources/assets/sass/app.scss', 'public/css')
   .webpackConfig({
    plugins: [
        new webpack.ProvidePlugin({
            $: 'jquery',
            jQuery: 'jquery',
            'window.jQuery': 'jquery',
            Popper: 'popper.js'
        })
    ],
   });

webpack 附带的 ProvidePlugin 将全局公开工厂变量,以便在您的应用程序中的任何地方使用。由于您使用的是 bootstrap 4,因此以下配置适用于您:

mix.webpackConfig({
  plugins: [
    new webpack.ProvidePlugin({
      $: 'jquery',
      jQuery: 'jquery',
      'window.jQuery': 'jquery',
      Popper: 'popper.js' //not sure if this is necessary
    })
  ],
});

这假设您已经在 webpack.mix.js 文件中的某处定义了 mix,例如:

const mix = require('laravel-mix')

即使您在 js 文件中包含 jQuery,这种方法也是必要的原因是 webpack 在内部为所有变量设置了别名,因此 jQuery在您的应用程序范围之外不可用。使用 ProvidePlugin 可确保变量在您的应用程序代码中的任何位置都可以作为它们的默认名称使用,无论是在包中还是在视图中。