メインコンテンツへスキップ

F8でのReact Nativeとオープンソースポッドキャスト

·3分で読めます
Christoph Nakazawa
Christoph Nakazawa
元Facebookエンジニア

今週、Eli WhiteF8 2019で、FacebookのAndroidおよびiOSアプリケーションにおけるReact Nativeについて講演しました。過去2年間何に取り組んできたか、そして次に何をしようとしているかをお伝えできることを嬉しく思います。

Facebookの開発者向けウェブサイトでビデオをチェックしてください

F8 Talk about React Native

講演のハイライト:

  • 2017年と2018年は、React Nativeの最大の製品であるFacebookのMarketplaceに焦点を当てました。私たちはMarketplaceチームと協力して、品質を向上させ、製品に喜びを加えました。現時点では、MarketplaceはAndroidとiOSの両方で、Facebookアプリ内で最も高品質な製品の1つです。
  • Marketplaceのパフォーマンスも大きな課題であり、特にミドルエンドのAndroidデバイスでは顕著でした。過去1年間で起動時間を50%以上短縮し、さらに改善を進めています!最大の改善点はReact Nativeに組み込まれており、今年後半にコミュニティに提供される予定です。
  • 私たちは、React Nativeを使ってFacebookが必要とする高品質で高性能なアプリを構築できるという自信を持っています。この自信により、React Nativeのコアを再考するなど、より大きな賭けに投資することができました。
  • Microsoftは、Windows向けにReact Nativeをサポートし使用しており、人々がその専門知識とコードベースを使用してMicrosoftのUniversal Windows Platformにレンダリングできるようにしています。来週のMicrosoft Buildで、彼らの話を聞いてみてください

オープンソースに関するReact Radioポッドキャスト

Eliの講演は、私たちの最近のオープンソース活動についての話で締めくくられています。私たちは3月に進捗状況を更新しました。最近、Nader DabitGant LabordeはChristophを彼らのポッドキャストReact Native Radioに招待し、オープンソースにおけるReact Nativeについて話しました。

ポッドキャストのハイライト:

  • FacebookのReact Nativeチームがオープンソースについてどのように考えているか、そしてReact Nativeの規模のプロジェクトに対応できる持続可能なコミュニティをどのように構築しているかについて話しました。
  • Lean Coreの取り組みの一環として、複数のモジュールを削除する予定です。WebViewやReact Native CLIのような多くのモジュールは、抽出されてから100件以上のプルリクエストを受けています。
  • 次に、私たちはReact Nativeのウェブサイトとドキュメントの全面的な見直しに注力します。ご期待ください!

このエピソードはまもなくお気に入りのポッドキャストアプリで配信されます。または、こちらですぐに録音を聴くこともできます。

React Native 0.59のリリース

·7分で読めます
Ryan Turner
コアメンテナー & React Native開発者

React Native 0.59のリリースへようこそ!これは、88人の貢献者による644のコミットを含む、もう1つの大規模なリリースです。貢献は他の形でも行われているため、問題の維持、コミュニティの育成、React Nativeに関する指導に感謝いたします。今月は待望の変更がいくつか行われ、皆様に楽しんでいただければ幸いです。

🎣 Hooksが登場

React Hooksはこのリリースの一部であり、コンポーネント間でステートフルなロジックを再利用できます。Hooksについては多くの話題がありますが、まだ聞いたことがない場合は、以下の素晴らしいリソースをご覧ください。

  • Hooksの紹介では、なぜReactにHooksを追加するのかを説明しています。
  • Hooksの概要では、組み込みHooksの概要を素早く説明しています。
  • 独自のHooksの構築では、カスタムHooksによるコードの再利用を示しています。
  • React Hooksを理解するでは、Hooksによって開かれた新しい可能性を探求しています。
  • useHooks.comでは、コミュニティが管理するHooksのレシピとデモを紹介しています。

ぜひご自身のアプリでお試しください。私たちと同じくらい、再利用性にワクワクしていただけることを願っています。

📱 JSCの更新により、Androidでのパフォーマンス向上と64ビットサポートが実現

React Nativeは、アプリケーションの動作にJSC(JavaScriptCore)を使用しています。Android版のJSCは数年前のものであり、多くの最新JavaScript機能がサポートされていませんでした。さらに悪いことに、iOSの最新JSCと比較してパフォーマンスが劣っていました。このリリースで、それらすべてが変わります。

@DanielZlotin@dulmandakh@gengjiawen@kmagiera、および@kudoの素晴らしい努力のおかげで、JSCはこの数年間の進歩に追いつきました。これにより、64ビットサポート、最新JavaScriptサポート、そして大幅なパフォーマンス改善が実現しました。将来のWebKitの改善を少ない労力で活用できる、維持可能なプロセスを構築してくれたことにも感謝します。また、この作業を可能にしてくれたSoftware MansionとExpoにも感謝します。

💨 インラインrequireでアプリの起動を高速化

私たちは、デフォルトでパフォーマンスの高いReact Nativeアプリを開発できるよう支援し、Facebookの最適化をコミュニティに提供することに取り組んでいます。アプリケーションは、起動を遅らせるのではなく、必要に応じてリソースをロードします。この機能は「インラインrequire」と呼ばれ、Metroが遅延ロードするコンポーネントを識別できるようにします。深く多様なコンポーネントアーキテクチャを持つアプリは、最も改善を実感できるでしょう。

source of the metro.config.js file in the 0.59 template, demonstrating where to enable inlineRequires

この機能をデフォルトで有効にする前に、コミュニティにその動作を知らせてもらう必要があります。0.59にアップグレードすると、新しいmetro.config.jsファイルが作成されます。オプションをtrueに設定して、ご意見をお聞かせください!アプリをベンチマークするには、パフォーマンスドキュメントでインラインrequireの詳細をご覧ください。

🚅 Lean Coreが進行中

React Nativeは、複雑なリポジトリを持つ大規模で複雑なプロジェクトです。これにより、コードベースがコントリビューターにとって扱いにくく、テストが困難になり、開発依存関係として肥大化しています。Lean Coreは、これらの問題に対処するため、より良い管理のためにコードを別のライブラリに移行する取り組みです。過去数回のリリースでその第一歩が踏み出されましたが、本腰を入れて取り組む時が来ました。

追加のコンポーネントが正式に非推奨になったことに気づかれるかもしれません。これは素晴らしいニュースです。なぜなら、これらの機能のアクティブなメンテナーが今やいるからです。警告メッセージに注意し、これらの機能には新しいライブラリに移行してください。なぜなら、それらは将来のリリースで削除されるからです。以下に、コンポーネント、そのステータス、そして移行先の場所を示す表を示します。

今後数ヶ月で、より多くのコンポーネントがこのパスに従ってよりスリムなコアに移行する予定です。これに関するご協力を求めています — ぜひリーンコアの包括的なイシューにご協力ください。

👩🏽‍💻 CLIの改善

React Nativeのコマンドラインツールは開発者にとってエコシステムへの入り口ですが、長年の問題があり、公式サポートが不足していました。CLIツールは新しいリポジトリに移動され、専任のメンテナーグループがすでにいくつかの素晴らしい改善を行っています。

ログのフォーマットが大幅に改善されました。コマンドはほぼ瞬時に実行されるようになりました。すぐに違いに気づくでしょう。

0.58's CLI is slow to start0.58's CLI is nearly instantaneous

🚀 0.59へのアップグレード

