CSSフレームワークもやればできる子(改訂版)

前のエントリ でやったほうほうだと、@import のパスを解決したりするのが面倒だったり、 複数ファイルで同じファイルを @import でマクロとして使うようにすると、コンパイル結果のファイルに重複定義が現れたり、、、ということで余り案配がよろしくないのです。

というわけで、少し改訂しました。

/**
 * addCssMacroFeature.js
 * Extends connect compiler middleware to support CSS framework
 */
var fs = require('fs');
var macros = [];
module.exports = function(filePath){
  macros.push(fs.readFileSync(filePath) + "\n");
}
// extend connect compiler
var compilers = require('connect/middleware/compiler').compilers;
['sass', 'less'].forEach(function(key){
  var compiler = compilers[key];
  var org = compiler.compile;
  compiler.compile = function(str, fn){
    // add the macro
    var macro = macros.join('');
    org(macro, function(err, mcompiled){
      if(err){
        console.error("macro compile failed " + err);
        fn(err);
      }else{
        org(macro + str, function(err, compiled){
          if( err ){
            console.error("concated compile failed " + err);
            fn(err);
          }else{
            fn(null, compiled.substr(mcompiled.length));
          }
        });
      }
    });
  };
});

これで、どんなフレームワークにも対応です。Expressの起動スクリプト

var addCssMacro = require('addCssMacroFeature.js');
addCssMacro('public/stylesheets/screen.css');
addCssMacro('public/stylesheets/print.css');

とやれば、screen.css, print.css に定義された .span-1 などはすべてマクロとしてコンパイラで利用することができます。マクロ部分しかコンパイル時に取り込まないので、screen.css や print.css などをリンクし忘れると余り意味がないですが。その辺の依存関係解決までやろうとすると大変ですね。