【Laravel】scriptとcssリソースの読み込み宣言先と読み込み順のメモ

# やりたいこと
特定の画面用にcssファイルを読み込んだり、jsコードを書いたりがあると思いますが、scriptタグをつける箇所によって読み込み順が変わるようなのでメモしていきます。

# 特定画面用のbladeテンプレートファイルに書く
jQueryの読み込み自体は、Laravelプロジェクトのデフォルトで生成されている「\resources\views\layouts\app.blade.php」にて記載があります。

``` php
<!doctype html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <!-- CSRF Token -->
    <meta name="csrf-token" content="{{ csrf_token() }}">

    <title>{{ config('app.name', 'Laravel') }}</title>

    <!-- Scripts -->
    <script src="{{ asset('js/app.js') }}" defer></script>
    <!-- jQuery -->
	<script src="js/jquery.min.js"></script>
	<!-- jQuery Easing -->
	<script src="js/jquery.easing.1.3.js"></script>
	<!-- Bootstrap -->
	<script src="js/bootstrap.min.js"></script>
	<!-- Waypoints -->
	<script src="js/jquery.waypoints.min.js"></script>
	<!-- Flexslider -->
	<script src="js/jquery.flexslider-min.js"></script>
	
	
	<!-- MAIN JS -->
	<script src="js/main.js"></script>
```

各画面を表示した際にいろいろとローカルからjQueryファイルを読み込んで前ページに反映されるようになっています。
※開発者ツールで見るとリクエストパス直下のjsを見に行っているように見えますが、実際には「public/js」の中を見にいっています。public配下にjsファイルがないと、画面上は何の変哲もありませんが裏では404を返しています。

# この状態で画面固有のblade側でjsコードを読み込む
サブコンテンツとして以下のようなbladeを用意しているとします。
この中で、「class:skill_type」に変更があった場合に「class:skill_timing」の表示を制御するjsも用意します。

``` php
@extends('create.base.index')
@section('sub-content')
<div>
	@if (session('message'))
		@if(session('result') == 2)
			<div class="alert alert-success" role="alert"><p>{{ session('message')}}</p></div>
		@endif
		@if(session('result') == 4)
			<div class="alert alert-danger" role="alert"><p>{{ session('message')}}</p></div>
		@endif
	@endif
	@foreach ($errors->get('name') as $message)
  	<p class="error-txt" class="alert alert-danger" role="alert">{{ $message }}</p>
	@endforeach
</div>
<div>
		<h1>スキル編集フォーム</h1>
		<div>
			@if ($data->leader_skill_id>0)
			<form action="{{ route('edit_skill', $data->leader_skill_id) }}" method="GET">
				<input type="submit" value="Laeder">
			</form>
			@endif
			@if ($data->passive_skill_id>0)
			<form action="{{ route('edit_skill', $data->passive_skill_id) }}" method="GET">
				<input type="submit" value="Passive">
			</form>
			@endif
			@if ($data->action_skill_id>0)
			<form action="{{ route('edit_skill', $data->action_skill_id) }}" method="GET">
				<input type="submit" value="Action">
			</form>
			@endif
		</div>
		<form action="{{ route('edit_skill_complate') }}" method="POST" enctype="multipart/form-data">
			@csrf
			@method('PATCH')
			<input type="hidden" class="form-control" id="validationDefault01" name="unit_skill_id" value='{{$target->unit_skill_id}}'/>
			<div class="mb-3">
				<label for="validationDefault01" class="form-label">スキルデータID</label>
				<input type="text" readonly class="form-control" id="validationDefault01" name='skill_id' value='{{$target->skill_id}}' required/>
			</div>
			<div class="mb-3">
				<label for="validationDefault01" class="form-label">キャラクターID</label>
				<input type="number" class="form-control" id="validationDefault01" name='character_id' value='{{$target->character_id}}' required/>
			</div>
			<div class="mb-3 skill_timing">
				<label for="validationDefault02" class="form-label">スキル発動タイミング</label>
				<select type="select" class="skill_timing" name='skill_timing' value='{{$target->skill_timing}}' >
					<option value='0'>なし</option>
					@foreach($skillTiming as $SkillTiming)
						<option @if($target->skill_timing === $SkillTiming) selected @endif
								value='{{$SkillTiming}}'>{{$SkillTiming}}</option>
					@endforeach
				</select>
			</div>
			<div class="mb-3">
				<label for="validationDefault02" class="form-label">スキル名</label>
				<input type="text" class="form-control" id="validationDefault02" name='skill_name' value='{{$target->skill_name}}' required/>
			</div>
			<div class="mb-3">
				<label class="form-label">スキル説明文</label>
				<input type="textarea" name='skill_discription' value='{{$target->skill_discription}}' />
			</div>
			<div class="mb-3">
				<label class="form-label">スキルタイプ</label>
				<select type="select" class="skill_type" name='skill_type' value='{{$target->skill_type}}' >
				<option value='0'>なし</option>
					@foreach($skillType as $SkillType)
						<option @if($target->skill_type === $SkillType) selected @endif
							 value='{{$SkillType}}'>{{$SkillType}}</option>
					@endforeach
				</select>
			</div>
			<input type="submit" value="更新" />
		</form>
	</div>
@endsection
 <script src="{{ asset('/js/skill/skill.main.js') }}"></script>
```
jQueryで実装。hiddenというクラスを追加して表示、非表示属性を制御します。
``` js
$(document).ready(function() {
    $('.skill_type').on('change', function() {
        var selectedValue = $(this).val();
		console.log(selectedValue);
        // 選択された値に応じて要素を非表示
        if (selectedValue === 'ACTION') {
            $('.skill_timing').addClass('hidden');
        } else{
			$('.skill_timing').removeClass('hidden');
        }
	});
	});
```