React Nativeのアップグレードプロセスに関するフィードバックをいただきましたので、今後のリリースでのエクスペリエンスを改善するための措置を講じています。0.59にアップグレードするには、rn-diff-purgeを使用して、現在のReact Nativeバージョンと0.59の間で何が変更されたかを特定し、それらの変更を手動で適用することをお勧めします。プロジェクトを0.59にアップグレードすると、新しく改善されたreact-native upgradeコマンド(rn-diff-purgeベース!)を使用して、新しいリリースが利用可能になったときに0.60以降にアップグレードできるようになります。

🔨 破壊的変更

0.59のAndroidサポートはGoogleの最新推奨事項に従って整理され、既存のアプリに潜在的な破損をもたらす可能性があります。この問題は、実行時クラッシュとして「このアクティビティではTheme.AppCompatテーマ(またはその子孫)を使用する必要があります」というメッセージで表示される場合があります。プロジェクトのAndroidManifest.xmlファイルを更新し、android:themeの値がAppCompatテーマ(例:@style/Theme.AppCompat.Light.NoActionBar)であることを確認することをお勧めします。

react-native-git-upgradeコマンドは0.59で削除され、新しく改良されたreact-native upgradeコマンドが推奨されます。

🤗 感謝

多くの新しいコントリビューターがフロー型からのネイティブコード生成を有効にすることやXcodeの警告を解決することに協力してくれました。これらはReact Nativeの動作を学び、より大きな善に貢献する素晴らしい方法です。ありがとうございました!今後も同様の問題に注目してください。

これらが私たちが注目したハイライトですが、他にも多くの興奮すべき点があります。すべてのアップデートを見るには、チェンジログをご覧ください。0.59は大規模なリリースです。ぜひお試しください。

年末にかけて、さらに多くの改善が予定されています。ご期待ください!

RyanReact Nativeコアチーム一同

React Nativeオープンソースアップデート 2019年3月

·6分で読めます
Christoph Nakazawa
Christoph Nakazawa
元Facebookエンジニア

2018年第4四半期に、React Nativeオープンソースコミュニティへの投資を増やすことを決定した後、React Nativeオープンソースロードマップを発表しました。

最初のマイルストーンとして、私たちはコミュニティの最も目に見える側面の特定と改善に注力しました。目標は、未解決のプルリクエストの削減、プロジェクトの表面積の削減、主要なユーザー問題の特定、コミュニティ管理のためのガイドラインの確立でした。

過去2ヶ月間で、私たちは予想以上の進歩を遂げました。詳細については、以下をお読みください。

プルリクエスト

健全なコミュニティを構築するためには、コード貢献に迅速に対応する必要があります。過去数年間、コミュニティからの貢献レビューを優先せず、280件のプルリクエスト(2018年12月)を蓄積していました。最初のマイルストーンでは、未解決のプルリクエストの数を約65件にまで減らしました。同時に、1日あたりの平均プルリクエスト開設数は3.5件から7件に増加し、これは過去3か月で約600件のプルリクエストを処理したことを意味します。

プルリクエストのほぼ3分の2をマージし、3分の1をクローズしました。これらは、陳腐化しているか、品質が低いか、またはプロジェクトの表面積を不必要に増加させる場合に、マージされずにクローズされました。マージされたプルリクエストのほとんどは、バグの修正、クロスプラットフォームの同等性の改善、または新機能の導入でした。特筆すべき貢献としては、型安全性の向上と、AndroidXをサポートするための継続的な作業が挙げられます。

Facebookでは、React Nativeをmasterから実行しているため、すべての変更はReact Nativeリリースに組み込まれる前に最初にテストされます。マージされたすべてのプルリクエストのうち、問題を引き起こしたのはわずか6件でした。そのうち4件は内部開発にのみ影響し、2件はリリース候補の段階で捕捉されました。

より目立つコミュニティ貢献の1つは、更新された「RedBox」画面でした。これは、コミュニティが開発者エクスペリエンスをより親しみやすいものにしている良い例です。

リーンコア

React Nativeは現在、Facebookであまり使用されていない、多くのメンテナンスされていない抽象化を持つ非常に広い表面積を持っています。私たちはReact Nativeをより小さくし、Facebookであまり使用されていない抽象化をコミュニティがより適切に管理できるようにするために、表面積を削減することに取り組んでいます。

最初のマイルストーンでは、Lean Coreプロジェクトでコミュニティに協力を求めました。その反応は圧倒的で、すべての進捗状況にほとんど追いつけないほどでした。1か月未満で完了したすべての作業をチェックしてください

私たちが最も興奮しているのは、メンテナーたちが長年の問題を修正し、テストを追加し、長く要望されていた機能をサポートするために飛び込んできたことです。これらのモジュールは、React Native内でこれまで以上にサポートを受けており、これはコミュニティにとって大きな一歩であることを示しています。そのようなプロジェクトの例としては、抽出以来多くのプルリクエストを受け取ったWebViewや、現在コミュニティのメンバーによってメンテナンスされており、必要な改善と修正を多く受けたCLIがあります。

主要なユーザー問題

12月に、コミュニティにReact Nativeについて嫌いな点を尋ねました。私たちはその回答を集計し、すべての問題に回答しました。幸いなことに、私たちのコミュニティが直面する問題の多くは、Facebookでも問題となっています。次のマイルストーンでは、主要な問題のいくつかに取り組む予定です。

最も多くの票を集めた問題の1つは、React Nativeの新しいバージョンにアップグレードする際の開発者エクスペリエンスでした。残念ながら、これは私たちがReact Nativeをmasterから実行しているため、私たちが経験することではありません。幸いなことに、コミュニティのメンバーがすでにこの問題に対処するために立ち上がっています。

0.59リリース

React Nativeコミュニティ、特にMike GrabowskiLorenzo Sciandraの協力がなければ、私たちはリリースを出荷することはできませんでした。リリース管理プロセスを改善し、今後より積極的に関与していく予定です。

  • 各メジャーリリースごとにブログ記事を作成するためにコミュニティメンバーと協力します。
  • 新しいバージョンにアップグレードする際に、破壊的変更をCLIに直接表示します。
  • リリースにかかる時間を短縮します。自動テストを増やす方法や、改善された手動テスト計画を作成する方法を検討しています。

これらの計画の多くは、今後のReact Native 0.59リリースに組み込まれる予定です。0.59には、React Hooks、Android用の新しい64ビット版JavaScriptCore、そして多くのパフォーマンスと機能の改善が搭載されます。現在、リリース候補として公開されており、今後2週間以内に安定版になる予定です。

次のステップ

今後2か月間、私たちは順調に進むようプルリクエストの管理を継続し、同時に未解決のGitHubイシューの削減を開始します。Lean Coreプロジェクトを通じてReact Nativeの表面積を削減し続けます。主要なコミュニティ問題のうち5つに取り組む予定です。コミュニティガイドラインを最終決定するにつれて、ウェブサイトとドキュメントに注意を向けます。

3月には、これらの取り組みのいくつかを進めるために、Facebookロンドンでコミュニティから10人以上の貢献者を招き、大変嬉しく思っています。React Nativeをご利用いただきありがとうございます。2019年に私たちが取り組んでいる改善を見て、感じていただけると幸いです。数か月後に別の更新情報を掲載し、その間に皆様のプルリクエストをマージしていきます!⚛️✌️

2018年のReact Nativeコミュニティの現状

