Web 開発を学んだことがある方なら、CSS はプログラミング言語ではなく、Web ページのスタイルを記述する方法であることをご存知でしょう。
CSS をソフトウェア工学手法に適用できるようにするために、プログラマーは CSS をプログラミング言語のようにするためのさまざまな方法を考えてきました。初期の Less と SASS から、その後の PostCSS、そして最近の JS の CSS に至るまで、それらはすべてこの問題を解決するために設計されています。
この記事で紹介する CSS モジュールは異なります。 CSS をプログラミング言語に変換するわけではありませんが、その機能は非常に単純で、ローカル スコープとモジュールの依存関係を追加するだけです。これはまさに Web コンポーネントの最も緊急に必要な機能です。
したがって、CSS モジュールにはルールがほとんどないため、習得が簡単であり、同時に、特定のコンポーネントのスタイルが他のコンポーネントに影響を与えないようにすることができます。
このチュートリアル用にサンプル ライブラリを作成しました。これには 6 つのデモが含まれています。これらを通じて、CSS モジュールを簡単に学ぶことができます。
まず、サンプル リポジトリのクローンを作成します。
$ git clone git@github.com:ruanyf/css-modules-demos.git
次に、依存関係をインストールします。
$ cd css-modules-demos$ npm install
これで、最初の例を実行できます。
$ npm run demo01
ブラウザを開いて http://localhost:8080 にアクセスして結果を表示します。他の例も同様に実行されます。
CSS ルールはグローバルであり、どのコンポーネントのスタイル ルールもページ全体に有効です。
ローカル スコープを作成する唯一の方法は、他のセレクターと同じ名前を持たない一意のクラス名を使用することです。これが CSS モジュールの機能です。
以下は React コンポーネント App.js です。
import React from 'react';import style from './App.css';export default () => { return ( <h1 className={style.title}> Hello World </h1> );};
上記のコードでは、スタイル ファイル App.css をスタイル オブジェクトに入力し、style.title を参照してクラスを表しています。
.title { color: red;}
ビルド ツールは、クラス名 style.title をハッシュ化された文字列にコンパイルします。
<h1 class="_3zyde4l1yATCOkgn-DBWEL"> Hello World</h1>
App.css も同時にコンパイルされます。
._3zyde4l1yATCOkgn-DBWEL { color: red;}
このようにして、クラス名は一意になり、App コンポーネントに対してのみ有効になります。
CSS モジュールは、さまざまなビルド ツールをサポートするさまざまなプラグインを提供します。この記事では、Webpack の css-loader プラグインを使用します。これは、CSS モジュールを最もよくサポートしており、使いやすいためです。ちなみに、Webpack を学びたい場合は、私のチュートリアル Webpack-Demos を読んでください。
この例の webpack.config.js は次のとおりです。
module.exports = { entry: __dirname + '/index.js', output: { publicPath: '/', filename: './bundle.js' }, module: { loaders: [ { test: /\.jsx?$/, exclude: /node_modules/, loader: 'babel', query: { presets: ['es2015', 'stage-0', 'react'] } }, { test: /\.css$/, loader: "style-loader!css-loader?modules" }, ] }};
上記のコードのキー行は style-loader!css-loader?modules で、css-loader の後にクエリ パラメータ module を追加し、CSS モジュールを開くことを示します。関数。
次に、デモを実行します。
$ npm run demo01
http://localhost:8080 を開くと結果が表示され、h1 タイトルが赤色で表示されます。
CSS モジュールでは、:global(.className) 構文を使用してグローバル ルールを宣言できます。この方法で宣言されたクラスは、ハッシュ文字列にコンパイルされません。
App.css にグローバル クラスを追加します。
.title { color: red;}:global(.title) { color: green;}
App.jsは通常のクラス記述方法を使用しており、グローバルクラスを参照します。
import React from 'react';import styles from './App.css';export default () => { return ( <h1 className="title"> Hello World </h1> );};
この例を実行します。
$ npm run demo02
http://localhost:8080 を開くと、h1 ヘッダーが緑色で表示されるはずです。
CSS モジュールは、明示的なローカル スコープ構文 local(.className) も提供します。これは .className と同等であるため、上記の App.css は次のように記述することもできます。
:local(.title) { color: red;}:global(.title) { color: green;}
css-loader のデフォルトのハッシュ アルゴリズムは [hash:base64] で、.title を文字列にコンパイルします。 ._3zyde4l1yATCOkgn-DBWEL のように。
ハッシュ文字列の形式は webpack.config.js でカスタマイズできます。
module: { loaders: [ // ... { test: /\.css$/, loader: "style-loader!css-loader?modules&localIdentName=[path][name]---[local]---[hash:base64:5]" }, ]}
この例を実行します。
$ npm run demo03
.title が、demo03-components-App---title---GpMto にコンパイルされていることがわかります。
CSS モジュールでは、セレクターは別のセレクターのルールを継承できます。これを「合成」と呼びます。
App.css で、 .title に .className を継承させます。
.className { background-color: blue;}.title { composes: className; color: red;}
App.js を変更する必要はありません。
import React from 'react';import style from './App.css';export default () => { return ( <h1 className={style.title}> Hello World </h1> );};
この例を実行します。
$ npm run demo04
http://localhost:8080 を開くと、青い背景に赤い h1 が表示されます。
App.css は以下のコードにコンパイルされます。
._2DHwuiHWMnKTOYG45T0x34 { color: red;}._10B-buq6_BEOTOl9urIjf8 { background-color: blue;}
同様に、 h1 クラスも
セレクターは他の CSS ファイルのルールを継承することもできます。
another.css
.className { background-color: blue;}
App.css は、another.css のルールを継承できます。
.title { composes: className from './another.css'; color: red;}
运行这个示例。
$ npm run demo05
打开 http://localhost:8080 ,会 看到 蓝色的背景上有一个红色的 h1 。
CSS Modules 支持使用变量,不过需要安装 PostCSS 和 postcss-modules-values 。
$ npm install --save postcss-loader postcss-modules-values
把 postcss-loader 加入 webpack.config.js 。
var values = require('postcss-modules-values');module.exports = { entry: __dirname + '/index.js', output: { publicPath: '/', filename: './bundle.js' }, module: { loaders: [ { test: /\.jsx?$/, exclude: /node_modules/, loader: 'babel', query: { presets: ['es2015', 'stage-0', 'react'] } }, { test: /\.css$/, loader: "style-loader!css-loader?modules!postcss-loader" }, ] }, postcss: [ values ]};
接着,在 colors.css 里面定义变量。
@value blue: #0c77f8;@value red: #ff0000;@value green: #aaf200;
App.css 可以引用这些变量。
@value colors: "./colors.css";@value blue, red, green from colors;.title { color: red; background-color: blue;}
运行这个示例。
$ npm run demo06
打开 http://localhost:8080 ,会 看到 蓝色的背景上有一个红色的 h1 。
(完)