cssも同じくjQueryの読み込みと同じく、「app.blade.php」のheaderで宣言します。
リクエストパスによってlinkタグ自体を制御するか、css内で指定するクラス名などがほかの画面のcssと競合しないよう制御するのがいいと思います。
``` php
<!doctype html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <!-- CSRF Token -->
    <meta name="csrf-token" content="{{ csrf_token() }}">

    <title>{{ config('app.name', 'Laravel') }}</title>

    <!-- Scripts -->
    <script src="{{ asset('js/app.js') }}" defer></script>
    <!-- jQuery -->
	<script src="{{ asset('js/lib/jquery-3.7.1.min.js') }}"></script>
	<!-- jQuery Easing -->
	<script src="js/jquery.easing.1.3.js"></script>
	<!-- Bootstrap -->
	<script src="js/bootstrap.min.js"></script>
	<!-- Waypoints -->
	<script src="js/jquery.waypoints.min.js"></script>
	<!-- Flexslider -->
	<script src="js/jquery.flexslider-min.js"></script>
	
	
	<!-- MAIN JS -->
	<script src="js/main.js"></script>

    <!-- Fonts -->
    <link rel="dns-prefetch" href="//fonts.gstatic.com">
    <link href="https://fonts.googleapis.com/css?family=Nunito" rel="stylesheet">

    <!-- Styles -->
    <link href="{{ asset('css/app.css') }}" rel="stylesheet">
    <!-- Animate.css -->
	<link rel="stylesheet" href="{{ asset('css/animate.css') }}">
	<!-- Icomoon Icon Fonts-->
	<link rel="stylesheet" href="{{ asset('css/icomoon.css') }}">
	<!-- Bootstrap  -->
	<link rel="stylesheet" href="{{ asset('css/bootstrap.css') }}">
	<!-- Flexslider  -->
	<link rel="stylesheet" href="{{ asset('css/flexslider.css') }}">
	<!-- Theme style  -->
	<link rel="stylesheet" href="{{ asset('css/style.css') }}">

    <link rel="stylesheet" href="{{ asset('css/skill.css') }}">
   
</head>
```

jQueryとcssは共有のheade内に、jsコードは画面固有のBladeファイルにて宣言しています。
この状態で画面表示すると、**先に画面固有のBladeファイル側のjsコードが読み込まれて、jQuery記述の未定義エラーが出ます。**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2796558/70532cd4-5a8d-0de1-4d0c-40124276c2e1.png)

どうやら固有画面のblade.php⇒app.blade.phpの順になるようです。

# 回避策
css同様、jQuery都の読み込み順を明確にするため「app.blade.php」の方にscriptタグを置きます
```php
~~~
    <link rel="stylesheet" href="{{ asset('css/skill.css') }}">
    <script src="{{ asset('/js/skill/skill.main.js') }}"></script>

</head>
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2796558/5f9f51b7-41b3-36b0-c652-de68d844d654.png)

Laravelのコンテンツ読み込みによる固有の制御なのか何なのかは調べて分かれば書きます。