·4分で読めます
Lorenzo Sciandra
コアメンテナー & React Native開発者

2018年、React NativeコミュニティはReact Nativeの開発とコミュニケーションの方法について多くの変更を行いました。数年後に振り返ったとき、この変化がReact Nativeにとっての転換点だったとわかるだろうと信じています。

多くの人々が、React Nativeのアーキテクチャの書き換え(広くFabricとして知られている)に期待を寄せています。これにより、とりわけReact Nativeのアーキテクチャにおける根本的な制限が修正され、JSIとTurboModulesとともに、将来のReact Nativeの成功を確実にします。

2018年の最大の変化は、React Nativeコミュニティに力を与えたことです。当初から、Facebookは世界中の開発者がReact Nativeのオープンソースプロジェクトに参加することを奨励しました。それ以来、リリースプロセスなどを担当する主要な貢献者が数多く現れました。

これらのメンバーは、コミュニティ全体がこのプロジェクトの未来を形作る力をより持てるようにするため、以下のリソースを用いていくつかの重要なステップを踏み出しました。

react-native-releases 📬

このリポジトリは1月に作成され、より協力的な方法で誰もが新しいリリースに追いつけるようにするという二重の目的を果たし、特定のリリースの一部となるものについての議論を開き、チェリーピック(0.57.8とそのすべての以前のバージョンなど)を提案したい人なら誰でも参加できるようにしました。

これは、月ごとのリリースサイクルから脱却し、現在バージョン0.57.xで採用されている「長期サポート」アプローチへと移行する原動力となりました。

これらの決定に至った功績の半分は、今年作られたもう一つのリポジトリによるものです。

discussions-and-proposals 🗣

このリポジトリは7月に作成され、React Nativeに関するよりオープンな議論の場というアイデアを広げました。以前は、この必要性はメインリポジトリのFor Discussionとラベル付けされた問題によって処理されていましたが、この戦略を他のライブラリ(例:React)が持つRFCアプローチに拡大したいと考えました。

この実験は、React Nativeのライフサイクルにおいてすぐにその役割を見出しました。Facebookチームは現在、コミュニティのRFCプロセスを使用して、React Nativeで改善できることについて議論し、Lean Coreプロジェクトを中心とした取り組みを調整しています(他にも興味深い議論があります)。

@ReactNativeComm 🐣

私たちは、これらの取り組みを伝える私たちのアプローチが、私たちが望んでいたほど効果的ではなかったことを認識しており、React Nativeコミュニティで起こっているすべてのこと(リリースから活発な議論まで)を皆さんがより簡単に把握できるようにするために、頼りになる新しいTwitterアカウント@ReactNativeCommを作成しました。

もしあなたがそのSNSを利用していない場合でも、GitHub経由でリポジトリをWatchできることを覚えておいてください。この機能はここ数ヶ月で改善され、リリースのみの通知を受け取ることが可能になったので、いずれにせよ利用を検討する価値があります。

この先に待っているもの 🎓

過去7〜8か月間、主要な貢献者たちはReact Native Community GitHub組織を強化し、React Nativeの開発に対する所有権をさらに高め、Facebookとの連携を強化してきました。しかし、これには常に、同様のプロジェクトが持つかもしれない正式な構造が欠けていました。

この組織は、ホストされているすべてのパッケージ/リポジトリに一連の標準を適用し、メンテナーがお互いを助け、コミュニティで合意された標準に準拠する高品質のコードを貢献するための単一の場所を提供することで、より大きな開発者コミュニティのすべての人の模範となることができます。

2019年初頭には、この新しいガイドライン一式が整備される予定です。専用のディスカッションでご意見をお聞かせください。

これらの変更により、コミュニティはより協力的になり、バージョン1.0に到達したときには、この共同の取り組みを活用して、私たち全員が(さらに)素晴らしいアプリを書き続けることができると確信しています 🤗


皆さんが私たちと同じように、このコミュニティの未来にワクワクしていることを願っています。上記のリポジトリで行われている議論や、皆さんが生み出す素晴らしいコードを通じて、皆さんの参加を楽しみにしています。

ハッピーコーディング!

オープンソースのロードマップ

·5分で読めます
Héctor Ramos
Facebook エンジニア

今年、React Nativeチームは大規模なReact Nativeの再設計に注力してきました。Sophieが彼女のState of React Nativeの投稿で述べたように、私たちはFacebook以外のReact Nativeユーザーと協力者の活気あるコミュニティをより良くサポートするための計画を練り上げてきました。私たちが取り組んできたことについて、さらに詳しく共有する時が来ました。その前に、オープンソースにおけるReact Nativeの長期的なビジョンを説明したいと思います。

React Nativeに対する私たちのビジョンは…

  • 健全なGitHubリポジトリ。 IssueとPull Requestが妥当な期間内に処理されること。
    • テストカバレッジの向上。
    • Facebookのコードリポジトリから同期されるコミットが、オープンソースのテストを破壊しないこと。
    • より大規模で意味のあるコミュニティからのコントリビューション。
  • 安定したAPI群。 オープンソースの依存関係との連携が容易になること。
    • Facebookがオープンソースと同じ公開APIを使用すること。
    • React Nativeのリリースがセマンティックバージョニングに従うこと。
  • 活気のあるエコシステム。 コミュニティによって維持される、高品質なViewManager、ネイティブモジュール、および複数のプラットフォームのサポート。
  • 優れたドキュメント。 ユーザーが高品質な体験を創造する手助けに焦点を当て、APIリファレンスドキュメントを最新の状態に保つこと。

このビジョンを達成するために、以下の重点分野を特定しました。

✂️ Lean Core

私たちの目標は、非コアで未使用のコンポーネントを削除することで、React Nativeの表面積を減らすことです。非コアコンポーネントは、コミュニティがより速く動けるように、コミュニティに移管します。表面積が減ることで、React Nativeへの貢献の管理が容易になります。

WebViewは、コミュニティに移管したコンポーネントの例です。私たちは、これらのコンポーネントをリポジトリから削除した後も、内部チームがそれらを引き続き使用できるようなワークフローに取り組んでいます。私たちは、コミュニティに所有権を与えるさらに数十のコンポーネントを特定しました。

🎁 内部のオープンソース化と🛠ツール更新

FacebookのプロダクトチームにとってのReact Nativeの開発体験は、オープンソースとはかなり異なる場合があります。オープンソースコミュニティで人気のあるツールはFacebookでは使用されていません。同じ目的を達成する内部ツールがあるかもしれません。場合によっては、FacebookチームはFacebook以外の場所には存在しないツールに慣れてしまっていることもあります。これらの不一致は、今後のアーキテクチャ作業をオープンソース化する際に課題となる可能性があります。

私たちはこれらの社内ツールの一部を公開する作業を進めます。また、オープンソースコミュニティで人気のツールのサポートも改善します。以下は、私たちが取り組むプロジェクトの(すべてではない)リストです。

  • JSIをオープンソース化し、コミュニティが独自のJavaScript VMを持ち込み、RNの初期リリースからの既存のJavaScriptCoreを置き換えることを可能にします。JSIが何であるかについては今後の投稿で説明しますが、それまではReact ConfでのParashuramの講演からJSIについて詳しく学ぶことができます。
  • Androidでの64ビットライブラリのサポート。
  • 新しいアーキテクチャ下でのデバッグを可能にする。
  • CocoaPods、Gradle、Maven、および新しいXcodeビルドシステムのサポートを改善する。

✅ テストインフラストラクチャ

Facebookのエンジニアがコードを公開するとき、すべてのテストに合格すれば安全に適用できると考えられています。これらのテストは、変更が独自のReact Nativeの表面を破壊するかどうかを特定します。しかし、FacebookがReact Nativeを使用する方法には違いがあります。これにより、意図せずにオープンソースでReact Nativeを破壊してしまうことがありました。

オープンソースに可能な限り近い環境で実行されるように、内部テストを強化します。これにより、これらのテストを破るコードがオープンソースに公開されるのを防ぐことができます。また、GitHubのコアリポジトリのテストを改善するためのインフラストラクチャも開発し、将来のプルリクエストにテストを簡単に含めることができるようにします。

対象領域の縮小と組み合わせることで、コントリビューターは自信を持ってより迅速にPull Requestをマージできるようになります。

📜 パブリックAPI

意図しない破壊的変更を減らすため、Facebookはオープンソースと同じ方法でパブリックAPIを介してReact Nativeを利用します。これに対処するため、内部の呼び出しサイトの変換を開始しました。私たちの目標は、安定したパブリックAPIに収束し、バージョン1.0でセマンティックバージョニングの採用につながることです。

📣 コミュニケーション

React Nativeは、貢献者の数でGitHubでトップのオープンソースプロジェクトの1つです。私たちはそれを本当に嬉しく思っており、この状態を維持していきたいと考えています。透明性の向上やオープンな議論など、貢献者の参加を促すイニシアチブに引き続き取り組んでいきます。ドキュメントはReact Nativeに初めて触れる人が最初に目にするものですが、これまでは優先事項ではありませんでした。私たちはこれを改善したいと考えており、自動生成されたAPIリファレンスドキュメントの復活、質の高いユーザーエクスペリエンスの作成に焦点を当てた追加コンテンツの作成、そしてリリースノートの改善から始めます。

タイムライン

これらのプロジェクトは、今後1年程度の間に実施する予定です。これらの取り組みの一部はすでに進行中であり、例えばJSIはすでにオープンソースに組み込まれています。一方、表面積の削減など、完了までに少し時間がかかるものもあります。私たちは進捗状況をコミュニティに常に最新の状態で伝えるよう最善を尽くします。このロードマップで議論されているいくつかのイニシアチブの作成につながったReact NativeコミュニティのイニシアチブであるDiscussions and Proposalsリポジトリにご参加ください。

新しいiOS WebViewの導入

·3分で読めます
Facebook ソフトウェアエンジニア

長らくAppleはUIWebViewの使用を控え、WKWebViewの使用を推奨してきました。数ヶ月以内にリリースされるiOS 12では、UIWebViewは正式に非推奨となります。React NativeのiOS WebViewの実装は、UIWebViewクラスに大きく依存しています。そのため、これらの進展を受け、WKWebViewを使用するWebView React Nativeコンポーネント用の新しいネイティブiOSバックエンドを構築しました。

これらの変更の最終段階はこのコミットで取り込まれ、0.57リリースで利用可能になります。

この新しい実装を選択するには、useWebKitプロパティを使用してください。

<WebView
useWebKit={true}
source={{url: 'https://www.google.com'}}
/>

改善点

UIWebViewには、WebView内で実行されているJavaScriptとReact Native間の通信を円滑にする正当な方法がありませんでした。WebViewからメッセージが送信されるとき、私たちはそれらをReact Nativeに配信するためのハックに頼っていました。簡潔に言うと、メッセージデータを特殊なスキームを持つURLにエンコードし、WebViewをそのURLにナビゲートしていました。ネイティブ側では、このナビゲーションを傍受してキャンセルし、URLからデータを解析し、最終的にReact Nativeを呼び出していました。この実装はエラーが発生しやすく、安全ではありませんでした。この度、WKWebViewの機能を活用してこれを完全に置き換えることができたことをお知らせいたします。

WKWebViewがUIWebViewよりも優れている点として、JavaScriptの実行速度の向上やマルチプロセスアーキテクチャが挙げられます。詳細は2014年のWWDCをご覧ください。

注意点

コンポーネントが以下のプロパティを使用している場合、WKWebViewに切り替えると問題が発生する可能性があります。当面の間、これらのプロパティの使用は避けることをお勧めします。

動作の不整合

automaticallyAdjustContentInsets および contentInsets (コミット)

WKWebViewにcontentInsetsを追加しても、WKWebViewのビューポートは変更されません。ビューポートはフレームと同じサイズを維持します。UIWebViewでは、ビューポートのサイズが実際に変更されます(コンテンツインセットが正の場合、小さくなります)。

backgroundColor (コミット)

新しいWebViewのiOS実装では、このプロパティを使用すると、背景色がちらつく可能性があります。さらに、WKWebViewは透明な背景をUIWebviewとは異なる方法でレンダリングします。詳細については、コミットの説明をご覧ください。

非サポート

scalesPageToFit (コミット)

WKWebViewはscalesPageToFitプロパティをサポートしていなかったため、WebView React Nativeコンポーネントではこれを実装できませんでした。

アクセシビリティAPIの更新

·7分で読めます
Ziqi Chen
カリフォルニア大学バークレー校 学生

動機

テクノロジーが進歩し、モバイルアプリが日常生活においてますます重要になるにつれて、アクセシブルなアプリケーションを作成する必要性も同様に重要性を増しています。

React Nativeの限定的なアクセシビリティAPIは、開発者にとって常に大きな悩みの種でした。そこで私たちは、インクルーシブなモバイルアプリケーションをより簡単に作成できるように、アクセシビリティAPIにいくつかのアップデートを行いました。

既存APIの問題点

問題点1:まったく異なるのに似ている2つのプロパティ - accessibilityComponentType (Android) と accessibilityTraits (iOS)

accessibilityComponentTypeaccessibilityTraits は、AndroidのTalkBackとiOSのVoiceOverに、ユーザーがどのようなUI要素を操作しているかを伝えるために使用される2つのプロパティです。これらのプロパティの最大の問題は、

  1. それらは、使用方法が異なりながらも同じ目的を持つ2つの異なるプロパティであることです。以前のAPIでは、これらは(プラットフォームごとに1つずつ)2つの別々のプロパティであり、不便なだけでなく、多くの開発者にとって混乱を招くものでした。iOSのaccessibilityTraitsは17種類の異なる値を許容しますが、AndroidのaccessibilityComponentTypeは4種類の値しか許容しません。さらに、ほとんどの場合、これらの値には重複がありませんでした。これら2つのプロパティの入力型さえ異なります。accessibilityTraitsは特性の配列または単一の特性を渡すことができますが、accessibilityComponentTypeは単一の値のみを許容します。
  2. Androidでの機能が非常に限られています。 古いプロパティでは、Talkbackが認識できるUI要素は「button」、「radiobutton_checked」、「radiobutton_unchecked」のみでした。

問題点2:存在しないアクセシビリティヒント

アクセシビリティヒントは、TalkBackやVoiceOverを使用しているユーザーが、アクセシビリティラベルだけでは明らかでないアクセシビリティ要素に対してアクションを実行したときに何が起こるかを理解するのに役立ちます。これらのヒントは、設定パネルでオンオフを切り替えることができます。以前は、React NativeのAPIはアクセシビリティヒントをまったくサポートしていませんでした。

問題点3:反転色を無視する

