javascript再勉強のためにreact + ardaでマインスイーパーをつくったので気づきを忘れないようにメモ
一ヶ月近くの有給休暇を経て8/1から完全な無職になりました。前職ではjsといえばviewsに$()
を書きまくるという所業をはたらいておりましたが、railsはapi、フロントは別口でというのが流れであるっぽいので、ちゃんとしたjs作業をしましょうというのが今月のあらすじ。
成果物
うごいてるもの
左右同時押しがMouseEvent
から簡単にとれてびっくりした。
ソース
https://github.com/mmmpa/mine
はじめてつかった
Browserify
とくにBrowserifyはとてもよくて、javascriptのファイル分割に関する知見がまったくない自分でも、簡単に分割と結合が行えるようになっており本当によかった。
Browserifyについて勘違いしていたこと
Browserifyを読み込んでおくとrequire
が使えるようになると思っていた。
しかしそうではなくて、require
を使ったファイルを事前にbrowserify
すればそれが動くように展開したファイルを生成してくれて、結果的に動くという感じだった。
Arda
各コンポーネントからイベントをうちあげてcontextで打ちかえすみたいな流れが綺麗にできた気がしてよかった。
ちょっとしたコードの書き方の参考にもできて本当によかった。
React
乱暴にデータをとりあつかってもよしなにしてくれるので、表示への反映で考えることが大幅に削減されて本当によかった。
さわりはじめるまえにチュートリアル | React(いつのまにか日本語版が)をやって、簡単なページネーションをArdaとともに実装してみてからとりかかりました。
ファイルの書き出しかた
全部まとめるべきか、全部わけるべきか、どれとどれをまとめるべきかなどまったく知識がなかったので、とりあえず自分がさわる場所、さわらない場所などでわけた。
public
├─ js
│ ├─ vendor.min.js
│ ├─ build.min.js
│ ├─ app.js
│ └─ *
│
vendor.min.js
React、Arda、lodashといったフレームワーク的なもので自分が手をくわえない骨格をbrowserifyでrequireした上でuglifyしたもの。
ライセンス記載については渡りに船とばかりに良記事がきていたので参考にできて本当によかった。
React + BrowserifyプロジェクトでJS/CSS/HTMLを圧縮(Minify)する - Umi Uyuraのブログ
licensify+uglifyをgulpる場合はこう。
gulp.task 'vendor', ->
browserify
entries: ['./vendor.coffee']
extensions: ['.coffee']
debug: true
.transform 'coffeeify'
.plugin 'licensify'
.bundle()
.on('error', onError)
.pipe source('vendor.js')
.pipe streamify(uglify
output:
comments: /generated by licensify/
)
.pipe rename('vendor.min.js')
.pipe gulp.dest(publicJsPath)
build.min.js
今回であればマインスイーパー部分の実装をすべてまとめてuglifyしたもの。
app.js
htmlからのアプリケーション起動に関する記述のみ
*
bootstrap paperやfont-awesomeをつかったりしている関係でその他もろもろのファイルがあるけれども、内部の実装にかかわりないものは未加工で配置した。
名前空間と全体からどうやって参照するか問題
グローバル変数汚染よくないというのはふんわりと知っていたが、ほかに解決方法がわからなかったので、ひとつグローバルに定義してそれに生やす感じで解決とした。App
は乱暴すぎるのでもっと他のがよかったかも。
App = {}
App.Context = require './context'
App.Util = require './util'
App.Model = require './model'
App.View = require './view'
module.exports = View = {}
View.Table = require './views/table'
View.Cell = require './views/cell'
View.Fa = require './views/fa'
View.Configuration = require './views/configuration'
View.Preset = require './views/preset'
View.Game = require './views/game'
結果としてこんな呼び出しになった。
detectFace: ->
switch @props.config.state
when App.Model.Table.status.play
'meh-o'
when App.Model.Table.status.win
'smile-o'
when App.Model.Table.status.lose
'frown-o'
ながい。
javascriptのテストをよくわかってない問題
modelのテストは少々mocha?でやったもののよくわからないので未解決。
次
作成中のapiがあるので、それをつかったデータ通信のあるフロントエンドをつくりたい。