Edited at

Laravel5.5 Riot.jsのセットアップ


概要

Laravel+Riot.jsを使ってみたかったのでその環境構築準備。

まともに使用したことがないので、より良い方法があったら指摘いただけると嬉しいです。

(yarnを使用しているので、npmの人は読み替えてください。)

この辺りを参考に上手く動かなかったので、試行錯誤した結果こうなった。

https://qiita.com/B73W56H84/items/b9968bd97e3128d891d0


環境

Laravel 5.5.42

PHP 7.1.16


プロジェクト作成およびライブラリ追加

# プロジェクト作成

composer create-project --prefer-dist laravel/laravel riot-demo "5.5.*"

# デフォルトで入っているものを削除(bootstrap, jQuery, vueなど)
php artisan preset none

# bootstrapが必要なら戻す
php artisan preset bootstrap

# laravel用のriotライブラリを追加
yarn add laravel-mix-riot


アセットコンパイル周りのソースを修正


app.js

require('./bootstrap');

// ここから下を追加
window.riot = require('riot');



webpack.mix.js

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

mix.riot = require('laravel-mix-riot');

/*
|--------------------------------------------------------------------------
| Mix Asset Management
|--------------------------------------------------------------------------
|
| Mix provides a clean, fluent API for defining some Webpack build steps
| for your Laravel application. By default, we are compiling the Sass
| file for the application as well as bundling up all the JS files.
|
*/

mix
// riotに変更
//.js('resources/assets/js/app.js', 'public/js')
.riot('resources/assets/js/app.js', 'public/js')
.sass('resources/assets/sass/app.scss', 'public/css')
;



Todoアプリを実装

riot.jsの公式ページにあるTodoアプリを実装してみる。

https://riot.js.org/ja/play/todo/


resources/assets/js/todo/todo.tag

<todo>

<h3>{ opts.title }</h3>

<ul>
<li each={ items.filter(whatShow) }>
<label class={ completed: done }>
<input type="checkbox" checked={ done } onclick={ parent.toggle }> { title }
</label>
</li>
</ul>

<form onsubmit={ add }>
<input ref="input" onkeyup={ edit }>
<button disabled={ !text }>Add #{ items.filter(whatShow).length + 1 }</button>

<button type="button" disabled={ items.filter(onlyDone).length == 0 } onclick={ removeAllDone }>
X{ items.filter(onlyDone).length } </button>
</form>

<!-- this script tag is optional -->
<script>
this.items = opts.items

edit(e) {
this.text = e.target.value
}

add(e) {
if (this.text) {
this.items.push({ title: this.text })
this.text = this.refs.input.value = ''
}
e.preventDefault()
}

removeAllDone(e) {
this.items = this.items.filter(function(item) {
return !item.done
})
}

// an two example how to filter items on the list
whatShow(item) {
return !item.hidden
}

onlyDone(item) {
return item.done
}

toggle(e) {
var item = e.item
item.done = !item.done
return true
}
</script>

</todo>



resources/assets/js/app.js

require('./bootstrap');

window.riot = require('riot');

// 追加
require('./todo/todo.tag');



resources/views/welcom.blade.php

<!doctype html>

<html lang="{{ app()->getLocale() }}">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="csrf-token" content="{{ csrf_token() }}">

<title>Demo: Riot.js</title>
<link rel="stylesheet" href="{{ mix('/css/app.css') }}">

<style type="text/css">

body {
font-family: 'myriad pro', sans-serif;
font-size: 20px;
border: 0;
}

todo {
display: block;
max-width: 400px;
margin: 5% auto;
}

form input {
font-size: 85%;
padding: .4em;
border: 1px solid #ccc;
border-radius: 2px;
}

button {
background-color: #1FADC5;
border: 1px solid rgba(0,0,0,.2);
font-size: 75%;
color: #fff;
padding: .4em 1.2em;
border-radius: 2em;
cursor: pointer;
margin: 0 .23em;
outline: none;
}

button[disabled] {
background-color: #ddd;
color: #aaa;
}

ul {
padding: 0;
}

li {
list-style-type: none;
padding: .2em 0;
}

.completed {
text-decoration: line-through;
color: #ccc;
}

label {
cursor: pointer;
}
</style>
</head>
<body>

<todo></todo>

<script src=" {{ mix('js/app.js') }} "></script>
<script>
riot.mount('todo', {
title: 'I want to behave!',
items: [
{ title: 'Avoid excessive caffeine', done: true },
{ title: 'Hidden item', hidden: true },
{ title: 'Be less provocative' },
{ title: 'Be nice to people' }
]
})
</script>
</body>
</html>


# アセットのコンパイル

yarn run dev


実行

スクリーンショット 2018-09-13 0.35.28.png