一部の視覚障害のあるユーザーは、画面のコントラストを高めるために、携帯電話で反転色を使用しています。Appleは、開発者が特定のビューを無視できるiOS用のAPIを提供しています。これにより、ユーザーが反転色設定をオンにしていても、画像や動画が歪むことはありません。このAPIは現在、React Nativeではサポートされていません。

新しいAPIの設計

解決策1:accessibilityComponentType (Android) と accessibilityTraits (iOS) の統合

accessibilityComponentTypeaccessibilityTraitsの間の混乱を解決するために、それらを単一のプロパティに統合することを決定しました。これらは技術的に同じ意図された機能を持っていたため、統合することで理にかなっていました。開発者はアクセシビリティ機能を構築する際に、プラットフォーム固有の複雑さを心配する必要がなくなりました。

背景

iOSでは、UIAccessibilityTraitsは任意のNSObjectに設定できるプロパティです。JavaScriptプロパティを介してネイティブに渡される17個の特性はそれぞれ、Objective-CのUIAccessibilityTraits要素にマッピングされます。特性はそれぞれlong intで表現され、設定されたすべての特性はOR演算で結合されます。

しかしAndroidでは、AccessibilityComponentTypeはReact Nativeによって作られた概念であり、Androidのプロパティに直接マッピングされません。アクセシビリティはアクセシビリティデリゲートによって処理されます。各ビューにはデフォルトのアクセシビリティデリゲートがあります。アクセシビリティアクションをカスタマイズしたい場合は、新しいアクセシビリティデリゲートを作成し、カスタマイズしたい特定のメソッドをオーバーライドし、そして処理しているビューのアクセシビリティデリゲートを新しいデリゲートと関連付けるように設定する必要があります。開発者がAccessibilityComponentTypeを設定すると、ネイティブコードは渡されたコンポーネントに基づいて新しいデリゲートを作成し、そのアクセシビリティデリゲートを持つようにビューを設定しました。

行われた変更

新しいプロパティでは、2つのプロパティのスーパセットを作成したいと考えました。新しいプロパティは、既存のaccessibilityTraitsプロパティを主としてモデル化することにしました。accessibilityTraitsには、はるかに多くの値があるためです。これらの特性に対するAndroidの機能は、アクセシビリティデリゲートを修正することでポリフィルされます。

iOSのaccessibilityTraitsに設定できるUIAccessibilityTraitsの値は17種類あります。しかし、そのすべてを新しいプロパティの可能な値として含めたわけではありません。これは、これらの特性の一部を設定する効果があまりよく知られておらず、これらの値の多くは事実上ほとんど使用されていないためです。

UIAccessibilityTraitsの値は、一般的に2つの目的のいずれかを果たしました。UI要素が持つ役割を記述するか、UI要素の状態を記述するかのどちらかです。以前のプロパティのほとんどの使用例では、通常、役割を表す1つの値を使用し、「state selected」、「state disabled」、またはその両方と組み合わせていました。そのため、accessibilityRoleaccessibilityStateの2つの新しいアクセシビリティプロパティを作成することにしました。

accessibilityRole

新しいプロパティaccessibilityRoleは、TalkbackやVoiceoverにUI要素の役割を伝えるために使用されます。この新しいプロパティは、以下のいずれかの値を取ることができます。

  • none
  • button
  • link
  • search
  • image
  • keyboardkey
  • text
  • adjustable
  • header
  • summary
  • imagebutton

このプロパティは、UI要素が論理的にこれらのうちの1つ以上を取ることが一般的にないため、1つの値のみを渡すことができます。例外はimageとbuttonなので、両方を組み合わせたimagebuttonという役割を追加しました。

accessibilityStates

新しいプロパティaccessibilityStatesは、TalkbackやVoiceoverにUI要素がどのような状態にあるかを伝えるために使用されます。このプロパティは、以下の値のいずれかまたは両方を含む配列を取ります。

  • selected
  • disabled

解決策2:アクセシビリティヒントの追加

このために、新しいプロパティaccessibilityHintを追加しました。このプロパティを設定すると、TalkbackやVoiceoverがユーザーにヒントを読み上げることができるようになります。

accessibilityHint

このプロパティは、読み上げられるアクセシビリティヒントを文字列の形式で受け取ります。

iOSでは、このプロパティを設定すると、ビューに対応するネイティブプロパティAccessibilityHintが設定されます。iPhoneでアクセシビリティヒントがオンになっている場合、ヒントはVoiceoverによって読み上げられます。

Androidでは、このプロパティを設定すると、ヒントの値がアクセシビリティラベルの末尾に付加されます。この実装の利点は、iOSのヒントの動作を模倣していることですが、欠点は、AndroidではiOSのように設定でこれらのヒントをオフにできないことです。

Androidでこの決定を下した理由は、通常、アクセシビリティヒントは特定のアクション(例:クリック)に対応しており、プラットフォーム間で動作の一貫性を保ちたかったためです。

問題点3の解決策

accessibilityIgnoresInvertColors

私たちはAppleのAPIであるAccessibilityIgnoresInvertColorsをJavaScriptに公開しました。これにより、色を反転させたくないビュー(例:画像)がある場合、このプロパティをtrueに設定すると、反転されなくなります。

新しい使用法

これらの新しいプロパティは、React Native 0.57リリースで利用可能になります。

アップグレード方法

現在accessibilityComponentTypeaccessibilityTraitsを使用している場合は、以下の手順で新しいプロパティにアップグレードできます。

1. jscodeshiftを使用する

最も単純なユースケースは、jscodeshiftスクリプトを実行することで置き換えることができます。

このスクリプトは、以下のインスタンスを置き換えます。

accessibilityTraits=“trait”
accessibilityTraits={[“trait”]}

以下のように

accessibilityRole= “trait”

このスクリプトはまた、AccessibilityComponentTypeのインスタンスを削除します(AccessibilityComponentTypeを設定するすべての場所でAccessibilityTraitsも設定すると仮定しています)。

2. 手動のコードモッドを使用する

AccessibilityTraitsを使用し、AccessibilityRoleに該当する値がない場合、および複数の特性がAccessibilityTraitsに渡された場合は、手動でコードモッドを行う必要があります。

一般的に、

accessibilityTraits= {[“button”, “selected”]}

は手動で以下のように置き換えられます。

accessibilityRole=“button”
accessibilityStates={[“selected”]}

これらのプロパティはすでにFacebookのコードベースで使用されています。Facebookのコードモッドは驚くほどシンプルでした。jscodeshiftスクリプトは約半分のインスタンスを修正し、残りの半分は手動で修正されました。全体として、全プロセスにかかった時間は数時間未満でした。

更新されたAPIが役立つことを願っています!そして、引き続きアクセシブルなアプリを作り続けてください!#inclusion

0.56のリリース

·6分で読めます
Lorenzo Sciandra
Drivetribeのコアメンテナー兼React Native開発者

待望のReact Native 0.56バージョンが利用可能になりました🎉。このブログ記事では、この新しいリリースで導入された変更点の一部をハイライトしています。また、3月以降、私たちが何に忙殺されてきたのかを説明する機会でもあります。

破壊的変更のジレンマ、あるいは「いつリリースするか?」

コントリビューターガイドでは、React Nativeへのすべての変更が経る統合プロセスについて説明しています。プロジェクトは多くの異なるツールで構成されており、すべてを適切に機能させるために連携と継続的なサポートが必要です。これに、プロジェクトに貢献する活気あるオープンソースコミュニティが加わると、その途方もない規模がわかるでしょう。

