Проблема с загрузкой скрипта Laravel 5.4

Я работаю над своим первым проектом Laravel (5.4), на самом деле я не понимаю, почему мой js-скрипт не работает так, как я ожидал. Я использую Mix и Blade:

// webpack.mix.js
let { mix } = require('laravel-mix').mix;

    // copy fonts and patterns
mix .copy('resources/assets/vendor/bootstrap/fonts', 'public/fonts')
    .copy('resources/assets/vendor/font-awesome/fonts', 'public/fonts')
    .copy('resources/assets/patterns', 'public/css/patterns')

    // compile scss and concatenate css files
    .sass('resources/assets/sass/app.scss', 'public/css')
    .styles([
        'resources/assets/vendor/bootstrap/css/bootstrap.css',
        'resources/assets/vendor/animate/animate.css'
        // ...
    ], 'public/css/vendor.css')

    // concatenate js files
    .js([
        'resources/assets/vendor/jquery/jquery-3.1.1.min.js',
        'resources/assets/vendor/bootstrap/js/bootstrap.js',
        'resources/assets/js/app.js'
        // ...
    ], 'public/js/app.js')
    .options({ processCssUrls: false }); // fix for path issue : https://github.com/almasaeed2010/AdminLTE/issues/1360

После компиляции npm run dev выглядит хорошо:

DONE  Compiled successfully in 6497ms                                                     4:20:57 PM

                                   Asset      Size  Chunks                    Chunk Names
  fonts/glyphicons-halflings-regular.ttf   45.4 kB          [emitted]         
                              /js/app.js    1.2 MB       0  [emitted]  [big]  /js/app
                       mix-manifest.json  66 bytes          [emitted]         
  fonts/glyphicons-halflings-regular.eot   20.1 kB          [emitted]         
fonts/glyphicons-halflings-regular.woff2     18 kB          [emitted]         
  fonts/glyphicons-halflings-regular.svg    109 kB          [emitted]         
 fonts/glyphicons-halflings-regular.woff   23.4 kB          [emitted]         
                            /css/app.css    178 kB       0  [emitted]         /js/app
           fonts/fontawesome-webfont.ttf    166 kB          [emitted]         
           fonts/fontawesome-webfont.svg    444 kB          [emitted]  [big]  
           fonts/fontawesome-webfont.eot    166 kB          [emitted]         
          fonts/fontawesome-webfont.woff     98 kB          [emitted]         
         fonts/fontawesome-webfont.woff2   77.2 kB          [emitted]         
                   fonts/FontAwesome.otf    135 kB          [emitted]         
         css/patterns/header-profile.png   5.88 kB          [emitted] 

CSS работает нормально, bootstrap.js тоже работает и когда я проверяю внутри /js/app.js вроде все внутри.

Вот мой шаблон:

{{-- app.blade.php--}}
<!DOCTYPE html>
<html lang="{{ config('app.locale', 'en') }}">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>@yield('title')</title>
    <link rel="stylesheet" href="{!! asset('css/vendor.css') !!}" />
    <link rel="stylesheet" href="{!! asset('css/app.css') !!}" />
</head>
<body>
    <!-- Main view  -->
    @yield('content')

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

    @section('scripts')
    @show
</body>
</html>

Мои проблемы начались, когда я хочу добавить скрипт в раздел сценариев от ребенка.

@extends('layouts.app')

@section('scripts')
    <script type="text/javascript">
        $(document).ready(function () {
            alert('test');
        });
    </script>
@endsection

Я получил Uncaught ReferenceError: $ is not defined лайков, если jquery не был загружен.

Я понятия не имею, почему, есть идеи?

[note]
Это работает, если я заменю внутри app.blade.php:

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

с :

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.0/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>

person Opsse    schedule 30.03.2017    source источник
comment
Ради интереса, если вы замените $ на jQuery (чтобы у вас было jQuery(document).ready(function () {), это сработает? Кроме того, если вы откроете инструменты разработчика в своем браузере, успешно ли загрузится app.js?   -  person Chris Forrence    schedule 30.03.2017
comment
Та же ошибка с jQuery. Насколько я вижу, app.js загружен, поэтому я не понимаю, что не так.   -  person Opsse    schedule 30.03.2017


Ответы (3)


Наконец-то я понял, кто виноват: Микс (или то, как я использовал Микс)

Я ошибочно полагал, что mix.js и mix.scripts это одна и та же функция. Но mix.scripts только объединяет и минимизирует файлы, а mix.js также компилирует ECMAScript 2015 и связывает модули. Я действительно не знаю, почему, но это была проблема в моем случае.

mix.js(['public/js/admin.js',
    'public/js/dashboard.js'], 'public/js');

заменен на :

mix.scripts(['public/js/admin.js',
    'public/js/dashboard.js'], 'public/js/all.js');

Подробнее : документ Laravel

person Opsse    schedule 31.03.2017
comment
Вам необходимо указать параметр имени файла назначения для mix.scripts, например «public/js/all.js», простое указание каталога приводит к ошибке EISDIR: недопустимая операция с каталогом. - person madz; 10.05.2017
comment
Извините, я имел в виду только один файл mix.scripts, файл mix.js подойдет как папка. - person madz; 11.05.2017

У меня была аналогичная проблема, и проблема заключалась в том, что в тот момент, когда я впервые использовал jQuery, файл app.js, сгенерированный webpack, еще не был загружен.

Вы можете сделать простой тест, чтобы узнать, есть ли у вас такая же проблема. В вашем первом фрагменте кода, где вы используете jQuery (строка кода, которая выдает вам ошибку $), оберните этот код следующим образом:

document.addEventListener("DOMContentLoaded", function(event) { 
 // Your jQuery code
});

Одним из обходных путей является загрузка app.js раньше в основной файл макета блейда, но я уверен, что это можно сделать лучше. Я новичок в Laravel, поэтому я все еще разбираюсь в таких вещах...

Изменить:

Хорошо, я думаю, теперь я понял, как это сделать правильно:

  1. В макете основного блейда (в моем случае app.blade.php) в правом нижнем углу перед тегом </body> загрузите свой сценарий веб-пакета, все остальные внешние сценарии, которые вы можете загрузить, и, наконец, добавьте раздел сценариев yield.

Пример:

<script src="/js/app.js"></script>
<script src="other/scripts/that/you/need.js"></script>
@yield('scripts')
  1. В шаблоне блейда, где вам нужен код jQuery, вместо того, чтобы добавлять его непосредственно в раздел содержимого, вы создаете новый раздел с именем скрипты.

Пример:

@section('content')
//Your view code
@endsection

@section('scripts')
//Your jQuery code
@endsection

Таким образом, ваш код jQuery загружается после того, как основной макет уже загрузил файл javascript webpack (который загружает jQuery).

person Jordan    schedule 31.03.2017
comment
Хорошая попытка, но она не работает, document.addEventListener не решает проблему. И структура html, которую вы предлагаете, - это та, которую я сейчас использую. - person Opsse; 31.03.2017
comment
Это только что сэкономило мне часы разочарования. Спасибо приятель. - person insomniac22; 11.02.2021

Просто включите файл js, как показано ниже, в ваши блейд-файлы, так как в моем случае я включаю add-section.js, который находится внутри public/js.

<script src="{{ asset('/js/add-section.js') }}"></script>
@yield('scripts')
person Rashi Goyal    schedule 22.05.2017