【问题标题】:$ is not defined in Laravel 5.6 projects with make:auth scaffolding and default app.js$ 在 Laravel 5.6 项目中没有定义 make:auth 脚手架和默认 app.js
【发布时间】:2018-04-03 15:36:33
【问题描述】:

我有两个独立的 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>

根据 Network Inspector,所有资源都加载正常。我尝试将脚本块移动到正文的末尾,但这没有帮助。我也尝试像这样调用 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'
        })
    ],
   });

【问题讨论】:

  • 您需要使用ProvidePlugin 和webpack 以全局方式向您的应用程序公开jQuery。向我们展示您的 webpack.mix.js 文件,我们将帮助您修复它

标签: jquery laravel laravel-mix


【解决方案1】:

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 可确保变量在应用程序代码中的任何位置都可以作为它们的默认名称使用,无论是在包中还是在视图中。

【讨论】:

  • 感谢您的快速回复和简单的解释。这是最近对 Laravel 的更改吗?我从来不用搞乱 webpack。
  • @MichaelRodriguez 我不知道,至少有几个版本是这样的。
  • 好的,所以我想我可以从这里拿走它,但我似乎仍然无法让它工作。在实施您的建议后,我编辑了我的问题以显示我的 webpack.mix.js。运行 npm run production 后,控制台中仍然出现相同的错误(已安装依赖项)。
  • @MichaelRodriguez 如果您在浏览器的 javascript 控制台中登录 $ 会发生什么?
  • 有趣的开发:如果我从调用 app.js 的脚本元素中删除“defer”属性,我发现它开箱即用,无需更改 webpack。所以我想这意味着问题实际上是我的 jquery sn-p 在它完全加载之前试图使用它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-05-18
  • 2019-04-01
  • 2019-02-02
  • 2013-11-07
  • 1970-01-01
  • 1970-01-01
  • 2021-10-28
相关资源
最近更新 更多