React は、当時のバージョン 1 についてこちらのページ等で利用方法をまとめた Angular と比較されることの多い、UI 構築のための JavaScript ライブラリです。Angular と異なり、ES6 や JSX の構文が利用された JavaScript コードをブラウザが解釈可能な JavaScript にコンパイルする Babel や、ファイル分割された複数のファイルからなる JavaScript コードを Node.js で利用可能な require と同等の構文によって一つのファイルにまとめる Browserify といった周辺ライブラリを併用した開発になります。開発を行うために必要な環境の構築手順についてまとめます。方法は複数存在します。以下に示すのはそのうちの一部です。
create-react-app を利用すると、Babel や Browserify といった周辺ライブラリ群が適切に設定された React アプリケーションの雛形を生成できます。まずは create-react-app
をグローバルインストール -g
または以下のように適当なディレクトリでローカルインストールします。
npm init
npm install --save-dev create-react-app
npm-scripts を追加します。
$ cat package.json
{
"name": "xxxx",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"create-react-app": "create-react-app", ←追記
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"devDependencies": {
"create-react-app": "^1.4.3"
}
}
アプリケーションの雛形を生成します。
npm run create-react-app my-app
生成されたディレクトリに移動します。ローカルインストールした場合のディレクトリは以降は不要です。
cd my-app
以下のようなファイルが存在します。
$ ls -al
total 232
drwxr-xr-x 8 username staff 272 11 3 03:20 .
drwxr-xr-x 5 username staff 170 11 3 03:17 ..
-rw-r--r-- 1 username staff 285 11 3 03:20 .gitignore
-rw-r--r-- 1 username staff 108875 11 3 03:20 README.md
drwxr-xr-x 895 username staff 30430 11 3 03:20 node_modules
-rw-r--r-- 1 username staff 343 11 3 03:20 package.json
drwxr-xr-x 5 username staff 170 11 3 03:20 public
drwxr-xr-x 9 username staff 306 11 3 03:20 src
react-scripts
の内部で Babel や Browserify といった周辺ライブラリが利用されています。
$ cat package.json
{
"name": "my-app",
"version": "0.1.0",
"private": true,
"dependencies": {
"react": "^16.0.0",
"react-dom": "^16.0.0",
"react-scripts": "1.0.16"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
}
}
npm-scripts を利用してアプリケーションを起動できます。start などについては run
は省略可能です。
npm start
起動に成功すると以下のようになります。
アプリケーションをビルドすると nginx 等で静的なページとして設置可能な build ディレクトリが生成されます。
$ npm run build
> my-app@0.1.0 build /Users/username/path/to/my-app
> react-scripts build
Creating an optimized production build...
Compiled successfully.
File sizes after gzip:
40.13 KB build/static/js/main.50e1065b.js
299 B build/static/css/main.c17080f1.css
The project was built assuming it is hosted at the server root.
To override this, specify the homepage in your package.json.
For example, add this to build it for GitHub Pages:
"homepage" : "http://myname.github.io/myapp",
The build folder is ready to be deployed.
You may serve it with a static server:
npm install -g serve
serve -s build
このビルド結果は、あくまでもクライアント側のブラウザで実行するための静的なファイル群です。実用的なアプリケーション開発を行う場合は、別途何らかのフレームワークを用いて React から利用するサーバー側の API を開発する必要があります。
package.json を生成します。
npm init
React を dependencies に追加します。
npm install --save react react-dom
Browserify および Babel を devDependencies に追加します。
npm install --save-dev browserify
npm install --save-dev babel-core babel-preset-env babel-preset-react babelify
React のビルド方法には、開発時にデバッグ等で有益な情報を含めたビルドと、それらの情報を除外した production ビルドが存在します。Browserify における production ビルドのために必要な envify および uglifyify を devDependencies に追加します。また、production ビルドとは直接関係ありませんが、ビルド結果を minify するために uglifyjs を devDependencies に追加します。
npm install --save-dev envify uglifyify uglify-js
npm-scripts の設定を追加します。
$ cat package.json
{
"name": "xxxx",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"build": "browserify script.js -t [ babelify --presets [ env react ] ] -o bundle.js", ←↓追記
"production-build": "browserify script.js -t [ babelify --presets [ env react ] ] -g [ envify --NODE_ENV production ] -g uglifyify | uglifyjs --compress --mangle -o bundle.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"react": "^16.0.0",
"react-dom": "^16.0.0"
},
"devDependencies": {
"babel-core": "^6.26.0",
"babel-preset-env": "^1.6.1",
"babel-preset-react": "^6.24.1",
"babelify": "^8.0.0",
"browserify": "^14.5.0",
"envify": "^4.1.0",
"uglify-js": "^3.1.6",
"uglifyify": "^4.0.4"
}
}
動作検証のために script.js と index.html を作成します。
script.js
import React from 'react';
import ReactDOM from 'react-dom';
ReactDOM.render(
<h1>Hello, world!</h1>,
document.getElementById('root')
);
index.html
<html>
<head>
</head>
<body>
<div id="root"></div>
<script src="./bundle.js"></script>
</body>
いずれかの方法でビルドしてブラウザで確認します。
npm run build
npm run production-build
以下のように表示されれば成功です。
$ du -h bundle.js
816K bundle.js
production ビルドの場合は以下のように右上のアイコンの色が異なります。
$ du -h bundle.js
116K bundle.js
これらのビルド結果は、あくまでもクライアント側のブラウザで実行するための静的なファイルです。実用的なアプリケーション開発を行う場合は、別途何らかのフレームワークを用いて React から利用するサーバー側の API を開発する必要があります。
CDN で提供される React を利用する方法です。以下の例では開発時にデバッグ等で有益な情報を含めたバージョンの React development を利用しています。また、Babel の babel-standalone バージョンを利用して、ES6 や JSX の構文が利用された JavaScript コードをブラウザが解釈可能な JavaScript にコンパイルする処理をブラウザ内で行っています。簡単なデモや検証用途で利用できます。ファイル分割はされていないため Browserify は登場しません。
sample.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Hello World</title>
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
</head>
<body>
<div id="root"></div>
<script type="text/babel">
ReactDOM.render(
<h1>Hello, world!</h1>,
document.getElementById('root')
);
</script>
</body>
</html>
react-rails を利用すると、こちらのページなどで利用方法をまとめた Rails ビューの補助的なパーツとして React を利用できます。ビューヘルパー react_component の引数として初期値を与えることができるため、React とのデータの受け渡しのために必ずしも API を用意する必要がなくなります。
ReactDOM.render() can also be called multiple times for independent parts of the UI which can be as small as a button, or as large as an app.
In fact, this is exactly how React is used at Facebook. This lets us write applications in React piece by piece, and combine it with our existing server-generated templates and other client-side code.
https://reactjs.org/docs/integrating-with-other-libraries.html#integrating-with-other-view-libraries
上記ドキュメントによると、少なくとも 2017/11/10 現在において、React を開発する Facebook でも、React はサーバーサイドで生成された HTML 内でパーツとして部分的に利用されています。Facebook ではなく React Training が開発する react-router 等による Single Page Application (SPA) や Server Side Rendering (SSR) ではないということになります。
create-react-app で生成された serviceWorker.js
を利用するとオフラインで動作するアプリケーションを作成できます。index.js
内で以下の記述を register()
に変更すると有効になります。
// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();
アプリケーションとして CORS が問題になる場合は、サーバ側で設定する以外の方法として、一時的にプラグインで回避することもできます。例: CORS Unblock
CI
環境変数に true
を設定すると lint 結果にエラーがある際にビルドを失敗させることができます。
CI=true npm run build