作って壊せるReact開発環境をつくる(gulp + browserify + babel)

  • 38
    Like
  • 2
    Comment
More than 1 year has passed since last update.

社内 React(flux)勉強会のために、シンプルなReact開発環境を作ったので公開します。
https://github.com/kjugk/flux_boilerplate

基本的な部分をこの記事で解説しますので、これからReact始めたいけど設定が面倒くさそう・・という方は是非お試しください!(フィードバック大歓迎です。)

前提

  • node v5.3.0 で動作確認済

ディレクトリ構成

ディレクトリ構成は以下になります。(とりあえずReact に慣れることが目的なので、test や css は省略しています。)

2016/03/27 追記
JestでReact Component をテストする記事を作成しましたので、合わせてご参照ください!
http://qiita.com/kjugk/items/d0306eb2a1ff97a07d6f
追記ここまで

.
├── .babelrc
├── dist         //browserify でコンパイルされた bundle.js ファイルを配置する。
├── gulpfile.js
├── index.html
├── js           // JavaScript ファイルを配置する
│    └── index.js
│    └── 〜
│  
├── node_modules
└── package.json

ビルドのフロー

Untitled (1).png

各ファイルの説明

gulpfile.js

gulp task を記述します。
jsタスクでは、js ディレクトリ配下のファイルを browserify で bundle.js ファイルにまとめて、dist ディレクトリに配置しています。

gulpfile.js
''use strict';
var gulp = require('gulp');
var gutil = require('gulp-util');

var browserify = require('browserify');
var watchify = require('watchify');
var babelify = require('babelify');

var source = require('vinyl-source-stream');
var buffer = require('vinyl-buffer');
var sourcemaps = require('gulp-sourcemaps');

var b = browserify({
  entries: ['./js/index.js'],
  transform: ['babelify'],
  cache: {},
  packageCache: {},
  plugin: [watchify]
})
.on('update', bundle)
.on('log', gutil.log)

function bundle(){
  return b.bundle()
    .on('error', gutil.log.bind(gutil, 'Browserify Error')  )
    .pipe(source('bundle.js'))
    .pipe(buffer())
    .pipe(sourcemaps.init({loadMaps: true}))
    .pipe(sourcemaps.write('./'))
    .pipe(gulp.dest('./dist'));
}

gulp.task('js', bundle);
gulp.task('default', ['js']);

ここで重要なのは、browserify を設定している以下の記述です。

gulpfile.js
var b = browserify({
  entries: ['./js/index.js'],
  transform: ['babelify'],
  cache: {},
  packageCache: {},
  plugin: [watchify]
})
.on('update', bundle) //ソース更新時に bundle を再実行
.on('log', gutil.log) //標準出力にログを書き出す
  • transform に babelify を指定しています。b.bundle 関数実行時に、babelify によるES6, JSX のtranspile が実行されます。
  • plugin に watchify を指定しています。b.bundle 関数実行時に watchify によるソースの監視が始まり、ソースを更新するたびに差分build が実行されます。

.babelrc

  • babelify モジュール の設定はここに記述します。
.babel.rc
{
  "presets": ["es2015", "react"],
  "plugins": ["transform-object-assign"]
}
  • ES6 と JSX をコンパイルするために、es2015react presets(基本的なpluginのセット) を定義しています。
  • React 開発でよく利用する、Object.assign() を有効にするため、transform-object-assign plugin を定義しています。

  • その他の babel の plugin は こちら

index.html

では、以下のように、script タグで コンパイル済みのbundle.js を読み込んでいるだけです。

index.html
~
<body>
  <div id="root"></div>
  <script src="dist/bundle.js"></script>
</body>
~

index.js

browserify のエントリーポイントになるファイルです。
以下のように、index.html の DOM に React Component をマウントしています。
前述のbabelify の 設定により、以下全ての js ファイルで、import 構文や JSX の記述が使えます。

index.js
import React from 'react'
import {render} from 'react-dom'
import ExampleApp from './components/ExampleApp'

render(
  <ExampleApp />,
  document.getElementById('root')
)

build

以上の設定により、コンソール から gulp コマンドを叩くと、ソースのコンパイル + 監視が始まります。(global に gulp をインストールしている場合は、gulp コマンドでOKです。)

$ node ./node_modules/gulp/bin/gulp
[15:31:10] Using gulpfile ~/flux_boilerplate/gulpfile.js
[15:31:10] Starting 'js'...
[15:31:12] 690771 bytes written (2.48 seconds)

buildが失敗すると、以下のようなエラー(一部dir name改変)がコンソールに吐き出されます。

[15:36:01] Browserify Error { [SyntaxError: /xxx/flux_boilerplate/js/components/ExampleApp.js: Adjacent JSX elements must be wrapped in an enclosing tag (33:6) while parsing file: /xxx/flux_boilerplate/js/components/ExampleApp.js]
  pos: 675,
  loc: Position { line: 33, column: 6 },
  _babel: true,

どうやら Example.js ファイルの33行目のJSX が、タグで閉じられていないことが原因のようです。

修正してファイルを更新すれば、自動的にコンパイルが始まりるので、エラーが出なくなるまでコードを修正していきます。

動作確認

ブラウザで index.html を開くと、bundle.js が実行されます。


以上長々と説明してきましたが、ここまでできればあとは作って壊して、React に慣れるだけです!
ちなみに、Redux などを導入したい場合でも、基本的に上記の設定を流用できますので、試してみてください。

今後の課題

参考にさせていただいた記事

React.js + Babel + Browserify + gulp の環境を作ってみた