LoginSignup
5
5

More than 5 years have passed since last update.

MojoliciousでSassを使ってみた

Last updated at Posted at 2016-02-22

MojoliciousでSassを使う

今MojoliciousでCGIゲームの三国志NETの改造版だったものをぼちぼち作りなおしているんですが、css書いている時にやっぱりSass使いたいなー、と思って色々調べてみました。
環境
Ubuntu 14.04
perl 5.22.2
Mojolicious 7.00
Mojolicious::Plugin::AssetPack 1.17
CSS::Sass 3.3.0

どんなモジュールがあるか

早くMojoliciousでSassを使う方法を知りたい人はここは飛ばした方がいいです。

CPANやgithubを軽く調べた感じだと、MojoliciousでSassを使うには以下のモジュールが
・Mojolicious::Plugin::AssetPack
・Mojolicious::Plugin::Sass
・Mojolicious::Plugin::SassRenderer
更にPlackのモジュールが
・Plack::Middleware::File::Sass

Mojolicious::Plugin::AssetPack

唯一今でも活発に開発&メンテが続いているモジュールでした。
仕組みとしては CSS::Sass もしくはRubyのgemからSassをインストールしたものを使ってコンパイルしているようです。
別ファイルに記述したSassファイルをサーバー立ち上げ時にコンパイルする、といったプラグインのようです。
ちなみにこのプラグインでCoffeeScriptやlessなども使えるそうです。

Mojolicious::Plugin::Sass

Text::Sassをつかって、テンプレートの中に記述したSassをコンパイルするプラグインのようです。
しかし別ファイルに記述したSassファイルはコンパイルしてくれませんし、何よりも Text::Sass はSassの実装がちゃんとできていないのでSassの機能のいくつかが使用できません。(import,extendが使えないなど...)

Mojolicious::Plugin::SassRenderer

5年近く更新されていませんでした。また、これもText::Sassを使っているのでボツですね...

Plack::Middleware::File::Sass

これも何年も更新されてなく、Text::Sassを使っていてますし、そもそも僕はPlackで立ち上げていないのでボツですね...

というわけで、各モジュールを調べた結果Mojolicious::Plugin::AssetPack一択となりました。
ですがMojolicious::Plugin::AssetPackではちょっとテンプレートの中にSassを記述したい時などには使えないようなので、テンプレートの中でSassを記述するプラグインは別途自作してしまうことにしました。

1.別ファイルにSassを記述するとき→Mojolicious::Plugin::AssetPackを使う

1.CSS::Sass、Mojolicious::Plugin::AssetPackをインストールする

cpanm CSS::Sass
cpanm Mojolicious::Plugin::AssetPack

でCSS::Sass、Mojolicious::Plugin::AssetPackをインストール。
ちなみに僕の環境ではMojolicious::Plugin::AssetPackのインストール時にテストにこけてインストールに失敗したので、--forceオプションをつけてインストールしなおしました。

2.基本的な使い方

※Sassファイルはプロジェクトディレクトリ内のassetsディレクトリ内に置きます。

/lib/Myapp.pm
$self->plugin('AssetPack' => {pipes => [qw/Css Sass/]});
$self->asset->process('base.css' => ('scss/base.scss'));
テンプレート側
%= asset 'base.css'

これでサーバーを立ち上げるたびに(変更があれば)別ファイルに記述したsassファイルをコンパイルし、できたcssファイルを読み込んでくれるようになります。

他にも色々できます、詳しくはドキュメントを読むべし!

2.テンプレートの中に直接Sassを記述したい場合→CSS::Sassを使った自作プラグインで

なかなかいい感じの Mojolicious::Plugin::AssetPack ですが、テンプレートの中に直接記述したSassの面倒までは見てくれません。
他のSass関係のモジュールは未完成の Text::Sass を使用しているため満足に記述できません。
なので CSS::Sass を使って簡単にテンプレートの中のSassコードをコンパイルしてくれるプラグインを作ってみました。
コードはこんなかんじです:

InnerSass.pm
package Mojolicious::Plugin::InnerSass {

  use Mojo::Base 'Mojolicious::Plugin'; # Mojolicious::Plugin を継承

  use Mojo::Cache; # キャッシュに使用
  use CSS::Sass; # Sass,Scssコンパイラ

  has 'sass' => sub { CSS::Sass->new( output_style => CSS::Sass::SASS_STYLE_EXPANDED() ) };
  has 'cache' => sub { Mojo::Cache->new(max_keys => 200) };

  sub register {
    my ($self, $app, $conf) = @_;

    $app->helper(sass_to_css => sub {
      my ($c, $sass, $conf) = @_;
      my $route = $c->current_route();
      my $cache = $self->cache->get($route) // '';
      if ($cache) {
        $app->log->debug('Loading sass data...');
        return $cache;
      } else {
        my $compile_sass = $self->sass->compile($sass);
        $self->cache->set($route => $compile_sass) if $conf;
        return $compile_sass;
      }
    });
  }

}
1;
テンプレート側
%= stylesheet begin
<% my $sass = ' # sassコードを変数に格納

$red:'.$config->{'color'}{'red'}.';  

.red {  
  color: $red;  
}  

'; %>
%== sass_to_css($sass, 1); #sassコードをcssに変換、キャッシュする、返却値はXMLエスケープせずに出力
%= end

プラグインのファイルは/lib/Mojolicious/Pluginに置いて、あとは Myapp.pm で読みこめばテンプレートでSass,Scssが記述できるようになります。
一度コンパイルしたものはメモリに保存しているので、初回以外は処理時間がかかるということもありません。
まあ処理時間がかなりかかるほど大きいコードなら別ファイルに分けた方がいいですし、主に開発時に使用する用のプラグインになりますが。
テンプレート側の記述もちょっと気持ち悪いですけど、個人で使う分だしこんなもんでいいかなあと。

5
5
1

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
5
5