React Nativeの目覚ましい普及に伴い、破壊的変更は細心の注意を払って行われる必要があり、そのプロセスは望むほどスムーズではありません。コアチームが新しい一連の破壊的変更を統合しテストするために、4月と5月のリリースをスキップする決定がなされました。専用のコミュニティコミュニケーションチャネルが使用され、2018年6月の(0.56.0)リリースが、安定版リリースを辛抱強く待っていた人々にとって可能な限り問題なく採用できるものとなるよう、その過程で確保されました。

0.56.0 は完璧か?いいえ、世の中のすべてのソフトウェアと同様にそうではありません。しかし、「さらなる安定性を待つ」ことと「テストによって成功した結果が得られたので、前に進めることができる」ことのトレードオフにおいて、リリースする準備ができたと感じる時点に達しました。さらに、最終的な 0.56.0 リリースで解決されていない いくつかの 問題 ある ことも認識しています。ほとんどの開発者は 0.56.0 へのアップグレードで問題はないはずです。前述の問題でブロックされている方々には、議論にご参加いただき、これらの問題の解決に向けて皆様と協力できることを楽しみにしています。

0.56.0は、より安定したフレームワークに向けた基礎的なビルディングブロックと考えることができるでしょう。すべてのエッジケースが取り除かれるまでには、おそらく1~2週間の普及期間が必要となるでしょうが、これにより2018年7月の(0.57.0)リリースはさらに優れたものになるはずです。

このセクションの最後に、合計818コミット (!) に取り組んだ67名のコントリビューター全員に感謝の意を表したいと思います。彼らの貢献があなたのアプリをさらに良くするでしょう 👏。

それでは、早速ですが...

大きな変更点

Babel 7

ご存知のように、私たち全員がJavaScriptの最新かつ最高の機能を使用できるようにするトランスパイラツールであるBabelは、まもなくv7に移行します。この新しいバージョンにはいくつかの重要な変更が伴うため、今がアップグレードの良い時期だと感じ、Metroその改善を活用できるようにしました。

アップグレードで問題が発生した場合は、関連するドキュメントセクションを参照してください。

Androidサポートの近代化

Android では、多くの周辺ツールが変更されました。 Gradle 3.5Android SDK 26Fresco を 1.9.0、OkHttp を 3.10.0 に更新し、さらには NDK API ターゲットを API 16 にしました。これらの変更は問題なく行われ、ビルドが高速化されるはずです。さらに重要なことは、これにより開発者が来月施行される 新しい Play ストア要件 を遵守できるようになることです。

これに関連して、特にDulmandakh氏が、これを可能にするために提出された多くのPRに感謝したいと思います👏。

この方向性でさらにいくつかのステップを踏む必要があります。Androidサポートの更新に関する今後の計画と議論は、専用のイシュー(およびJSCに関する追加のイシュー)で追跡できます。

新しいNode、Xcode、React、Flow – 盛りだくさん!

Node 8がReact Nativeの標準になりました。実はすでにテストが行われていましたが、Node 6がメンテナンスモードに入ったため、私たちは両足を前に踏み出しました。Reactも16.4にアップデートされ、多くの修正がもたらされました。

iOS 8のサポートを終了し、iOS 9をターゲットにできる最古のiOSバージョンとしました。iOS 8が実行できるデバイスはすべてiOS 9にアップグレードできるため、これが問題になるとは予測していません。この変更により、iOS 8を実行している古いデバイスの回避策を実装するためにほとんど使用されていなかったコードを削除できました。

継続的インテグレーションツールチェーンはXcode 9.4を使用するように更新され、すべてのiOSテストがAppleが提供する最新の開発者ツールで実行されることを保証します。

多くの開発者に好評な新しいエラー形式を使用するためにFlow 0.75にアップグレードしました。また、さらに多くのコンポーネントの型を作成しました。まだプロジェクトで静的型付けを強制していない場合は、実行時ではなくコーディング中に問題を特定するためにFlowの使用を検討してください。

その他多くのこと...

たとえば、YellowBoxは新しい実装に置き換えられ、デバッグが大幅に改善されました。

完全なリリースノートについては、こちらの完全な変更ログを参照してください。また、この新しいバージョンへの移行で問題が発生しないように、アップグレードガイドにも注意してください。


最後に:今週から、React Nativeコアチームは毎月の会議を再開します。会議で何が議論されたかについて全員が最新の情報を把握できるようにし、今後の会議のために皆様からのフィードバックを手元に置いておくようにします。

皆さん、楽しいコーディングを!

LorenzoRyan、そしてReact Nativeコアチーム一同

追伸:いつものように、React Nativeはまだ多くの変更が進行中であるため0.xバージョンであることを皆さんに思い出させたいと思います。したがって、アップグレードの際には、おそらく何らかの問題が発生したり、壊れたりする可能性があることを忘れないでください。問題提起やプルリクエストの提出の際にはお互いに協力し、施行されているCoCに従うことを忘れないでください。画面の向こうには常に人間がいます。

React Nativeの現状 2018

·5分で読めます
Sophie Alpert
Facebook React エンジニアリングマネージャー

React Nativeの現状について最後のアップデートを公開してから、しばらく時間が経ちました。

Facebookでは、これまで以上に多くのReact Nativeを、そして多くの重要なプロジェクトで使用しています。最も人気のある製品の1つはMarketplaceで、私たちのアプリのトップレベルタブの1つであり、毎月8億人のユーザーが利用しています。2015年の立ち上げ以来、MarketplaceのすべてはReact Nativeで構築されており、アプリのさまざまな部分にわたって100以上の全画面ビューが含まれています。

また、アプリの多くの新しい部分にもReact Nativeを使用しています。先月のF8基調講演をご覧になった方は、献血、災害時対応、プライバシーショートカット、ウェルネスチェックを覚えているでしょう。これらはすべてReact Nativeで構築された最近の機能です。そして、主要なFacebookアプリ以外のプロジェクトでもReact Nativeが使用されています。新しいOculus Go VRヘッドセットには、完全にReact Nativeで構築されたコンパニオンモバイルアプリが含まれています。ヘッドセット自体の多くの体験にReact VRが利用されていることは言うまでもありません。

もちろん、アプリを構築するために他の多くのテクノロジーも使用しています。LithoComponentKitは、アプリで広く使用されている2つのライブラリです。どちらも、ネイティブ画面を構築するためのReactのようなコンポーネントAPIを提供します。React Nativeが他のすべてのテクノロジーを置き換えることが目標だったことは一度もありません。私たちはReact Native自体をより良くすることに焦点を当てていますが、他のチームがReact Nativeからアイデアを借用し、JavaScript以外のコードにもインスタントリロードをもたらすのを見るのが大好きです。

アーキテクチャ

2013年にReact Nativeプロジェクトを開始したとき、JavaScriptとネイティブの間に単一の「ブリッジ」があり、それが非同期で、シリアル化可能で、バッチ処理されるように設計しました。React DOMがReactの状態更新を、document.createElement(attrs).appendChild()のようなDOM APIへの命令的で可変的な呼び出しに変換するように、React Nativeは、[["createView", attrs], ["manageChildren", ...]]のように、実行するミューテーションをリストする単一のJSONメッセージを返すように設計されました。私たちは、同期応答が返されることに決して依存せず、そのリスト内のすべてがJSONに完全にシリアル化されて元に戻せることを保証するように、システム全体を設計しました。これは、私たちに与えられた柔軟性のために行ったことです。このアーキテクチャの上に、WebSocket接続を介してすべてのJavaScriptコードを非同期に実行するChromeデバッグのようなツールを構築することができました。

