忘備録

日々の調べ物をまとめる。アウトプットする。基本自分用。

【React】とりあえず環境

Reactを弄る環境を整えてみる

環境

  • OS: OS X 10.10.5
  • React: 0.14.7
  • npm: 3.3.12

前提

  • npmがインストールされていること

参考

Getting Started | React

npmを使った方法

CommonJSのモジュールシステムとして「browserify」と「webpack」を使う方法があるが、今回はbrowserifyを利用する

※「browserify」とは

browserify をはじめてみる - Please Sleep

CommonJS のモジュールの仕組み、つまり Node.js の require をブラウザ上でも使えるようにするもの、ということでいいみたい。

公式:Browserify

browserifyのインストール

$ sudo npm install -g browserify
Password:
/usr/local/bin/browserify -> /usr/local/lib/node_modules/browserify/bin/cmd.js
/usr/local/lib
└─┬ browserify@13.0.0 
  ├── assert@1.3.0 
#〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜中略〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
  ├─┬ vm-browserify@0.0.4 
  │ └── indexof@0.0.1 
  └── xtend@4.0.1 

Reactのインストール

$ npm install --save react react-dom babelify babel-preset-react
npm WARN saveError ENOENT: no such file or directory, open '/path/package.json'
/path/Using_React_from_npm
├─┬ babel-preset-react@6.3.13 
│ ├─┬ babel-plugin-syntax-flow@6.3.13 
#〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜中略〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
│   └── whatwg-fetch@0.9.0 
└── react-dom@0.14.7 

npm WARN ENOENT ENOENT: no such file or directory, open '/path/Using_React_from_npm/package.json'
npm WARN EPACKAGEJSON Using_React_from_npm No description
npm WARN EPACKAGEJSON Using_React_from_npm No repository field.
npm WARN EPACKAGEJSON Using_React_from_npm No README data
npm WARN EPACKAGEJSON Using_React_from_npm No license field.

ワーニングは後で調べます。。。

サンプルソース

サンプルソースとして以下を用意する

helloworld.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>Hello React!</title>
  </head>
  <body>
    <div id="example"></div>
    <script src="bundle.js"></script>
  </body>
</html>

main.js

var React = require('react');
var ReactDOM = require('react-dom');

ReactDOM.render(
  <h1>Hello, world!</h1>,
  document.getElementById('example')
);

トランスパイル

main.jsをbundle.jsとしてトランスパイルする

$ browserify -t [ babelify --presets [ react ] ] main.js -o bundle.js

HTMLファイルを開いてみると

f:id:mktktmr:20160203160602p:plain

ちなみに最終的なディレクトリ構成以下です

Root/
├ bundle.js
├ helloworld.html
├ main.js
└ node_modules/

Error

ちょっとハマりました。。。

当初HTMLを以下のように書いていて

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>Hello React!</title>
  </head>
  <body>
    <div id="example"></div>
    <script src="bundle.js"></script>
  </body>
</html>

↓こんなエラー出てました。。。

f:id:mktktmr:20160203161011p:plain

Invariant Violation: _registerComponent(...): Target container is not a DOM element.
invariantbundle.js:908
_registerComponentbundle.js:13104:165
_renderNewRootComponentbundle.js:13126
ReactMount__renderNewRootComponentbundle.js:14476
_renderSubtreeIntoContainerbundle.js:13206
renderbundle.js:13226
React_renderbundle.js:14476
(anonymous 関数)bundle.js:34
sbundle.js:16
ebundle.js:25
(anonymous 関数)bundle.js:27

javascript - Invariant Violation: _registerComponent(...): Target container is not a DOM element - Stack Overflow

上記のコードだと、スクリプトが読まれた時点では、バインドしたいDOMが生成されていなため、エラーをこいてしまうってことだと思う。

スクリプトを読み込む位置を変えずに、

<script async src="bundle.js"></script> <!-- add async -->

でもいけるが、スクリプトを読み込む位置を変える方がベターらしい

starter kitを使った方法

starter kitを利用するとnpmなしでもReactをできるよ!とのことでこちらも試してみる

