Help us understand the problem. What is going on with this article?

React Native+TypeScriptの環境構築

More than 1 year has passed since last update.

React Nativeに実際にチャレンジした時の忘備録として残しておく。
ReactNativeを始める際には、Expoとreact-native-cliの二択がまず真っ先に浮かぶと思いますが、後者でやったのでその記録です。ただ、今から始めるならまずはExpoのことを調べてみるのをお勧めします。

今回この記事では
- ReactNativeにTypeScriptを導入する
- ReactNativeでローカルの画像を使用できるようにしておく
この2つを行います。

前提条件

  • yarnをインストール済み
  • VSCodeを利用(codeコマンドでterminalから起動できるようにしておく)
  • react-nativeのバージョンは0.59.0
  • macOS mojave(10.14.4)
  • 2019年4月時点での情報です。

プロジェクトの作成

まずyarnを用いてreact-natiev-cliを使えるようにします。

$ yarn global add react-native-cli

そしてプロジェクト作成。プロジェクト名にハイフンなどは使えないため注意。

$ react-native init <プロジェクト名>
$ cd <プロジェクト名>

typescript関連の依存環境を構築。
reactとreact-native本体には型定義が含まれていないので、型定義ファイルも追加。

$ yarn add --dev typescript
$ yarn add --dev react-native-typescript-transformer
$ yarn add --dev @types/react @types/react-native

typescriptの設定ファイルのtsconfigを作成

$ yarn tsc --init --pretty --jsx react

以下のような内容のtsconfig.jsonが生成される。
多分実際はもっと大量のコメントアウト行だらけなので、ここではコメントアウトされていない行のみを抜粋。

tsconfig.json
{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "jsx": "react", 
    "strict": true, 
    "esModuleInterop": true
  }
}

そのうち、以下の項目のコメントアウトを外す。

{
  ...
   "allowSyntheticDefaultImports": true,  /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
  ...
}

さらにcompilerOptionsをnode_modulesでは対象外にする。,の追加を忘れずに。

tsconfig.json
{
  "compilerOptions": {
    ...
+  },
+ "exclude": [
+   "node_modules"
+ ]
}

ここでtsconfig.jsonを自分好みに書き換えると良い。
StrictNllCheckをオンにしたりなど...

ソースコードをroot直下に起き続けるのは気が進まないので、
階層を1つ下げるためにsrcフォルダを作成する。

$ mkdir src
$ code ./

VSCodeが開いたら、App.jsApp.tsxにリネームし、./src配下に移動する。
するとVScodeによって自動でimportの更新をしていいか聞かれるのでYesを選択。
もし更新するかのダイアログが出なかった場合なども下記のVSCodeを使わずに更新する場合を参照

VScodeを使わずに更新する場合
srcフォルダを作成し、そこにApp.jsを移動。

$ mkdir src
$ mv App.js src/

index.jsを下記の様に編集する

index.js
+ import App from "./src/App";
- import App from "./App";

rn-cli.config.jsというファイルを作成する。

$ touch rn-cli.config.js

このファイルの内容は次の通りにする

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

package.jsonを開いて、script内にrun-iosrun-androidを追加することで、いちいちreact-native run-iosと打たずにyarn run-iosで動かせるようにする。

package.json
{
  "name": "tsSampleTest",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "start": "node node_modules/react-native/local-cli/cli.js start",
    "test": "jest",
+   "run-ios": "react-native run-ios",
+   "run-android": "react-native run-android"
  },
  "dependencies": {
    "react": "16.6.3",
    "react-native": "0.58.6"
  },
  "devDependencies": {
    "@types/react": "^16.8.7",
    "@types/react-native": "^0.57.38",
    "babel-core": "^7.0.0-bridge.0",
    "babel-jest": "24.3.1",
    "jest": "24.3.1",
    "metro-react-native-babel-preset": "0.53.0",
    "react-native-typescript-transformer": "^1.2.12",
    "react-test-renderer": "16.6.3",
    "typescript": "^3.3.3333"
  },
  "jest": {
    "preset": "react-native"
  }
}

以下のコマンドを叩いて動作確認しておしまい。

$ yarn run-ios