過去5年間で、これらの初期原則が一部の機能の構築をより困難にしていることがわかりました。非同期ブリッジとは、同期応答を期待する多くのネイティブAPIとJavaScriptロジックを直接統合できないことを意味します。ネイティブ呼び出しをキューに入れるバッチ処理されたブリッジは、React Nativeアプリがネイティブに実装された関数を呼び出すことをより困難にします。そして、シリアル化可能なブリッジは、2つの世界間でメモリを直接共有するのではなく、不必要なコピーを意味します。完全にReact Nativeで構築されたアプリの場合、これらの制限は通常耐えられます。しかし、React Nativeと既存のアプリコードとの複雑な統合を持つアプリの場合、それらはフラストレーションを引き起こします。

React Nativeのフレームワークをより柔軟にし、ハイブリッドJavaScript/ネイティブアプリでネイティブインフラストラクチャとより適切に統合するために、React Nativeの大規模な再アーキテクチャに取り組んでいます。このプロジェクトでは、過去5年間で学んだことを適用し、アーキテクチャを段階的により現代的なものにします。React Nativeの内部の多くを書き直していますが、変更のほとんどは内部的なものです。既存のReact Nativeアプリは、変更なしまたはほとんど変更なしで引き続き動作します。

React Nativeをより軽量にし、既存のネイティブアプリにより適切に適合させるために、この再アーキテクチャには3つの主要な内部変更があります。まず、スレッドモデルを変更しています。各UI更新が3つの異なるスレッドで作業を実行する必要がある代わりに、応答性を維持するために優先度の低い作業をメインスレッドから外しながら、高優先度の更新のために任意の​​スレッドでJavaScriptを同期的に呼び出すことが可能になります。次に、複数のレンダリング優先度を可能にし、非同期データ処理を簡素化するために、React Nativeに非同期レンダリング機能を組み込んでいます。最後に、ブリッジを簡素化して、より高速で軽量にします。ネイティブとJavaScript間の直接呼び出しはより効率的になり、クロス言語スタックトレースのようなデバッグツールの構築を容易にします。

これらの変更が完了すると、より密接な統合が可能になります。現在、複雑なハックなしに、ネイティブナビゲーションとジェスチャー処理、またはUICollectionViewやRecyclerViewのようなネイティブコンポーネントを組み込むことはできません。スレッドモデルの変更後、このような機能の構築は簡単になります。

この作業が完了に近づくにつれて、今年後半に詳細を公開する予定です。

コミュニティ

Facebook内のコミュニティとともに、Facebook以外にも活発なReact Nativeユーザーと協力者がいることを嬉しく思います。React Nativeユーザーをより良くサポートし、プロジェクトへの貢献を容易にすることで、React Nativeコミュニティをさらに支援したいと考えています。

アーキテクチャの変更がReact Nativeと他のネイティブインフラストラクチャとのよりクリーンな相互運用を助けるのと同様に、React NativeはVMとバンドラーを交換可能にすることを含め、JavaScriptエコシステムにより良く適合するようにJavaScript側でよりスリムであるべきです。私たちは、破壊的変更のペースに追いつくのが難しいことを知っているので、より少ないメジャーリリースを行う方法を見つけたいと考えています。最後に、一部のチームが、私たちの専門知識がまだ書き留められていない起動最適化のようなトピックで、より徹底したドキュメントを求めていることを知っています。来年には、これらの変更の一部が見られることを期待してください。

あなたがReact Nativeを使用しているなら、あなたは私たちのコミュニティの一員です。React Nativeをあなたにとってより良くするために、引き続きご意見をお聞かせください。

React Nativeはモバイル開発者の道具箱の中の一つのツールに過ぎませんが、私たちが強く信じているツールであり、過去1年間で500人以上のコントリビューターから2500以上のコミットを得て、日々改善しています。

React NativeでTypeScriptを使用する

·8分で読めます
Ash Furrow
Artsy ソフトウェアエンジニア

JavaScript!私たちは皆、JavaScriptを愛しています。しかし、私たちの中にはを愛する者もいます。幸いなことに、JavaScriptに強力な型を追加する選択肢は存在します。私のお気に入りはTypeScriptですが、React NativeはFlowをそのままサポートしています。どちらを好むかは個人の好みであり、それぞれがJavaScriptに型の魔法を追加する方法について独自のアプローチを持っています。今日は、React NativeアプリでTypeScriptを使用する方法について見ていきます。

この記事では、MicrosoftのTypeScript-React-Native-Starterリポジトリをガイドとして使用します。

更新: このブログ記事が書かれてから、さらに簡単になりました。このブログ記事で説明されているセットアップはすべて、たった1つのコマンドを実行するだけで置き換えられます。

npx react-native init MyAwesomeProject --template react-native-template-typescript

ただし、BabelのTypeScriptサポートにはいくつかの制限があり、上記のブログ記事で詳しく説明されています。この投稿で概説されている手順は引き続き機能し、Artsyは引き続きreact-native-typescript-transformerを本番環境で使用していますが、React NativeとTypeScriptを使い始めるための最も速い方法は、上記のコマンドを使用することです。必要であれば、いつでも後で切り替えることができます。

いずれにせよ、楽しんでください!元のブログ記事は以下に続きます。

前提条件

いくつかの異なるプラットフォームで開発し、いくつかの異なる種類のデバイスをターゲットにしている可能性があるため、基本的なセットアップには手間がかかる場合があります。まず、TypeScriptなしで通常のReact Nativeアプリを実行できることを確認する必要があります。React Nativeのウェブサイトの手順に従って開始してください。デバイスまたはエミュレーターにデプロイできるようになったら、TypeScript React Nativeアプリを開始する準備が整います。

Node.jsnpm、およびYarnも必要です。

初期化

通常のReact Nativeプロジェクトのひな形を作成してみたら、TypeScriptを追加する準備が整います。さあ、やってみましょう。

react-native init MyAwesomeProject
cd MyAwesomeProject

TypeScriptの追加

次のステップは、プロジェクトにTypeScriptを追加することです。以下のコマンドは、

  • プロジェクトにTypeScriptを追加します
  • プロジェクトにReact Native TypeScript Transformerを追加します
  • 空のTypeScript設定ファイルを初期化します。これは次に設定します
  • 空のReact Native TypeScript Transformer設定ファイルを追加します。これは次に設定します
  • ReactとReact Nativeの型定義を追加します

では、これらを実行してみましょう。

yarn add --dev typescript
yarn add --dev react-native-typescript-transformer
yarn tsc --init --pretty --jsx react
touch rn-cli.config.js
yarn add --dev @types/react @types/react-native

tsconfig.jsonファイルにはTypeScriptコンパイラのすべての設定が含まれています。上記のコマンドで作成されたデフォルトはほとんど問題ありませんが、ファイルを開いて次の行のコメントを解除してください。

{
/* Search the config file for the following line and uncomment it. */
// "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
}

rn-cli.config.jsにはReact Native TypeScript Transformerの設定が含まれています。それを開いて以下を追加してください。

