8
8

More than 5 years have passed since last update.

私のReact用SPA向けgulpfile.js

Posted at

動機

ReactでSPAを作ろうとしたとき、何も工夫せずにbrowserifyを使うとコンパイル等で非常に時間がかかったり、生成物のサイズがでかくなりすぎたりしがちです。
そこで、ライブラリ等はなるべくCDN経由で取得してみてはどうかと思い、gulpfile.jsを考えてみました。
結果として、コンパイル後の生成物のサイズが抑えられ、タスクも短時間で完了するようになりました。(たとえばuglifyを使う場合などには如実です)

npmパッケージ

まず、本記事で利用するnpmパッケージは、次のとおりです。
(バージョン等は、投稿時のものです。)

package.json
{
  ... 省略 ...
  "dependencies": {
    "babel-preset-es2015": "^6.3.13",
    "babel-preset-react": "^6.3.13",
    "babelify": "^7.2.0",
    "browserify": "^12.0.1",
    "gulp": "^3.9.0",
    "literalify": "^0.4.0",
    "react": "^0.14.3",
    "react-dom": "^0.14.3",
    "react-router": "^1.0.0"
  }
}

gulpfile.js

gulpfile.jsは下記のようにしてみました。
内容としては、browser.jsxをbrowser.jsにコンパイルするというものです。babelifyの後にliteralifyを使っているのがポイントです。

gulpfile.js
const gulp = require('gulp');
const browserify = require('browserify');
const babelify = require('babelify');
const literalify = require('literalify');
const fs = require('fs');

gulp.task('browser', () => {
  return browserify({debug: true})
  .transform(babelify.configure({
    presets: ['es2015', 'react']
  }))
  .transform(literalify.configure({
    'react': 'window.React',
    'react-dom': 'window.ReactDOM',
    'react-router': 'window.ReactRouter'
  }))
  .require('browser.jsx', {entry: true})
  .bundle()
  .on('error', (error) => {
    console.log(`Error: ${error.message}`);
  })
  .pipe(fs.createWriteStream('browser.js'));
});

index.html

次に、SPAのレンダリング先となるindex.htmlを準備します。reactやreact-router等はcdnjsから取ってくるようにしています。

index.html
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8" />
    <meta http-equiv="x-ua-compatible" content="ie=edge" />
    <title>SPA</title>
  </head>
  <body>
    <div id="application"></div>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.3/react.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.3/react-dom.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-router/1.0.0/ReactRouter.js"></script>
    <script src="browser.js"></script>
  </body>
</html>

JSXファイル

説明用のシンプル(すぎる)アプリケーションは次のとおりです。特筆すべき点はありません。ご参考まで。

browser.jsx
import React from 'react';
import ReactDOM from 'react-dom';
import {Router, Route} from 'react-router';

const Header = () => (
  <header>header</header>
);

const Main = () => (
  <main>main</main>
);

const Footer = () => (
  <footer>footer</footer>
);

const Application = React.createClass({
  render() {
    return (
      <div>
        <Header />
        <Main />
        <Footer />
      </div>
    );
  }
});

ReactDOM.render((
  <Router>
    <Route path="/" component={Application} />
  </Router>
), document.getElementById('application'));

$ gulp browser [Enter]

これで、ひとまずコマンドラインでのgulp browserが実行できるようになります。
(その前にnpm install -g gulpも必要かも)

できあがったjsファイルを覗いてみると、うまいこと動いていることが確認できます。

(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){... 省略 ...
'use strict';

var _react = window.React;

var _react2 = _interopRequireDefault(_react);

var _reactDom = window.ReactDOM;

var _reactDom2 = _interopRequireDefault(_reactDom);

var _reactRouter = window.ReactRouter;

... 省略 ...

おわりに

名前の付け方やディレクトリ分け等については、社内文化などもあると思いますので適宜設定ください。その際は、fs.createWriteStreamのパス指定先のディレクトリがない場合にエラーがでますので、予め出力先ディレクトリを準備する必要があります。
そのほか、必要あらばgulpのwatchタスク等もご準備ください。

あと気になった点としては、requireとimportの使い分けが必要なところが、一貫性という点では問題のある方法かもしれません...

8
8
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
8
8