LoginSignup
10
9

More than 5 years have passed since last update.

npmのみでSassのstylelint 〜webpackとPostCSS不要編〜

Last updated at Posted at 2018-03-02

2回目の投稿です。優しくしてください。

前回の投稿ではwebpack3について書きましたが、今回はその中で使用していた stylelint について掘り下げていきます。
最近リリースされたばかりのwebpack4ではなく、あえてstylelint。

なぜstylelintなのか。
前回の投稿ではstylelintをあまり理解せず良さを出しきれていなかったこと、
webpack?PostCSS?という人でも簡単に導入できるので、積極的に取り入れてほしいという思いから。

そもそもstylelintってなに?

CSSがコーディング規約に準拠しているかどうか機械的に検知するためのnpm製ツール。
設定ルールを元にリンティングしてくれます。
定義されているルールはおよそ160以上。
パーサーとしてPostCSSが使えるため、もともとPostCSSを取り入れている場合は速やかに導入が可能。
今回はPostCSSを使わずstylelintのみで構築します。

:star: stylelint 公式サイト

導入するメリット

  • コードスタイルの一貫性を保つことができる
    誰でも嫌でもコーディング規約に準拠したコードを書くことができます。
    可読性・品質が向上することにより、保守性がぐんと増します。
  • 潜在的エラーや非推奨パターンを見分けられる
    無効な構文、非推奨プロパティ、宣言の重複等、エラーを検知することが可能です。
  • 手間を省くことができる
    設定ファイルを元に違反しているスタイルを自動修正してくれます。
    ※ 現在では一部ルールにのみ適用。
  • レビュー負担軽減
    コーディング規約に準拠しているか血眼になってチェックする時間と手間が省けます。

やりたいこと

  • CSSやSass独自の構文、スタイルをチェック
  • ブロック内コンテンツやプロパティの順序をチェック
  • スタイル違反を自動修正

必要なプラグインをインストール

yarnの場合は npm iyarn add に読み替えてください。


$ npm i stylelint stylelint-scss stylelint-order

ディレクトリ階層


┃
┣━ sass
┃   ┣━ common
┃   ┃   ┣━ common.scss
┃   ┃   ┣━ _parts.scss
┃   ┃   ...
┃   ┃
┃   ┣━ main
┃   ┃   ┣━ main.scss
┃   ┃   ┣━ _parts.scss
┃   ┃   ...
┃   ┃
┃   ┣━ sub
┃   ┃   ┣━ sub.scss
┃   ┃   ┣━ _parts.scss
┃   ┃   ...
┃   ┃
┃   ...
┃
┣━ package.json
┗━ .stylelintrc.json

設定ファイルについて

package.json

npmプラグインを管理するための設定ファイルです。
stylelintを実行するためのエイリアスコマンドを "scripts" に設定します。
オプションに --fix を付与することで自動修正をしてくれます。

package.json
{
  "name": "hello-webpack",
  "version": "1.0.0",
  "description": "",
  "scripts": {
    "stylelint": "stylelint \"sass/**/*.scss\" --fix",
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "stylelint": "^9.1.1",
    "stylelint-order": "^0.8.1",
    "stylelint-scss": "^2.4.0",
  }
}

.stylelintrc.json

リンターの設定ファイルです。

  • ignoreFiles
    無視したいファイルを設定できます。
  • syntax
    今回はSCSSファイルをチェックするので scss を設定します。
    PostCSSを使っている場合は、syntaxを設定しないと // comment が /*comment*/ にされてしまうので注意。
  • plugins
    • stylelint-scss ( scss/Rule... )
      SCSS独自の構文ルールを追加。
    • stylelint-order ( order/Options... )
      スタイル順序を設定。
  • rules
    設定したいルールを指定します。
    ルールの詳細については公式サイトをご参照ください。
