アカベコマイリ

HEAR NOTHING SEE NOTHING SAY NOTHING

Normalize.css を npm で管理して Stylus に組み込む

これまで Stylus から Normalize.css を利用する場合、以下のように管理していた。

  1. bymathias/normalize.styl から normalize.styl をダウンロード
  2. プロジェクトの src/stylus/lib フォルダ内に normalize.styl を配置
  3. Stylus のエントリー ポイントで @import "lib/normalize.styl"

つまり静的リソースとして扱い、バージョン更新があれば手動で置き換えていた。面倒な作業だが、CSS では JavaScript における npm と Browserify/webpack のようなリンカー的な仕組みが確立していないと考えており、また、更新も滅多にないことから放置していた。

しかしふと、Normalize.css のサイトをチェックしたら 公式 npm が用意されていた。また Stylus 版の最終更新をみると 11 months ago である。necolas/normalize.css だと a day ago なので、確実に最新へ追従できていない。

というわけで、以下の対応を検討することにした。

  • Normalize.css を npm で管理する
  • npm でインストールした Normalize.css を Stylus に組み込む

Normalize.css を npm で管理する

公式 npm をインストールする。

$ npm i -S normalize.css

Normalize.css は以下の階層に配置されていた。

node_modules/normalize.css/normalize.css

JavaScript の場合、Browserify などが node_modules 配下をよしなに判定してパッケージ名による import/require 処理してくれるのだが、Stylus にそのような特別措置はないので、このパスが重要になる。

Stylus に Normalize.css を組み込む

私は Stylus のコンパイルは CLI で実行している。package.json の npm-scripts 定義は以下のようになる。

{
  "scripts": {
    "build:css": "stylus -c ./src/stylus/App.styl -o ./src/bundle.css -m --sourcemap-root ./stylus",
    "watch:css": "stylus -c -w ./src/stylus/App.styl -o ./src/bundle.css -m --sourcemap-root ./stylus",
    "release:css": "stylus -c ./src/stylus/App.styl -o ./dist/bundle.css"
  }
}

App.styl を Stylus のエントリー ポイントにして、Web サイトやアプリの部位ごとに定義した .styl ファイルを @import している。前述のように Normalize.css は外部の静的リソースということで lib に配置したものを参照。

@import "lib/Normalize.css"
@import "Base.css"
@import "Header.css"

これを npm 版に変更する。

@import "../../node_modules/normalize.css/normalize.css"
@import "Base.css"
@import "Header.css"

この状態でコンパイル実行してみると、生成された bundle.css では通常の @import になってしまった。

@import "../../node_modules/normalize.css/normalize.css"

/* Base.css と Header.css の定義 */

同一または下層の .styl であれば埋め込みになるので、npm 側もそうなると考えていたのだが、違った。Executable — Stylus を読むと @import を常に埋め込みとする場合は --include-css オプションが必要とのこと。

npm-scripts を修正する。

{
  "scripts": {
    "build:css": "stylus -c --include-css ./src/stylus/App.styl -o ./src/bundle.css -m --sourcemap-root ./stylus",
    "watch:css": "stylus -c -w --include-css ./src/stylus/App.styl -o ./src/bundle.css -m --sourcemap-root ./stylus",
    "release:css": "stylus -c --include-css ./src/stylus/App.styl -o ./dist/bundle.css"
  }
}

この状態で Stylus をコンパイルしたら、npm の Nomarlize.css が埋め込まれるようになった。

/*! normalize.css v4.1.1 | MIT License | github.com/necolas/normalize.css */

/**
 * 1\. Change the default font family in all browsers (opinionated).
 * 2\. Prevent adjustments of font size after orientation changes in IE and iOS.
 */

/* ...中略  */

/* Base.css と Header.css の定義 */

Stylus 内に node_moduels のパスを書くのは抵抗あるけど、しかたない。

この方法は bootstrapmaterial-ui みたいなフレームワークの利用には不向きだが、Normalize.css みたいに単体で完結した CSS ライブラリなら機能するだろう。