13
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

react-native-web を試す

Posted at

とある API を作っいて、動作確認にしょぼいクライアントアプリを作りたくなった。

  • 目標1: まずは Web で試して後から Native アプリ化したい。
  • 目標2: TypeScript で書きたい。

Twitter Lite で開発されたという react-native-web を使ってみる。react-native-web とは、react-native に入れ替えると ReactNative アプリが HTML アプリになるという物。同一のコードを携帯でも HTML でも動かそうと思うとまだちょっと手間がかかるようだ。

react-native-web アプリの一番簡単な作り方

react-dom の代わりに react-native-web を使うだけなら非常に簡単。create-react-app がすでに対応している。

まず、create-react-app で普通の React アプリを作る。ちなみに、npx はローカルにインストールされた node コマンドを実行するだけの物だと思っていたら、ローカルにインストールされてない時は勝手にインストールして使い終わったらアンインストールしてくれるという便利機能があった。

npx create-react-app react-native-web-simple

react-native-web をインストール

cd react-native-web-simple
yarn add react-native-web

src/index.js を書き換える

import { AppRegistry } from 'react-native';
import App from './App';

AppRegistry.registerComponent('App', () => App);

AppRegistry.runApplication('App', {
  rootTag: document.getElementById('root')
});

src/App.js を書き換える

import React, { Component } from 'react';
import logo from './logo.svg';
import { Image, StyleSheet, Text, View } from 'react-native';

const Link = (props) => <Text {...props} accessibilityRole="link" style={StyleSheet.compose(styles.link, props.style)} />

class App extends Component {
  render() {
    return (
      <View style={styles.app}>
        <View style={styles.header}>
          <Image accessibilityLabel="React logo" source={logo} resizeMode="contain" style={styles.logo} />
          <Text style={styles.title}>React Native for Web</Text>
        </View>
        <Text style={styles.text}>
          This is an example of an app built
          with <Link href="https://github.com/facebook/create-react-app">Create React App</Link> and{' '}
          <Link href="https://github.com/necolas/react-native-web">React Native for Web</Link>
        </Text>
        <Text style={styles.text}>
          To get started, remix this starter kit by editing <Link href="https://glitch.com/edit/#!/react-native?path=src/App.js" style={styles.code}>src/App.js</Link>.
        </Text>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  app: {
    marginHorizontal: 'auto',
    maxWidth: 500
  },
  logo: {
    height: 80
  },
  header: {
    padding: 20
  },
  title: {
    fontWeight: 'bold',
    fontSize: '1.5rem',
    marginVertical: '1em',
    textAlign: 'center'
  },
  text: {
    lineHeight: '1.5em',
    fontSize: '1.125rem',
    marginVertical: '1em',
    textAlign: 'center'
  },
  link: {
    color: '#1B95E0'
  },
  code: {
    fontFamily: 'monospace, monospace'
  }
});

export default App;

上記コードは https://glitch.com/edit/#!/react-native から拝借しました。不思議な事に react-native-web をインストールすると react-native を import 出来るようになる。これは webpack の alias という機能を使っていて、あらかじめ create-react-app の生成する webpack に alias の設定が入っているからだった。https://github.com/facebook/create-react-app/pull/407

Native でも Web でも動くアプリを作る。

https://github.com/necolas/react-native-web/blob/master/website/guides/getting-started.md#web-packaging-for-existing-react-native-apps の通りに作業するだけですが、私は初見でかなり戸惑ったので丁寧に書きます。手順としては以下になります。

  • 普通に ReactNative のプロジェクトを作る。
  • JavaScript を合体させるために webpack + babel の設定を書く。
    • babel-plugin-react-native-web でソースコードで react-native を import すると react-native-web を import した事になる。
  • ブラウザで表示するために index.html や index.web.js を書く。
  • 微調整。

普通に react-native のプロジェクトを作る

brew install node watchman yarn
npm install -g react-native-cli
react-native init ReactNativeTest
cd ReactNativeTest
react-native run-ios

react-native-Web 化に必要なモジュールをインストール

yarn add react-dom react-native-web
yarn add --dev babel-plugin-react-native-web babel-loader url-loader webpack webpack-dev-server webpack-cli

web/webpack.config.js の作成

通常の ReactNative では、Metro というツールでソースコードを合体させますが、react-native-web では webpack + babel を使います。

https://github.com/necolas/react-native-web/blob/master/website/guides/getting-started.md#web-packaging-for-existing-react-native-apps に書いてある通りの内容で web/webpack.config.js を作成します。

index.html の作成

ウェブブラウザがアクセスする HTML を適当に書きます。

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <title>React Native Web</title>
  </head>
  <body>
    <div id="react-app"></div>
  </body>
  <script type="text/javascript" src="bundle.web.js"></script>
</html>

index.web.js の作成

アプリを記述する App.js を HTML 上に設置する部分です。

index.web.js の作成

import App from './src/App';
import { AppRegistry } from 'react-native';

// register the app
AppRegistry.registerComponent('App', () => App);

AppRegistry.runApplication('App', {
  initialProps: {},
  rootTag: document.getElementById('react-app')
});

App.js の移動

react-native init で作ると最上位に App.js が作られますが、webpack に合わせて src に移します。

mkdir src
mv App.js src/App.js

実行

./node_modules/.bin/webpack-dev-server -d --config ./web/webpack.config.js --inline --hot --colors

ブラウザで http://localhost:8080/ を開く。

13
15
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?