dayjournal memo

Total 977 articles!!

Try #010 – Riot.jsとMaterializeとwebpackでSPA環境構築してみた

Yasunori Kirimoto's avatar

画像


画像


画像



この記事は、「Riot.js Advent Calendar 2017」の23日目の記事です。

お仕事で、Riot.jsMaterializewebpackでwebアプリを構築した時の環境構築のメモ。


ビルド環境をGitHubでも公開しています。Riot.jsを手軽に始めたい方ぜひご利用ください。

riot-starter


実際に構築したwebアプリは、この環境にDynamoDBを追加利用してます。できるだけサーバーレスでSPAを構築しています。



画像



ディレクトリ構成


画像


package.json


{
  "name": "riot-starter",
  "version": "1.0.0",
  "description": "",
  "main": "main.js",
  "scripts": {
    "build": "webpack"
  },
  "keywords": [],
  "author": "Yasunori Kirimoto",
  "license": "ISC",
  "devDependencies": {
    "riot": "^3.6.1",
    "riot-hot-reload": "^1.0.0",
    "riot-tag-loader": "^1.0.0",
    "webpack": "^3.5.4"
  },
  "dependencies": {
    "css-loader": "^0.28.7",
    "style-loader": "^0.18.2",
    "url-loader": "^0.5.9",
    "file-loader": "^1.1.4",
    "jquery": "^2.1.4",
    "materialize-css": "^0.100.2",
    "ress": "^1.2.2",
    "riot-route": "^3.1.2"
  }
}


webpack.config.js


var webpack = require('webpack');

module.exports = {
    entry: './_resouce/main.js',
    output: {
        path: __dirname + '/dist',
        filename: 'app.js'
    },
    module : {
        rules : [
            {
                test: /\.tag$/,
                exclude: /node_modules/,
                loader: 'riot-tag-loader',
                query: {
                    hot: true,
                    debug: true
                }
            },
            {
                test: /\.css/,
                loaders: ['style-loader', 'css-loader']
            },
            {
                test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
                loader:"url-loader?limit=10000&mimetype=application/font-woff"
            },
            {
                test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
                loader: "file"
            }
        ]
    },
    plugins: [
        new webpack.optimize.UglifyJsPlugin({
            compress: {
                warnings: false
            }
        }),
        new webpack.ProvidePlugin({
            riot: 'riot',
            $: 'jquery',
            jQuery: 'jquery',
            'window.jQuery': 'jquery'
        })
    ]
};


./_resouce


main.js


// JS一式を読み込んでパッケージ
import {sample01} from './js/sample01.js';
import {sample02} from './js/sample02.js';

// CSS一式を読み込んでパッケージ
import 'ress/ress.css';
import 'materialize-css/dist/css/materialize.css';
import './css/icon.css';
import './css/style.css';

// materialize(JS)を読み込んでパッケージ
import 'materialize-css';

// riot-route読み込み(v3からRiot.jsに既存では入っていない)
import route from 'riot-route';

// 入力画面を読み込んでパッケージ
import './tag/input_page.tag';
// ルートページに割り当て
route('/', function() {
    riot.mount('app','input_page', {
        type: 'input',
        sample01: sample01
    });
});

// 結果画面を読み込んでパッケージ
import './tag/output_page.tag';
// #outputに割り当て
route('/output', function(){
    riot.mount('app', 'output_page', {
        type: 'output',
        sample02: sample02
    });
});

// ルータースタート
route.start(true);


./_resouce/css

iconフォントファイルも準備

  • MaterialIcons-Regular.woff
  • MaterialIcons-Regular.woff2

style.css


html, body {
    background-color: #FFFFFF;
    color: #383838;
}


icon.css


@font-face {
    font-family: 'Material Icons';
    font-style: normal;
    font-weight: 400;
    src: url(MaterialIcons-Regular.woff2) format('woff2'),
         url(MaterialIcons-Regular.woff) format('woff');
}

.material-icons {
    font-family: 'Material Icons';
    font-weight: normal;
    font-style: normal;
    font-size: 24px;
    line-height: 1;
    letter-spacing: normal;
    text-transform: none;
    display: inline-block;
    white-space: nowrap;
    word-wrap: normal;
    direction: ltr;
    -webkit-font-feature-settings: 'liga';
    -webkit-font-smoothing: antialiased;
}


./_resouce/js


sample01.js


export function sample01() {
    var sample = "sample01 実行";
    console.log(sample);
}


sample02.js


export function sample02() {
    var sample = "sample02 実行";
    console.log(sample);
}


./_resouce/tag


input_page.tag


<input_page>

    <div class="row">
        <div class="container">
            <div class="col s12 center">
                <p>
                    Riot Starter
                </p>
            </div>
            <div class="col s12 center">
                <button class="btn waves-effect waves-light light-blue darken-4" type="button" name="action" onclick={click}>
                    Go
                    <i class="material-icons left">
                        done
                    </i>
                </button>
            </div>
        </div>
    </div>

    <style scoped>

        p {
           font-size: 40px;
        }

    </style>

    <script>

        // ページ読み込み時処理
        this.on('mount', function() {

            // 関数読み込み
            var sample01 = opts.sample01;

            // 関数実行
            sample01();

        });

        // ボタンクリック時処理
        this.click = function() {

            // 出力ページへ移動
            location.href = "/#output";

        }.bind(this);

    </script>

</input_page>


output_page.tag


<output_page>

    <div class="row">
        <div class="container">
            <div class="col s12 center">
                <p>
                    Output
                </p>
            </div>
            <div class="col s12 center">
                <i class="large material-icons">
                    hot_tub
                </i>
            </div>
        </div>
    </div>

    <style scoped>

        p {
            font-size: 60px;
        }

    </style>

    <script>

        // ページ読み込み時処理
        this.on('mount', function() {

            // 関数読み込み
            var sample02 = opts.sample02;

            // 関数実行
            sample02();
        });

    </script>

</output_page>


./dist

app.jsとフォントファイルは自動でビルド


index.html


<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Riot Starter</title>
</head>
<body>
    <app></app>
    <script src="./app.js"></script>
</body>
</html>


ファイルの準備ができたら対象ディレクトリでコマンド実行


パッケージインストール


npm install


ビルド



npm run build

ローカルサーバーを立ち上げて確認すると表示される。


Riot.jsについて、他にも記事を書いています。よろしければぜひ。
tags - Riot.js



book

Q&A