webpack2でReactを使う

webpacke2でReactの開発環境を作る。

フォルダ・ファイルを作る

$ mkdir react1
$ cd react1
$ mkdir src
$ mkdir public
$ touch public/index.html
$ touch src/index.js
$ touch webpack.config.js
$ touch postcss.config.js

インストール

$ npm init -y
$ npm i -D webpack webpack-dev-server
$ npm i -D babel-loader babel-core babel-plugin-syntax-dynamic-import babel-preset-es2015 babel-preset-react
$ npm i -D extract-text-webpack-plugin
$ npm i -D style-loader css-loader postcss postcss-loader autoprefixer cssnano precss react-css-modules
$ npm i -D react react-dom

package.jsonは下記のようになった。

webpack.config.jsを作る

postcss.config.jsを作る

public/index.htmlを作る

src/index.jsを作る

webpackを実行する。実行後、public/bundle.jsが作成される。

$ webpack

webpack-dev-serverを実行する。実行後、http://localhost:8080にアクセスすると確認できる。

$ webpack-dev-server

手書き文字を作れるJavascriptをつくってTensorFlowで予測させてみた(2)

この前、「手書き文字を作れるJavascriptをつくってTensorFlowで予測させてみた」という投稿でブラウザ上で手書きした文字画像を、MNISTで訓練したモデルで予測してみましたが、ものすごく精度が悪かったです。今回改めて、CNNを使ってやってみたらかなり精度が上がりました。何%か測ったりしてませんが、自分の手書きだと90%は超える感じでした。やっぱりCNNはすごいなーと思いました。でももしかしたら前回のものにミスがあり、CNNではなくても精度は本当はもっと高い可能性はあります。

もうちょっとやるとしたら、文字を画像の中心に適度な大きさで書く必要があり、例えば右上に小さく2と書いても認識されません。あとは、現在はMNISTに合わせて、手書き文字画像も背景黒、文字色白で作成するように固定していますが、これらの色を変えても認識するようにしたいです。今度やってみます。

Github

https://github.com/endoyuta/mnist_test

index.html

cgi-bin/mnist.py

cgi-bin/mytensor.py

手書き文字を作れるJavascriptをつくってTensorFlowで予測させてみた

MNISTでテストしているだけだと味気ないので、ブラウザで数字を手書きして、それを予測するようにしてみました。JavascriptのCanvasでお絵かきアプリみたいのを作って、そこに手書きで数字を書いてボタン押したら、28×28に縮小して、Base64の状態でサーバに送ります。サーバでPythonが、numpyの配列にして、TensorFlowに渡して推測しております。

多分やり方は大体あってるのではないかと思ってるのですが、いかんせん精度が超悪いです。そもそもまだTensorFlowがCNNになっていないのですが、それでもMNISTで学習・テストすると97%位にはなっているものです。背景黒・文字色白で0-255の明るさを28×28もつ配列にしているので、形式は合っているはずなのですが、やはり文字の太さとか大きさとかそういうのによって、全然違うということなのかなと思っております。ブラウザで割と適当に数字を書いてもいい感じの精度で答えを言ってくるのかなと期待していたので残念です。とりあえず、今度CNNで対応してみて、それでもダメだったら、Javascriptの画像自体で訓練をしていくようにしてみようかなと思ってます。(何か根本的な原因がありそうな気もしますが)

GitHub

一応GitHubに入れておきました。誰か精度よくしてくれたら嬉しいです。

追記(2017/01/25)
上記のリポジトリは、「手書き文字を作れるJavascriptをつくってTensorFlowで予測させてみた(2)」の内容に更新しました。

PythonでWEBサーバ起動して、必要なディレクトリ・ファイルを作成

各ファイルの中身を作成

index.html

cgi-bin/mnist.py

cgi-bin/mytensor.py

ブラウザでアクセス

下記URLにアクセスすると、MNIST TESTというお絵かきページみたいのがでてきます。ちなみに、最初にsubmitボタン押すと、MNISTのダウンロードから学習までをするので、時間かかるし、結果も表示されません。2回目からはちゃんと結果が(一応)表示されます。

cordova + onsen ui + reactの開発環境

cordova + onsen ui + reactの開発環境を作成してみます。cordovaのテンプレートにして、メンテしていければと思います。環境は、windows10、npm3.10.8です。エディタは、visual studio code1.6.1を使ってます。

プロジェクトを作る

npmはインストール済みです。

必要なものをnpm install

下記のpackage.jsonを配置して、npm installを実行。

git

.gitignoreを編集

cordovaにプラットフォーム追加

babelの設定

.babelrcを編集

eslintの設定

.eslintrcの編集

.eslintignoreの設定

webpackの設定

元となるjsを入れるフォルダを作る

webpack.config.jsの編集

