Upgrade to Pro — share decks privately, control downloads, hide ads and more …

ReactNativeのAsyncStorageをNodeのReplから操作する

B72422afc5f3ffc844f672b59122e16d?s=47 joe_re
December 14, 2017

 ReactNativeのAsyncStorageをNodeのReplから操作する

Introduce liblary named async-storage-repl.
AsyncStorage repl provides you to access your ReactNative Application AsyncStorage using your console node REPL.
It makes easy to development your app.
and it has more feture...

B72422afc5f3ffc844f672b59122e16d?s=128

joe_re

December 14, 2017
Tweet

Transcript

  1. ReactNative の AsyncStorage をNode の Repl から操作する @joe_re

  2. Who am I? twitter: @joe_re github: @joe­re community: Nishinippori.rb, GraphQL

    Tokyo Organizer
  3. Note Gotanda.js で発表した以下の発表とかぶる部分が多いです。 いらしていた方はすみません https://speakerdeck.com/joere/asyncstoragewonodefalsereplkaracao­ zuo­surutamenitop­leveldeawaitsitairen­sheng­datuta

  4. What is AsyncStorage? ReactNative の標準で搭載されたkey­value ストレージ 気軽にReactNative に永続化したいデータを持つときに便利 ReactNative で使えるLocalStorage

    みたいなもの
  5. Example Persisting date: try { await AsyncStorage.setItem('@MySuperStore:key', 'I like to

    save it.'); } catch (error) { // Error saving data } Fetching date: try { const value = await AsyncStorage.getItem('@MySuperStore:key'); if (value !== null){ // We have data!! console.log(value); } } catch (error) { // Error retrieving data }
  6. AsyncStorage をNode のREPL から操作したいという欲望 AsyncStorage には外部から叩けるAPI は用意されていない 開発中にデータ構造が変わったときにアプリケーションに データを修正するためのコードを書くのは面倒 ちゃんとデータが保存されたかどうか確かめるのも面倒

    REPL からAsyncStorage のAPI を叩きたい (rails console みたいなイメージ)
  7. 作った https://github.com/joe­re/async­storage­repl

  8. DEMO

  9. 仕組み Node とReactNative との通信はWebsocket で行う REPL 起動時に子プロセスとしてReactNative アプリケーションと通信するWSS を立ち上げる REPL

    とWSS はプロセス間通信を行う
  10. イメージ図

  11. ん?

  12. どうしてこうなった

  13. Node.js ではTop Level で非同期処理の 結果を扱えない 人類はES2017 よりasync/await を獲得したが、 await はasync

    function の中でしか使えない // ng function request { const response = await fetch( '/data.json' ); const json = await response.json(); const result = await hydrateSomehow(json); return result; } // ok function async request { const response = await fetch( '/data.json' ); const json = await response.json(); const result = await hydrateSomehow(json); return result; }
  14. REPL で Promise オブジェクトを 扱おうとすると.. > let out = null;

    > promiseObj.then((res) => { out = res }); > out // finally available here
  15. だるすぎワロた

  16. Top­level await is a footgun https://gist.github.com/Rich­ Harris/0b6f317657f5167663b493c722647221 Top­level のawait を許すと1

    つの依存を解決するだけでも、 その先の関係のない処理まで止めざるを得ない await は直列を強要するので、ネットワークを介した処理 ( 動的なmodule import など) の並列化ができない
  17. Example(borrow from Harris) // main.js import './foo.js'; import './bar.js'; //

    foo.js await delay( Math.random() * 1000 ); console.log( 'foo happened' ); // bar.js await delay( Math.random() * 1000 ); console.log( 'bar happened' );
  18. 将来的にはTop­level await が できるかも? https://github.com/tc39/ecmascript­asyncawait/issues/9

  19. 今回はこのような実装に _resolveMessageFromRN(fileName) { let json = {}; let received =

    false; for (let i = 0; i < this.timeout; i++) { sleep.msleep(100); const fileContent = fs.readFileSync(fileName, 'utf8'); if (fileContent) { json = JSON.parse(fileContent); delete this.que[Number(json.queId)]; received = true; break; } sleep.msleep(900); } fs.unlinkSync(fileName); if (!received) { throw new Error("can't receive response from ReactNative Application"); } if (json.error === 1) { throw new Error(json.message); } return json.result; }
  20. ここまで作った当時(2017/5 月) の情報

  21. Chrome のDevTool には top­level await が入った

  22. それを受けてNode のRepl にも実装された v10 系から入る予定。試してみたい人はlatest のソースコー ドからビルドすれば今でも使えるはずです https://github.com/nodejs/node/pull/15566

  23. というわけでファイル監視は そのうちやめられそう

  24. Flow Runtime の採用 https://codemix.github.io/flow­runtime/ compile でassertion をさし挟むことで、 flowtype の型チェックを動的に実行できる 全ての関数呼び出しでassertion

    を挟むのはパフォーマンス に影響するのでproduction ではoff にすべきだが、 development やtest でon にしておくとより多くの型違反を 検出できる REPL でこれを有効にしたら思ったよりこれぞ型チェックっ て感じになって感動した
  25. example > RNAsyncStorage.getItem(1) RuntimeTypeError: key must be a string Expected:

    string Actual Value: 1 Actual Type: number at RNAsyncStorage.getItem (/Users/noguchimasato/src/async-storage- cli/src/node/RNAsyncStorage.js:25:24) at repl:1:16 at sigintHandlersWrap (vm.js:92:15) at ContextifyScript.Script.runInThisContext (vm.js:42:12) at REPLServer.defaultEval (repl.js:239:29) at bound (domain.js:301:14) at REPLServer.runBound [as eval] (domain.js:314:12) at REPLServer.onLine (repl.js:433:10) at emitOne (events.js:120:20) at REPLServer.emit (events.js:210:7)
  26. Extensible AsyncStorage API 基本はAsync Storage のAPI をそのまま提供しているけど、 仕組み上API を組み合わせて新しいAPI を作ることや、

    拡張することも可能 現在は dump() と load() のAPI を提供している もっと便利にしていきたいので是非アイディアをください
  27. ReactNative のお供にぜひ!

  28. ありがとうございました