Carpe Diem

備忘録

React.js+Babel+webpackでfizzbuzz

概要

React.jsを勉強しようと思って簡単なfizzbuzz表示するだけのものを作ってみました。

github.com

動作ページはこちら

役割

ツール名 役割
React.js UIを構築するためのライブラリ。フレームワークではない。
Babel ES6など新しい記法を既存のブラウザでも動くようにトランスパイルしてくれる
webpack ES6のimportを解釈して必要な依存ファイルをかき集めてビルドしてくれる

環境

  • React.js 0.14.7
  • Babel 6.5.2
  • webpack 1.12.14

前提

今回はReactでコンポーネントを作成するだけで、Fluxは使用しません。

準備

フォルダ用意

$ mkdir fizzbuzz
$ cd fizzbuzz
$ mkdir src dist

srcにはビルド前の.jsxファイルをdistにはビルド後の.jsファイルが生成されます。

プロジェクト初期化

$ npm init

ビルド用ツールの用意

$ npm install --save webpack babel babel-core babel-loader babel-preset-es2015 babel-preset-react

babelの設定

.babelrcを用意してpresetを設定します。

{
  "presets": ["es2015", "react"]
}

webpackの設定

webpack.config.jsというファイルを用意します。中身は以下です。

module.exports = {
  entry: __dirname + "/src/fizzbuzz.jsx",
  output: {
    path: __dirname + "/dist",
    filename: "fizzbuzz.js"
  },
  module: {
    loaders: [{
      test: /\.jsx?$/,
      loader: 'babel-loader',
      exclude: /node_modules/
    }]
  }
};

ちゃんと動くか確かめるため、以下の検証用ファイルを用意します。

$ touch ./src/fizzbuzz.jsx

中にはconsole.log()でも入れておいてください。

webpackが動くか確認

$ webpack 
Hash: a07a7a4b12c56a889d12
Version: webpack 1.12.14
Time: 392ms
      Asset     Size  Chunks             Chunk Names
fizzbuzz.js  1.42 kB       0  [emitted]  main
    + 1 hidden modules

distフォルダを見るとちゃんと生成されてます。

$ tree dist/
dist/
└── fizzbuzz.js

npm run でビルドが動くようにする。

package.jsonに以下を追記します。

{
...
  "scripts": {
    ...
    "build": "rm -rf dist/*.js && webpack",
    "watch": "rm -rf dist/*.js && webpack -w"
  },
...
}

確認してみます。

$ npm run build

先ほどのwebpackと同じ結果でしたら大丈夫です。

作成

HTMLファイルの用意

dist/index.html

<!doctype html>
<html>
<head>
  <meta charset="UTF-8">
  <title>fizzbuzz sample</title>
</head>
<body>
  <h1>fizzbuzz sample</h1>
  <div id="fizzbuzz"></div>
  <script src="fizzbuzz.js"></script>
</body>
</html>

reactの用意

$ npm install --save react react-dom

reactのコンポーネント作成

src/fizzbuzz.jsxを以下のようにします。

import React from "react";
import ReactDom from "react-dom";

class FizzBuzz extends React.Component {
  constructor(props) {
    super(props);
  }

  render() {
    return (
      <h1>react component test</h1>
    );
  }
}

ReactDom.render(
  <FizzBuzz />,
  document.getElementById("fizzbuzz")
);

React.Componentを継承し、renderメソッドを実装すると、Reactコンポーネントになります。 Reactコンポーネントは、クラス名をそのままJSXのタグに使うことができます。

index.htmlを開いてみると、ちゃんと表示されます。 f:id:quoll00:20160229144813p:plain

fizzbuzzのロジックを記述

import React from "react";
import ReactDom from "react-dom";

class FizzBuzz extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0,
      display: 0
    };
    setInterval(() => this.tick(), 1000);
  }

  tick() {
    var n = this.state.count + 1;
    this.setState({
      count: n,
      display: this.display(n)
    });
  }

  display(n) {
    if (n % 15 === 0) {
      return 'FizzBuzz';
    }
    if (n % 3 === 0) {
      return 'Fizz';
    }
    if (n % 5 === 0) {
      return 'Buzz';
    }
    return n
  }

  render() {
    return (
      <h1>{this.state.display}</h1>
    );
  }
}

ReactDom.render(
  <FizzBuzz />,
  document.getElementById("fizzbuzz")
);

動作確認

dist/index.htmlを起動すると以下のように数字がカウントアップされて、fizzbuzzが表示されます。

13のとき

f:id:quoll00:20160229145000p:plain

15のとき

f:id:quoll00:20160229145008p:plain

ソース