taiki-t's diary

React Native, Rails そして雑多な記録: The world is waiting for you to give it a meaning.

FacebookのOSSとかFB内部版とかについてメモ

FacebookOSSについてRelayとかReact Nativeは割とIssueなど見たりしてきた。 その結果、それらにはどうやらFB内部版とOSS版があるんだなあといつしか思うようになった。

そう思うに至った会話すべてをあげつらうことはできないけど、いくつか記憶に残ってたり調べたりした結果出てきたものをメモしておこうと思った次第。

React NativeはOSSのものをそのままFacebook内部で使っているわけではない(※)

We use different Image and caching modules internally - - https://github.com/facebook/react-native/issues/9581#issuecomment-287834859

※と書いたのは、下記の記事には「OSSと全く同じものを使っている」と書いてあったりするから。ただ日付としては上記のIssueの方が新しい。全く同じものを使っていたらImageモジュールは別なの使っているとは言わないから、やっぱ別なのかなって感じ。

Facebook engineers use the exact same React Native code you see on GitHub; we don’t have a fork of the codebase. -- React Native: A year in review – Facebook Code

RelayもOSS版とFacebook内部版に違いがあるぽい

there is an issue with the OSS compiler -- https://github.com/facebook/relay/issues/1656#issuecomment-303007406

Relay Classicの時は割と顕著だった:

Relay was built to support server-side rendering, and we are doing so internally at Facebook. @voideanvalue gives a great overview of how that works. However, the necessary hooks and APIs are not exposed in the OSS release. --https://github.com/facebook/relay/issues/136#issue-102433255

 

We have one failing test in OSS which doesn't fail internally. -- Fix OSS-only test failure in RelayGraphQLMutation · Issue #1065 · facebook/relay · GitHub

Relay、Classicの時すでに数々の欠けていた機能、SSRやオフライン対応、サブスクリプションがFB内部の実装では使えていたぽい。これを見ると"in OSS"と新機能欄に書かれている。

  • server rendering in OSS
  • work offline in OSS
  • subscriptions in OSS

--https://github.com/facebook/relay/blob/ea03e9ba6bc5763c18b9745eeab375087507307e/meta/meeting-notes/2016-02-05-product-requirements-and-core-values.md

FBにはでかいモノレポがある

Facebook中の人によるとレポジトリ2つしかないぽい

まあこんなツールも作ってるしね

github.com

感想

React Nativeでは画像のキャッシュ調べてたときは「その内部で使われてるモジュール公開してもらえると嬉しいです」と思ったり「使ってないからメンテされないのか」みたいな納得をした。Relayについては client schema はやはり内部的には困ってないのかあ(内部では使えてる実装があるから)みたいなことを思った。

最後に

詳しい方や、OSS版と内部版の関係について書かれているドキュメントを知っている方がいれば教えてもらえたら嬉しいです。

日記

なんか翻訳したいなーと衝動が出たのでとりあえずReact Navigationの最初のところだけ訳した。本家のページに反映する方法がよくわかってないし、ざっと訳した感じなのでとりあえずここにおいておく。Docusaurusの仕組みに乗っかって、crowdinというところにアップロードすれば良いぽいけど。 気が向いたらまたやる。


Hello React Navigation · React Navigation (v2)

より

Hello React Navigation

webブラウザではアンカータグ(<a>)を使って異なるページへリンクできます。ユーザがリンクをクリックすると、そのURLがブラウザの履歴スタックに追加されます。ユーザーが戻るボタンを押すと、ブラウザは追加したものを履歴スタックの一番上から取り出します。それにより、現在アクティブなページは1つ前に訪れたページになります。React Nativeには、webブラウザにあるような「最初から存在するグローバルな履歴スタック」といった概念はありません。そうです。ここでReact Navigationが登場します。

React Navigationのスタックナビゲーターによって、アプリはスクリーン間を遷移し、ナビゲーションヒストリーを管理できるようになります。アプリがスタックナビゲーターを1つだけ使うのであれば、概念的にはwebブラウザがナビゲーションステートを処理する方法に似ています。ユーザーの操作に合わせて、アプリはナビゲーションステートに要素の追加と取り出しを行います。そしてその結果、ユーザーは別なスクリーンを見ることになります。この一連の仕組みにおけるwebブラウザとReact Navigationの重要な違いは、React Navigationのスタックナビゲーターはジェスチャーとアニメーションを提供することです。これは通常AndroidiOSでスタック内のルートをナビゲーションする時に期待されるものです。

React Navigationを使い始めるために必要なのはcreateStackNavigatorと呼ばれる関数だけです。

スタックナビゲーターを作る

createStackNavigatorはReactコンポーネントを返す関数です。これはルート設定オブジェクトとオプションオブジェクトをとります(下記の例ではオプションオブジェクトについては一旦省略します)。createStackNavigatorはReact Componentを返すので、App.jsから直接エクスポートしてアプリのルートコンポーネントとして使えます。

一括ダウンロードがないページで無理やり全部ダウンロードするchrome console スニペット

プロローグ

一括ダウンロードしたいけど一括ダウンロードボタンがない時がある。 ログインが必要ない画面だったらwgetなりで引っ張ってくればいいんだけど、管理画面とかだとちょっとしたそういうのがめんどくさい。 chrome consoleからやればページさえ開けていれば一括ではないけれど自動化できるのでそうすることにした。

コード

const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms))
const links = $$("任意のセレクター, a要素を選択")
for (const link of links) { link.click(); await sleep(3000); console.log(link) }

sleepは状況に合わせて適当に時間を。for...ofを使ったのは、forEachとかmap内では非同期処理ができなかったから。

papertrailのlogダウンロードならこんな感じ

const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms))
const links = $$("#archives-list > ul > li > span > a")
for (const link of links) { link.click(); await sleep(3000); console.log(link) }

セレクターもchrome consoleで簡単にとってこれる

f:id:taiki-t:20180521200939p:plain

余談

最近暑くね

React Native (iOS)で電話番号のリンク

Androidはまた別ぽいけどiOSだけ対応でざっくりやるならこんな感じ

<View>
  <Text
    style={{textDecorationLine: 'underline' }}
    onPress={() => {
      // <actural phone number>は実際の番号で置き換える
      const url = 'tel:<actural phone number>'
      Linking.openURL(url).catch(err => console.error('An error occurred', err));
    }}
  >
    電話をかける
  </Text>
</View>

Linkingコンポーネント使ってtel:nnnuuuummmm形式のurlひらけば良い

メモ: GitHubにpush/pullする時に毎回SSH key使うためにパスワード入れないといけない問題

極たまに設定が必要な状況になって毎回調べてる気がするのでメモ これ:

Generating a new SSH key and adding it to the ssh-agent - User Documentation