isomorphic tokyo meetupの感想とメモ・資料 #isomorphic_meetup
ニフティの場所難易度高い&都庁前駅でGoogleマップ使ったら現在地が御徒町になるなどのトラブルがあり、最初の発表の半分くらいを聞き逃したorz
感想
- 真のIsomorphic(Truly Isomorphic)ってのがよくわかってなかったが、「IsomorphicってServer Side Renderingのことっしょ?」に対する「いやいや、Viewだけじゃなくて全部が両方で動くことやで」みたいな理解であっていますでしょうか?
- @koichikさんの歴史から辿っていく感じの発表が非常に面白くて、聞き逃したのが本当に悔やまれる
- Mojitoを結構触っていた時期があったので、Mojitoという言葉が出てきた時点でかなり高まった
- Rendrは結局触ってないなーと思ったけど、React、Fluxが出てきてもう今からは手を出さなくてもいいかなという気持ち
- Fluxibleは出た頃にちょっと触って「あーこれちょっとゴツイなー」と思って追っていなかったが、Fetchrはよさそうなので、他のFlux実装と組み合わせて使いたい
- Scala.jsの話はピザ食いながらだったのでメモあまり取れなかった。
- Scala好きだったらすごく楽しい発表だったろうなー。
- 興味はあるので、取っ掛かりとしてScala.js使ってみようかな
- APIリクエストの型判定(で合ってるか?)の話とか、BinaryでSerializeして渡すやつの話はすごい面白かったー。
- Service WorkerをタダのキャッシュとかProxyやろと思っていたところがあるが、mizchiさんやJxckさんみたいなFEとBEの中間のレイヤとして捉えて、FEのインターフェースを考えなおすみたいな発想(なんか既にうまく説明できてない)はしたことなかったし、あんまり重要と思っていなかったので、再考したい。
「あー早く帰ってコード書きたい&読みたいー!」みたいな感じになる、すごくいい勉強会だった!! が、Isomorphicは結構追っていたのに理解力が追い付いていない部分が多々あり、危機感を感じたので、本日の資料を見ながらよく考えねばと思った。
以下、メモや資料
「Isomorphic Survival Guide」 by @koichik
(遅刻したため、途中からしか聞いてない。。)
先駆者
- Flation(Nodejitsu)
- http://flatironjs.org/
- 生みの親
- 小さなIsomorphicライブラリの集まり
- 忘れられた存在
- Mjito(Yahoo)
- Yahooほぼの規模がないとねー
- Meteor
- Minimongo
- PhantomJSでサーバサイドレンダリング
- Isomorphicと呼んでいいか微妙
- backendをclientとserverで使う
- Truly Isomorphic
- だいぶ小さなライブラリになりそうな気がする
課題が重要
- Isomorphicの先駆者がぱっとしてない
- Flatiron 課題が不明瞭
- Mojito 課題がニッチ
- Meteor 人類には早い
Rendr
- Airbnb
- Backboneベース、フロントエンドのIsomorphic
- SPAの課題解決
- BackboneのIsomorphic化
- レンダー用のServer(JS)は何と呼べばいいのか?
- rendering server?
- 否。
- BEサーバとproxyするmiddlewareが提供されていた
- Backendがステートレスにできる
- Orchestration
- Server(JS)とBEが1対多
- microservice
- http://microservices.io/patterns/apigateway.html
- Rendrはなぜ流行らなかったか?
- Angularがめっちゃ流行ってた時期。
React
- みんな、知ってるよね?
- Flux オレオレ実装乱立
- flux comparison
- Singleton free
- FacebookはStore, Dispatcherをシングルトン推奨
- サーバではリクエスト毎にデータを共有してしまうのでダメ
- Store, Dispatcherをシングルトンにしてない実装が多い
- contextにまとめる
- Routing
- React Router
- Flatiron Director
- Fetching
- superagent
- isomorphic fetch
- 実装
- Flummox
- Fluxible
- Yahoo
- 重厚
- Pluggable
- Routr, Fetchr, Dispatchr
- ↑はFluxibleには依存してないのでfluxible-*系を使う
- 結構大きく変えている
- Fetchrの旨味
- Serviceというオブジェクトを直接呼び出す
- NOT Isomorphic, Server side ONLY
- Client sideの場合はAPI経由で呼び出す
- fetchrが提供するexpress middleware
まとめ
- FE/BEをC/S両方で動かしてブレークスルー
- 共通化
「Isomorphic Web development with Scala & Scala.js」 by @TanUkkii
www.slideshare.net
- Web FE Engineer
- C/S間で
- 開発環境の共有
- Motivation
- 開発環境の共有
- addSbtPluginでscala-jsを
「実践isomorphic(+ Electron)」 by @mizchi
- @mizchi
- isomorphicの目的(個人的な)
- 一昔前→JSとJQueryの区別がなかった時代
- ex) marked
- node, browser, workerでも動く
- PhantomJSへの敵意
- 不安定、重い
- グローバル空間
- window, global, self
- 環境依存
- document, navigator, setImmediate などなど
- require
- 実際には
- node, browserのみ対応していれば
- ネイティブモジュールは使えない
- どうしてもの場合は、emscripten
- commonjs
- webpack browserify, require1k, duojs
- ASTを変換する
require(変数)
ができないとかある
- lib以下にフラットなJSを吐く
- 単体でテストできるように
- watchifyつかえ
- インクリメンタルビルド
- ES6のimport/export
- babelはrequire
- TypeScriptはexport defaultは未対応
- Electron
- Electronでのbrowserify
- node_modulesの中で必要な物だけ欲しい
- 250MB -> 2.2MB
- 一部browserify出来ないものは、
global.require('app')
する- bad knowhowやけどな
- DOMとは
- Electronのいいところ
- 環境の固定
- NetworkのIsomorphic
- Service worker内でExpress likeなrouter
- mizchi/sabizan
「Unified Interface on Isomorphic JavaScript」 by @axross_
www.slideshare.net
- @axross_
- Asaiさん
- 社内ツールでIsomorphicした話
- Try
- IF統一、Validator統一
- Interface統一
- SPAだとクラス欲しい
- コミュニケーションコスト
- Validation統一
- 分かれてるとリスキー
- toJSON, fromJSONでValidate
- Server Side Rendering
- あんまやってない
- まとめ
- Client Sideはすごく書きやすい
- Serverはそんなに。。
- 区切りを薄くするといいで。
「Isomorphic Architecture & Interface」 by @jxck
- @jxck
- 今日定時ダッシュして書いた。
- やみくもにisomorphic isomorphic言ってねえか?
- よく言われる
- ロジック共通化、ブラウザ無しでテスト。。。
- 現実
- validationくらいしか
- 結局ブラウザテストいる
- 何があり、何がないか
- 部品はある、V-DOM、browserify、moduleなどなど
- Architectureがないのでは
- Interfaceがないのでは
- Architecture
- DOMに依存しないという話だったが、V-DOM出てきたし、SW出てきたし、NginxでJS書けるようになるしー
- Proxyの役目
- インターフェース
- JSとProxy間のインて~フェースがない
- Req, Resを渡す層がない
- connectは枯れてるけどNode前提
- Streamに抽象化しよう
- エコシステム
- middleware
- container
- FWから無駄を排除
- mindset
- どっちで動くかからの脱却
- このインターフェースに依存する
- i8cを加速する
- 枠組みを整えよう
- 車輪に載ってFWが作れる
- やみくもやめよう
- 消耗しすぎ、効率よく
- 最大の敵
- Node/IO.js core team
- i8cに興味ない
- Streamの共通化やってほしい
- URLのパースができはじめた
- Jxck/URL
Gunosy React Meetup行った #gunosyreact
行った。オフィスすごく綺麗だった。 みなさんすごい勢いで発表していくし、ピザの香りでお腹すくし、終わった後の疲労感すごかったw
ReactNativeの話も、v0.13〜の話も、実践?の話も聞けて結構満足度高めだった。
感想
- React.jsで考える再利用性の高いUIデザイン
- うまく抽象化できれば確かになんか楽になりそうと、よくわからんけどワクワクした
- 「Componentが貯まればよりスピード感高まる」と言っていて、なるほどーと思った。
- が、まだv0.13だし、Componentのメンテが大変にならないかなーとも思った
- React Canvasで作るFlappy Bird
- 元某エヴァンジェリストが見るReact Native
- React v0.13
- 生koba04さん初めて見た
- context周りは全然しらなかった。というか結構知らないことあって、さすがや~と思った
- ES6 ClassesでComponent書く記法、mixinもいつかは対応するのだろうと思ったけど、対応しない方に向かいそうなのかー
- ES6 Classesは出来ないこと多いしまだ使わんとこと思っていたが、今日から全部classで書くと誓った
以下、メモ貼り付け
メモ
React.jsで考える再利用性の高いUIデザイン
再利用性
- Reusable Components
UI Designとコンポーネントの関係
- UI Design = Micro Design in Macro Design
- Micro Design => UIパーツ
- これらの組み合わせてページを作る => Macro Design
- Component => Micro Design
- 同じ機能のものが同ページ内に複数あるケースが散見
- つらい
- 「機能」にフォーカスすると結構そういうのあるで
- 「機能」
- 同じならテスト楽、使いまわせる、最小単位でUX検証可能に
それが「Reusable Component」なんやないか
既にあるで
- react-components.com
- react rocks
- open source at FaceBook
デザインワークフロー
- これまで
- これから
- Reactの価値を下げないように考えないといけない
- 作り直しの防止
- 例)modal
- ありがちなヘッダーとか閉じるボタンはReactで共通化
- デザイン検証したいとこは画像渡すだけにしとく
- これやるとプロトタイピングから実装への移行が楽や。スピード感マシマシや。
まとめ
- Reusable
- Componentが貯まればよりスピード感高まる
- 全てはComponentに宿るで〜
React Canvasで作るFlappy Bird
www.slideshare.net
- @tejitakさん
- 余興や。楽しんで聞いてくれ
- LINE
React Canvas
- https://github.com/Flipboard/react-canvas
- flipboard社製
- CanvasをDOM的に扱えるReact Component郡
- Flex layoutなどCSS互換なAPIもある
- flipboardのモバイル版で使われている
Glaxy Octopus
どうやって作るか
- とりあえずJS+DOMで実装してみ手考えた
- 170行くらい、意外と短い
- React Componentでも作ってみた
- パイプ作るときにkeyを一意にしないとうまくいかない
- React Canvas
パフォーマンス
- 今回程度の実装ではあんまり差は出ない
- setStateとアニメーションがあんまり相性良くなかった
- 非同期で値が反映されるため
まとめ
Immutable.js and Kizuna.js
- @Greg at Gunosy
- サーバサイド
- 俺がReactを初めて推したんや
Purity
- 純粋関数
- 参照透過性
- 副作用が無い
- React.PureRenderMixin
- componentが純粋だったら、最適化してくれる
- stateとpropsに変更がない場合、再レンダーしない
- 早くなるで
- 問題点
- 配列やオブジェクトやオブジェクトの比較
- ex) pushなど、内容は変わるのに参照が変わらないので死
- 配列やオブジェクトやオブジェクトの比較
- Immutable.js使おうで
Immutable.js
- Facebook製
- push後は新しいオブジェクトができる
おまけ:Data Flow
- 親のデータをどう変えるか
- 親からCallbackもらう
- 階層増えるとつらい
- thisの扱いつらい
- Flux
- 実装多すぎ
- は?これJava?
- 親からCallbackもらう
- Kizuna.js
- 作った
- テストしてねえけどな!
- おすすめしない
- angular.jsっぽい
- binding属性
- $scope的な感じ
- binding属性
- 作った
元某エヴァンジェリストが見るReact Native
- @masuidriveさん
- http://masuidrive.jp/
- IT芸人で検索
ReactNative
- とある似たようなプロダクトのエヴァンジェリストを2年くらいやってた
- JSでネイティブアプリ
- CSS like
- Androidはcomming soon...
- Learn once, Write everywhere
Titanium Mobile
- 今はXMLで画面書く
- Css Like
- Write once, Adapt everywhere
- ReactNativeについてブログ書いてる
- Titaniumはクライアントだけじゃなくて
- Mbaasとかもやってるんや
共通点
- JS Core
- ネイティブの機能は直接使えない
- ラップしたコンポーネントを呼ぶ
- 1つのソースで全部動くとは言ってない
相違点
- JSX or not
- TitaniumはHyperloopっていうネイティブ呼べるようになるやつがそのうち入る
- Business
共通の問題点
- Nativeをラッピングする必要性
- 使う人と作る人の乖離
- Titaniumの勢いが落ちてきてるのもこれが原因や
じゃあFacebookはやるのか?
React v0.13
- @koba04
v0.13
- 3/10 release
- ES6 Class syntax
- thisのbindがされないとか
- このままmixinはずっと使えないかも
- 他にも使えない関数ガガガ
- getDOMNode, isMouted etc
- prop immutable
- v0.14でこれを前提としたパフォーマンス改善が入る
- shouldComponentUpdateで変更検知できない
- setState
- function渡せる
- 初回のsetStateも非同期に
- isMounted時にsetStateしても死なない
- getDomNode -> findDOMNode
- owner, parent
- context
- ドキュメントにないやーつ
- 暗黙的に子に渡す値
- childContextTypes
- getChildContext
- thic.context
- react-routerもthis.context使う実装になった
- refにfunction渡せる
ref={(c) => this._hoge = c}
- React.cloneElement
- refは保持される
- childrenにIterator渡せるようになった
- keyed objectはWarningでる
- createFragment使え
- --targetのdefaultはes5
- ES6 classで書くとメソッドとかが列挙されない感じになる
- shallow rendering
- 元々合ったけどちゃんとドキュメントになった
- 1階層までをrenderして結果を返す
- nodeでも動く
0.14
- Reuse Constant Value Types #3226
- Tagging ReactElements #3227
- Inline ReactElements #3228
more feature
- Observable API #3398
- React ♡ Parse
1.0
- Road to 1.0
- 既にProduction readyや
- contextどうするか
- Addonsの整理
- Animationの改善
NativeApp開発者からみたReactNative
ネイティブ開発でのスタンス
- ちゃんと各プラットフォームで最適化するべき
- ますいさん「おれもそう思うで」
- あんまりマルチプラットフォームに夢見るべきじゃない
Qiita Reader作ったで
ダメ
- npmモジュールが使いまわせるかは微妙
- 結局iOS+Reactの学習が必要
- RCTBridgeModule
感想
- 劇的に開発を楽にするものではない
最後に
- Reactの文脈をナイティ部に持ってくる仕組みなのでは。
ng-japan 2015行った #ng_jp
ng-japan - AngularJS Japan User Group | Doorkeeper
Angular1.3以降や2系についてはあんまり追っていなかったので、参加してみた。 最近はディスられていた印象が強かったけど、Communityがすごい規模になってもCommunityを重視して開発を進めようとしているっぽいので、Angularは長く支持されそうだなと思った。 2系ではパフォーマンスがかなり改善されるし、TypeScriptとの連携も強くなるようなので、しばらく使っていなかったが触っておかないと今後困ることがありそうだなと感じた。
以下、メモ。
Angular 1.4 and beyond @chirayuk
- Chirayu Krishnappa
- 1.4まだ出てないけど1週間位で出るで
- もっとも安定したリリースや
- onlineにいっぱい情報あるで
- めっちゃCommunityでかなっとるねん
- Github 100K+unique visitors / 2week
- 1600くらい新しいissueとPRができる / 2week
- 200人くらいコントリビューター増える / 2week
- 1.4
- weeklyでrelease condidate
- 35以上のFeatures
- 140以上のBug fix
- パフォーマンス改善
- みんな興味ありそうなアップデート
- New Router
- Brianから発表するで
- Pluralization and Gender support
- ng-animate update
- ng-messages update
- ng-cookie
- New Router
Pluralization and Gender
Pluralization
- based on ICU MessageFormat
- Use in interpolation expressions
- Use in attributes
Gender
ng-massages updates
- 複数のinludeが可能に
- 式が書けるようになった。
ng-message-exp
ng-cookies updates
- cookie周りはいろんな要望が来る
path
とdomain
の設定が可能に- bug fix
more
- commonJS対応
- injectorのエラーが詳細に(あってるか不安)
- ng-jq
- ng-options
- limitTo
- ngModelに$setDirtyメソッドを追加
- routeProvider case-insensitive
- ngAria, $http improvements
- ChangeLog読めや
Better Peformance
- 1.3と比べて30% faster(digestのとこが) − 起きたイベントによって何に影響をおよぼすかの判定部分
- メモリフットプリント 2~4%改善
- まぁブラウザや作ってるアプリによるけどな!
Everyone should upgrade!
- 後方互換性に気を使っているので、出たらすぐ使えや!
- サポートブラウザも1.3と一緒
Future
- 1.5
- 1.4がリリースされたら1.5何するかの計画が始まる
- VoteとかPRとかくれや
- リリースサイクル短くなっておる
You can help
- Add a future
- contact us
- minimal set of changes per PR
- unit tests
- follow conventions
- Work on issues
- バグを見つけてfailするテストをくれ
- Help closing issues and PRs
- issueとかPRとかに「これもう直ってるで」とかコメントしてくれると助かる
AngularとOnsen UIで作る最高のHTML5ハイブリッドアプリ @anatoo
www.slideshare.net
- 久保田 光則
- https://twitter.com/anatoo
- アシアル株式会社
- Onsen UI
- ハイブリッドアプリ用のUIフレームワーク
HTML5ハイブリッドアプリとは
- WebViewでUIを構築するやつ
- メリット
どんな問題があるのか?
- 多くの開発者がハイブリッドで頑張ったが死んでいった
- 有名な例はFacebookさんやで
- 数年前に比べて好転しつつある
- 端末スペック向上
- WebViewの性能向上
- Android2.3のシェア低下
- etc
- railsのDHHも言ってるらしい
- 直接の問題
- パフォーマンスや安定性
- UIパーツをHTML・CSSで再構成する必要がある
- チューニングができるFEエンジニアが少ない
効率的なチューニング
- Loading, Scripting, Rendering, Paintingの1frameを16ms以下にすれば60fps
- これ以上やってもしょうがない
- Loading
- リソースの読み込みやパース
- ハイブリッドアプリの場合、ここは短いはず
- ローカルにあるから
- Scriptiong
- JSの実行時間
- CPU Profileとれや
- Bottom Upのselfみろや
- Rendering
- Painting
- DisplayListの生成
- Rasterize(DisplayListのピクセル化)
- Composite Layers レイヤの合成
CSS Triggersでググれや!カスどもが!
DOMリークを防ぐ
- reflow
- GPUバウンド
- CPUよりGPUの処理の時間がかかっている状態
- でかい要素のtranslateZ hackすれば再現できる
- こんなこと全員が考えないといけないのはおかしいでござる
なぜAngularとOnsen UIが必要なのか
- アプリ開発者がそれに集中できるようにするのが目的や
- Angular, stylus, topcoat, BEM...
Routing your way in an Angular app @briantford
- Brian Ford
- http://angular.github.io/router/
- Angularの場合、componentに対してURLをマッピングする
- Deep Linking
- Angularのroutingの歴史
- ngRoute
- よかったがシンプルなユースケースしか対応できてなかった
- ニーズに対応しきれない
- UI Router
- ngRouteに満足しないコミュニティから生まれた
- New Router
- 1系でも2系でもうまく連携できるものを作りたかった
- ngRoute
- Reusable and Composable
- Familiar
- 既に使い慣れているもの(expressとか)に似せた
- Controller.$routeConfig
<ng-viewport></ng-viewport>
に展開される
ng-link
でdeep link- 遷移時にアニメーションできるで
- Sibiling Routes
<div ng-viewport="left"></div>
- Lifecycle Hook
- 遷移時にイベント取れる
- 遷移のキャンセルとかできる。
Controller.prototype.canDeactivate
- falseで遷移をキャンセル
- Promiseを返せば待つ
- canReactivate, canDeactivate, instatiate, canActivate...
- Migration
- 1系と2系で設定が同じ
- Router内で1系と2系のコンポーネントが両方動く
- Componentごとに2系に移行できるやんけ
- state
- 0.5
- 1.0はAngular1.4と一緒に出す
- 故に来週くらい
- 詳しいやつ
TypeScript+Angular 1.3 @vvakame
www.slideshare.net
- vvakame
- わかめ まさひろ
- https://twitter.com/vvakame
- TopGate
- TypeScript人間
- AtScript
- AtScript == ES6 + Annotation(Decorators)
- ES6には含まれない
- TypeScriptのSuper set
- TypeScript
- ES6取り込み中
- 1.5でだいぶ取り込む
- JS + 型
- ES6取り込み中
- DefinitelyTyped
- 型定義ファイルが1000以上ある
- 2015/3/15 AngularがTypeScriptを採用することを表明
- TypeScriptのsuper setを作るのは難しい。
- TypeScriptの開発速度が早い!
- TypeScriptのsuper setを作るのは難しい。
- 今からTypeScriptやっておこう
- tslint
- typescript固有のやつ
- typedoc
- JSDoc like
- grunt-typedocはちょっと古いけど直します
- dtsm
- 型定義ファイルの管理
- tsdのオプションが使いづらかったので作った
- エディタ
- 基礎知識
- 型の名前を覚える、d.tsを見る
- tsc --noImplicitAnyでやれ、常に
- 暗黙的にanyになるのを防ぐ
- 出力順問題
- 読み込み順が重要になる
- index.tsをルートにして、ツリー構造にするといい
- protractor
- 型定義ファイルの干渉が起きる
- e2eテストコードと本番コードを混ぜない
- FAQ
- browserify使わない方がいい
- --taget es6は使わない方がいい
- babelは使わない
- source map使わない方がいい
- 壊れやすいのでやめた方がいい
- sourcemapにValidationの仕様がない
- 実戦投入
- 既にいくつかの案件でうまく行っている
- typescript + angularjs 1.3 いけるで
- Q&A
- coverageとコード解析は何を使えばいい?
- ない
- coverageは変換後のJSでやれ
- ヒアドキュメントはどうしてる?
- ES6のTemplate String使えばええやんけ
- coverageとコード解析は何を使えばいい?
Angular 2 @IgorMinar
- Igor Minar
Why Angular 2?
- 5年前にAngular1の開発を始めた
- 多くのユーザがangularjs.orgにやってくる
- 1Million per 30days
- Google内で2000のアプリケーションがAngularを作っている
- 多くの信頼を得たが、改善への責任も伴っている
What's in Angular2?
- Themes
- シンプル、一貫性、柔軟性、速さ、効率
- 1系と似てる
- DI, Data binding, Directivesなどなど
- new features
- viewports,
- new languages
- web components
- template syntax
- unidirectional data flow
- ultra-fast change detection
- ツールの活用
- TypeScript 1.5
- 2系はTypeScriptで開発するが、2系を使う時はTypeScriptを使わなくても書ける
- でもTypeScript使ったほうがいろいろサポートするよ
Performance
- benchpress作ったで〜
- Deep Tree
- 深い構造のComponent、複雑なUIをどれくらい速く構築できるのかのベンチマーク
- baseline:vanilaJSでとにかく速いコード(汚いけど速い)を基準に。
- baselineを1とすると
- 1.3は8.58倍のオーバーヘッド、他のライブラリもだいたい同じくらい
- 2系は3.11倍
- View cache有りだと1.44倍
- virtual scrolling, viewの行き来の改善
- memory
- 1.3は9.5倍、2系のview cache有りは1.3倍
- Immutable Data Structures
- change detectionの改善
- Virtual Scrolling
what does it look like?
When?
- 今はまだalpha
- communityを重視したいので、フィードバックちょうだいな
- Google内部のいくつかのチームでは5月からMigrateを始める
- https://angular.io/
- 2系に特化したサイト
What about Angular 1?
- 1系はどうなるのか?
- ほとんどのエンジニアが2系のMigrationが終わったと感じるまで、1系のサポートを続ける
- ng-conf 2015の動画見ろや
ES6のarrow functionとbabel
最近、JSを書く時はBabelを使ってES6で書いている。 mochaでテストを書く場合も下記で簡単に導入できる。
$ npm i -D mocha babel $ $(npm bin)/mocha --compilers js:babel/register
そんな感じでTestiumとmochaで下記のようにテストケースを書いて、テストを実行するとエラーが出た。
// test/home.js 'use strict'; import injectBrowser from 'testium/mocha'; describe('Some page', () => { before(injectBrowser()); it('should display "Hello World"', () => { this.browser.navigateTo('/'); this.browser.assert.httpStatus(200); this.browser.assert.elementHasText('h1', 'Hello World'); }); });
$ mocha --compilers js:babel/register /home 1) should display "Hello World" 0 passing (2s) 1 failing 1) /home should displays "Hello World": TypeError: Cannot read property 'browser' of undefined (stack traceは省略。。。)
ぬぬぬ。undefinedにbrowserなんてプロパティねえよ!このボケ!とのこと。
babelコマンドでテストがどう変換されているか確認してみる。
// babel test/home.jsの出力結果 "use strict"; var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; }; var injectBrowser = _interopRequire(require("testium/mocha")); describe("/home", function () { before(injectBrowser()); it("should display \"Hello World\"", function () { undefined.browser.navigateTo("/"); undefined.browser.assert.httpStatus(200); undefined.browser.assert.elementHasText("h1", "Hello World"); }); });
arrow functionの中のthisがundefinedに変換されていた。 このように書くとうまくいく。
'use strict'; import injectBrowser from 'testium/mocha'; describe('/home', () => { before(injectBrowser()); // ここはarrow functionを使わずにいつものFunction let browser; beforeEach(function () { browser = this.browser; }); it('should display "Hello World"', () => { browser.navigateTo('/'); browser.assert.httpStatus(200); browser.assert.elementHasText('h1', 'Hello World'); }); });
arrow functionがただのFunctionの省略じゃないのは知っていたが、 なぜ、このようにarrow functionの中のthisはundefinedに変換されてしまうのか。
arrow functionはただの省略記法じゃない
ちょっと調べてみるとそれっぽいissueを発見。(他にもそれっぽいissueがいっぱいあったが、「これを見ろ」と下記のURLが貼られていたw)
「arrow functionはthisがbind」されるのが原因だ、とのこと。
https://github.com/nzakas/understandinges6/blob/master/manuscript/02-Functions.md#arrow-functions
var hoge = () => { ... } // 普通のFunctionで書くとこんな感じ var hoge = function () { }.bind(this);
(他にもnewできない、argumentsが無いとか、普通のFunctionとちょっと違う)
「いやいや、でもdescribeの中で実行されるときに別のthisをbindされるかもしれないから、undefinedに変換してしまうのはやり過ぎなんじゃないのか」と思ったが、arrow functionはapply, callを使って後からthisを変更して実行することができない(普通のFunctionにbindを使った場合も同様)。故にBabelでは、定義時の状態でどれがthisになりうるか判断して、arrow function内のthisを書き換えてるみたい。
なので、さきほど失敗したテストケースの場合、describeに渡しているarrow functionにはglobalのthisがbindされるが、globalのthisはundefinedなので、それ以降のarrow functionのthisもundefinedに変換しているっぽい。
じゃあ、describeに渡しているarrow functionを普通のfuncitonに変えればいいのでは。
'use strict'; import injectBrowser from 'testium/mocha'; describe('/home', function () { // ここだけ普通のfunciton before(injectBrowser()); it('should display "Hello World"', () => { // ここはarrow function this.browser.navigateTo('/'); this.browser.assert.httpStatus(200); this.browser.assert.elementHasText('h1', 'Hello World'); }); })
変換してみる。↓
"use strict"; var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; }; var injectBrowser = _interopRequire(require("testium/mocha")); describe("/home", function () { var _this = this; before(injectBrowser()); it("should display \"Hello World\"", function () { _this.browser.navigateTo("/"); _this.browser.assert.httpStatus(200); _this.browser.assert.elementHasText("h1", "Hello World"); }); });
ちゃんとthisを_thisに代入してitのarrow functionではそれを参照するように書き換わっている!!いけそう!!!が、実行してみるとエラーがでる。
$ mocha --compilers js:babel/register /home 1) should displays "Hello World" 0 passing (1s) 1 failing 1) /home should display "Hello World": TypeError: Cannot call method 'navigateTo' of undefined (stack traceは省略。。。)
before, beforeEach, itの中のthisは全て同じだと思っていたが、完全な思い込みだった。。。orz
'use strict'; describe('this', function () { var _this = this; before(function () { console.log('in before:', this===_this ? 'same' : 'not same'); }); it('...', function () { console.log('in it:', this===_this ? 'same' : 'not same'); }); }); // 出力結果 in before: not same in it: not same
なるほど。thisがなんなのかよくわかんない時にarrow functionは使うべきではないのかー。
まとめ
- arrow functionはただの「普通のfunctionの省略記法」ではないので、気をつけなはれや!
- babelがんばってる。本当にすごい。
gulpfile.es6でgulp.watchが動かない
上記の記事を参考にgulpfileもES6で書けるようにした。が、watchが何故か動かなかった。
// gulpfile.js require('babel/register'); require('./gulpfile.es6'); // gulpfile.es6 import gulp from 'gulp'; gulp.task('scripts', () => { ... }); gulp.task('watch', () => { gulp.watch(['...'], ['scripts']); });
$ gulp watch [00:39:17] Using gulpfile ~/src/github.com/toybox/gulpfile.js [00:39:17] Starting 'watch'... [00:39:17] 'watch' errored after 622 μs [00:39:17] TypeError: boolean is not a function at Function.isPlainObject (/Users/pirosikick/src/github.com/toybox/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule/node_modules/lodash/dist/lodash.js:1652:64) at Object.globule.find (/Users/pirosikick/src/github.com/toybox/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule/lib/globule.js:64:19) at Gaze.add (/Users/pirosikick/src/github.com/toybox/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/lib/gaze.js:174:19) at new Gaze (/Users/pirosikick/src/github.com/toybox/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/lib/gaze.js:74:10) at gaze (/Users/pirosikick/src/github.com/toybox/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/lib/gaze.js:86:10) at Object.module.exports [as watch] (/Users/pirosikick/src/github.com/toybox/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/index.js:12:17) at Gulp.watch (/Users/pirosikick/src/github.com/toybox/node_modules/gulp/index.js:35:16) at Gulp.<anonymous> (/Users/pirosikick/src/github.com/toybox/gulpfile.es6:11:8) at module.exports (/Users/pirosikick/src/github.com/toybox/node_modules/gulp/node_modules/orchestrator/lib/runTask.js:34:7) at Gulp.Orchestrator._runTask (/Users/pirosikick/src/github.com/toybox/node_modules/gulp/node_modules/orchestrator/index.js:273:3)
エラーでググるとbabelにIssueが立っていた。
6to5-node breaks gulp watch · Issue #489 · babel/babel · GitHub
babelが原因ではなく、gulpが依存しているvinyl-fsが依存しているglob-watcherが依存しているgazeが依存しているglobuleが依存しているlodashのバージョンが古いのが原因らしい。。。glob-watcherが参照しているgazeのバージョンが上がればいいっぽいが、待てないので、上記Issueのコメントに書いてあった方法で凌ぐ。
$ npm i --save lodash $ cd node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule $ vim package.json ... lodashをdependenciesから削除 // 古いlodashを消す $ rm -r node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule/node_modules/lodash
これでうまくいった!!npm scriptsのpostinstallに書いておけば上記手順は勝手にやってくれる(結構微妙な対応だけど。。。)
"scripts": { "postinstall": "pushd node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule; perl -pi -e 's/\"lodash\".*,$//' package.json; rm -r node_modules/lodash; popd" }
長い!!!早く根本的に解決して欲しい。。。
でかいjsonをJSONStreamでちょっとずつTSVにする
小ネタ。
最近、ニフティクラウドのmobile backendにあるデータの集計を頼まれて、エクスポート機能で全てのデータをダウンロードしてとりあえずMySQLに入れようとしたんだけど、そのjsonが600MBくらいあってrequireで読み込めなかった。
$ cat hoge.js var json = require('./big-data.json'); $ node hoge.js FATAL ERROR: CALL_AND_RETRY_0 Allocation failed - process out of memory
こういう時のStreamなんだろうなーでも誰か実装してそうだなと思ったらやっぱりあった。
dominictarr/JSONStream · GitHub
{ "results": [{ ... }, { ... } ・・・ ] }
↑こういうJSONがあってresultsの中が欲しい場合、JSONStream.parse('results.*')でOK。
var fs = require('fs'); var _ = require('lodash'); var JSONStream = require('JSONStream'); var map = require('event-stream').map; fs.createReadStream('./big-data.json') // JSONのroot["results"] .pipe(JSONStream.parse('results.*')) .pipe(map(function (data, callback) { // なんかしら処理する callback(null, _.values(data).join("\t") + "\n"); })) .pipe(process.stdout);
ES6+カジュアルトーク行った #es6_casual
6つのLTどれも面白くて前日申し込みで滑り込めて本当に良かった。 カジュアルトークということで、全部で1時間半くらいとあんまり疲れなかったし、 でも内容は全然カジュアルじゃなく深い感じで本当に楽しい時間だった。
@teppeisさんのLTがかなり良くて資料をあとで見直したい。 Closure Compilerがあんなに高機能だったとは知らなかったw
ハッシュタグに かなり補足情報があったので後で読もう。
以下、メモ
Runstantで始めるEcmaScript6
- @phi_jp
- Runstant
- http://phi-jp.github.io/runstant/release/alpha/
- 全部消して「es6」と入力してCmd-sでES6サンプル集
Node.js v0.12で使えるようになるES6+αの機能
Node.js v0.12で使えるようになるES6+の機能一覧 // Speaker Deck
- @yosuke_furukawa
- DeNA
- Node.js日本ユーザグループ代表
- v0.12ブランチをビルドして確認、v8のバージョンは3.28
- v8の最新は3.30
- v0.12で削除されたオプション
harmony_typeof
typeof null == 'null'
がtrue
になるオプション- 元から非推奨
- 追加されたオプション
harmony_arrow_functions
- アロー関数
- デフォルトになった機能
- Symbol
- オブジェクトのkeyに利用できる特殊なオブジェクト
- Symbol
function getObj() {// // _nameはこのスコープじゃないと使えないので実質的に_nameはprivaete var _name = Symbol("_name"); var obj = { name: 'hoge' }; obj[_name] = 'hoge'; return obj; } var obj = getObj(); console.log(obj) // { name: 'hoge '}
- Collections
- Map, Set
- Set.prototype.keysとSet.prototype.valuesは同じものが返る
- -> 内部はMapでできてる
- for-of
- IterableなものならOK
Symbol.iterator
で作れる
var hoge = { [Symbol.iterator]() { return { next () { if (終わってない) return {done: false, value: '...'}; return {done: true}; } }; } }
- GeneratorもIterable
- Promise
- Object.observe
Array.observe(array, callback(changes))
ES6による 関数型プログラミング
- @TanUkkii007
- 安田さん
- 株式会社トライフォート
- 関数型とJavaScript
- JSはSchemeベース
- 第1級関数オブジェクトがあるでござる
const
不変性use strict
有り無しで挙動ちゃうで
- パターンマッチ
- 分割代入
- 再帰
- 関数型は再帰や。副作用使わんからな
- ES6で末尾呼び出し最適化入るで。
function hoge (n) { return hoge(n - 1); // これが末尾呼び出しや }
- 不変性
Introducing break the Web
- @Constellation
- ES6はArray結構拡張した
Array.prototype
って既に拡張してる人いない?居るならぶっ壊れるよvalues
,keys
とか被りそうな名前やし
var values = []; with(object) { values = ...; // objectがArray継承してたら死 }
@@unscopables
- case1 MooTools
−
Array.prototype.contains
の上書き- jsfiddleがぶっ壊れた
- es-discussでは
has
にしようかみたいな議論が出てた- 出てたソリューションはどうしようもない感じ
- case2 outlook.com
- ChromeのStableで。
- まとめ
- コードを省略しない
in
じゃなくてhasOwnProperty
使おう
- Object.prototypeとか将来的に拡張される可能性があるのでそういうの考えよう
with
使うな。use strict
で使えなくなるけど。
- コードを省略しない
Closure CompilerのES6対応あるいはES6時代のAltJS生存戦略
Closure CompilerのES6対応 あるいはES6時代のAltJS生存戦略
- @teppeis
- サイボーズ
- kintone作ってる
- Closure Compiler − 超圧縮&最適化
- ECMASCript6
- オプションで指定
- 未実装:Modules, super(class)
- es6 tableにclosure compilerあるからそこで見ればOK
- Tracuerは自前で実装しすぎててruntimeが大きくなってて微妙
- ES6はAltJSのいいとこ取りなので全部実装されればいい感じやで
- AltJSと出口戦略
- ES6時代のAltJS
- Facebook Flow, TypeScript, AtScript, etc
- ECMAScript Typesが提案に
明日には使えなくなるES7トーク
http://azu.github.io/slide/es6talks/
- @azu_re
- JSer.info
- TC = 専門委員会
- Stage 0 ~ 4
- 今日は0はほとんどアイデアレベル
- 4でテスト作る。
- AtScript, FlowはTypeScriptの型定義を真似てるらしい
- tc39-notesを見ればだいたいわかるよー