.stylelintrc.json
{
  "ignoreFiles": [
    "sass/common/*.scss"
  ],

  "syntax": "scss",

  "plugins": [
    "stylelint-scss",
    "stylelint-order"
  ],

  "rules": {
    "color-no-invalid-hex": true,
    "color-hex-case": "lower",
    "color-hex-length": "short",

    "font-family-name-quotes": "always-where-recommended",
    "font-family-no-duplicate-names": true,

    "function-calc-no-unspaced-operator": true,
    "function-comma-space-after": "always-single-line",
    "function-comma-space-before": "never",
    "function-max-empty-lines": 0,
    "function-name-case": [
      "lower",
      {
        "ignoreFunctions": [
          "DXImageTransform.Microsoft.gradient",
          "Alpha"
        ]
      }
    ],
    "function-parentheses-space-inside": "always",
    "function-url-quotes": "always",
    "function-whitespace-after": "always",

    "number-leading-zero": "never",
    "number-no-trailing-zeros": true,

    "string-no-newline": true,
    "string-quotes": "double",

    "length-zero-no-unit": true,

    "unit-case": "lower",
    "unit-no-unknown": true,

    "shorthand-property-no-redundant-values": true,

    "value-keyword-case": "lower",
    "value-list-comma-newline-after": "always-multi-line",
    "value-list-comma-space-after": "always-single-line",
    "value-list-comma-space-before": "never",
    "value-list-max-empty-lines": 0,

    "property-case": "lower",
    "property-no-unknown": true,

    "declaration-bang-space-after": "never",
    "declaration-bang-space-before": "always",
    "declaration-block-no-duplicate-properties": [
      true,
      {
        "ignore": [
          "consecutive-duplicates"
        ]
      }
    ],
    "declaration-block-no-redundant-longhand-properties": true,
    "declaration-block-no-shorthand-property-overrides": true,
    "declaration-block-semicolon-newline-after": "always",
    "declaration-block-semicolon-space-after": "always-single-line",
    "declaration-block-semicolon-space-before": "never",
    "declaration-block-single-line-max-declarations": 1,
    "declaration-block-trailing-semicolon": "always",
    "declaration-colon-space-after": "always",
    "declaration-colon-space-before": "never",

    "block-closing-brace-empty-line-before": "never",
    "block-closing-brace-newline-before": "always-multi-line",
    "block-no-empty": true,
    "block-opening-brace-space-before": "always",

    "selector-attribute-brackets-space-inside": "never",
    "selector-attribute-operator-space-after": "never",
    "selector-attribute-operator-space-before": "never",
    "selector-attribute-quotes": "always",
    "selector-combinator-space-after": "always",
    "selector-combinator-space-before": "always",
    "selector-descendant-combinator-no-non-space": true,
    "selector-list-comma-newline-after": "always",
    "selector-list-comma-newline-before": "never-multi-line",
    "selector-list-comma-space-before": "never",
    "selector-max-empty-lines": 1,
    "selector-pseudo-class-case": "lower",
    "selector-pseudo-class-parentheses-space-inside": "never",
    "selector-pseudo-element-case": "lower",
    "selector-pseudo-element-colon-notation": "single",
    "selector-type-case": "lower",

    "media-feature-colon-space-after": "always",
    "media-feature-colon-space-before": "never",
    "media-feature-name-case": "lower",
    "media-feature-parentheses-space-inside": "always",
    "media-feature-range-operator-space-after": "always",
    "media-feature-range-operator-space-before": "always",

    "media-query-list-comma-newline-after": "always-multi-line",
    "media-query-list-comma-newline-before": "never-multi-line",
    "media-query-list-comma-space-after": "always-single-line",
    "media-query-list-comma-space-before": "never",

    "at-rule-name-case": "lower",
    "at-rule-name-newline-after": "always-multi-line",
    "at-rule-name-space-after": "always-single-line",
    "at-rule-semicolon-newline-after": "always",

    "indentation": 2,
    "max-empty-lines": 2,
    "no-eol-whitespace": true,
    "no-extra-semicolons": true,
    "no-missing-end-of-source-newline": true,


    "scss/at-if-closing-brace-newline-after": "always-last-in-chain",
    "scss/at-mixin-parentheses-space-before": "never",
    "scss/dollar-variable-colon-space-after": "always",
    "scss/dollar-variable-colon-space-before": "never",


    "order/order": [
      "dollar-variables",
      "custom-properties",
      {
    type: 'at-rule',
    name: ' extend'
      },
      {
    type: 'at-rule',
    name: 'include'
      },
      "declarations",
      "at-variables",
      {
    type: 'at-rule',
    name: 'media',
    hasBlock: true
      },
      "rules"
    ],

    "order/properties-order": [
      "position",
      "width",  
      "margin",
      "font-size",
      "border",
      "content",
      "animation"
      ... omit ...
    ]
  }
}

stylelint実行

npm
$ npm run stylelint
yarn
$ yarn stylelint

before
.sample {
  @media #{$sp} {
    display: none;
  }
  span {
    font-size: 1.0rem;
  }
  @include box-shadow;
  width: 30.0rem;
  font-size: 0.8rem;
  $color: #fff;
  background: $color;
  position: relative;
  @extend %reset-box;
}
after
.sample {
  $color: #fff;
  @extend %reset-box;
  @include box-shadow;
  position: relative;
  width: 30rem;
  font-size: .8rem;
  background: $color;
  @media #{$sp} {
    display: none;
  }
  span {
    font-size: 1rem;
  }
}

:sparkles:

10
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
9