0%

Framework7でHTML5モバイルアプリをつくる - Part1: Getting Started

HTML5モバイルアプリ開発のためのFramework7を試してみようと思います。最近はWindows 10もタブレットモードで操作することが多くなりました。WebコンテンツやアプリのUIはモバイル用の方が使いやすく感じるようになってきています。少し調べたところFramework7がネイティブに近い画面をWebで作ることができそうなので、Getting Startedしてみます。

Framework7

Framework7はiOSとAndroidのネイティブ風な画面を作ることができる、HTML/JavaScript/CSSのモバイルWebフレームワークです。iOSとMaterialのテーマが使えます。ドキュメントチュートリアルサンプルも多くそろっているので学習しやすいです。また、ネイティブアプリを作成する前のプロトタイプにも向いているようです。

プロジェクト

Getting Startedの短いチュートリアルを実行するプロジェクトを作成します。リポジトリはこちらです。

基本的には掲載されているコードを少し修正して、ExpressとDockerで動くようにしただけです。

$ cd ~/node_apps/docker-framework7
$ tree
.
├── Dockerfile
├── README.md
├── app.js
├── bower.json
├── bower_components -> /dist/bower_components
├── docker-compose.yml
├── node_modules -> /dist/node_modules
├── package.json
└── public
├── about.html
├── css
├── index.html
└── js
└── index.js

Dockerfile

ベースイメージにio.js3.2を使います。

~/node_apps/docker-framework7/Dockerfile
FROM iojs:3.2
MAINTAINER Masato Shimizu <ma6ato@gmail.com>

RUN mkdir -p /app
WORKDIR /app

RUN adduser --disabled-password --gecos '' --uid 1000 docker && \
mkdir -p /dist/node_modules /dist/bower_components && \
ln -s /dist/node_modules /app/node_modules && \
ln -s /dist/bower_components /app/bower_components && \
chown -R docker:docker /app /dist/node_modules /dist/bower_components

USER docker
COPY package.json /app/
COPY bower.json /app/

RUN npm install

COPY . /app
CMD ["npm","start"]

docker作業ユーザー

npmやbowerはrootで実行しないほうが良いので作業用の「docker」ユーザーを作りました。Dockerホストでコンテナを起動するユーザーと同じuidを指定しています。Dockerホストのカレントディレクトリをコンテナのボリュームにマウントしたときに、直接Dockerホスト上からファイルを修正できるようにしています。

シンボリックリンク

Dockerfile内でnode_modulesbower_componentsはシンボリックリンクを作成して、カレントディレクトリには直接インストールしないようにしています。Dockerホストでも同様にシンボリックリンクを作成してボリュームにマウントしたときにこの2つのディレクトリが隠れないようにします。

$ cd ~/node_apps/docker-framework7
$ ln -s /dist/node_modules .
$ ln -s /dist/bower_components .

docker-compose.yml

docker-compose.ymlは、Dockerホストのカレントディレクトリをコンテナのボリュームにマントしています。またDockerホストの/etc/localtimeもマウントして、コンテナでも同じタイムゾーンが使えるようにします。

~/node_apps/docker-framework7/docker-compose.yml
framework7:
build: .
volumes:
- .:/app
- /etc/localtime:/etc/localtime:ro
ports:
- 3033:3000

サーバーサイド

package.json

dependenciesフィールドにExpressとBowerのパッケージを指定します。scriptsstartフィールドに書いたnode app.jsのコマンドは、DockerfileのCMD ["npm","start"]から実行されます。postinstallフィールドのbower installコマンドは、DockerfileのRUN npm installでサーバーサイドのnpmパッケージをインストールした後に、Bowerでフロントエンドのパッケージをインストールします。

~/node_apps/docker-framework7/package.json
{
"name": "framework7-docker",
"description": "framework7 docker",
"version": "0.0.1",
"private": true,
"dependencies": {
"express": "~4.13.3",
"bower": "~1.5.2"
},
"scripts": {
"start": "node app.js",
"postinstall": "bower install"
}
}

app.js

今回のExpressは、/public/bower_componentsディレクトリから静的ファイルをサーブする目的で使います。

~/node_apps/docker-framework7/app.js
"use strict";

var express = require('express'),
app = express();

app.use(express.static(__dirname + '/public'));
app.use('/bower_components', express.static(__dirname + '/bower_components'));

var server = app.listen(3000, function () {
var host = server.address().address,
port = server.address().port;

console.log('Example app listening at http://%s:%s', host, port);
});

フロントエンド

bower.json

Bowerを使ってframework7のパッケージをインストールします。

~/node_apps/docker-framework7/bower.json
{
"name": "framework7-docker",
"version": "0.0.1",
"private": true,
"dependencies": {
"framework7": "~1.2.0"
}
}

index.html

Getting Startedなので/bower_componentsでインストールしたパッケージを直接参照していますが、gulpからwebpackでビルドしておいた方がよいです。publicディレクトリに配置したフロントエンドのメインプログラムを指定します。

~/node_apps/docker-framework7/public/index.html
    <!-- Path to Framework7 iOS CSS theme styles-->
<link rel="stylesheet" href="/bower_components/framework7/dist/css/framework7.ios.min.css">
<!-- Path to Framework7 iOS related color styles -->
<link rel="stylesheet" href="/bower_components/framework7/dist/css/framework7.ios.colors.min.css">
<!-- Path to your custom app styles-->
<!--
<link rel="stylesheet" href="path/to/my-app.css">
-->
...
<div class="page-content">
<p>Page content goes here</p>
<!-- Link to another page -->
<a href="/about.html">About app</a>
</div>
...
<!-- Path to Framework7 Library JS-->
<script type="text/javascript" src="/bower_components/framework7/dist/js/framework7.min.js"></script>
<!-- Path to your app js-->
<script type="text/javascript" src="/js/index.js"></script>

index.js

index.jsは掲載されているコードをそのまま使います。Option 2をどちらも書いているので、aboutページに移動したときに’Here comes About page`のメッセージが2度表示されます。

~/node_apps/docker-framework7/public/js/index.js
// Initialize app and store it to myApp variable for futher access to its methods
var myApp = new Framework7();

// We need to use custom DOM library, let's save it to $$ variable:
var $$ = Dom7;

// Add view
var mainView = myApp.addView('.view-main', {
// Because we want to use dynamic navbar, we need to enable it for this view:
dynamicNavbar: true
});

// Now we need to run the code that will be executed only for About page.

// Option 1. Using page callback for page (for "about" page in this case) (recommended way):
myApp.onPageInit('about', function (page) {
// Do something here for "about" page

});

// Option 2. Using one 'pageInit' event handler for all pages:
$$(document).on('pageInit', function (e) {
// Get page data from event data
var page = e.detail.page;

if (page.name === 'about') {
// Following code will be executed for page with data-page attribute equal to "about"
myApp.alert('Here comes About page');
}
});

// Option 2. Using live 'pageInit' event handlers for each page
$$(document).on('pageInit', '.page[data-page="about"]', function (e) {
// Following code will be executed for page with data-page attribute equal to "about"
myApp.alert('Here comes About page');
});

実行とiOSから確認

docker-composeからDockerイメージのビルドとコンテナの起動を行います。

$ docker-compose build
$ docker-compose up framework7

iOSのSafariからdocker-compose.ymlに指定したDockerホストの3033ポートを開きます。/public/js/index.jsのコードはAbout appをクリックした後のabout.htmlで実行されます。

framework7-index.png

ページのロード時にmyApp.alert('Here comes About page');が2回実行されます。

framework7-about.png