starter kitのダウンロード

f:id:mktktmr:20160215171515p:plain

とりあえずHTMLに直書きでReactのコードを差し込む

以下HTMLファイルをダウンロードしてきたディレクトリ配下に置く

react-0.14.7/
┣ README.md
┣ build
┣ examples
helloworld.html

helloworld.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>Hello React!</title>
    <script src="build/react.js"></script>
    <script src="build/react-dom.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.23/browser.min.js"></script>
  </head>
  <body>
    <div id="example"></div>
    <script type="text/babel">
      ReactDOM.render(
        <h1>Hello, world!</h1>,
        document.getElementById('example')
      );
    </script>
  </body>
</html>

helloworld.htmlを開いてみる

f:id:mktktmr:20160215173414p:plain

HTMLとjsファイルを分割してみる

以下jsファイルを追加

react-0.14.7/
┣ README.md
┣ build
┣ examples
┣ helloworld.html
┗ src/
    ┗ helloworld.js

ReactDOM.render(
  <h1>Hello, world!!</h1>,
  document.getElementById('example')
);

上記jsファイルを読み込むようHTMLを修正

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>Hello React!</title>
    <script src="build/react.js"></script>
    <script src="build/react-dom.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.23/browser.min.js"></script>
  </head>
  <body>
    <div id="example"></div>
    <script type="text/babel" src="src/helloworld.js"></script> <!-- 修正 -->
  </body>
</html>

helloworld.htmlを開く

f:id:mktktmr:20160215175725p:plain

※ちなみに公式の説明にもある通りブラウザによっては直接HTMLファイルを開くとエラーが発生することがある

Note that some browsers (Chrome, e.g.) will fail to load the file unless it's served via HTTP.

Chromeで開くとこんな具合

f:id:mktktmr:20160215180504p:plain

そんな時はpythonのhttpモジュールを呼ぶと便利(最近知った)

# python -m SimpleHTTPServerと一行叩くだけでhttpseverが起動する。。。
$ python -m SimpleHTTPServer
Serving HTTP on 0.0.0.0 port 8000 ...

んで、http://localhost:8000/helloworld.htmlにアクセスすると

f:id:mktktmr:20160215180847p:plain

オフラインでトランスパイル

Babelを利用することで、オフラインでもJavaScriptをトランスパイルできる

※「Babel」とは

Babelで始める!モダンJavaScript開発 | HTML5Experts.jp

ECMAScript2015 (ES6)やECMAScript7などで書かれたソースコードを一般的なブラウザがサポートしているECMAScript5の形式に出力することができます。

とりあえずbabelをインストール

npm install --global babel-cli
npm install babel-preset-react

_人人人人人人人人人人人人人_
> Quick Start Without npm <
 ̄Y^Y^Y^Y^Y^Y^Y^YY^Y^Y^ ̄

なんて銘打っておいてnpm使ってるじゃんっていうツッコミをしたくなるんですが、まあ、置いときます

ソースファイル修正

以下jsファイルを修正

src/helloworld.js

ReactDOM.render(
  React.createElement('h1', null, 'Hello, world!!!'),
  document.getElementById('example')
);

HTMLファイルも修正

src/helloworld.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>Hello React!</title>
    <script src="build/react.js"></script>
    <script src="build/react-dom.js"></script>
    <!-- No need for Babel! -->
  </head>
  <body>
    <div id="example"></div>
    <script src="build/helloworld.js"></script>
  </body>
</html>

bable発動

# srcディレクトリを監視して、トランスパイルしたファイルをbuildディレクトリに出力する
$ babel --presets react src --watch --out-dir build
src/helloworld.js -> build/helloworld.js

ブラウザでhtmlファイルオープン

f:id:mktktmr:20160215185051p:plain

こんな感じで色々な方法でReactを利用できる

どれがベスト・ベターな方法なのかはこれから探っていく

個人的にはReactはWebフロントのJavaScriptフレームワークの中で一番注目している

また、WebだけでなくNativeアプリを向けのReact Nativeなんてのも開発中みたいで、これから先も楽しみなフレームワークです