metalsmith-sass で Sass で書かれたスタイルシートをコンパイルできます。この記事では、metalsmith-sass の基本的な使い方に加えて、node-sass の拡張モジュールをインストールして、SVG 画像をインライン展開する方法を紹介します。

インストール&設定

例によって npm でインストールします。

$ npm install metalsmith-sass --save
...
└─┬ metalsmith-sass@1.5.1
...
$

以下では、src/sass/style.scss をエントリーポイントとしてコンパイルし、build/css/style.css を出力すると想定します。

  • build/
    • css/
      • style.css
  • src/
    • posts/
    • sass/
      • _normalize.scss
      • style.scss

index.js は 次のようになります。ソースマップはお好みで指定してください。


const sass = require('metalsmith-sass');

Metalsmith(__dirname)

  ...

  .use(sass({
    outputDir: 'css/',
    sourceMap: false,
    sourceMapContents: false
  }))

  ...

以上で終わりです。

SVG を CSS の中でインライン展開する

最近は SVG 画像の素材も充実してきて、コンパクトな SVG 画像を CSS の中でインライン展開して利用することが増えました。残念ながら、本来の Sass では base64 でエンコードしたものを手作業で埋め込んでいくしかなく、結構大変です。

metalsmith-sass は内部で node-sass を使用しており、node-sass には独自の関数を宣言して Sass 内で利用する機能があります。sass-inline-svg はこの独自関数を定義した拡張モジュールの一つで、SVG ファイルを読み込んで、インライン展開してくれるモジュールです。

$ npm install sass-inline-svg --save
...
└─┬ sass-inline-svg@1.1.0
...
$

例えば、次のような SVG ファイルを用意し、Sass コンパイル時に読み込んでインライン展開したいとします。。

  • src/
    • posts/
    • sass/
      • style.scss
    • svg/
      • down-arrow.svg

index.js は以下のようになります。inliner の引数は SVG ファイルが格納されているディレクトリへのパスです。


const sass = require('metalsmith-sass');
const inliner = require('sass-inline-svg');

Metalsmith(__dirname)

  ...

  .use(sass({
    outputDir: 'css/',
    sourceMap: false,
    sourceMapContents: false,
    functions: {
      'inline-svg': inliner('./src/svg')
    }
  }))

  ...

これで、関数 inline-svg が使用できるようになりました。Sass 内では、次のように書けます。


.some-class {
  ...
  background-image: inline-svg('down-arrow.svg');
  ...
}

これがコンパイルされると、インライン展開されて次のようになります。


.some-class {
  ...
  background-image: url("data:image/svg+xml;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDUxMiA1MTIiIHhtbDpzcGFjZT0icHJlc2VydmUiPgo8cGF0aCBmaWxsPSIjRkZGRkZGIiBkPSJNMjU2LDcuOUMxMTksNy45LDcuOSwxMTksNy45LDI1NlMxMTksNTA0LjEsMjU2LDUwNC4xczI0OC4xLTExMS4xLDI0OC4xLTI0OC4xUzM5Myw3LjksMjU2LDcuOXpNMzk2LjksMjM4LjdDMzU5LjMsMjc2LjMsMzIxLjcsMzEzLjksMjg0LjEsMzUxLjVjLTExLjIsMTEuMy0zMC4xMDEsMTEuNi00MS41LDAuMTk5QzIwNSwzMTQuMSwxNjcuNCwyNzYuNSwxMjkuOCwyMzguOUMxMDIuOSwyMTIsMTQ0LjMsMTcwLjMsMTcxLjEsMTk3LjFjMzAuNjk5LDMwLjcsNjEuMzk5LDYxLjQsOTIuMSw5Mi4xMDFjMzAuNy0zMC42MDEsNjEuMy02MS4zMDEsOTEuOS05MS45QzM4MS45LDE3MC40LDQyMy41OTksMjExLjgsMzk2LjksMjM4Ljd6Ii8+PC9zdmc+");
  ...
}

これは捗りますね。