本記事はReact Native Advent Calendar 2020の8日目の記事です
Expo, ReactNative初心者ですが、monorepoが必要になったのでExpo + Nxでmonorepoな環境を用意してみました。
そもそもmonorepoと
自分は全然しらなかったですが、1つのリポジトリで複数のパッケージを管理することをmonorepoと言うらしいです。
気づいたらこういう流れになっているみたいですね。
(基本的にはPHPerなので知らなかった...)
リリースサイクルや、ロジックの共有もできるので便利かなと思います。
Nxとはなにか?
nrwl/nx
monorepo用の拡張ツールです。
キャッシュのおかげでビルドが早かったり、色々と便利ですね。
(自分はそんなに使いこなせてないですが...)
ExpoでNxを利用する
公式だと対応してないので,
ExpoでNxを利用するためにはJacopoPatroclo/nx-react-native-expoが必要になります。
monorepoを作ってみる。
実際にmonorepoを作ってみます。
まずはNxのワークスペースを作成
まずはNxのワークスペースを作成します。
presetは empty
を指定します。
$ npx create-nx-workspace --cli=nx --preset=empty
? Workspace name (e.g., org name) polidog-monorepo-sample
? Use Nx Cloud? (It's free and doesn't require registration.) No
nx-react-native-expoのnpmパッケージを追加する
ここでnx-react-native-expoのパッケージを追加します。
$ yarn add --dev nx-react-native-expo
appを作成する
$ npx nx g nx-react-native-expo:app appA
ポイントなのはx-react-native-expo:app
を指定している点かと思います。
これでexpoのプロジェクトが生成されています。
念の為にExpoのプロジェクトが生成されているかを確認してみた。
$ ls apps/app-a
drwxr-xr-x 20 polidog staff 640 12 8 03:06 ./
drwxr-xr-x 4 polidog staff 128 12 8 03:01 ../
-rw-r--r-- 1 polidog staff 98 12 8 03:01 .eslintrc.json
drwxr-xr-x 5 polidog staff 160 12 8 03:09 .expo/
-rw-r--r-- 1 polidog staff 457 12 8 03:01 App.spec.tsx
-rw-r--r-- 1 polidog staff 524 12 8 03:01 App.tsx
-rw-r--r-- 1 polidog staff 478 12 8 03:01 app.json
drwxr-xr-x 5 polidog staff 160 12 8 03:01 assets/
-rw-r--r-- 1 polidog staff 108 12 8 03:01 babel.config.js
-rw-r--r-- 1 polidog staff 132 12 8 03:01 index.js
-rw-r--r-- 1 polidog staff 325 12 8 03:01 jest.config.js
-rw-r--r-- 1 polidog staff 214 12 8 03:01 metro.config.js
drwxr-xr-x 3 polidog staff 96 12 8 03:06 node_modules/
-rw-r--r-- 1 polidog staff 117 12 8 03:01 package.json
-rw-r--r-- 1 polidog staff 53 12 8 03:01 test-setup.d.ts
-rw-r--r-- 1 polidog staff 171 12 8 03:01 test-setup.js
-rw-r--r-- 1 polidog staff 207 12 8 03:01 test-setup.js.map
-rw-r--r-- 1 polidog staff 299 12 8 03:01 tsconfig.json
-rw-r--r-- 1 polidog staff 273 12 8 03:01 tsconfig.spec.json
-rw-r--r-- 1 polidog staff 287 12 8 03:01 webpack.config.js
起動してみる
$ yarn nx start app-a
特に問題もなく起動できてちょっとビビります。
ライブラリを作成してみる
$ npx nx g nx-react-native-expo:lib data
このようにコマンドを実行すると./libs/data
ディレクトリが作成されています。
ということで、適当にコードを用意して、appA側でimportさせたいと思います。
// libs/data/src/index.ts
export const now = () => Date.now()
続いてappA側を下記のように修正します。
// apps/app-a/App.tsx
import { StatusBar } from 'expo-status-bar';
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import { now } from '@polidog-monorepo-sample/data'
export default function App() {
const [nowTimestampe, setNowTimestamp] = React.useState(0.0)
React.useEffect(() => {
setNowTimestamp(now())
}, [])
return (
<View style={styles.container}>
<Text testID="heading">
Timestamp: {nowTimestampe}
</Text>
<StatusBar style="auto" />
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
ポイントとはimoprt文書くときに@polidog-monorepo-sample/data
って形になるところかと思います。
import { now } from '@polidog-monorepo-sample/data'
その他のコマンド
workspace.jsonを見るとわかりますが、他にも以下のコマンドが使えます
- bundle
- run-start
- run-ios
- run-android
- run-web
- publish
例:
$ yarn nx publish app-a
まとめ
JacopoPatroclo/nx-react-native-expoを使うと非常に簡単にexpoでのmonorepoを実現出来ます。