Help us understand the problem. What is going on with this article?

webpackのcss-loaderでCSS Modulesをやる

More than 3 years have passed since last update.

はじめに

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の振る舞いをするようになります。

webpack.config.js
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にしておくと良さそうです。

app.css
.hogeHoge {
  background-color: green;
}

最後に、Reactを使ったJS部分です。
app.cssをimport(またはrequire)することで、衝突しないように変換されたクラス名を読み込むことができます。
importした結果をdiv要素のclassNameに与えています。

app.jsx
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も置いておきます。

index.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の代替手段として機能しそうです。

_likr
はたらきたくない
https://vdslab.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした