Day.2 BABELがバージョン6系になって盛大にはまった件
もはやAdventCalendarやってませんね。。。
11月後半から鬱状態で休日は用事がない時はずっと家で寝ていました。
そんな時に、業務中に面白そうなアプリ案を思いついて
electron + React + (Redux ?) で実装してみようと思い
何も考えず、npm init
でプロジェクト作成。
JavaScriptなのだからes6を使いたいのでbabel
、gulp
を追加
ここまでは問題なくいつもどおりだった。。。
そして問題は起こった
babel
のバージョンが6系だった
JavaScriptをes6で書いていって、gulp
でタスク追加して
いざテストとして、タスク実行している時に事件は起きた。
es6で書いたJavaScriptがコンパイルされない!!
訳が分からずテストコードを書いてみて、CLIからコンパイルしてみるが
結果は変わらず。。。
$ babel test.js class Person { constructor() { this.name = "arukmn"; } } const obj = (() => { return { log() { alert('Hello Babel!'); } }; })();
やっぱりわけがわからない私は相談してみることに。
解決編
調べてみるとbabel
のバージョン6について下記のようなことが判明した。
- 全体的に色々と修正が加えられていること
React
などを使用する際はpresets
を指定しなければならないpresets
はbabel
とは別にインストールする必要があるpresets
は.babelrc
という設定ファイルに記述しなければならない
ということで、上記の変更点を反映させました。
- 必要な
presets
をnpm i -S
package.json
と同一階層に.babelrc
を作成presets
の設定を記述
私は今回、下記のpresets
をインストールしました。
Presets | Package |
---|---|
es2015 | babel-preset-es2015 |
stage-0 | babel-preset-stage-0 |
React | babel-preset-react |
全ての工程が完了後、再度テストをかけると正常にコンパイルされました。
$ babel src/test.js "use strict"; function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var Person = function Person() { _classCallCheck(this, Person); this.name = "arukmn"; }; var obj = (function () { return { log: function method() { alert('Hello Babel!'); } }; })();
さいご
技術的情報は逐次チェックする事、分かっていたことですが
今あるものがずっと続く訳がない事を再確認しました。
最近はJavaScriptを書けていなかったこともあり
いつもes5を使っていたことも仇になってしまったかもしれません。
さいごに、
コンパイル遅せぇぇ
なんで?なんで?
- [✔] コンパイルがクソ遅い原因が何なのか調査してみる
Day.1 Flux入門
React.jsは以前触っていましたが、Fluxのアーキテクチャについては不勉強だったため、
この機会に入門してみる。
まずはということで簡単なアプリを作ります。
今回勉強のために使わせていただいたのは下記のスライド↓(ありがとうございます)
私の方でもほぼ同一のものを作成しました。
アーキテクチャ
Fluxのアーキテクチャです。
React.jsだけを勉強していた私でも見たことがある有名な図ですね。
図から自明ですが、データの流れが一方向になっています。(Angularとかは双方向でしたよね)
Component
Viewですね。ここでAction(イベント)を呼び出します。
Store(state)が更新されたタイミングでViewが更新されます。
ユーザーは更新を意識する必要はありません。
Action
ここでは、システム的なイベントやユーザー入力(onClick等)等の管理を行います。
この後、Dispatcherへデータを渡します。
その他外部(API)との通信等も行います。
Dispatcher
DispatcherはFluxで提供されているモジュール。
Fluxの中ではコアな部分?
ここで、事前にStoreに登録されているコールバックを呼び出す。
本来はEventEmitterを内包しているのがDispatcherで、
EventEmitterの制御を行っているとのこと。
私自身EventEmitterは全然知らなくて、参考にしている記事からの情報しか知らないので
AdventCalendarのどこかで取り上げたい…
Store
Storeは基本的にデータの管理(state)を行います。
また、ビジネスロジックを記述する部分です。
またはStoreはSetterを持たず、コールバックにて、値の代入などを行います。(Getterはある)
処理に関して
私の理解で記述したファイルの処理を書きます。
自分のためなんじゃ…
※下記にプログラムを掲載しますが、参考記事様のコードとほぼほぼ同一なので
そちらを参照した方がよいかもしれません。
Component -> (Component.js)
今回作成したのは簡単なカウンターなので、
必要なViewは下記の2点のみです。
- カウントするボタン
- カウントを表示するラベル
constructor
- stateの初期値をStoreから取得
- Storeからのコールバックを登録(このタイミングで再描画)
tickメソッド
- Actionの呼び出し
"use strict"; import React from "react" import ActionCreator from "./ActionCreator" import Store from "./Store" import EventEmitter from "./EventEmitter" var dispatcher = new EventEmitter(); var action = new ActionCreator(dispatcher); var store = new Store(dispatcher); export default class Component extends React.Component { constructor(props) { super(props); this.state = { count: store.getCount() }; // Observe store's change store.on("CHANGE", () => { this._onChange(); }); } _onChange() { this.setState({ count: store.getCount() }); } tick() { action.countUp(this.state.count + 1); } render() { return ( <div> <button onClick={this.tick.bind(this)}>Count Up</button> <p> Count: {this.state.count} </p> </div> ); } }
Action -> (ActionCreator.js)
ここではcountUpメソッドが呼び出された際に、
Dispatcherにデータ全て横流ししています。
"use strict"; export default class ActionCreator { constructor(dispatcher) { this.dispatcher = dispatcher; } countUp(data) { this.dispatcher.emit("countUp", data); } }
Dispatcher -> (EventEmitter.js)
下記の指示を行うためのプロセスを登録
- カウンター値の更新
- Viewの更新
"use strict"; export default class EventEmitter { constructor() { this._handlers = {}; } on(type, handler) { if (typeof this._handlers[type] === 'undefined') { this._handlers[type] = []; } this._handlers[type].push(handler); } emit(type, data) { var handlers = this._handlers[type] || []; for (var i = 0; i < handlers.length; i++) { var handler = handlers[i]; handler.call(this, data); } } }
Store -> (Store.js)
??なぜEventEmitterを継承するんだろう…
constructor
onCountUpメソッド
Dispatcherから渡ってきたcountをStoreにて更新
画面を更新指示出しを行っている(emit)
"use strict"; import Emitter from "./EventEmitter" export default class Store extends Emitter { constructor(dispatcher) { super(); this.count = 0; dispatcher.on("countUp", this.onCountUp.bind(this)); } getCount() { return this.count; } onCountUp(count) { this.count = count; this.emit("CHANGE"); } }
さいご
使ってみてFluxの良さわかってません。
自分で考えて作成しようと思います。
ただ、一方向のデータバインディングなのでわかりやすいし、自分のタスクに集中出来る所がいいですね。
一人で雑多AdventCalendarやっぞ
勝手にAdventCalendarやります。
やろうとしてることは下記
- 技術記事(本当になんでもJS中心になるかも。)
- アプリ制作途中経過報告
- 愚痴
最近は私生活というか今後生きていくために
色々と忙しいけどこれくらい出来なくて何がエンジニアなんだってことでやりきってみたい。
初日からサボりそうで怖い・・・・