UNPKG

css-pipeline

Version:

roots extension for handling css production builds

182 lines (154 loc) 5.06 kB
// Generated by CoffeeScript 1.7.0 (function() { var CleanCSS, RootsUtil, crypto, fs, minimatch, path, yaml, _; fs = require('fs'); path = require('path'); _ = require('lodash'); minimatch = require('minimatch'); CleanCSS = require('clean-css'); crypto = require('crypto'); RootsUtil = require('roots-util'); yaml = require('js-yaml'); module.exports = function(opts) { var CSSPipeline; opts = _.defaults(opts, { files: 'assets/css/**', manifest: false, out: false, minify: false, hash: false, opts: {} }); opts.files = Array.prototype.concat(opts.files); return CSSPipeline = (function() { /** * Sets up the custom category and view function. * The view function grabs either the single output path or collects * all non-ignored output paths for the input files and returns them * as html link tags. * * @param {Function} @roots - Roots class instance */ var get_output_paths, load_manifest_file; function CSSPipeline(roots) { var _base; this.roots = roots; this.category = 'css-pipeline'; this.file_map = {}; this.util = new RootsUtil(this.roots); if (opts.manifest) { this.roots.config.ignores.push(opts.manifest); opts.manifest = load_manifest_file.call(this, opts.manifest); } this.files = opts.manifest || opts.files; if ((_base = this.roots.config).locals == null) { _base.locals = {}; } this.roots.config.locals.css = (function(_this) { return function() { var matcher, paths, _i, _len, _ref; paths = []; if (opts.out) { paths.push(opts.out); } else { _ref = _this.files; for (_i = 0, _len = _ref.length; _i < _len; _i++) { matcher = _ref[_i]; paths = paths.concat(get_output_paths.call(_this, matcher)); } } return paths.map(function(p) { return "<link rel='stylesheet' href='" + p + "' />"; }).join("\n"); }; })(this); } /** * Minimatch runs against each path, quick and easy. */ CSSPipeline.prototype.fs = function() { return { extract: true, detect: (function(_this) { return function(f) { return _.any(_this.files, minimatch.bind(_this, f.relative)); }; })(this) }; }; /** * After compile, if concat is happening, grab the contents and save them * away, then prevent write. */ CSSPipeline.prototype.compile_hooks = function() { return { write: function() { return !opts.out; }, after_file: (function(_this) { return function(ctx) { if (opts.out) { return _this.file_map[ctx.file.relative] = ctx.content; } }; })(this) }; }; /** * Write the output file if necessary. */ CSSPipeline.prototype.category_hooks = function() { return { after: (function(_this) { return function(ctx) { var all_contents, content, file, hash, matcher, res, _i, _len, _ref, _ref1; if (!opts.out) { return; } all_contents = ''; _ref = _this.files; for (_i = 0, _len = _ref.length; _i < _len; _i++) { matcher = _ref[_i]; _ref1 = _this.file_map; for (file in _ref1) { content = _ref1[file]; if (minimatch(file, matcher)) { all_contents += content; } } } if (opts.minify) { all_contents = (new CleanCSS(opts.opts)).minify(all_contents); } if (opts.hash) { hash = crypto.createHash('md5').update(all_contents, 'utf8'); res = opts.out.split('.'); res.splice(-1, 0, hash.digest('hex')); opts.out = res.join('.'); } return _this.util.write(opts.out, all_contents); }; })(this) }; }; /** * @private */ load_manifest_file = function(f) { var res; res = yaml.safeLoad(fs.readFileSync(path.join(this.roots.root, f), 'utf8')); return res.map(function(m) { return path.join(path.dirname(f), m); }); }; get_output_paths = function(files) { return this.util.files(files).map((function(_this) { return function(f) { return path.sep + _this.util.output_path(f.relative, 'css').relative; }; })(this)); }; return CSSPipeline; })(); }; }).call(this);