module.exports = {
getTransformModulePath() {
return require.resolve('react-native-typescript-transformer');
},
getSourceExts() {
return ['ts', 'tsx'];
},
};

TypeScriptへの移行

生成されたApp.js__tests_/App.jsファイルをApp.tsxに名前変更します。index.js.js拡張子を使用する必要があります。すべての新しいファイルは.tsx拡張子(またはファイルにJSXが含まれていない場合は.ts)を使用する必要があります。

今すぐアプリを実行しようとすると、「object prototype may only be an object or null」のようなエラーが発生します。これは、Reactからのデフォルトエクスポートと、同じ行での名前付きエクスポートのインポートに失敗したことが原因です。App.tsxを開き、ファイルの先頭にあるインポートを変更します。

-import React, { Component } from 'react';
+import React from 'react'
+import { Component } from 'react';

これの一部は、BabelとTypeScriptがCommonJSモジュールと相互運用する方法の違いに関係しています。将来的には、両者は同じ挙動に安定するでしょう。

この時点で、React Nativeアプリを実行できるはずです。

TypeScriptテストインフラストラクチャの追加

React NativeにはJestが同梱されているため、TypeScriptでReact Nativeアプリをテストするには、devDependenciests-jestを追加します。

yarn add --dev ts-jest

次に、package.jsonを開き、jestフィールドを以下に置き換えます。

{
"jest": {
"preset": "react-native",
"moduleFileExtensions": [
"ts",
"tsx",
"js"
],
"transform": {
"^.+\\.(js)$": "<rootDir>/node_modules/babel-jest",
"\\.(ts|tsx)$": "<rootDir>/node_modules/ts-jest/preprocessor.js"
},
"testRegex": "(/__tests__/.*|\\.(test|spec))\\.(ts|tsx|js)$",
"testPathIgnorePatterns": [
"\\.snap$",
"<rootDir>/node_modules/"
],
"cacheDirectory": ".jest/cache"
}
}

これにより、Jestは.tsおよび.tsxファイルをts-jestで実行するように設定されます。

依存関係の型宣言のインストール

TypeScriptで最高の体験を得るには、型チェッカーが依存関係の形状とAPIを理解している必要があります。一部のライブラリは、基になるJavaScriptの形状を記述できる.d.tsファイル(型宣言/型定義ファイル)を含むパッケージを公開します。他のライブラリの場合、@types/ npmスコープ内の適切なパッケージを明示的にインストールする必要があります。

たとえば、ここではJest、React、React Native、およびReact Test Rendererの型が必要になります。

yarn add --dev @types/jest @types/react @types/react-native @types/react-test-renderer

これらの宣言ファイルパッケージは、開発中のみこれらの依存関係を使用し、実行時には使用しないReact Native アプリであるため、開発依存関係として保存しました。ライブラリをNPMに公開する場合、これらの型依存関係の一部を通常の依存関係として追加する必要があるかもしれません。

.d.tsファイルの入手方法についてはこちらで詳しく読むことができます。

さらにファイルを無視する

ソース管理では、.jestフォルダを無視するように設定する必要があります。gitを使用している場合は、.gitignoreファイルにエントリを追加するだけです。

# Jest
#
.jest/

チェックポイントとして、ファイルをバージョン管理にコミットすることを検討してください。

git init
git add .gitignore # import to do this first, to ignore our files
git add .
git commit -am "Initial commit."

コンポーネントの追加

アプリにコンポーネントを追加しましょう。Hello.tsxコンポーネントを作成します。これは教育的なコンポーネントであり、実際にアプリで書くようなものではありませんが、React NativeでTypeScriptを使用する方法を示すための、ある程度複雑なものです。

componentsディレクトリを作成し、以下の例を追加してください。

// components/Hello.tsx
import React from 'react';
import {Button, StyleSheet, Text, View} from 'react-native';

export interface Props {
name: string;
enthusiasmLevel?: number;
}

interface State {
enthusiasmLevel: number;
}

export class Hello extends React.Component<Props, State> {
constructor(props: Props) {
super(props);

if ((props.enthusiasmLevel || 0) <= 0) {
throw new Error(
'You could be a little more enthusiastic. :D',
);
}

this.state = {
enthusiasmLevel: props.enthusiasmLevel || 1,
};
}

onIncrement = () =>
this.setState({
enthusiasmLevel: this.state.enthusiasmLevel + 1,
});
onDecrement = () =>
this.setState({
enthusiasmLevel: this.state.enthusiasmLevel - 1,
});
getExclamationMarks = (numChars: number) =>
Array(numChars + 1).join('!');

render() {
return (
<View style={styles.root}>
<Text style={styles.greeting}>
Hello{' '}
{this.props.name +
this.getExclamationMarks(this.state.enthusiasmLevel)}
</Text>

<View style={styles.buttons}>
<View style={styles.button}>
<Button
title="-"
onPress={this.onDecrement}
accessibilityLabel="decrement"
color="red"
/>
</View>

<View style={styles.button}>
<Button
title="+"
onPress={this.onIncrement}
accessibilityLabel="increment"
color="blue"
/>
</View>
</View>
</View>
);
}
}

// styles
const styles = StyleSheet.create({
root: {
alignItems: 'center',
alignSelf: 'center',
},
buttons: {
flexDirection: 'row',
minHeight: 70,
alignItems: 'stretch',
alignSelf: 'center',
borderWidth: 5,
},
button: {
flex: 1,
paddingVertical: 0,
},
greeting: {
color: '#999',
fontWeight: 'bold',
},
});

おお!たくさんありますが、分解してみましょう。

  • divspanh1などのHTML要素をレンダリングする代わりに、ViewButtonなどのコンポーネントをレンダリングしています。これらは、異なるプラットフォームで動作するネイティブコンポーネントです。
  • スタイリングは、React Nativeが提供するStyleSheet.create関数を使用して指定されます。Reactのスタイルシートを使用すると、Flexboxを使用してレイアウトを制御したり、CSSの他の構成要素に似たものを使用してスタイルを設定したりできます。

コンポーネントテストの追加

コンポーネントができたので、テストしてみましょう。

テストランナーとしてJestはすでにインストールされています。コンポーネントのスナップショットテストを記述するので、スナップショットテストに必要なアドオンを追加しましょう。

yarn add --dev react-addons-test-utils

それでは、componentsディレクトリに__tests__フォルダを作成し、Hello.tsxのテストを追加しましょう。

// components/__tests__/Hello.tsx
import React from 'react';
import renderer from 'react-test-renderer';

import {Hello} from '../Hello';

it('renders correctly with defaults', () => {
const button = renderer
.create(<Hello name="World" enthusiasmLevel={1} />)
.toJSON();
expect(button).toMatchSnapshot();
});

テストが最初に実行されると、レンダリングされたコンポーネントのスナップショットが作成され、components/__tests__/__snapshots__/Hello.tsx.snapファイルに保存されます。コンポーネントを変更すると、スナップショットを更新し、意図しない変更がないか更新を確認する必要があります。React Nativeコンポーネントのテストについては、こちらで詳しく読むことができます。

次のステップ

公式のReactチュートリアルと状態管理ライブラリReduxもご覧ください。これらのリソースは、React Nativeアプリを作成する際に役立ちます。さらに、Web上のReactとReact Nativeの両方をサポートする、完全にTypeScriptで書かれたコンポーネントライブラリであるReactXPも検討するとよいでしょう。

より型安全なReact Native開発環境で楽しんでください!