Riot.js で Sass を導入して使う方法

phi phi on Riot.js, Sass

Twitter を見ていると 『Riot.js でも Sass 使いたいー!』ってのをちらほら見かけます.

Riot.js は, 標準で Less にも Sass にも対応してると思っていたんですが, ちゃんと中身を読んでみると Less にしか対応していませんでした💦 (以前ドキュメントで対応してるっての見た気がするんだけどなぁ...)

ただ, 引数で簡単に拡張できるよう良い感じに作ってくれているので, 手軽に Sass を導入できます.
なので今回は, 実際に Riot.js のパーサーに Sass を追加してコンパイルする方法を紹介したいと思います.

riot 使ってやるのか gulp-riot 使ってやるのか, プリコンパイルかランタイムコンパイルかユーザーさんによって環境が異なると思うのでそれぞれで Sass を導入する方法を紹介したいと思います.

応用すれば自作の言語なんかにも対応できて便利ですよ♪

デモ

デモです. View タブをクリックするとタグ定義部分を確認できます. 実際に style は Sass で記述し, 結果が反映されているのがわかるかと思います.

前準備: tag の style に sass を指定する

まず, コンパイル対象となるタグを定義します. 下記のようなタグをコンパイルする前提として進めます.

<app>  
  <h1>Riot.js で Sass を導入して使う方法</h1>
  <style type='sass'>
  $color: blue;
  h1 {
    color: $color;
  }
  </style>
</app>  

Sass のコンパイルを適応させたい style タグの type 属性に sass を指定しましょう.

riot でプリコンパイルする際に Sass を導入する方法

今回は node-sass を使って Sass コンパイルしたいと思います. まず下記のコマンドで node-sass をインストールします.

$ npm install --save-dev node-sass

あとは下記のような build 用のスクリプトを作ります.

var fs = require('fs');  
var riot = require('riot');  
var sass = require('node-sass');

riot.parsers.css.sass = function(tagName, css) {  
  var result = sass.renderSync({
    data: css
  });
  return result.css.toString();
};

var code = fs.readFileSync('app.tag', 'utf-8');  
var js = riot.compile(code);

// 結果は下記
fs.writeFile('app.js', js);  

app.js の出力結果は下記のようになります.

riot.tag2('app', '<h1>Riot.js で Sass を導入して使う方法</h1>', 'h1 { color: blue; }', '', function(opts) {  
});

ちゃんと color の値が blue に置換されているのがわかるかと思います.

やっていることは,

  • riot の parsers の css に sass を関数として追加
  • その関数内で渡ってきた css に sass コンパイルして返す処理を追加
  • riot で普通にコンパイル

といった感じです.

gulp-riot でプリコンパイルする際に Sass を導入する方法

これが一番よくある用途ではないでしょうか. riot でやった時同様 node-sass をインストールします. gulp-riot もついでに♪

$ npm install --save-dev node-sass
$ npm install --save-dev gulp-riot

以下 gulpfile.js です.

/*
 * gulpfile.js
 */

var gulp = require('gulp');  
var riot = require('gulp-riot');  
var sass = require('node-sass');

gulp.task('riot', function() {  
  gulp
    .src('app.tag')
    .pipe(riot({
      parsers: {
        css: {
          sass: function(tagName, css) {
            var result = sass.renderSync({
              data: css
            });
            return result.css.toString();
          },
        },
      },
    }))
    .pipe(gulp.dest('./'))
    ;
});

あとは gulp riot を実行すれば app.tag を Sass 含めコンパイルした app.js を出力してくれます.

見て分かるように gulp-riot は, parsers を簡単に追加できるよう考慮して作ってくれているので オプションに渡すだけで反映してくれます. @e-jigsaw san 流石すぎる!!

クライアントサイドでランタイムでビルドする際に Sass を導入する方法

クライアントサイドでは node-sass 使えないので代わりにに sass.js を使います. 注意点として, sass.js 最新版だと同期コンパイルする方法が分からなかったので(そもそも出来なくなってる?) sass.js の v0.6.3 を読み込んで使用しています.

<script src='https://cdn.rawgit.com/medialize/sass.js/v0.6.3/dist/sass.js'></script>  

あとは, node のときと同じように riot の parsers に追加するだけです.

riot.parsers.css.sass = function(tagName, css) {  
  var result = Sass.compile(css);
  return result;
};

var tags = riot.mount('*');  

これでランタイムでも Sass に対応したタグを作ることが出来ます!

Less の場合はどうやるのj?

Less の場合はデフォルトで parser が用意されているのでもっと手軽に導入できます.

node の場合

tag に type='less' を指定して

<style type='less'>  
  ...
</style>  

下記実行して

$npm install --save-dev less

コンパイルするだけです.

ランタイムビルドの場合

tag に type='less' を指定して

<style type='less'>  
  ...
</style>  

下記スクリプトを読み込んで

<script src='http://cdnjs.cloudflare.com/ajax/libs/less.js/2.5.3/less.min.js'></script>  

実行するだけです.

Demo

Reference