reactnative

React Native v0.57 Highlightsメモ(暫定版)

次にリリースされるReact Native v0.57のリリースノートを読んでいたら、それなりに大きな変更が多かったので、心の準備をする意味で概要を感想文をメモしておきます。

Accessibility API Updates

まずは比較的マイルドなものから。

スマートフォンを使うすべての人々が、よく見える目や、画面に触れる指、聞こえる耳を持っているわけではありません。AndroidやiOSには、そういった方々が情報を感じたり扱ったりできるように、アクセシビリティAPIと呼ばれるものを通じて通常のUIを拡張する手段が用意されています。画像のメタデータとしてテキストを定義しておいて、スマートフォンの音声読み上げ機能の対象にする、などの機能があります。

以前からRNにもアクセシビリティAPIへのアクセス方法は存在していましたが、今回v0.57で入るのはその改善です。RN公式ブログでその詳細が紹介されています。

Accessibility API Updates · React Native
https://facebook.github.io/react-native/blog/2018/08/13/react-native-accessibility-updates

(あんまり詳しくないのでボロが出ないうち終わりにします)

Androidのビルド環境のアップデート

いろいろ上がります。

  • compileSdkVersion27(Android 8.1 Oreo)になります
  • buildToolsVersion27.0.3になります
  • Support Libraryが27.1.1になります
  • Android Gradle Pluginが3.1.4になります

今まで停滞していたツール群を大幅アップデートしました、という感じです。
Support Libraryの次世代版であるAndroidXは、今回はまだ影も形も見えませんが、いつか入るのでしょうね。

Android Gradle Plugin(AGP)のアップデートも大きなトピックです。AGPとGradleバージョン対応表によれば、AGP 3.1.4と対応するのはGradle 4.4+です。かなり最新に近いGradleを使っても問題なくなるのは嬉しいですね。

AGP 2.x→3.xの更新時に大きなトピックだったのは、Gradleの大幅バージョンアップに伴う記法の変更でした。compileimplementationになったりしたやつですね。地味にプロダクトフレーバーの書き方も変わっています。
AGP 2.3.3ベースで書かれているネイティブモジュールとの相性問題が起きそうな気もしますので、早めの対応が期待されます。腕に覚えのある各位は、普段使っているライブラリにプルリクエストをどんどん送ってあげてください。

Babelのpresetを変更した

babel-preset-react-nativeを使うのをやめて、metro-react-native-babel-presetを使うことになるようです。また、Babelの公式プラグイン・プリセットに関してはbeta.56のバージョンに揃えるように、とのこと。

名前から察するに、Metro Bundlerにロックインしたプリセットなのでしょうか。これまで.babelrcの設定を共有することもあった、React Native for Web方面にも影響が出そうな話です。

ビルトインTypeScriptサポート

There is now built-in TypeScript support in the Metro bundler through Babel 7 and some other work!

!!? 😯

Metro Bundlerが標準でTypeScriptに対応してくれる・・・? まじで・・・? (後で動かしてみます)動いたので記事にしました

実際、Babel7の正式リリースに伴って、Microsoftから「BabelでTypeScriptがパースできるようになったよ!」というアナウンスがありましたし、それを活用したということのようです。

ただこれ、実際にはTypeScriptをコンパイルできるようになった(Metro Bundlerがtscを扱えるようになった)わけではなく、Flow向けのplugin-transform-flow-strip-typesのTypeScript版ができたと見たほうがよさそうです。TypeScriptはもともとJavaScriptのスーパーセットなので、TypeScript独自の文法を削ってあげれば、Babelでパース可能なJavaScriptの形になるわけです。この方式をとっている(tscでパースしているわけではない)都合で、いくつかの(古い?)文法はサポートされていないのは注意が必要です。

  • namespace
  • <Hoge>hogeスタイルのキャスト(asでのキャストは問題ない)
  • enumを用いた特殊な表現(普通のenumはサポートされている)
  • import foo = require("foo")スタイルのインポート(import foo from "foo"const foo = require("foo")は問題ない)

どれも古めの文法で、これらの文法が使えなくて困ることも少ないとは思うので、まあ大丈夫だと思います。

なお、この環境を用いる場合、tscコマンドはflowコマンドと同様に、型チェックを行うためだけに使用することになります。その場合のtsconfig.jsonの設定方法についてもMSからアナウンスが出ていますので、参照してください。

私も個人的に同じことにチャレンジしていたのですが、Metro Bundler側でTypeScriptを読み込み対象にしてもらわないとどうにもならない状況で困っていたので、渡りに船でした。

5月に公式ブログでreact-native-typescript-transformerの紹介をしてくれた記事が早速オワコンになりそうですが、ts-jestの設定の仕方などは相変わらず参考になるので、気になる方はこちらも参照してください。

<WebView>でWKWebViewが使えるようになりました

iOS SDKにはUIWebViewWKWebViewというふたつのWebViewがあります。UIWebViewが古いほうで、WKWebViewはiOS 8で登場した比較的新しいほうです。React Nativeの<WebView>コンポーネントはUIWebViewをベースに作られています。

さて、このたび、iOS 12でUIWebViewが非推奨になることになりました。Androidのように非推奨になってからもなんだかんだで長いこと使えることが多いAPIとは違い、iOSは割とバッサリ切ってくるので、iOS 13で削除されていてもおかしくありません。同じくUIWebViewベースだったCordova界隈ではてんやわんやだったようです(仕事仲間からの又聞きの情報)。

ということで、React NativeでもWKWebViewが使えるようになります、というのが次の公式ブログの記事です。

Introducing new iOS WebViews · React Native
https://facebook.github.io/react-native/blog/2018/08/27/wkwebview

今回のAPIはオプトイン方式で、useWebKitのpropsをtrueにしておけば、内部でWKWebViewが採用される模様です。

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

さて、ガワが変わっただけで済めばいいのですが、どうなるでしょうね……。
もし上手く動かないケースが出てきた場合は、UIの種類によってはSFSafariViewControllerを使う方法にシフトする選択肢も検討したほうがいいのかも知れません。

まとめ

v0.56への更新でも少し混乱がありましたが、v0.57も歯を食いしばりながらアップデートをしていく内容になりそうです。

今回のAGPのアップデートは、Androidアプリ開発者にとって待望の嬉しいトピックになります。心の準備を済ませておいて、v0.57がリリースされたら対応に取り掛かってみましょう。