はじめに
CSS Modulesの発想はよくわかったけど、具体的にどうやって導入したらいいかわかりにくく感じたので、webpackでCSS Modulesを使うための設定と、ReactでCSS Modulesを使う簡単な例を紹介します。
CSS Modulesの概要やいいところについてはこのあたりをどうぞ。
CSS Modulesを行うための方法はwebpack以外にもいくつかあるようです。
Browserify pluginのcss-modulesifyも人気そうです。(発音できない)
やってみる
まずは、必要なモジュールをインストールします。
CSS Modulesを使うために、style-loaderとcss-loaderが必要です。
React+babel+webpackの構成に必要なものも記述しています。
$ npm init -y
$ npm install --save react react-dom
$ npm install --save-dev webpack style-loader css-loader babel-loader babel-preset-es2015 babel-preset-react
次に、webpackの設定です。
loaders部分には、babel-loaderとCSS Modulesの二つが設定されています。
'css?modules'
と書いてある部分が重要です。
modules
オプションを与えることで、css-loaderがCSS Modulesの振る舞いをするようになります。
module.exports = {
module: {
loaders: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: 'babel-loader',
query: {
presets: ['es2015'],
plugins: ['transform-react-jsx'],
},
},
{
test: /\.css$/,
loaders: ['style-loader', 'css-loader?modules'],
},
],
},
entry: './app',
output: {
path: __dirname,
filename: 'bundle.js',
},
resolve: {
extensions: ['', '.js', '.jsx'],
},
};
次に、CSSをこんな感じで書きます。。
CSSのクラス名は一般的にはhyphen-caseが多いような気がしますが、CSS Modulesの場合はJS側からアクセスしやすいようにcamelCaseにしておくと良さそうです。
.hogeHoge {
background-color: green;
}
最後に、Reactを使ったJS部分です。
app.cssをimport(またはrequire)することで、衝突しないように変換されたクラス名を読み込むことができます。
importした結果をdiv
要素のclassName
に与えています。
import React from 'react';
import ReactDOM from 'react-dom';
import styles from './app.css'
class App extends React.Component {
render() {
return <div className={styles.hogeHoge}>hello</div>;
}
}
ReactDOM.render(<App/>, document.getElementById('content'));
一応HTMLも置いておきます。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>CSS Modules Example</title>
</head>
<body>
<div id="content"></div>
<script src="bundle.js"></script>
</body>
</html>
以下のように適当にwebpackでビルドします。
私は普段はnpm scriptsに書いています。
$ ./node_modules/.bin/webpack
ブラウザでアクセスするとdivのクラス名が_3PdwrDVeQurTJpm2SrFLC2
というように変換されていることが確認できると思います。
クラスの命名ルールはcss-loaderのlocalIdentName
オプションで変更することができます。
例えば、'css?modules&localIdentName=[path][name]---[local]---[hash:base64:5]'
のように設定するとクラス名がapp---hogeHoge---3Pdwr
のようになります。
おわりに
どうしてもSassを書きたくなかったので、これでBEM+Sassの代替手段として機能しそうです。