subsetcssでcssの値の制限をする(例えばfont-sizeの値を13px、16pxに設定するとそれ以外の値はエラーにしてくれる)

みなさん、大人数での開発でCSSの一貫性を保つのに苦労していませんか？
この問題を軽減する一つの選択肢として、今回は`subsetcss`というライブラリを紹介します！

# subsetcss

## 公式 ： [knownasilya/subsetcss - github](https://github.com/knownasilya/subsetcss)

- **※2019/05/07現在では v0.1.4 が最新**
 - https://github.com/knownasilya/subsetcss/releases

自分でCSSの値を定義し、その値のみに制限できます。

### install

公式にある通りインストール

```bash:bash
yarn init -y
yarn add -D subsetcss stylelint
#または、
npm init -y
npm i -D subsetcss stylelint
```

### Setup

公式にある通りセットアップ

`stylelint`のプラグインで`subsetcss`を使用します。

```json:.stylelintrc
{
  "plugins": [
    "subsetcss"
  ],
  "rules": {
    "subsetcss/config": "./.subsetcss.js"
  }
}
```

```js:.subsetcss.js
module.exports = {
    'subsets': {
        'font-size': [
            '.75rem',
            '.875rem',
            '1rem',
            '1.125rem',
            '1.25rem',
            '1.5rem',
            '1.875rem',
            '2.25rem',
            '3rem',
        ],
        'border-width': [
            '0',
            '1px',
            '2px',
            '3px'
        ],
        'border-color': [
            'transparent',
            '#22292f',
            '#3d4852',
            '#606f7b',
            '#8795a1',
            '#b8c2cc'
        ],
        'border-style': ['solid'],
        '@media': {
            'params': {
                'max-width': ['400px', '768px'],
            },
            'subsets': {
                'font-size': [
                    '1rem',
                    '1.125rem',
                    '1.25rem',
                    '1.5rem',
                    '1.875rem'
                ]
            }
        }
    }
};
```

### 実行

```src/css/style.css
.sample1 {
    font-size: 3rem;
}

.sample2 {
    border-width: 5px;
}

.sample3 {
    border-color: #fff;
}
```

```bash:bash
yarn stylelint "src/css/*.css"
#または、
npx stylelint "src/css/*.css"
```

![Screen Shot 2019-06-07 at 23.15.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142910/050c9422-4e45-48e0-9160-f05f22127d21.png)

このように、`.subsetcss.js`で指定されていない値をエラーにしてくれます。
とっても簡単ですね！

---

# オマケ

stylelintを使う際は、gulpやwebpackから実行することが多いと思います。自分用にwebpackでstylelintを動かすサンプルを作成してみました。
**↓ここからは私の備忘録です。読まなくても問題ありません。**

## 1 webpackで試してみた

【[自分で試してみたサンプル](https://github.com/okumurakengo/subsetcss-sample/tree/master/webpack-sample)】

```bash:bash
yarn init -y
yarn add -D subsetcss stylelint stylelint-webpack-plugin webpack webpack-cli style-loader css-loader
#または、
npm init -y
npm i -D subsetcss stylelint stylelint-webpack-plugin webpack webpack-cli style-loader css-loader
```

```src/index.js
import "./css/style.css";
```

```webpack.config.js
const StyleLintPlugin = require("stylelint-webpack-plugin");

module.exports = {
    mode: "development",
    module: {
        rules: [{
            test: /\.css/,
            use: [
                "style-loader",
                "css-loader",
            ],
        }]
    },
    plugins: [
        new StyleLintPlugin({
            configFile: `${__dirname}/.stylelintrc`,
            context: `${__dirname}/src/css`,
            files: "**/*.css",
        }),
    ],
};
```

`stylelint-webpack-plugin`は[こちら](https://github.com/webpack-contrib/stylelint-webpack-plugin)を参考に設定しました。間違いなどありましたら指摘お願いしますm(_ _)m

- `configFile`:stylelintの設定ファイルの場所

- `context`:ルートディレクトリ

- `files`:ファイルを見つけるためのglobパターン

**※`.stylelintrc`と`.subsetcss.js`は先ほどと同じです**

これでwebpackから動かせますので試してみます。

![OL50KpYCYm.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142910/058bbb32-7b71-ea3c-3870-ae9af236b6d2.gif)

webpackで、設定していない値をエラーで見ることができました。

## 2 webpack + Sass で試してみた

【[自分で試してみたサンプル](https://github.com/okumurakengo/subsetcss-sample/tree/master/webpack-sass-sample1)】

`sass-loader`と`node-sass`が新たに必要になります。

```bash:bash
yarn init -y
yarn add -D subsetcss stylelint stylelint-webpack-plugin webpack webpack-cli style-loader css-loader sass-loader node-sass
#または、
npm init -y
npm i -D subsetcss stylelint stylelint-webpack-plugin webpack webpack-cli style-loader css-loader sass-loader node-sass
```

```src/index.js
import "./scss/style.scss";
```

```src/scss/style.scss
.sample1 {
    font-size: 3rem;

    .sample2 {
        border-width: 5px;

        .sample3 {
            border-color: #fff;
        }
    }
}
```

```webpack.config.js
const StyleLintPlugin = require("stylelint-webpack-plugin");

module.exports = {
    mode: "development",
    module: {
        rules: [{
            test: /\.scss/,
            use: [
                "style-loader",
                "css-loader",
                "sass-loader",
            ],
        }]
    },
    plugins: [
        new StyleLintPlugin({
            configFile: `${__dirname}/.stylelintrc`,
            context: `${__dirname}/src/scss`,
            files: "**/*.scss",
        }),
    ],
};
```

![Screen Shot 2019-06-08 at 0.59.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142910/8f04318f-1af0-f136-2964-80cec4c29895.png)

sassを使っても特に問題なく使えました

### 2-1 webpack + sass で cssファイルで出力するようにする

【[自分で試してみたサンプル](https://github.com/okumurakengo/subsetcss-sample/tree/master/webpack-sass-sample2)】

先ほどまで`index.js`ファイルをバンドルしていましたが、
`index.js`をなくし、`style.scss`ファイルをwebpackの起点となるファイルに設定、cssファイルで出力するように設定してみます。

`extract-text-webpack-plugin`を使用して、cssファイルで出力するようにします

```bash:bash
yarn init -y
yarn add -D subsetcss stylelint stylelint-webpack-plugin webpack webpack-cli css-loader sass-loader node-sass extract-text-webpack-plugin@next
#または、
npm init -y
npm i -D subsetcss stylelint stylelint-webpack-plugin webpack webpack-cli css-loader sass-loader node-sass extract-text-webpack-plugin@next
```

↑ webpack 4だと、`extract-text-webpack-plugin` がうまく動かないため、
`extract-text-webpack-plugin@next` をインストールするようにしましょう。 ※2019/05/07現在

```webpack.config.js
const ExtractTextPlugin = require("extract-text-webpack-plugin");
const StyleLintPlugin = require("stylelint-webpack-plugin");

module.exports = {
    mode: "development",
    entry: "./src/scss/style.scss",
    output: {
        path: `${__dirname}/dist`,
        filename: "[name].css", // 生成するjsファイル名
    },
    module: {
        rules: [{
            test: /\.scss/,
            use: ExtractTextPlugin.extract({
                use: [
                    "css-loader",
                    "sass-loader",
                ],
            }),
        }]
    },
    plugins: [
        // cssファイルを生成されたjsファイルと同じ名前にし上書きする
        //  -> cssファイルのみ出力という結果になる
        new ExtractTextPlugin("[name].css"),

        new StyleLintPlugin({
            configFile: `${__dirname}/.stylelintrc`,
            context: `${__dirname}/src/scss`,
            files: "**/*.scss",
        }),
    ],
};
```

![Screen Shot 2019-06-08 at 1.26.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142910/25ab8643-a9c0-a2e8-2ed7-bca64dc6e34c.png)


scssファイルからcssを出力し、かつsubsetcssでエラーを出すこともできました。

---

最後まで読んでいただいてありがとうございました。m(_ _)m