index.htmlの作成

www/index.html

Javascriptの作成

onsen ui + reactを使った簡単なjavascriptを作成してみる。

src/App.jsx

src/main.jsx

webpackする

webpackすると、www内に、assetsと、bundle.jsと、main.cssが出力される。

webpack-dev-serverを使う

webpack-dev-serverを使っていると、ウォッチしてくれて、対象ファイルに変更があると、webpackしなおして表示してくれる。
webpackした結果は、メモリに保存されるので、www内への展開はされない。

screen

Androidの実機で確認する

webpack + eslint

webpackでeslintを使う場合、eslintとは別に、eslint-loaderをインストールする必要があります。

インストール

そして、webpack、eslintそれぞれの設定ファイルを作成します。

webpackの設定

下記のように、webpack.config.jsを設定します。
moduleのpreLoadersにeslint-loaderの設定を書きます。moduleは、eslint-loader等の-loaderを省略できます。あと、下の方にあるeslintというところで、eslintの設定ファイルを指定します。eslintrc.jsonとか、.eslintrcというファイル名であれば指定は不要かもです。

eslintの設定

eslintのルールは沢山あって自分でルールを使うかどうか決められますが、AirBnBのルールが人気だし、そういうところに合わせておいて悪いことはないと思うので、基本AirBnBを使います。ただ、Reactとbabelを使っているときに沢山エラーがでたので、ちょっと修正しました。AirBnBのルールを使いつつ、このエラーは出なくてもいいやと思ったら、ルールを無効にして調整してます。まだ、使いだしたばかりなので、単なる一例です。

.eslintrc

jsx拡張子に関するルール

reactはjsxを使いますが、jsxを使っているファイルの拡張子はjsxにしないと、AirBnBルールに怒られます。jsxを使っていないファイルはjsのままだと思うので、拡張子がjsとjsx共に、webpackがjavascriptに対して実行する処理を適用させるようにしてみます。

該当ファイルの拡張子をjsxに変更し、webpack.config.jsを下記のように修正します。

eslint

ESLint

参考:ESLint 最初の一歩

ESLint は JavaScript のための静的検証ツールです。コードを実行する前に明らかなバグを見つけたり、括弧やスペースの使い方などのスタイルを統一したりするのに役立ちます。同様のツールとしては JSLint, JSHint 等があります。

インストール

package.jsonの設定

グローバルインストールでないので、npmから実行できるようにします。
package.jsonのscriptsを下記のようにします。

初期化(設定ファイルの作成)

eslint –initで対話的に設定ファイルが作成できます。グローバルインストールでないので、eslint –initというコマンドがそのままは使えない為、上記で設定したnpmのscriptsを使います。設定ファイルの作成が終わったら、上記のlint-initは不要です。

色々聞かれたので、popularのAirBnBのjsonにとりあえずしてみました。設定ファイル、.eslintrc.jsonが出力されます。
.eslintrc.jsonの中身

jsファイルを適当に作ってみる

hoge.js

使ってみる

使えました。下記が表示されました。

おー厳しい。

どんなルール設定にしたら最適なのでしょうか?
とりあえずAirbnbに合わせることはいいことだとは思いますが。あと、改行文字とか、ブロックの前にスペース空けるとかは、自動整形とかあると便利なのですが、あるのでしょうか?

結構Airbnbは人気みたい。
visual studio codeでは、Shift+Alt+Fで自動整形できる。拡張機能にeslintもあるし、eslintの設定は、eslintrc.jsonを読んでくれる。eslintはデフォルトで、node_modulesの中はみないとどこかに書いてあったんだけど、visual studio codeのeslint拡張は見ちゃうみたい。.eslintignoreで設定したら消えた。改行文字もvisual studio codeの設定変更した。これでエラー消えた。

npmでパッケージ管理

参考:npmでnode.jsのpackageを管理する

npmパッケージ管理の初期化

-gは、グローバルインストール。

–save-devは、自動でpackage.jsonに追記される。
空白をあけてつなげると複数インストールできる。
-gをつけないと、プロジェクト毎にインストールされて、node_modulesフォルダに入る。

node_modulesはgitで管理する必要ない。npm installとすると、package.jsonに記載されている内容がインストールされる。

devDependenciesというのは開発時のみ利用するlibraryのversionを管理します。
libraryとして公開するようなprojectだと、–saveになります。

ということは、開発時のみ利用するライブラリを、npm i –save-dev hogeとやるということだろうか。本番時も使う場合は、npm i –saveということかな?babelとかreactとかは全部開発時しか使わないか。

npmはscriptというのもあって、コマンドが実行できるっぽい。
参考:npm script を試す (サンプル付き忘備録)

scriptを使って、webpackの代わりになるものを作る人も最近多いらしい。scriptの使い方は、package.jsonのscriptsに書いて、npm run buildとかやるらしい。試してみたけどエラーになった。-sをつけるとエラーがでなくなるらしい。

ちなみに、babelのドキュメントに、buildというスクリプトのサンプルがあって、下記のように書いてある。
babel src -d lib
これを実行したら、src doesn’t existといわれた。

babelのドキュメントに解説があった。
babelはbabelの投稿にまとめる。

babel

babel

babel-cliは、コマンドラインで使えるやつらしい。

es2015に変換するには、babel-preset-es2015が必要らしい。

さらに、.babelrcというファイルに、presetを記載する必要があるらしい。

下記を実行したら、es2015に変換された。

react用のやつもためしてみる。
reactのjdx使っているコードかいて$babel hoge.jsとやっても今はエラーになる。
.babelrcのpresetsにreactを追加して、下記を実行すると変換できた。

babelのドキュメントに色々使い方が書いてある。

出力ファイルを指定できるらしい。

npmのscriptで実行できるか試してみる。
package.jsonに下記のbabelを追加する。

下記で、babelを実行したらできた。–out-fileは、-oでもいいらしい。

あと、ウォッチもできるらしい。–watchだけど、-wでもいいらしい。

おー便利だ。

ソースマップというのも出力できるらしい。
参考:Babelで始める!モダンJavaScript開発

SourceMapを使うことで変換前のコードと変換後のコードを対応付けることができるため、実行時に問題が発生しても元のソース上でどこに問題があったのかを容易に把握することができます。

BabelのsourceMapsオプションはソースコードと同時にsourceMapファイルを出力することができ、trueを指定した場合変換後のソースとは別にsourceMapファイルを、”inline”を指定した場合変換後のソースファイルにsourceMapファイルを埋め込んで出力できます。

デバッグしたりするときに便利なんでしょうか。とりあえず出力してみる。

script.js.mapというのが出力された。jsファイル毎に元になるファイルを教えてくれるやつらしい。

–out-dirというのはコンパイルしてくれるらしい。-dでもいいらしい。

これは、src内のjsファイルをすべて変換して、libに出力してくれる。ファイル名は同じ。

–out-fileは、ディレクトリ内のjsファイルを一つのファイルに出力してくれる。

Reactの開発環境

node.jsをインストールして、npmも最新版にする。
npmでプロジェクトつくって、下記をインストールする。

reactは、jdxを使うのが基本で、ES6の書き方でjdxを使って書いたものを、babelを使って、ES5のjsに変換する。webpackとbabelを連動させて、webpackで自動的に変換できるようにする。CSSはsassを使って書いて、これもwebpackを使って変換する。全てnpmでインストールできて、npmはpackage.jsonというファイルで、必要なパッケージとそれらのバージョンと依存関係を管理する。npmでインストールしたものは、自動的にpackage.jsonに反映される。必要に応じて手動でメンテナンスすることで、自動的な開発環境を構築する。あとはこれをgitで管理すればみんなで開発できる。大体こんな感じでやっていく。ReactはAngularと違って、オールインワンな感じのフレームワークではなく、基本viewに特化したフレームワーク?であり、大規模なシステムをつくる場合は、Reduxを使うといい。

あと、これらの開発環境セットアップをコマンド一発で完了できるcreate-react-appをfacebookが作ったらしい。

参考サイト:
10年のツケを支払ったフロント界隈におけるJavaScript開発環境(2016年4月現在)。
もうはじめよう、ES6~ECMAScript6の基本構文まとめ(JavaScript)~
npmとpackage.json使い方
webpackを使ってJSとCSSをコンパイルする(ES6 / Sass)
webpack で始めるイマドキのフロントエンド開発
babelとwebpackを使ってES6でreactを動かすまでのチュートリアル
Webpackでイチから作るReact.js開発環境
Reduxの実装とReactとの連携を超シンプルなサンプルを使って解説
コマンド一発でReactの開発環境を構築してくれるFacebook製ツール「create-react-app」

Node.js

Node.jsやってみる。

macは、El Capitan 10.11.5です。

ここでNode.jsをダウンロードしたり、ドキュメントを取得できたりする。
http://nodejs.jp/nodejs.org_ja/
Node.js v0.11.11 マニュアル & ドキュメンテーション

Node.jsは、サーバ側の言語。Nginxとかを使わないらしい。

(引用:いまさら聞けないNode.jsの基礎知識とnpm、Gulpのインストール (1/2)

これでWEBサーバ作ったことになる。Node.jsはWEBサーバで、nginx.confみたいなのが上記なんでしょうか??とりあえずやってみる。

~/nodejs/app.jsを作って、上記を書いた。その後、下記を実行。

おー表示された。

nodejs

モジュール管理は、npmでやる。
ビルドツールは、GruntとかGulpとかでやるんだけど、最近はちょっと嫌われているようで、使わないでやるケースも多いらしい。Gulpのがまだ人気あるらしい。

npmでgulpをグローバルインストールする

gulp用ディレクトリを作って、そこにgulpをインストールする

gulpfile.jsを作成してみる。

gulp実行

ファイルを追加したり、変更したり、削除したりすると、eventを検知して、event.path、event.typeとかが取得できる。これをもとにテストしたり、コンパイルしたりするんだろう。

ただ、上記コードだと、結構な頻度でエラーが出る。try-catchとかしっかりしたらOKになるのだろうか。

ここにあるコンテンツとドットインストールみたらいいかも。
「Node.jsでサーバサイドJavaScript開発入門」

Backbone.js Marionette イベント 他View間の連携

参考:Event Aggregator

アプリに、vent.onというのを使って、イベント発生時の挙動を登録する。あとは、登録したイベントを発生させたいところで、vent.triggerする。

他のView間で連携する場合は、Viewのinitialize関数で、下記のようにやる。

このViewのインスタンスが作成されるときに、initalize関数が呼ばれますが、そのときにHogeHogeというイベントが発生したら、このViewのhogeを実行するよと、登録している。あとは、他のViewで、App.vent.trigger(‘HogeHoge’);とやると、HogeHogeイベントが発火する。

Backbone.js ModelのSave

model.save(data, options);
第一引数は、登録するデータ。nullならモデルにセットされているデータが使われる。optoinsはsuccessとかerrorとか。

saveのrequest dataは、phpでうまく取得できない。cakePHPでサーバ側のコードをつくったけど、$this->request->data等が空になる。
参考:Backbone.js Model.save()によるPOSTデータをPHPで読み込む
ここに記載されている、“php://input”を使うと出来た。

Backbone.js(Marionette) – CollectionViewとCompositeView

ItemViewはシンプルだけど、collectionViewとcompositeViewというのがあるので、使い分けを確認する。

参考1:Marionette.jsまとめ その3 CompositeView, Layout, Region

CompositeViewは、テンプレートを設定することができるらしい。CollectionViewは、テンプレートを設定できない。では、CollectionViewの一般的使い方を確認します。

CollectionViewの使い方

参考2:Marionette.jsまとめ その2 View, ItemView, CollectionView

下記は、上記参考2の引用です。

ItemViewをセットして、CollectionViewが紐づくエレメントを指定する感じです。#fooList内に、#itemTemplateがcollectionが保持するModel分出力される感じになります。単純ではあります。

テンプレートをもうひとはさみしたい的な感じに、CompositeViewを使います。

CompositeViewの使い方

下記は、上記参考1の引用です。

多分、#listTemplateの中にある、#fooListの中に、collectionが保持するModel数分、FooItemViewを出力されます。そして、#listTempalteが、#mainの中に出力されます。って感じだと思う。

ちなみに、#foolistが、<ul>の場合、ItemViewのtagNameは、”li”にする必要があります。tagNameを設定しないとデフォルトでは、<div>で囲われますので、下記みたいな感じになってしまいます。

画面の高さに画像サイズを合わせる

トップページのでっかい画像を画面の高さに合わせることで、スマホでもPCでも最初の表示は画面全体に画像が表示されるようにしたい。

画面の高さは、$(window).height()なんじゃないかと思っている。だから最初に、$(‘#top_img’).height($(window).height())みたいにすればいいだけなのではないかと思っております。しかし、画面リサイズ時の画像サイズ調整も考えた方がいいかもしれない。画像を入れるdivと、画像自体のサイズを変更しないといけないかもしれない。

HTML

CSS

.top_boxの背景画像は、別のところで設定している。

Javascript

これだけ。画像リサイズは考慮しなくていいと思った。

スマホでfixedをサポートするのはめんどくさい

参考:
iPhone、Android position:fixed 対応状況と対応方法
Fixed固定ナビゲーションを設置するときに気をつけたい4つのこと
user-scalable=noを使う理由と弊害(スマホのviewportを見直す)

スマホではfixedがサポートされていないのがある。ios5から対応していて、Android 4.1は対応しているらしい。Android 2.3は、viewport で、content=”user-scalable=no” にすると対応されるらしい。あら、自分のAndroidは、4.1.2となってるが、fixedには対応されていないな。user-scalable=noを設定してもうまくうごかない。

今時点では確かにfixed使うと問題が多いなあ。解決は、jQuery Mobileとか、iScrollとかいうのを使う必要があるらしい。Bootstrapは大丈夫だった気がするが、あれは上記のようなツールと同じように、javascript含めて色々な調整がされているのかもしれない。

とりあえず、スマホでfixed使うのやめることにしよう。画面狭くなるしな。