GitHub PagesをReact + CSS Modulesで

created at 2016/09/23 23:04:35

個人用の名刺を作ったのでついでにポートフォリオを作ってみました :muscle:

その際React + CSS Modulesな感じで作ったので、その雑感とやり方です :memo:

雑感

静的ページをReactで作ることについて

GitHub Pagesなので静的ページです。なかなか良かったです :blush:

生のHTMLをそのまま書くのはだるいのであり得ない。けどRuby使ったりJadeも違うなーって感じでReactでした。

ヌルヌル動かしたりするなら別かもしれませんが、

  • 部品をコンポーネントとして再利用できる
  • 繰り返しとか楽ちん
  • プログラミング楽しい

らへんがよかったです。

CSS Modulesについて

今回デザインは、Atomic Designを意識してCSS Modulesを使って組みました。
CSS Modulesよかったです :sparkles:

  • 普通のCSSで書ける
  • コンポーネントで閉じている

っていうのがよかったです。わかりやすくてシンプルになるので、脳みその負担を減らせる感じでした。

ただもっと込み入ったもの作ろうとするとcomposes使ったりしないといけないだろうし、コンポーネントの設計にもっと力入れないといけないんだろうと思います。

Atomic Designについて

React使ってるとコンポーネントがどんどん増えていくので整理する方法として、Atomic Designの考え方を取り入れようとしました。
結論としては、Atomic Designの考え方そのままでReactのコンポーネントをわけるのはやめた方がいい、ってのがわかりました :disappointed:

Atomic Designは大雑把に言えば最小単位のAtomsからMolecules、Organismsを構成してそれを組み合わせてTemplatesを作り、コンテンツを流し込んでPagesを完成させる、って考え方です。
これでReactを構成しようとすると次のような課題にぶつかりました。

  • Templates以下の要素はコンテンツを持つべきではないので、すべてのコンテンツをRootコンポーネントに持たせる必要がある
  • MoleculesとOrganismsを分ける明確な基準がわからん 1

で、最終的にこんな感じに落ち着きました。

  • Atoms: それ以上分割できない再利用可能なコンポーネント
  • Organisms: コンテンツを持たない再利用可能なコンポーネント
  • Parts: コンテンツを持ち、AtomsやOrganismsで構成されるコンポーネント

Partsの名前は気に入ってないんですが、いいのが思い浮かばず…。ReactでAtomic Designやってるとこのベストプラクティスが知りたいです。

How to

React + CSS Modulesで静的ページを作るまで with Webpackです。
ボイラープレートをnownabe/skel-static_websiteに用意しました。

ディレクトリ構造

最終的なディレクトリ構造はこのようになります。

$ tree .
.
├── bundle.js
├── index.html
├── package.json
├── src
│   ├── index.css
│   └── index.js
└── webpack.config.js

ローカルでビルドして、直接masterブランチにPushしていく感じです。

セットアップ

まずは適当なディレクトリを作ってnpm initpackage.jsonを作ります。

mkdir my-website
cd my-website
npm init

必要なパッケージをインストールします。

npm install --save react react-dom
npm install --save-dev webpack style-loader css-loader babel-loader babel-preset-es2015 babel-preset-react browser-sync-webpack-plugin browser-sync

Webpack

Webpackを設定します。

webpack.config.js
var BrowserSyncPlugin = require("browser-sync-webpack-plugin")

module.exports = {
  entry: {
    javascript: "./src/index.js"
  },
  output: {
    filename: "bundle.js"
  },
  devtool: "inline-source-map",
  module: {
    loaders: [
      { test: /\.js$/, exclude: /node_modules/, loader: "babel-loader" },
      { test: /\.css$/, loaders: ["style", "css?modules"] }
    ]
  },
  resolve: {
    extentions: ["", ".js"]
  },
  plugins: [
    new BrowserSyncPlugin({
      host: "localhost",
      port: 3000,
      server: { baseDir: ["."] }
    })
  ]
}

これで、webpack --watchコマンドでいい感じに開発できるようになります。
ついでにnpm startで起動できるようにpackage.jsonを修正しておきます。

package.json
  // ...
  "scripts": {
    "start": "node_modules/.bin/webpack --watch"
  },
  // ...

.babelrc

バベる設定。

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

index.html

index.htmlは何の変哲もない感じで。

index.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>website</title>
  </head>
  <body>
    <div id="app"></div>
    <script src="bundle.js"></script>
  </body>
</html>

React / CSS Modules

最後にReactとCSS Modulesです。

こんな感じで、javascript内でCSSを読み込んであげることで、適当なクラス名に変換されます。

src/index.js
import React from "react"
import { render } from "react-dom"

import styles from "./index.css"

render(
  <h1 className={styles.hello}>
    Hello, world!
  </h1>,
  document.getElementById("app")
)

CSSは普通に書きます。

src/index.css
.hello {
  font-size: 5rem;
}

おわりに

すぐに目で確認できるフロントのコーディングは楽しいですね :relaxed:


  1. ただ勉強不足なだけだと思います