【jQuery X Laravel 】 Marked.jsでマークダウン機能の実装

#Marked.jsでマークダウン機能の実装

2019年11月から、[Laravel歴数ヶ月の初心者が投稿型ナレッジベースのコミュニティサイトを作る](https://qiita.com/AkiYanagimoto/items/216ea9549e758342baab "投稿型ナレッジベースのコミュニティサイトを作る")というチャレンジ中。作りたいアプリケーション→機能を因数分解→ググる→先人の轍をたどる（写経する）→ぬかるみにはまる→エラー解消の神を探す→解決を繰り返す日々( ·ㅂ·)و 。備忘録として、Qiitaに投稿しています。

今回はマークダウン機能を実装していきます！

## 副課題
今回は、マークダウン機能の実装に併せて、以下の副題をつけてみました。これまでは、バックエンド側だけでしたが、徐々にフロントエンドについても勉強をしていきたいと思います。

- bladeとjsファイルを分けて書く方法を試す！！
- Webpack/Laravel Mixを使ってみたい！！


## 参考図書
marked.jsの実装については、こちらの記事を参考にさせていただきました。
[マークダウンエディターを5分で作る【Marked.js & highlight.js】]
(https://qiita.com/samuraibrass/items/d40d54aa0754692d5439)

ですので、基本的には参考図書をみれば十分なんだと思いますが、私の場合、bladeとjsファイルを分けて書く方法やファイルの置き場所などで調べ物をしたので、その点も含めて投稿しています。大半の方にとっては、既存の内容も多いかと思いますがご容赦ください。


## 使用するファイル

```
# project directory傘下
resources/views/posts/create.blade.php //マークダウンで入力＆表示させるブレード
resources/views/layouts/app.blade.php　//create.bladeの親に当たるレイアウトテンプレート
resources/js/assets/markdown_jquery.js //入力されたテキストを処理して表示させるjavascriptを書くファイル
webpack.mix.js //JavaScriptファイルの変換や結合といった操作をコマンド1つで実行できるツール...
らしい。今後の勉強のためにトライ。
```


## Marked.jsの読み込み

marked.jsは、npmを使ってインストールしました。

```terminal:terminal
// コマンドを実行
$ npm install marked --save

// 以下の結果が表示されて、無事にインストールされた模様
+ marked@0.8.0
added 1 package from 1 contributor and audited 17204 packages in 10.339s
found 0 vulnerabilities
```

本当にインストールされたかの確認は、package.jsonを見るとわかります。dependemciesディレクトリに入っていればインストールOKの印です。コマンドを叩いた結果が目視できると安心できるタイプです、私。素人感半端ないですね。

```json:package.json
    "dependencies": {
        "marked": "^0.8.0", 　//dependemciesディレクトリに入っていればインストールOKです。
    }
```

## テキスト入力・表示用のbladeを準備する
今回のケースでは、新規投稿ページにマークダウン機能を入れます。resources/views/posts傘下に、create.blade.php という新規投稿ファイルを作り、テキストを入力するエリアと、marked.jsを通した後のテキストを出力するコードを記述します。


```php:create.blade.php
@extends('layouts.app')

@section('javascript-head')
{{-- この場所に画面毎(ヘッダ位置)のjsを記述する --}}
<script src="{{ asset('js/assets/markdown_jquery.js') }}" defer></script>
@endsection

@section('content')
    <div class="container mt-4">
            <h1 class="h5 mb-4">
                投稿の新規作成 
            </h1>
            <!-- マークダウン -->
            <div class="row">
                <div class="col-5 m-1">
                    <!-- ここに入力-->
                    <textarea name="article" id="markdown_editor_textarea" cols="30" rows="30" class="form-control"></textarea>
                </div>
                <div class="col-6 m-1 border">
                    <!-- ここに出力される -->
                    <div id="markdown_preview">
                </div>
            </div>
        </div>
    </div>
@endsection
```


冒頭で説明の通り、javascriptは別ファイルに書くことを想定しているので、blade内にはありません。@section記載で、jsファイルを呼び出すようにします。

```php:create.blade.php
@section('javascript-head')
<script src="{{ asset('js/assets/markdown_jquery.js') }}" defer></script>
@endsection
// contentの前
@section('content')
    //content記述
@endsection
```

今回の場合は、jQueryで書いているので、@section('content')の上部（＝前）に記載しますが、vueやvanillaの場合は、以下のように、下部（＝後）に記述するようです。多分。

```php:create.blade.php
@section('content')
    //content記述
@endsection
// contentの後
@section('javascript-head')
<script src="{{ asset('js/assets/markdown_vue.js') }}" defer></script>
@endsection
```

## 親となるレイアウトのapp.blade.jsを修正

create.blade.phpの@sectionで呼び出したjsファイルを、親となるレイアウトのapp.blade.jsへ渡してあげましょう。app.blade.phpファイルを開き、headタグ内、@yield部分でjavascriptが呼び出します。

```javascript:app.blade.php
<head>
    {{-- 個別のjavaScript読み込み --}}
    @yield('javascript-head')
    
    <!-- Laravel Mix -->
    <link rel="stylesheet" href="{{ mix('/css/app.css') }}">
</head>
<body>
    <div id="app">
        <main class="py-4">
            @yield('content')
        </main>
    </div>
</body>
</html>
```


## jsファイル

jQueryのコードは、直接bladeには書かず、別のjsファイルを作成し、bladeに読み込ませる方法をとりました。ファイルは、resourcesフォルダ傘下の、js/assets/markdown_jquery.jsに配置します。


```javascript:markdown_jquery.js
import marked from 'marked'; // 冒頭に記載を追加
```

すると、markdown_jquery.js に、以下の様な警告（？）表示（？）が出ました。

```javascript:markdown_jquery.js
// hogehoge.js 
'marked' is declared but its value is never read.ts(6133)
```

「宣言したのに、呼び出してないじゃないか！！」というお叱りなのかしら？後で呼び出してあげればそれでいいということなんだと思います。気になって調べてみたら、tsconfig.jsonというファイル内の、noUnusedParametersの部分を、falseへ書き換えてあげると表示は治りました。

```javascript:tsconfig.json
// tsconfig.json
   "noUnusedParameters": false,　// trueになっていたら、falseへ書き換える
```

ちょっと脱線しましたが、話をmarkdown_jquery.jsファイルに戻します。
ブラウザで入力されたテキストを取得してmarked.jsで処理し、表示エリアに出力するプロセスを記述します。これは原書（[マークダウンエディターを5分で作る【Marked.js & highlight.js】]
(https://qiita.com/samuraibrass/items/d40d54aa0754692d5439)）のそのままの記述です。

```javascript:markdown_jquery.js
// marked.jsの呼び出し
import marked from "marked";

$(function () {
    $('#markdown_editor_textarea').keyup(function () {
        var html = marked($(this).val());
        $('#markdown_preview').html(html);
    });
});
```

また、今回はLaravel Mixを体感するという副題があるので、使ってみます。Laravel Mixてなんぞや？というところについては、こちら（[Laravel mix事始め](https://qiita.com/ryosukes/items/24a556b9e634c183f93b)）のQiita投稿を参考にして、進めました。webpack.mix.jsに、今回追加した、markdown_jquery.jsファイルを相対パスで指定します。

```javascript:webpack.mix.js
mix.js([
        'resources/js/app.js',
        'resources/js/assets/markdown_jquery.js', // 第一引数を[]に入れて配列にし、新しく作ったmarkdown_jquery.jsのファイル名を追加する。
    ], 'public/js')
    .sass('resources/sass/app.scss', 'public/css');
```


markdown_jquery.jsファイルの加筆が終わったら、ターミナルで以下のコマンドを実行し、対象ファイルを全てコンパイルして、マークダウン機能の実装は完了です。

```terminal:terminal
// コマンドを実行
$ npm run dev
```

お疲れ様でしたー\( *´ω`* )/