No Bundle Url Presentみたいなエラーが表示されてしまったときは、
まずはシミュレーター画面内下部のReloadを押す(またはSimulator上でCommand+R)をしてみる。
それでもダメな場合xcodeprojからXcode開いて直接実行させちゃうのが自分の環境では効果的でした。
そのあとXcode止めて、もう一度コマンド叩けば高確率で動く。

tslint、prettierの導入

書き方をチーム内で統一させるためのツール。複数人でやるなら入れておきたい。
いらないと思う場合はこの章はスキップしていいです。
自分の場合はインデント破壊されたコードが飛んでくることがあったので全員に導入。

yarn add --dev prettier 
yarn add --dev tslint tslint-react
yarn add prettier --dev tslint-config-prettier  tslint-plugin-prettier

tslintとprettierが競合したときprettierを優先する。
prettierとtslintの設定を記述する。

{
    "printWidth": 120, 
    "trailingComma": "all",
    "singleQuote": true,
    "jsxBracketSameLine": false
}

printWidthは1つの行での最大文字数,
trailingCommaは、配列や辞書での末尾カンマ強制,
singleQuoteは、シングルクオーテーション,
jsxBracketSameLineは、jsxの開始タグでの改行をするように

tslint.json
{
  "extends": ["tslint:recommended", "tslint-react", "tslint-config-prettier"],
  "rules": {
    "jsx-no-lambda": false, // JSX(TSX)内でのラムダ式
    "member-access": false,  // アクセス権の表記なし
    "interface-name": false,  // InterFace名の前に"I"をつけることを強制しない
    "prefer-for-of": false,  // for(i=0;i<9;i++)の代わりにfor-of構文を強制しない
    "ordered-imports": false, // importをアルファベット順にしなくても良い
    "object-literal-sort-keys": false, // Object(Dictionary)の順序をアルファベットに強制しない
    "no-console": false,  // console.log()を禁止しない
  },
  "linterOptions": {
    "exclude": [
      "config/**/*.js",
      "node_modules/**/*.ts",
      "coverage/lcov-report/*.js"
    ]
  }
}

これらの設定は好きなように変えればいいと思います。

imageを読み込んでも怒られないようにする

Imageタグでローカルの画像を読み込む時には下記2つのどちらかを使うことになるかと思います。
他のコンポーネント読み込むときも上部にimportを書くので、同じように確認すれば済むようにimportを使う方が個人的に好きです。

import img from './resources/image/hoge.png'
<Image source={img} />

// または
<Image source={require('./resources/image/hoge.png')} />

で、これを使えるようにするには、まず型定義ファイルimages.d.tsをプロジェクト直下(index.jsなどと同じ場所)に作成して、中身を次の通りに編集する。追加したい拡張子を記載すれば良い。

images.d.ts
declare module '*.svg'
declare module '*.png'
declare module '*.jpg'
declare module '*.jpeg'
declare module '*.gif'
declare module '*.bmp'
declare module '*.tiff'

それに加えて、tsconfig.jsonを編集する。

tsconfig.json
    "typeRoots": ["./images", "node_modules/@types"], 

こうするとimportで画像を読み込んで表示することができるようになります。

まとめ

これで自分的には色々試せる環境になったかなと。
react-native-cliだと自分が何をやったか覚えておけばプロジェクトの中身はつかみやすいですが、ライブラリの追加時にやることが多く、ある程度ネイティブの環境への理解がないと辛いことがちらほらあるかもしれないなと感じました。
それに対してExpoは一部のライブラリが対応していないことがネックであるとよく言われます。
しかし、記事作成時点で自分が使おうとしたライブラリはExpoに対応しているのが多かったように見受けられました(厳密に検証したりしたわけではありませんが)。
自分の環境下ではExpoで作ったTypescript環境だと、ejectすると動かなくなる状況に見舞われて、解決にかける時間がちょっと微妙だったこともありcliで挑戦しました。

参考URL

めちゃくちゃ頼りました
TypeScriptでReact Native開発をする方法2018年最新版

kado34
AppStoreでアプリを公開しています。 https://apple.co/2Ip9SxV UnityとかGoogle Apps Scriptとかもやってます。
http://kad0randum.techblog.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした